Fix textures/font lifetimes

This commit is contained in:
2026-05-05 21:29:44 +01:00
parent 0da950caf9
commit 306a053276
4 changed files with 61 additions and 67 deletions
+26 -7
View File
@@ -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<float> 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<float> 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<float> size, const char *title, Animation loading_animation) {
App(Vec2<float> 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);
+9 -8
View File
@@ -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<float> 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();
}
+26 -14
View File
@@ -7,18 +7,39 @@
struct Image {
SDL_Texture *texture;
Vec2<float> size;
~Image() {
SDL_DestroyTexture(texture);
}
};
struct Font {
TTF_Font *font;
bool pixel_art;
~Font() {
TTF_CloseFont(font);
}
};
struct Text {
SDL_Texture *texture;
Vec2<float> size;
~Text() {
SDL_DestroyTexture(texture);
}
};
// Image pool
inline Pool<Image> image_pool;
// Font pool
inline Pool<Font> font_pool;
// Text pool
inline Pool<Text> 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> 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<float> 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<float> get_text_size(int text_id);
bool write(int text_id, Vec2<float> position, float z, float angle = 0.0f, Vec2<float> 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> image_pool;
// Font pool
Pool<Font> font_pool;
// Text pool
Pool<Text> text_pool;
struct RenderInstruction {
enum Type {
DRAW_IMAGE,
-38
View File
@@ -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<float> 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<float> 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<float> 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<float> position, float z, float angle, Vec2<float> scale) {
if (!text_pool.is_valid(text_id)) {
fprintf(stderr, "Invalid text ID: %d\n", text_id);