aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorfschildt <florian.schildt@protonmail.com>2025-10-17 12:03:56 +0200
committerfschildt <florian.schildt@protonmail.com>2025-10-17 12:03:56 +0200
commit7935895480b74fb9fe02e5f26a82265a72604d77 (patch)
tree1c300cdc13ec38747a7253ff705fa18c0b59c33c /src
parent22d0b0b1ef6717270b3fcda45500c98e5b803974 (diff)
add arena allocator
Diffstat (limited to 'src')
-rw-r--r--src/common/Arena.hpp53
-rw-r--r--src/games/tetris/Tetris.cpp51
-rw-r--r--src/games/tetris/Tetris.hpp4
3 files changed, 81 insertions, 27 deletions
diff --git a/src/common/Arena.hpp b/src/common/Arena.hpp
new file mode 100644
index 0000000..b5e1eb7
--- /dev/null
+++ b/src/common/Arena.hpp
@@ -0,0 +1,53 @@
+#pragma once
+
+#include <cstddef>
+#include <cstdint>
+#include <cassert>
+
+#include <vector>
+
+
+class Arena {
+public:
+ Arena(size_t size) : buffer(size)
+ {
+ }
+
+ template<typename T>
+ size_t
+ Align() const
+ {
+ size_t alignment = alignof(T);
+ return (offset + alignment - 1) & ~(alignment - 1);
+ }
+
+ template<typename T, typename... Args>
+ T&
+ Allocate(Args&&... args)
+ {
+ offset = Align<T>();
+ assert(offset + sizeof(T) <= buffer.size() && "Arena out of memory");
+
+ T* ptr = new (&buffer[offset]) T(std::forward<Args>(args)...);
+ objects.emplace_back(ptr, [](void* p) { static_cast<T*>(p)->~T(); });
+
+ offset += sizeof(T);
+ return *ptr;
+ }
+
+ void
+ Reset()
+ {
+ for (auto& [ptr, dtor] : objects) {
+ dtor(ptr);
+ }
+ objects.clear();
+ offset = 0;
+ }
+
+
+ size_t offset = 0;
+ std::vector<uint8_t> buffer;
+ std::vector<std::pair<void*, void (*)(void*)>> objects;
+};
+
diff --git a/src/games/tetris/Tetris.cpp b/src/games/tetris/Tetris.cpp
index 2413dd1..b59d1e9 100644
--- a/src/games/tetris/Tetris.cpp
+++ b/src/games/tetris/Tetris.cpp
@@ -9,6 +9,7 @@
#include <fstream>
#include <iostream>
+#include <string>
static
@@ -25,7 +26,6 @@ Tetris::Tetris()
, m_active_tetromino{m_board.m_bitmap}
, m_highscore {ReadHighscore()}
{
- m_frame_strings.reserve(s_frame_strings_capacity);
}
void
@@ -51,18 +51,18 @@ Tetris::Start()
bool
Tetris::Update(std::vector<SDL_Event>& events)
{
- Color clear_color = {0.2f, 0.2f, 0.2f, 1.0f};
- g_renderer.SetCameraSize(4.0f, 3.0f);
- g_renderer.Clear(clear_color);
-
- m_frame_strings.clear();
-
+ m_frame_arena.Reset();
if (m_game_status == game_starting) {
Start();
}
+ Color clear_color = {0.2f, 0.2f, 0.2f, 1.0f};
+ g_renderer.SetCameraSize(4.0f, 3.0f);
+ g_renderer.Clear(clear_color);
+
+
float dt = ProcessDt();
@@ -93,8 +93,6 @@ Tetris::Update(std::vector<SDL_Event>& events)
Draw();
- assert((float)m_frame_strings.size() <= 0.8f * s_frame_strings_capacity);
-
return true;
}
@@ -272,7 +270,7 @@ Tetris::DrawGameOverMenu()
void
Tetris::DrawLineCounter()
{
- static std::u32string text = U"Lines: xxx";
+ std::u32string& text = m_frame_arena.Allocate<std::u32string>(U"Lines: xxx");
V3F32 pos = {0.5f, 2.6f, 4.0f};
Color color = {0.9f, 0.9f, 0.9f, 1.0f};
@@ -296,11 +294,10 @@ Tetris::DrawStatistics()
V3F32 pos = {0.4f, 0.5f, s_text_z};
- static std::u32string title_text = U"Statistics";
+ std::u32string& title_text = m_frame_arena.Allocate<std::u32string>(U"Statistics");
V3F32 title_pos = {pos.x + 0.02f, pos.y + 1.64f, pos.z};
g_renderer.PushText(title_text, m_font, title_pos, s_text_color);
-
float yadvance = -0.2f;
float tetrominoes_x0 = pos.x;
float tetrominoes_y0 = pos.y - (float)Tetromino::id_count * yadvance;
@@ -328,17 +325,19 @@ Tetris::DrawStatistics()
tetromino_pos.y += yadvance;
+ // Todo: reorder tetrominoes' bitmaps and just for-loop this?
+
float counters_x0 = pos.x + 0.4f;
float counters_y0 = pos.y + 0.05f - yadvance * (float)Tetromino::id_count;
V3F32 counters_pos = {counters_x0, counters_y0, s_text_z};
- std::u32string& t_count = m_frame_strings.emplace_back(int32_to_u32string(m_tetromino_counters[Tetromino::t_piece]));
- std::u32string& j_count = m_frame_strings.emplace_back(int32_to_u32string(m_tetromino_counters[Tetromino::j_piece]));
- std::u32string& z_count = m_frame_strings.emplace_back(int32_to_u32string(m_tetromino_counters[Tetromino::z_piece]));
- std::u32string& o_count = m_frame_strings.emplace_back(int32_to_u32string(m_tetromino_counters[Tetromino::o_piece]));
- std::u32string& s_count = m_frame_strings.emplace_back(int32_to_u32string(m_tetromino_counters[Tetromino::s_piece]));
- std::u32string& l_count = m_frame_strings.emplace_back(int32_to_u32string(m_tetromino_counters[Tetromino::l_piece]));
- std::u32string& i_count = m_frame_strings.emplace_back(int32_to_u32string(m_tetromino_counters[Tetromino::i_piece]));
+ std::u32string& t_count = m_frame_arena.Allocate<std::u32string>(int32_to_u32string(m_tetromino_counters[Tetromino::t_piece]));
+ std::u32string& j_count = m_frame_arena.Allocate<std::u32string>(int32_to_u32string(m_tetromino_counters[Tetromino::j_piece]));
+ std::u32string& z_count = m_frame_arena.Allocate<std::u32string>(int32_to_u32string(m_tetromino_counters[Tetromino::z_piece]));
+ std::u32string& o_count = m_frame_arena.Allocate<std::u32string>(int32_to_u32string(m_tetromino_counters[Tetromino::o_piece]));
+ std::u32string& s_count = m_frame_arena.Allocate<std::u32string>(int32_to_u32string(m_tetromino_counters[Tetromino::s_piece]));
+ std::u32string& l_count = m_frame_arena.Allocate<std::u32string>(int32_to_u32string(m_tetromino_counters[Tetromino::l_piece]));
+ std::u32string& i_count = m_frame_arena.Allocate<std::u32string>(int32_to_u32string(m_tetromino_counters[Tetromino::i_piece]));
g_renderer.PushText(t_count, m_font, counters_pos, s_text_color);
counters_pos.y += yadvance;
@@ -361,11 +360,11 @@ Tetris::DrawScore()
V3F32 pos = {3.0f, 2.6f, s_text_z};
- std::u32string& top_label = m_frame_strings.emplace_back(U"Top");
- std::u32string& top_value = m_frame_strings.emplace_back(int32_to_u32string(m_highscore));
+ std::u32string& top_label = m_frame_arena.Allocate<std::u32string>(U"Top");
+ std::u32string& top_value = m_frame_arena.Allocate<std::u32string>(int32_to_u32string(m_highscore));
- std::u32string& score_label = m_frame_strings.emplace_back(U"Score");
- std::u32string& score_value = m_frame_strings.emplace_back(int32_to_u32string(m_score));
+ std::u32string& score_label = m_frame_arena.Allocate<std::u32string>(U"Score");
+ std::u32string& score_value = m_frame_arena.Allocate<std::u32string>(int32_to_u32string(m_score));
g_renderer.PushText(top_label, m_font, pos, s_text_color);
@@ -385,7 +384,7 @@ Tetris::DrawNextTetromino()
V3F32 label_pos = {pos.x, pos.y + 0.4f, pos.z};
- std::u32string& label_text = m_frame_strings.emplace_back(U"Next:");
+ std::u32string& label_text = m_frame_arena.Allocate<std::u32string>(U"Next:");
g_renderer.PushText(label_text, m_font, label_pos, s_text_color);
@@ -398,11 +397,11 @@ Tetris::DrawLevel()
{
V3F32 pos = {3.0f, 1.1f};
- std::u32string& label = m_frame_strings.emplace_back(U"Level");
+ std::u32string& label = m_frame_arena.Allocate<std::u32string>(U"Level");
g_renderer.PushText(label, m_font, pos, s_text_color);
pos.y -= 0.1f;
- std::u32string& level = m_frame_strings.emplace_back(int32_to_u32string(m_level));
+ std::u32string& level = m_frame_arena.Allocate<std::u32string>(int32_to_u32string(m_level));
g_renderer.PushText(level, m_font, pos, s_text_color);
}
diff --git a/src/games/tetris/Tetris.hpp b/src/games/tetris/Tetris.hpp
index 2d1dfba..1c60a98 100644
--- a/src/games/tetris/Tetris.hpp
+++ b/src/games/tetris/Tetris.hpp
@@ -1,9 +1,11 @@
#pragma once
+#include <common/defs.hpp>
#include <games/Game.hpp>
#include <games/tetris/Tetromino.hpp>
#include <games/tetris/Board.hpp>
#include <common/Font.hpp>
+#include <common/Arena.hpp>
class Tetris : public Game {
@@ -51,7 +53,7 @@ private:
int32_t m_softdrop_counter = 0;
int32_t m_highscore = 0;
- std::vector<std::u32string> m_frame_strings;
+ Arena m_frame_arena {KIBIBYTES(2)};
};