Make localization parameters better, and add a single frame animation helper

This commit is contained in:
2026-05-21 19:01:44 +01:00
parent e1d18743b5
commit 582b2fcd9e
5 changed files with 122 additions and 50 deletions
+101 -24
View File
@@ -16,6 +16,59 @@ inline mrb_value wrap(mrb_state *mrb, RClass *cls, const mrb_data_type *type, ui
return obj;
}
static void Params_free(mrb_state *mrb, void *ptr) {
UNUSED(mrb);
uint64_t id = ((Wrapper *)ptr)->id;
app::element_pool.release(id);
delete (Wrapper *)ptr;
}
static const struct mrb_data_type Params_type = {"Params", Params_free};
static mrb_value Params_init(mrb_state *mrb, mrb_value self) {
Wrapper *old = (Wrapper *)DATA_PTR(self);
if (old)
mrb_free(mrb, old);
mrb_data_init(self, nullptr, &Params_type);
Wrapper *s = new Wrapper();
mrb_int id;
mrb_get_args(mrb, "z", &id);
s->id = id;
mrb_data_init(self, s, &Params_type);
return self;
}
static mrb_value params_get(mrb_state *mrb, mrb_value self) {
mrb_sym key;
mrb_get_args(mrb, "n", &key);
uint64_t id = ((Wrapper *)DATA_PTR(self))->id;
app::element_pool.use(id);
app::EText *element = (app::EText *)app::element_pool[id];
auto it = element->params.find(mrb_sym2name(mrb, key));
if (it == element->params.end())
return mrb_nil_value();
return mrb_str_new_cstr(mrb, it->second.c_str());
}
static mrb_value params_set(mrb_state *mrb, mrb_value self) {
mrb_sym key;
mrb_value value;
mrb_get_args(mrb, "no", &key, &value);
uint64_t id = ((Wrapper *)DATA_PTR(self))->id;
app::element_pool.use(id);
app::EText *element = (app::EText *)app::element_pool[id];
element->params[mrb_sym2name(mrb, key)] = mrb_str_to_cstr(mrb, mrb_obj_as_string(mrb, value));
return mrb_nil_value();
}
static void Font_free(mrb_state *mrb, void *ptr) {
UNUSED(mrb);
uint64_t id = ((Wrapper *)ptr)->id;
@@ -26,7 +79,6 @@ static void Font_free(mrb_state *mrb, void *ptr) {
static const struct mrb_data_type Font_type = {"Font", Font_free};
static mrb_value Font_init(mrb_state *mrb, mrb_value self) {
UNUSED(mrb);
Wrapper *old = (Wrapper *)DATA_PTR(self);
if (old)
mrb_free(mrb, old);
@@ -89,7 +141,6 @@ static void Image_free(mrb_state *mrb, void *ptr) {
static const struct mrb_data_type Image_type = {"Image", Image_free};
static mrb_value Image_init(mrb_state *mrb, mrb_value self) {
UNUSED(mrb);
Wrapper *old = (Wrapper *)DATA_PTR(self);
if (old)
mrb_free(mrb, old);
@@ -156,7 +207,6 @@ static const struct mrb_data_type Animation_type = {
};
static mrb_value Animation_init(mrb_state *mrb, mrb_value self) {
UNUSED(mrb);
Wrapper *old = (Wrapper *)DATA_PTR(self);
if (old)
mrb_free(mrb, old);
@@ -202,6 +252,31 @@ inline uint64_t get_id_Animation(mrb_state *mrb, mrb_value self) {
return wrapper->id;
}
static mrb_value static_image_animation(mrb_state *mrb, mrb_value) {
mrb_value image_val;
mrb_get_args(mrb, "o", &image_val);
if (!mrb_obj_is_kind_of(mrb, image_val, mrb_class_get(mrb, "Image"))) {
mrb_raise(
mrb,
mrb_class_get(mrb, "Exception"),
"Expected an Image object"
);
return mrb_nil_value();
}
uint64_t frame_id = get_id_Image(mrb, image_val);
image_pool.use(frame_id);
std::vector<uint64_t> frames = {frame_id};
Animation *animation = new Animation{frames, 1.0f};
Wrapper *s = new Wrapper();
s->id = animation_pool.acquire(animation);
animation_pool.use(s->id);
return wrap(mrb, mrb_class_get(mrb, "Animation"), &Animation_type, s->id);
}
static mrb_value animation_equal(mrb_state *mrb, mrb_value self) {
mrb_value other;
mrb_get_args(mrb, "o", &other);
@@ -296,7 +371,6 @@ static const struct mrb_data_type ElementText_type = {
};
static mrb_value ElementText_init(mrb_state *mrb, mrb_value self) {
UNUSED(mrb);
Wrapper *old = (Wrapper *)DATA_PTR(self);
if (old)
mrb_free(mrb, old);
@@ -358,7 +432,18 @@ static mrb_value ElementText_init(mrb_state *mrb, mrb_value self) {
(uint8_t)((color_i) & 0xFF)
};
app::EText *element = new app::EText(key_id, id, color, t_args);
std::unordered_map<std::string, std::string> params;
if (!mrb_nil_p(t_args)) {
mrb_value keys = mrb_hash_keys(mrb, t_args);
for (mrb_int i = 0; i < RARRAY_LEN(keys); i++) {
mrb_value key = RARRAY_PTR(keys)[i];
mrb_value val = mrb_hash_get(mrb, t_args, key);
params[mrb_str_to_cstr(mrb, mrb_obj_as_string(mrb, key))] =
mrb_str_to_cstr(mrb, mrb_obj_as_string(mrb, val));
}
}
app::EText *element = new app::EText(key_id, id, color, params);
element->position = {x, y};
element->scale = {scale_x, scale_y};
element->rotation = rotation;
@@ -459,6 +544,12 @@ static mrb_value element_text_font_get(mrb_state *mrb, mrb_value self) {
return wrap(mrb, mrb_class_get(mrb, "Font"), &Font_type, element->font_id);
}
static mrb_value element_text_params(mrb_state *mrb, mrb_value self) {
uint64_t id = get_id_ElementText(mrb, self);
app::element_pool.use(id);
return wrap(mrb, mrb_class_get(mrb, "Params"), &Params_type, id);
}
static mrb_value element_text_font_set(mrb_state *mrb, mrb_value self) {
mrb_value font_val;
mrb_get_args(mrb, "o", &font_val);
@@ -501,19 +592,6 @@ static mrb_value element_text_color_set(mrb_state *mrb, mrb_value self) {
return mrb_nil_value();
}
static mrb_value element_text_params(mrb_state *mrb, mrb_value self) {
uint64_t id = get_id_ElementText(mrb, self);
app::EText *element = (app::EText *)app::element_pool[id];
return element->params;
}
static mrb_value element_text_params_load(mrb_state *mrb, mrb_value self) {
uint64_t id = get_id_ElementText(mrb, self);
app::EText *element = (app::EText *)app::element_pool[id];
element->reload_params();
return mrb_nil_value();
}
static mrb_value element_text_position_get(mrb_state *mrb, mrb_value self) {
uint64_t id = get_id_ElementText(mrb, self);
app::EText *element = (app::EText *)app::element_pool[id];
@@ -695,7 +773,6 @@ static const struct mrb_data_type ElementRect_type = {
};
static mrb_value ElementRect_init(mrb_state *mrb, mrb_value self) {
UNUSED(mrb);
Wrapper *old = (Wrapper *)DATA_PTR(self);
if (old)
mrb_free(mrb, old);
@@ -1042,7 +1119,6 @@ static const struct mrb_data_type ElementImage_type = {
};
static mrb_value ElementImage_init(mrb_state *mrb, mrb_value self) {
UNUSED(mrb);
Wrapper *old = (Wrapper *)DATA_PTR(self);
if (old)
mrb_free(mrb, old);
@@ -1371,7 +1447,6 @@ static void Scene_free(mrb_state *mrb, void *ptr) {
static const struct mrb_data_type Scene_type = {"Scene", Scene_free};
static mrb_value Scene_init(mrb_state *mrb, mrb_value self) {
UNUSED(mrb);
Wrapper *old = (Wrapper *)DATA_PTR(self);
if (old)
mrb_free(mrb, old);
@@ -1633,7 +1708,6 @@ static mrb_value app_current_scene(mrb_state *mrb, mrb_value) {
uint64_t id = app_->current_scene_id;
if (id == UINT64_MAX)
return mrb_nil_value();
app::Scene *scene = app::scene_pool[id];
app::scene_pool.use(id);
return wrap(mrb, mrb_class_get(mrb, "Scene"), &Scene_type, id);
}
@@ -1762,6 +1836,10 @@ static mrb_value app_exit(mrb_state *, mrb_value) {
}
inline void setup() {
DEF_CLASS(Params, MRB_ARGS_REQ(1));
ADD_METHOD(Params, "[]", params_get, MRB_ARGS_REQ(1));
ADD_METHOD(Params, "[]=", params_set, MRB_ARGS_REQ(2));
DEF_CLASS(Font, MRB_ARGS_REQ(2) | MRB_ARGS_OPT(1));
ADD_METHOD(Font, "==", font_equal, MRB_ARGS_REQ(1));
ADD_METHOD(Font, "eql?", font_equal, MRB_ARGS_REQ(1));
@@ -1775,6 +1853,7 @@ inline void setup() {
ADD_METHOD(Image, "height", image_height, MRB_ARGS_NONE());
DEF_CLASS(Animation, MRB_ARGS_REQ(1) | MRB_ARGS_OPT(1));
ADD_CLASS_METHOD(Animation, "from", static_image_animation, MRB_ARGS_REQ(1));
ADD_METHOD(Animation, "==", animation_equal, MRB_ARGS_REQ(1));
ADD_METHOD(Animation, "eql?", animation_equal, MRB_ARGS_REQ(1));
ADD_METHOD(Animation, "hash", animation_hash, MRB_ARGS_NONE());
@@ -1796,9 +1875,7 @@ inline void setup() {
ADD_METHOD(ElementText, "color", element_text_color_get, MRB_ARGS_NONE());
ADD_METHOD(ElementText, "font=", element_text_font_set, MRB_ARGS_REQ(1));
ADD_METHOD(ElementText, "font", element_text_font_get, MRB_ARGS_NONE());
#warning "Make text params a proper class instead of using a hash for text params"
ADD_METHOD(ElementText, "params", element_text_params, MRB_ARGS_NONE());
ADD_METHOD(ElementText, "params!", element_text_params_load, MRB_ARGS_NONE());
#warning "Make vector a proper class instead of using a hash for vectors"
ADD_METHOD(ElementText, "position=", element_text_position_set, MRB_ARGS_REQ(1));
ADD_METHOD(ElementText, "position", element_text_position_get, MRB_ARGS_NONE());