Finish basic ui binding to ruby

This commit is contained in:
2026-05-05 11:53:27 +01:00
parent a51eb903c4
commit 1b15f51e1e
10 changed files with 536 additions and 23 deletions
+43 -5
View File
@@ -8,6 +8,7 @@
namespace app {
struct Element {
int reference_count = 0;
Vec2<float> position = {0, 0};
float rotation = 0;
Vec2<float> scale = {1, 1};
@@ -51,11 +52,10 @@ struct EImage : Element {
struct EText : Element {
Localization::Key key;
int font_id;
int font_size = 16;
Color color = {255, 255, 255, 255};
EText(Localization::Key key, int font_id, int font_size, Color color)
: key(key), font_id(font_id), font_size(font_size), color(color) {}
EText(Localization::Key key, int font_id, Color color)
: key(key), font_id(font_id), color(color) {}
Vec2<float> size(Window *window) override {
return window->get_text_size(text_id);
@@ -96,9 +96,20 @@ struct ERect : Element {
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);
}
}
}
void add_element(int element_id) {
auto it = std::lower_bound(
element_ids.begin(),
@@ -108,9 +119,22 @@ struct Scene {
return element_pool[a]->z < element_pool[b]->z || (element_pool[a]->z == element_pool[b]->z && a < b);
}
);
element_pool[element_id]->reference_count++;
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_ids.erase(it);
}
}
void update_scene(uint64_t delta_time) {
if (!mrb_nil_p(update.proc)) {
int x = mrb_gc_arena_save(Ruby::mrb);
@@ -147,6 +171,21 @@ 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);
}
}
current_scene_id = scene_id;
}
App(Vec2<float> size, const char *title, Animation loading_animation) {
window.update(size, title);
#warning "Should try to center the loading image or scale it to fit the screen"
@@ -154,7 +193,7 @@ struct App {
EImage *image = new EImage(loading_animation);
int image_id = element_pool.acquire(image);
loading_scene->add_element(image_id);
scene_pool.acquire(loading_scene);
current_scene_id = scene_pool.acquire(loading_scene);
}
void loop() {
@@ -183,7 +222,6 @@ struct App {
break;
case Event::MOUSE_BUTTON_DOWN:
scene->click(&window, e.mouse_button.position);
printf("DT: %lu ms\n", dt);
break;
default:
break;