From 3f95bc6b463f629c620ba5811ca3ce53ed9c03a2 Mon Sep 17 00:00:00 2001 From: fschildt Date: Tue, 25 Nov 2025 06:21:26 +0100 Subject: add MemoryManager, enhance cmake,compile.sh --- src/common/MemoryManager.cpp | 24 ++++++++++++ src/common/MemoryManager.hpp | 23 ++++++++++++ src/games/Game.cpp | 8 ++++ src/games/Game.hpp | 5 +++ src/games/tetris/Tetris.cpp | 78 +++++++++++++++++++++------------------ src/games/tetris/Tetris.hpp | 3 -- src/main.cpp | 3 +- src/renderer/RSoftwareBackend.cpp | 16 ++++---- src/renderer/RSoftwareBackend.hpp | 2 +- src/renderer/Renderer.cpp | 18 ++++----- src/renderer/Renderer.hpp | 14 ++++--- 11 files changed, 131 insertions(+), 63 deletions(-) create mode 100644 src/common/MemoryManager.cpp create mode 100644 src/common/MemoryManager.hpp (limited to 'src') diff --git a/src/common/MemoryManager.cpp b/src/common/MemoryManager.cpp new file mode 100644 index 0000000..d4fd068 --- /dev/null +++ b/src/common/MemoryManager.cpp @@ -0,0 +1,24 @@ +#include + +std::vector MemoryManager::s_frame_string32s; + +std::u32string& +MemoryManager::GetString32(String32Id id) +{ + return s_frame_string32s[id]; +} + +String32Id +MemoryManager::EmplaceString32_Frame(std::u32string&& str) +{ + String32Id id = static_cast(s_frame_string32s.size()); + s_frame_string32s.emplace_back(str); + return id; +} + +void +MemoryManager::Clear_Frame() +{ + s_frame_string32s.clear(); +} + diff --git a/src/common/MemoryManager.hpp b/src/common/MemoryManager.hpp new file mode 100644 index 0000000..59c31d7 --- /dev/null +++ b/src/common/MemoryManager.hpp @@ -0,0 +1,23 @@ +#pragma once + +#include + +#include +#include + + +using String32Id = uint32_t; + + +class MemoryManager { +public: + static std::u32string& GetString32(String32Id id); + + static String32Id EmplaceString32_Frame(std::u32string&& str); + static void Clear_Frame(); + + +private: + static std::vector s_frame_string32s; +}; + diff --git a/src/games/Game.cpp b/src/games/Game.cpp index c403a40..7c63b4f 100644 --- a/src/games/Game.cpp +++ b/src/games/Game.cpp @@ -79,3 +79,11 @@ Game::DrawDefaultGamePausedMenu() ImGui::End(); } +Game::FrameString32 +Game::PushFrameString32(std::u32string&& str) +{ + m_frame_strings.emplace_back(str); + FrameString32 id = static_cast(m_frame_strings.size()-1); + return id; +} + diff --git a/src/games/Game.hpp b/src/games/Game.hpp index aad3c1b..e9eed82 100644 --- a/src/games/Game.hpp +++ b/src/games/Game.hpp @@ -34,6 +34,9 @@ public: z_text }; + using FrameString32 = uint32_t; + + static std::unique_ptr Select(GameType type); @@ -47,10 +50,12 @@ protected: void DrawDefaultGamePausedMenu(); float ProcessDt(); + uint32_t PushFrameString32(std::u32string&& str); GameStatus m_game_status {game_starting}; float m_dt_remaining_seconds {0.0f}; uint64_t m_tlast_milliseconds {SDL_GetTicks()}; + std::vector m_frame_strings; protected: diff --git a/src/games/tetris/Tetris.cpp b/src/games/tetris/Tetris.cpp index ecc2c3a..8db772f 100644 --- a/src/games/tetris/Tetris.cpp +++ b/src/games/tetris/Tetris.cpp @@ -2,6 +2,7 @@ #include #include #include +#include #include #include @@ -51,7 +52,7 @@ Tetris::Start() bool Tetris::Update(std::vector& events) { - m_frame_arena.Reset(); + m_frame_strings.clear(); if (m_game_status == game_starting) { Start(); @@ -270,21 +271,25 @@ Tetris::DrawGameOverMenu() void Tetris::DrawLineCounter() { - std::u32string& text = m_frame_arena.Allocate(U"Lines: xxx"); V2F32 pos = {0.5f, 2.6f}; Color color = {0.9f, 0.9f, 0.9f, 1.0f}; + + String32Id str_id = MemoryManager::EmplaceString32_Frame(U"Lines: xxx"); + std::u32string& str = MemoryManager::GetString32(str_id); int line_count = std::min(m_line_counter, 999); - text[9] = U'0' + char32_t(line_count % 10); + str[9] = U'0' + char32_t(line_count % 10); line_count /= 10; - text[8] = U'0' + char32_t(line_count % 10); + + str[8] = U'0' + char32_t(line_count % 10); line_count /= 10; - text[7] = U'0' + char32_t(line_count % 10); + + str[7] = U'0' + char32_t(line_count % 10); line_count /= 10; - g_renderer.PushText(text, m_font, pos, color, z_text); + g_renderer.PushString32(str_id, m_font, pos, color, z_text); pos.x += 0.2f; } @@ -294,9 +299,9 @@ Tetris::DrawStatistics() V2F32 pos = {0.4f, 0.5f}; - std::u32string& title_text = m_frame_arena.Allocate(U"Statistics"); + String32Id title_text = MemoryManager::EmplaceString32_Frame(U"Statistics"); V2F32 title_pos = {pos.x + 0.02f, pos.y + 1.64f}; - g_renderer.PushText(title_text, m_font, title_pos, s_text_color, z_text); + g_renderer.PushString32(title_text, m_font, title_pos, s_text_color, z_text); float yadvance = -0.2f; float tetrominoes_x0 = pos.x; @@ -331,27 +336,28 @@ Tetris::DrawStatistics() float counters_y0 = pos.y + 0.05f - yadvance * (float)Tetromino::id_count; V2F32 counters_pos = {counters_x0, counters_y0}; - std::u32string& t_count = m_frame_arena.Allocate(int32_to_u32string(m_tetromino_counters[Tetromino::t_piece])); - std::u32string& j_count = m_frame_arena.Allocate(int32_to_u32string(m_tetromino_counters[Tetromino::j_piece])); - std::u32string& z_count = m_frame_arena.Allocate(int32_to_u32string(m_tetromino_counters[Tetromino::z_piece])); - std::u32string& o_count = m_frame_arena.Allocate(int32_to_u32string(m_tetromino_counters[Tetromino::o_piece])); - std::u32string& s_count = m_frame_arena.Allocate(int32_to_u32string(m_tetromino_counters[Tetromino::s_piece])); - std::u32string& l_count = m_frame_arena.Allocate(int32_to_u32string(m_tetromino_counters[Tetromino::l_piece])); - std::u32string& i_count = m_frame_arena.Allocate(int32_to_u32string(m_tetromino_counters[Tetromino::i_piece])); - g_renderer.PushText(t_count, m_font, counters_pos, s_text_color, z_text); + String32Id t_count = MemoryManager::EmplaceString32_Frame(int32_to_u32string(m_tetromino_counters[Tetromino::t_piece])); + String32Id j_count = MemoryManager::EmplaceString32_Frame(int32_to_u32string(m_tetromino_counters[Tetromino::j_piece])); + String32Id z_count = MemoryManager::EmplaceString32_Frame(int32_to_u32string(m_tetromino_counters[Tetromino::z_piece])); + String32Id o_count = MemoryManager::EmplaceString32_Frame(int32_to_u32string(m_tetromino_counters[Tetromino::o_piece])); + String32Id s_count = MemoryManager::EmplaceString32_Frame(int32_to_u32string(m_tetromino_counters[Tetromino::s_piece])); + String32Id l_count = MemoryManager::EmplaceString32_Frame(int32_to_u32string(m_tetromino_counters[Tetromino::l_piece])); + String32Id i_count = MemoryManager::EmplaceString32_Frame(int32_to_u32string(m_tetromino_counters[Tetromino::i_piece])); + + g_renderer.PushString32(t_count, m_font, counters_pos, s_text_color, z_text); counters_pos.y += yadvance; - g_renderer.PushText(j_count, m_font, counters_pos, s_text_color, z_text); + g_renderer.PushString32(j_count, m_font, counters_pos, s_text_color, z_text); counters_pos.y += yadvance; - g_renderer.PushText(z_count, m_font, counters_pos, s_text_color, z_text); + g_renderer.PushString32(z_count, m_font, counters_pos, s_text_color, z_text); counters_pos.y += yadvance; - g_renderer.PushText(o_count, m_font, counters_pos, s_text_color, z_text); + g_renderer.PushString32(o_count, m_font, counters_pos, s_text_color, z_text); counters_pos.y += yadvance; - g_renderer.PushText(s_count, m_font, counters_pos, s_text_color, z_text); + g_renderer.PushString32(s_count, m_font, counters_pos, s_text_color, z_text); counters_pos.y += yadvance; - g_renderer.PushText(l_count, m_font, counters_pos, s_text_color, z_text); + g_renderer.PushString32(l_count, m_font, counters_pos, s_text_color, z_text); counters_pos.y += yadvance; - g_renderer.PushText(i_count, m_font, counters_pos, s_text_color, z_text); + g_renderer.PushString32(i_count, m_font, counters_pos, s_text_color, z_text); } void @@ -360,21 +366,21 @@ Tetris::DrawScore() V2F32 pos = {3.0f, 2.6f}; - std::u32string& top_label = m_frame_arena.Allocate(U"Top"); - std::u32string& top_value = m_frame_arena.Allocate(int32_to_u32string(m_highscore)); + String32Id top_label = MemoryManager::EmplaceString32_Frame(U"Top"); + String32Id top_value = MemoryManager::EmplaceString32_Frame(int32_to_u32string(m_highscore)); - std::u32string& score_label = m_frame_arena.Allocate(U"Score"); - std::u32string& score_value = m_frame_arena.Allocate(int32_to_u32string(m_score)); + String32Id score_label = MemoryManager::EmplaceString32_Frame(U"Score"); + String32Id score_value = MemoryManager::EmplaceString32_Frame(int32_to_u32string(m_score)); - g_renderer.PushText(top_label, m_font, pos, s_text_color, z_text); + g_renderer.PushString32(top_label, m_font, pos, s_text_color, z_text); pos.y -= 0.1f; - g_renderer.PushText(top_value, m_font, pos, s_text_color, z_text); + g_renderer.PushString32(top_value, m_font, pos, s_text_color, z_text); pos.y -= 0.2f; - g_renderer.PushText(score_label, m_font, pos, s_text_color, z_text); + g_renderer.PushString32(score_label, m_font, pos, s_text_color, z_text); pos.y -= 0.1f; - g_renderer.PushText(score_value, m_font, pos, s_text_color, z_text); + g_renderer.PushString32(score_value, m_font, pos, s_text_color, z_text); } void @@ -384,8 +390,8 @@ Tetris::DrawNextTetromino() V2F32 label_pos = {pos.x, pos.y + 0.4f}; - std::u32string& label_text = m_frame_arena.Allocate(U"Next:"); - g_renderer.PushText(label_text, m_font, label_pos, s_text_color, z_layer1); + String32Id label_text = MemoryManager::EmplaceString32_Frame(U"Next:"); + g_renderer.PushString32(label_text, m_font, label_pos, s_text_color, z_layer1); V2F32 tetromino_pos = {pos.x, pos.y}; @@ -397,11 +403,11 @@ Tetris::DrawLevel() { V2F32 pos = {3.0f, 1.1f}; - std::u32string& label = m_frame_arena.Allocate(U"Level"); - g_renderer.PushText(label, m_font, pos, s_text_color, z_text); + String32Id label = MemoryManager::EmplaceString32_Frame(U"Level"); + g_renderer.PushString32(label, m_font, pos, s_text_color, z_text); pos.y -= 0.1f; - std::u32string& level = m_frame_arena.Allocate(int32_to_u32string(m_level)); - g_renderer.PushText(level, m_font, pos, s_text_color, z_text); + String32Id level = MemoryManager::EmplaceString32_Frame(int32_to_u32string(m_level)); + g_renderer.PushString32(level, m_font, pos, s_text_color, z_text); } diff --git a/src/games/tetris/Tetris.hpp b/src/games/tetris/Tetris.hpp index 905458a..44ed9ff 100644 --- a/src/games/tetris/Tetris.hpp +++ b/src/games/tetris/Tetris.hpp @@ -5,7 +5,6 @@ #include #include #include -#include class Tetris : public Game { @@ -51,8 +50,6 @@ private: int32_t m_level = 0; int32_t m_softdrop_counter = 0; int32_t m_highscore = 0; - - Arena m_frame_arena {KIBIBYTES(2)}; }; diff --git a/src/main.cpp b/src/main.cpp index c830443..44b370b 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -1,3 +1,4 @@ +#include "common/MemoryManager.hpp" #include #include #include @@ -39,7 +40,6 @@ DrawGameMenu() } ImGui::End(); - return type; } @@ -197,6 +197,7 @@ main(int argc, char** argv) SDL_GL_SwapWindow(window); g_renderer.Reset(); + MemoryManager::Clear_Frame(); } return 0; diff --git a/src/renderer/RSoftwareBackend.cpp b/src/renderer/RSoftwareBackend.cpp index f4f31f3..927fc92 100644 --- a/src/renderer/RSoftwareBackend.cpp +++ b/src/renderer/RSoftwareBackend.cpp @@ -1,3 +1,4 @@ +#include "common/MemoryManager.hpp" #include "renderer/Renderer.hpp" #include @@ -39,8 +40,8 @@ RSoftwareBackend::Draw() SortRenderEntities(); - for (RZBuffEntry& entry : m_renderer.m_z_buff) { - REntity& entity = m_renderer.m_render_entities[entry.entity_index]; + for (auto& sort_entry : m_renderer.m_sort_entries) { + REntity& entity = m_renderer.m_render_entities[sort_entry.entity_index]; switch (entity.type) { case REntityType_Rectangle: { DrawRectangle(entity.rect); @@ -51,7 +52,7 @@ RSoftwareBackend::Draw() } break; case REntityType_Text: { - DrawText(entity.text); + DrawFrameString32(entity.string32); }; break; case REntityType_Circle: { @@ -93,9 +94,9 @@ RSoftwareBackend::Resize(int32_t w, int32_t h) void RSoftwareBackend::SortRenderEntities() { - auto& z_buff = m_renderer.m_z_buff; + auto& z_buff = m_renderer.m_sort_entries; std::sort(z_buff.begin(), z_buff.end(), - [](const RZBuffEntry& e1, const RZBuffEntry& e2) { + [](const RSortEntry& e1, const RSortEntry& e2) { return e1.z < e2.z; }); } @@ -218,11 +219,12 @@ RSoftwareBackend::DrawAlphaBitmap(REntity_AlphaBitmap& entity) } void -RSoftwareBackend::DrawText(REntity_Text& entity) +RSoftwareBackend::DrawFrameString32(REntity_String32& entity) { int32_t xscreen = m_renderer.WorldXToScreenX(entity.pos.x); int32_t yscreen = m_renderer.WorldYToScreenY(entity.pos.y); - for (char32_t ch : entity.text) { + std::u32string& str = MemoryManager::GetString32(entity.id); + for (char32_t ch : str) { Glyph& glyph = entity.font.GetGlyph(ch); int32_t x = xscreen + glyph.xoff; diff --git a/src/renderer/RSoftwareBackend.hpp b/src/renderer/RSoftwareBackend.hpp index 482bb52..2563558 100644 --- a/src/renderer/RSoftwareBackend.hpp +++ b/src/renderer/RSoftwareBackend.hpp @@ -30,7 +30,7 @@ private: void DrawClear(); void DrawRectangle(REntity_Rectangle& entity); void DrawAlphaBitmap(REntity_AlphaBitmap& entity); - void DrawText(REntity_Text& entity); + void DrawFrameString32(REntity_String32& entity); void DrawTextGlyph(Glyph& glyph, Color color, int32_t xscreen, int32_t yscreen); diff --git a/src/renderer/Renderer.cpp b/src/renderer/Renderer.cpp index 87e2ff7..17694b0 100644 --- a/src/renderer/Renderer.cpp +++ b/src/renderer/Renderer.cpp @@ -15,7 +15,7 @@ Renderer::Init(SDL_Window* window) { m_window = window; m_render_entities.reserve(1024); - m_z_buff.reserve(1024); + m_sort_entries.reserve(1024); m_backend = std::make_unique(*this); } @@ -23,7 +23,7 @@ void Renderer::Reset() { m_render_entities.clear(); - m_z_buff.clear(); + m_sort_entries.clear(); SetCameraSize(0.0f, 0.0f); } @@ -76,7 +76,7 @@ Renderer::PushAlphaBitmap(AlphaBitmap& bitmap, V2F32 pos, Color color, uint32_t pos, color }}); - m_z_buff.emplace_back(z, m_render_entities.size()-1); + m_sort_entries.emplace_back(z, m_render_entities.size()-1); } void @@ -87,7 +87,7 @@ Renderer::PushRectangle(Rectangle rect, Color color, uint32_t z) rect, color }}); - m_z_buff.emplace_back(z, m_render_entities.size()-1); + m_sort_entries.emplace_back(z, m_render_entities.size()-1); } void @@ -98,20 +98,20 @@ Renderer::PushCircle(Circle circle, Color color, uint32_t z) circle, color }}); - m_z_buff.emplace_back(z, m_render_entities.size()-1); + m_sort_entries.emplace_back(z, m_render_entities.size()-1); } void -Renderer::PushText(std::u32string& text, Font& font, V2F32 pos, Color color, uint32_t z) +Renderer::PushString32(String32Id id, Font& font, V2F32 pos, Color color, uint32_t z) { - m_render_entities.emplace_back(REntity{.text{ + m_render_entities.emplace_back(REntity{.string32{ REntityType_Text, - text, + id, font, pos, color }}); - m_z_buff.emplace_back(z, m_render_entities.size()-1); + m_sort_entries.emplace_back(z, m_render_entities.size()-1); } diff --git a/src/renderer/Renderer.hpp b/src/renderer/Renderer.hpp index da57e29..8981826 100644 --- a/src/renderer/Renderer.hpp +++ b/src/renderer/Renderer.hpp @@ -1,8 +1,10 @@ #pragma once +#include #include #include #include +#include #include #include @@ -45,9 +47,9 @@ struct REntity_Circle { Color color; }; -struct REntity_Text { +struct REntity_String32 { REntityType type; - std::u32string& text; + String32Id id; Font& font; V2F32 pos; Color color; @@ -59,10 +61,10 @@ union REntity { REntity_AlphaBitmap bitmap; REntity_Rectangle rect; REntity_Circle circle; - REntity_Text text; + REntity_String32 string32; }; -struct RZBuffEntry { +struct RSortEntry { uint32_t z; uint32_t entity_index; }; @@ -85,7 +87,7 @@ public: void PushAlphaBitmap(AlphaBitmap& bitmap, V2F32 pos, Color color, uint32_t z); void PushRectangle(Rectangle rect, Color color, uint32_t z); void PushCircle(Circle circle, Color color, uint32_t z); - void PushText(std::u32string& text, Font& font, V2F32 pos, Color color, uint32_t z); + void PushString32(String32Id id, Font& font, V2F32 pos, Color color, uint32_t z); /* helper functions */ @@ -108,7 +110,7 @@ public: Color m_clear_color {}; std::vector m_render_entities; - std::vector m_z_buff; + std::vector m_sort_entries; std::unique_ptr m_backend; friend class RSoftwareBackend; -- cgit v1.2.3