Fix major incorrect usage of mrb class definitions causing segfaults

This commit is contained in:
2026-05-05 21:09:52 +01:00
parent d362bbc114
commit 0da950caf9
9 changed files with 393 additions and 152 deletions
+12 -35
View File
@@ -8,7 +8,6 @@
namespace app {
struct Element {
int reference_count = 0;
Vec2<float> position = {0, 0};
float rotation = 0;
Vec2<float> scale = {1, 1};
@@ -21,11 +20,8 @@ struct Element {
virtual Vec2<float> size(Window *window) = 0;
void click() {
if (!mrb_nil_p(on_click.proc)) {
int x = mrb_gc_arena_save(Ruby::mrb);
if (!mrb_nil_p(on_click.proc))
on_click.call();
mrb_gc_arena_restore(Ruby::mrb, x);
}
}
};
@@ -93,21 +89,15 @@ struct ERect : Element {
}
};
inline Pool<Element *> element_pool;
inline Pool<Element> element_pool;
struct Scene {
bool unused = false;
std::vector<int> element_ids;
Ruby::Block update;
~Scene() {
for (const int &id : element_ids) {
element_pool[id]->reference_count--;
if (element_pool[id]->reference_count <= 0) {
delete element_pool[id];
element_pool.release(id);
}
}
for (const int &id : element_ids)
element_pool.release(id);
}
void add_element(int element_id) {
@@ -116,31 +106,27 @@ struct Scene {
element_ids.end(),
element_id,
[](auto &a, auto &b) {
return element_pool[a]->z < element_pool[b]->z || (element_pool[a]->z == element_pool[b]->z && a < b);
auto e_a = element_pool[a];
auto e_b = element_pool[b];
return e_a->z < e_b->z || (e_a->z == e_b->z && a < b);
}
);
element_pool[element_id]->reference_count++;
element_pool.use(element_id);
element_ids.insert(it, element_id);
}
void delete_element(int element_id) {
auto it = std::find(element_ids.begin(), element_ids.end(), element_id);
if (it != element_ids.end()) {
element_pool[element_id]->reference_count--;
if (element_pool[element_id]->reference_count <= 0) {
delete element_pool[element_id];
element_pool.release(element_id);
}
element_pool.release(element_id);
element_ids.erase(it);
}
}
void update_scene(uint64_t delta_time) {
if (!mrb_nil_p(update.proc)) {
int x = mrb_gc_arena_save(Ruby::mrb);
mrb_value dt_val = mrb_int_value(Ruby::mrb, delta_time);
update.call(1, &dt_val);
mrb_gc_arena_restore(Ruby::mrb, x);
}
}
@@ -165,24 +151,15 @@ struct Scene {
}
};
inline Pool<Scene *> scene_pool;
inline Pool<Scene> scene_pool;
struct App {
int current_scene_id = 0;
bool running = true;
void switch_to_scene(int scene_id) {
int scene_pool_size = (int)scene_pool.all().size();
for (int i = 0; i < scene_pool_size; ++i) {
auto &val = scene_pool[i];
if (i == scene_id && val != nullptr && val->unused)
val->unused = false;
if (val != nullptr && val->unused) {
delete val;
scene_pool.release(i);
}
}
scene_pool.release(current_scene_id);
scene_pool.use(scene_id);
current_scene_id = scene_id;
}