diff --git a/include/app/app.h b/include/app/app.h index 3885714..94665f3 100644 --- a/include/app/app.h +++ b/include/app/app.h @@ -26,17 +26,26 @@ struct Element { }; struct EImage : Element { - Animation animation; + int animation_id = -1; - EImage(Animation animation) : animation(std::move(animation)) {} + EImage(int animation_id) : animation_id(animation_id) { + animation_pool.use(animation_id); + } + + ~EImage() { + if (animation_id != -1) + animation_pool.release(animation_id); + } Vec2 size(Window *window) override { + Animation &animation = *animation_pool[animation_id]; if (animation.frames.empty()) return {0, 0}; return window->get_image_size(animation.frames[0]); } void render(Window &window, uint64_t abs_time) override { + Animation &animation = *animation_pool[animation_id]; if (animation.frames.empty()) return; @@ -47,11 +56,21 @@ struct EImage : Element { struct EText : Element { Localization::Key key; - int font_id; + int font_id = -1; + + ~EText() { + if (text_id != -1) + text_pool.release(text_id); + if (font_id != -1) + font_pool.release(font_id); + } + Color color = {255, 255, 255, 255}; EText(Localization::Key key, int font_id, Color color) - : key(key), font_id(font_id), color(color) {} + : key(key), font_id(font_id), color(color) { + font_pool.use(font_id); + } Vec2 size(Window *window) override { return window->get_text_size(text_id); @@ -61,7 +80,7 @@ struct EText : Element { if (last_language != Localization::current_language || last_key != key || text_id == -1) { std::string localized_str = Localization::get(key); if (text_id != -1) - window.unload_text(text_id); + text_pool.release(text_id); text_id = window.create_text(font_id, localized_str.c_str(), localized_str.size(), color); last_language = Localization::current_language; last_key = key; @@ -163,11 +182,11 @@ struct App { current_scene_id = scene_id; } - App(Vec2 size, const char *title, Animation loading_animation) { + App(Vec2 size, const char *title, int anim_loading) { window.update(size, title); #warning "Should try to center the loading image or scale it to fit the screen" Scene *loading_scene = new Scene{}; - EImage *image = new EImage(loading_animation); + EImage *image = new EImage(anim_loading); int image_id = element_pool.acquire(image); loading_scene->add_element(image_id); current_scene_id = scene_pool.acquire(loading_scene); diff --git a/include/binding/definitions.h b/include/binding/definitions.h index ad978f1..48ac47c 100644 --- a/include/binding/definitions.h +++ b/include/binding/definitions.h @@ -6,7 +6,7 @@ namespace definitions { DEF_RB( Font, - ({ window.unload_font(id); }), + ({ font_pool.release(id); }), ({ char *path; mrb_int size; @@ -29,7 +29,7 @@ DEF_RB( DEF_RB( Image, - ({ window.unload_image(id); }), + ({ image_pool.release(id); }), ({ char *path; mrb_value kwargs; @@ -43,7 +43,6 @@ DEF_RB( } s->id = window.load_image(path, alpha, pixel_art); -#warning "Fix lifetimes for images/fonts right now they'll always exist" }) ) @@ -70,7 +69,7 @@ DEF_RB( return mrb_nil_value(); } int frame_id = get_id_Image(mrb, frame_val); - window.use_image(frame_id); + image_pool.use(frame_id); frame_ids.push_back(frame_id); } @@ -114,7 +113,7 @@ DEF_RB( Vec2 position = {x, y}; int id = get_id_Font(mrb, font_val); - window.use_font(id); + font_pool.use(id); app::EText *element = new app::EText(key_id, id, {255, 255, 255, 255}); element->position = position; @@ -238,9 +237,8 @@ DEF_RB( } int id = get_id_Animation(mrb, animation_val); - Animation *animation = animation_pool[id]; - app::EImage *element = new app::EImage(*animation); + app::EImage *element = new app::EImage(id); element->position = {x, y}; element->z = z; element->click_through = click_through; @@ -363,7 +361,10 @@ static mrb_value app_run(mrb_state *mrb, mrb_value) { .loop = false }; - app_ = new app::App({(float)width, (float)height}, title, loading_animation); + int loading_animation_id = animation_pool.acquire(new Animation(loading_animation)); + animation_pool.use(loading_animation_id); + + app_ = new app::App({(float)width, (float)height}, title, loading_animation_id); return mrb_nil_value(); } diff --git a/include/window/window.h b/include/window/window.h index b12ee76..c85446a 100644 --- a/include/window/window.h +++ b/include/window/window.h @@ -7,18 +7,39 @@ struct Image { SDL_Texture *texture; Vec2 size; + + ~Image() { + SDL_DestroyTexture(texture); + } }; struct Font { TTF_Font *font; bool pixel_art; + + ~Font() { + TTF_CloseFont(font); + } }; struct Text { SDL_Texture *texture; Vec2 size; + + ~Text() { + SDL_DestroyTexture(texture); + } }; +// Image pool +inline Pool image_pool; + +// Font pool +inline Pool font_pool; + +// Text pool +inline Pool text_pool; + struct Event { enum Type { NONE, @@ -63,6 +84,11 @@ struct Animation { float frame_rate; bool loop; int reference_count = 0; + + ~Animation() { + for (int frame_id : frames) + image_pool.release(frame_id); + } }; inline Pool animation_pool; @@ -78,17 +104,12 @@ public: // Rendering functions int load_image(const char *path, float alpha = 1.0f, bool pixel_art = false); - void use_image(int image_id); - void unload_image(int image_id); Vec2 get_image_size(int image_id); int load_font(const char *path, int font_size, bool bold = false, bool italic = false, bool underline = false, bool pixel_art = false); - void use_font(int font_id); - void unload_font(int font_id); // text is copied internally, so it can be free'd by the caller after the text is created. int create_text(int font_id, const char *text, uint32_t length, Color color); - void unload_text(int text_id); Vec2 get_text_size(int text_id); bool write(int text_id, Vec2 position, float z, float angle = 0.0f, Vec2 scale = {1.0f, 1.0f}); @@ -138,15 +159,6 @@ private: // White pixel texture for drawing colored rectangles SDL_Texture *white_tex; - // Image pool - Pool image_pool; - - // Font pool - Pool font_pool; - - // Text pool - Pool text_pool; - struct RenderInstruction { enum Type { DRAW_IMAGE, diff --git a/src/window/window.cc b/src/window/window.cc index 02ff077..81c009a 100644 --- a/src/window/window.cc +++ b/src/window/window.cc @@ -80,10 +80,6 @@ int Window::load_image(const char *path, float alpha, bool pixel_art) { return id; } -void Window::use_image(int image_id) { - image_pool.use(image_id); -} - Vec2 Window::get_image_size(int image_id) { if (!image_pool.is_valid(image_id)) { fprintf(stderr, "Invalid image ID: %d\n", image_id); @@ -92,16 +88,6 @@ Vec2 Window::get_image_size(int image_id) { return image_pool[image_id]->size; } -void Window::unload_image(int image_id) { - if (!image_pool.is_valid(image_id)) { - fprintf(stderr, "Invalid image ID: %d\n", image_id); - return; - } - - SDL_DestroyTexture(image_pool[image_id]->texture); - image_pool.release(image_id); -} - int Window::load_font(const char *path, int font_size, bool bold, bool italic, bool underline, bool pixel_art) { TTF_Font *font = TTF_OpenFont(path, font_size); @@ -127,20 +113,6 @@ int Window::load_font(const char *path, int font_size, bool bold, bool italic, b return id; } -void Window::use_font(int font_id) { - font_pool.use(font_id); -} - -void Window::unload_font(int font_id) { - if (!font_pool.is_valid(font_id)) { - fprintf(stderr, "Invalid font ID: %d\n", font_id); - return; - } - - TTF_CloseFont(font_pool[font_id]->font); - font_pool.release(font_id); -} - int Window::create_text(int font_id, const char *text, uint32_t length, Color color) { if (!font_pool.is_valid(font_id)) { fprintf(stderr, "Invalid font ID: %d\n", font_id); @@ -184,16 +156,6 @@ Vec2 Window::get_text_size(int text_id) { return text_pool[text_id]->size; } -void Window::unload_text(int text_id) { - if (!text_pool.is_valid(text_id)) { - fprintf(stderr, "Invalid text ID: %d\n", text_id); - return; - } - - SDL_DestroyTexture(text_pool[text_id]->texture); - text_pool.release(text_id); -} - bool Window::write(int text_id, Vec2 position, float z, float angle, Vec2 scale) { if (!text_pool.is_valid(text_id)) { fprintf(stderr, "Invalid text ID: %d\n", text_id);