Fix textures/font lifetimes
This commit is contained in:
+26
-7
@@ -26,17 +26,26 @@ struct Element {
|
|||||||
};
|
};
|
||||||
|
|
||||||
struct EImage : 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 {
|
Vec2<float> size(Window *window) override {
|
||||||
|
Animation &animation = *animation_pool[animation_id];
|
||||||
if (animation.frames.empty())
|
if (animation.frames.empty())
|
||||||
return {0, 0};
|
return {0, 0};
|
||||||
return window->get_image_size(animation.frames[0]);
|
return window->get_image_size(animation.frames[0]);
|
||||||
}
|
}
|
||||||
|
|
||||||
void render(Window &window, uint64_t abs_time) override {
|
void render(Window &window, uint64_t abs_time) override {
|
||||||
|
Animation &animation = *animation_pool[animation_id];
|
||||||
if (animation.frames.empty())
|
if (animation.frames.empty())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
@@ -47,11 +56,21 @@ struct EImage : Element {
|
|||||||
|
|
||||||
struct EText : Element {
|
struct EText : Element {
|
||||||
Localization::Key key;
|
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};
|
Color color = {255, 255, 255, 255};
|
||||||
|
|
||||||
EText(Localization::Key key, int font_id, Color color)
|
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 {
|
Vec2<float> size(Window *window) override {
|
||||||
return window->get_text_size(text_id);
|
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) {
|
if (last_language != Localization::current_language || last_key != key || text_id == -1) {
|
||||||
std::string localized_str = Localization::get(key);
|
std::string localized_str = Localization::get(key);
|
||||||
if (text_id != -1)
|
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);
|
text_id = window.create_text(font_id, localized_str.c_str(), localized_str.size(), color);
|
||||||
last_language = Localization::current_language;
|
last_language = Localization::current_language;
|
||||||
last_key = key;
|
last_key = key;
|
||||||
@@ -163,11 +182,11 @@ struct App {
|
|||||||
current_scene_id = scene_id;
|
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);
|
window.update(size, title);
|
||||||
#warning "Should try to center the loading image or scale it to fit the screen"
|
#warning "Should try to center the loading image or scale it to fit the screen"
|
||||||
Scene *loading_scene = new Scene{};
|
Scene *loading_scene = new Scene{};
|
||||||
EImage *image = new EImage(loading_animation);
|
EImage *image = new EImage(anim_loading);
|
||||||
int image_id = element_pool.acquire(image);
|
int image_id = element_pool.acquire(image);
|
||||||
loading_scene->add_element(image_id);
|
loading_scene->add_element(image_id);
|
||||||
current_scene_id = scene_pool.acquire(loading_scene);
|
current_scene_id = scene_pool.acquire(loading_scene);
|
||||||
|
|||||||
@@ -6,7 +6,7 @@
|
|||||||
namespace definitions {
|
namespace definitions {
|
||||||
DEF_RB(
|
DEF_RB(
|
||||||
Font,
|
Font,
|
||||||
({ window.unload_font(id); }),
|
({ font_pool.release(id); }),
|
||||||
({
|
({
|
||||||
char *path;
|
char *path;
|
||||||
mrb_int size;
|
mrb_int size;
|
||||||
@@ -29,7 +29,7 @@ DEF_RB(
|
|||||||
|
|
||||||
DEF_RB(
|
DEF_RB(
|
||||||
Image,
|
Image,
|
||||||
({ window.unload_image(id); }),
|
({ image_pool.release(id); }),
|
||||||
({
|
({
|
||||||
char *path;
|
char *path;
|
||||||
mrb_value kwargs;
|
mrb_value kwargs;
|
||||||
@@ -43,7 +43,6 @@ DEF_RB(
|
|||||||
}
|
}
|
||||||
|
|
||||||
s->id = window.load_image(path, alpha, pixel_art);
|
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();
|
return mrb_nil_value();
|
||||||
}
|
}
|
||||||
int frame_id = get_id_Image(mrb, frame_val);
|
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);
|
frame_ids.push_back(frame_id);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -114,7 +113,7 @@ DEF_RB(
|
|||||||
Vec2<float> position = {x, y};
|
Vec2<float> position = {x, y};
|
||||||
|
|
||||||
int id = get_id_Font(mrb, font_val);
|
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});
|
app::EText *element = new app::EText(key_id, id, {255, 255, 255, 255});
|
||||||
element->position = position;
|
element->position = position;
|
||||||
@@ -238,9 +237,8 @@ DEF_RB(
|
|||||||
}
|
}
|
||||||
|
|
||||||
int id = get_id_Animation(mrb, animation_val);
|
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->position = {x, y};
|
||||||
element->z = z;
|
element->z = z;
|
||||||
element->click_through = click_through;
|
element->click_through = click_through;
|
||||||
@@ -363,7 +361,10 @@ static mrb_value app_run(mrb_state *mrb, mrb_value) {
|
|||||||
.loop = false
|
.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();
|
return mrb_nil_value();
|
||||||
}
|
}
|
||||||
|
|||||||
+26
-14
@@ -7,18 +7,39 @@
|
|||||||
struct Image {
|
struct Image {
|
||||||
SDL_Texture *texture;
|
SDL_Texture *texture;
|
||||||
Vec2<float> size;
|
Vec2<float> size;
|
||||||
|
|
||||||
|
~Image() {
|
||||||
|
SDL_DestroyTexture(texture);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
struct Font {
|
struct Font {
|
||||||
TTF_Font *font;
|
TTF_Font *font;
|
||||||
bool pixel_art;
|
bool pixel_art;
|
||||||
|
|
||||||
|
~Font() {
|
||||||
|
TTF_CloseFont(font);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
struct Text {
|
struct Text {
|
||||||
SDL_Texture *texture;
|
SDL_Texture *texture;
|
||||||
Vec2<float> size;
|
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 {
|
struct Event {
|
||||||
enum Type {
|
enum Type {
|
||||||
NONE,
|
NONE,
|
||||||
@@ -63,6 +84,11 @@ struct Animation {
|
|||||||
float frame_rate;
|
float frame_rate;
|
||||||
bool loop;
|
bool loop;
|
||||||
int reference_count = 0;
|
int reference_count = 0;
|
||||||
|
|
||||||
|
~Animation() {
|
||||||
|
for (int frame_id : frames)
|
||||||
|
image_pool.release(frame_id);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
inline Pool<Animation> animation_pool;
|
inline Pool<Animation> animation_pool;
|
||||||
@@ -78,17 +104,12 @@ public:
|
|||||||
|
|
||||||
// Rendering functions
|
// Rendering functions
|
||||||
int load_image(const char *path, float alpha = 1.0f, bool pixel_art = false);
|
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);
|
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);
|
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.
|
// 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);
|
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);
|
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});
|
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
|
// White pixel texture for drawing colored rectangles
|
||||||
SDL_Texture *white_tex;
|
SDL_Texture *white_tex;
|
||||||
|
|
||||||
// Image pool
|
|
||||||
Pool<Image> image_pool;
|
|
||||||
|
|
||||||
// Font pool
|
|
||||||
Pool<Font> font_pool;
|
|
||||||
|
|
||||||
// Text pool
|
|
||||||
Pool<Text> text_pool;
|
|
||||||
|
|
||||||
struct RenderInstruction {
|
struct RenderInstruction {
|
||||||
enum Type {
|
enum Type {
|
||||||
DRAW_IMAGE,
|
DRAW_IMAGE,
|
||||||
|
|||||||
@@ -80,10 +80,6 @@ int Window::load_image(const char *path, float alpha, bool pixel_art) {
|
|||||||
return id;
|
return id;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Window::use_image(int image_id) {
|
|
||||||
image_pool.use(image_id);
|
|
||||||
}
|
|
||||||
|
|
||||||
Vec2<float> Window::get_image_size(int image_id) {
|
Vec2<float> Window::get_image_size(int image_id) {
|
||||||
if (!image_pool.is_valid(image_id)) {
|
if (!image_pool.is_valid(image_id)) {
|
||||||
fprintf(stderr, "Invalid image ID: %d\n", 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;
|
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) {
|
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);
|
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;
|
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) {
|
int Window::create_text(int font_id, const char *text, uint32_t length, Color color) {
|
||||||
if (!font_pool.is_valid(font_id)) {
|
if (!font_pool.is_valid(font_id)) {
|
||||||
fprintf(stderr, "Invalid font ID: %d\n", 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;
|
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) {
|
bool Window::write(int text_id, Vec2<float> position, float z, float angle, Vec2<float> scale) {
|
||||||
if (!text_pool.is_valid(text_id)) {
|
if (!text_pool.is_valid(text_id)) {
|
||||||
fprintf(stderr, "Invalid text ID: %d\n", text_id);
|
fprintf(stderr, "Invalid text ID: %d\n", text_id);
|
||||||
|
|||||||
Reference in New Issue
Block a user