Fix textures/font lifetimes
This commit is contained in:
+26
-7
@@ -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);
|
||||
|
||||
@@ -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
@@ -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,
|
||||
|
||||
@@ -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);
|
||||
|
||||
Reference in New Issue
Block a user