Resolve macros and cleanup

This commit is contained in:
2026-05-05 23:10:14 +01:00
parent 7e9a5a7c4f
commit 08a642e07a
3 changed files with 445 additions and 252 deletions
+392 -224
View File
@@ -3,127 +3,231 @@
#include "app/app.h"
#warning "Define ==, eql?, hash for each class"
#warning "Define and bind elements_at in Scene (same as click method already defined but without callback)"
namespace definitions {
DEF_RB(
Font,
({ font_pool.release(id); }),
({
char *path;
mrb_int size;
mrb_value kwargs;
mrb_get_args(mrb, "zi|H", &path, &size, &kwargs);
inline mrb_value wrap(mrb_state *mrb, RClass *cls, mrb_data_type *type, int id) {
RBasic *obj_b = mrb_obj_alloc(mrb, MRB_TT_DATA, cls);
mrb_value obj = mrb_obj_value(obj_b);
bool pixel_art = false;
bool bold = false;
bool italic = false;
bool underline = false;
if (!mrb_nil_p(kwargs)) {
HASH_BOOL(kwargs, pixel_art, pixel_art);
HASH_BOOL(kwargs, bold, bold);
HASH_BOOL(kwargs, italic, italic);
HASH_BOOL(kwargs, underline, underline);
}
s->id = window.load_font(path, size, bold, italic, underline, pixel_art);
})
)
Wrapper *w = new Wrapper();
w->id = id;
DEF_RB(
Image,
({ image_pool.release(id); }),
({
char *path;
mrb_value kwargs;
mrb_get_args(mrb, "z|H", &path, &kwargs);
mrb_data_init(obj, w, type);
float alpha = 1.0f;
bool pixel_art = false;
if (!mrb_nil_p(kwargs)) {
HASH_FLOAT(kwargs, alpha, alpha);
HASH_BOOL(kwargs, pixel_art, pixel_art);
}
return obj;
}
s->id = window.load_image(path, alpha, pixel_art);
})
)
static void Font_free(mrb_state *mrb, void *ptr) {
UNUSED(mrb);
int id = ((Wrapper *)ptr)->id;
font_pool.release(id);
delete (Wrapper *)ptr;
}
DEF_RB(
Animation,
({
animation_pool.release(id);
}),
({
const mrb_value *frames_val;
mrb_int frames_len;
mrb_value kwargs;
mrb_get_args(mrb, "a|H", &frames_val, &frames_len, &kwargs);
static const struct mrb_data_type Font_type = {"Font", Font_free};
float fps = 1.0f;
if (!mrb_nil_p(kwargs))
HASH_FLOAT(kwargs, fps, fps);
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);
mrb_data_init(self, nullptr, &Font_type);
Wrapper *s = new Wrapper();
std::vector<int> frame_ids;
for (mrb_int i = 0; i < frames_len; i++) {
mrb_value frame_val = frames_val[i];
if (!mrb_obj_is_kind_of(mrb, frame_val, mrb_class_get(mrb, "Image"))) {
mrb_raise(mrb, mrb_class_get(mrb, "Exception"), "Expected an array of Image objects");
return mrb_nil_value();
}
int frame_id = get_id_Image(mrb, frame_val);
image_pool.use(frame_id);
frame_ids.push_back(frame_id);
}
char *path;
mrb_int size;
mrb_value kwargs;
mrb_get_args(mrb, "zi|H", &path, &size, &kwargs);
Animation *animation = new Animation{frame_ids, fps, true};
s->id = animation_pool.acquire(animation);
animation_pool.use(s->id);
})
)
bool pixel_art = false;
bool bold = false;
bool italic = false;
bool underline = false;
if (!mrb_nil_p(kwargs)) {
HASH_BOOL(kwargs, pixel_art, pixel_art);
HASH_BOOL(kwargs, bold, bold);
HASH_BOOL(kwargs, italic, italic);
HASH_BOOL(kwargs, underline, underline);
}
DEF_RB(
ElementText,
({
app::element_pool.release(id);
}),
({
mrb_value font_val;
mrb_sym key;
mrb_value kwargs;
mrb_get_args(mrb, "no|H", &key, &font_val, &kwargs);
s->id = window.load_font(path, size, bold, italic, underline, pixel_art);
auto key_id = Localization::key_from_sym(mrb, key);
mrb_data_init(self, s, &Font_type);
return self;
}
if (!mrb_obj_is_kind_of(mrb, font_val, mrb_class_get(mrb, "Font"))) {
mrb_raise(mrb, mrb_class_get(mrb, "Exception"), "Expected a Font object");
inline int get_id_Font(mrb_state *mrb, mrb_value self) {
Wrapper *wrapper;
Data_Get_Struct(mrb, self, &Font_type, wrapper);
return wrapper->id;
}
static void Image_free(mrb_state *mrb, void *ptr) {
UNUSED(mrb);
int id = ((Wrapper *)ptr)->id;
image_pool.release(id);
delete (Wrapper *)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);
mrb_data_init(self, nullptr, &Image_type);
Wrapper *s = new Wrapper();
char *path;
mrb_value kwargs;
mrb_get_args(mrb, "z|H", &path, &kwargs);
float alpha = 1.0f;
bool pixel_art = false;
if (!mrb_nil_p(kwargs)) {
HASH_FLOAT(kwargs, alpha, alpha);
HASH_BOOL(kwargs, pixel_art, pixel_art);
}
s->id = window.load_image(path, alpha, pixel_art);
mrb_data_init(self, s, &Image_type);
return self;
}
inline int get_id_Image(mrb_state *mrb, mrb_value self) {
Wrapper *wrapper;
Data_Get_Struct(mrb, self, &Image_type, wrapper);
return wrapper->id;
}
static void Animation_free(mrb_state *mrb, void *ptr) {
UNUSED(mrb);
int id = ((Wrapper *)ptr)->id;
animation_pool.release(id);
delete (Wrapper *)ptr;
}
static const struct mrb_data_type Animation_type = {
"Animation", Animation_free
};
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);
mrb_data_init(self, nullptr, &Animation_type);
Wrapper *s = new Wrapper();
const mrb_value *frames_val;
mrb_int frames_len;
mrb_value kwargs;
mrb_get_args(mrb, "a|H", &frames_val, &frames_len, &kwargs);
float fps = 1.0f;
if (!mrb_nil_p(kwargs))
HASH_FLOAT(kwargs, fps, fps);
std::vector<int> frame_ids;
for (mrb_int i = 0; i < frames_len; i++) {
mrb_value frame_val = frames_val[i];
if (!mrb_obj_is_kind_of(mrb, frame_val, mrb_class_get(mrb, "Image"))) {
mrb_raise(
mrb,
mrb_class_get(mrb, "Exception"),
"Expected an array of Image objects"
);
return mrb_nil_value();
}
int frame_id = get_id_Image(mrb, frame_val);
image_pool.use(frame_id);
frame_ids.push_back(frame_id);
}
float x = 0;
float y = 0;
float z = 0;
bool click_through = false;
if (!mrb_nil_p(kwargs)) {
mrb_value pos_hash = HASH_GET(kwargs, position);
HASH_FLOAT(pos_hash, x, x);
HASH_FLOAT(pos_hash, y, y);
Animation *animation = new Animation{frame_ids, fps, true};
s->id = animation_pool.acquire(animation);
animation_pool.use(s->id);
HASH_FLOAT(kwargs, z, z);
HASH_BOOL(kwargs, click_through, click_through);
}
mrb_data_init(self, s, &Animation_type);
return self;
}
Vec2<float> position = {x, y};
inline int get_id_Animation(mrb_state *mrb, mrb_value self) {
Wrapper *wrapper;
Data_Get_Struct(mrb, self, &Animation_type, wrapper);
return wrapper->id;
}
int id = get_id_Font(mrb, font_val);
font_pool.use(id);
static void ElementText_free(mrb_state *mrb, void *ptr) {
UNUSED(mrb);
int id = ((Wrapper *)ptr)->id;
app::element_pool.release(id);
delete (Wrapper *)ptr;
}
app::EText *element = new app::EText(key_id, id, {255, 255, 255, 255});
element->position = position;
element->z = z;
element->click_through = click_through;
static const struct mrb_data_type ElementText_type = {
"ElementText", ElementText_free
};
s->id = app::element_pool.acquire(element);
app::element_pool.use(s->id);
})
)
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);
mrb_data_init(self, nullptr, &ElementText_type);
Wrapper *s = new Wrapper();
mrb_value font_val;
mrb_sym key;
mrb_value kwargs;
mrb_get_args(mrb, "no|H", &key, &font_val, &kwargs);
auto key_id = Localization::key_from_sym(mrb, key);
if (!mrb_obj_is_kind_of(mrb, font_val, mrb_class_get(mrb, "Font"))) {
mrb_raise(mrb, mrb_class_get(mrb, "Exception"), "Expected a Font object");
return mrb_nil_value();
}
float x = 0;
float y = 0;
float z = 0;
bool click_through = false;
if (!mrb_nil_p(kwargs)) {
mrb_value pos_hash = HASH_GET(kwargs, position);
HASH_FLOAT(pos_hash, x, x);
HASH_FLOAT(pos_hash, y, y);
HASH_FLOAT(kwargs, z, z);
HASH_BOOL(kwargs, click_through, click_through);
}
Vec2<float> position = {x, y};
int id = get_id_Font(mrb, font_val);
font_pool.use(id);
app::EText *element = new app::EText(key_id, id, {255, 255, 255, 255});
element->position = position;
element->z = z;
element->click_through = click_through;
s->id = app::element_pool.acquire(element);
app::element_pool.use(s->id);
mrb_data_init(self, s, &ElementText_type);
return self;
}
inline int get_id_ElementText(mrb_state *mrb, mrb_value self) {
Wrapper *wrapper;
Data_Get_Struct(mrb, self, &ElementText_type, wrapper);
return wrapper->id;
}
static mrb_value element_text_on_click(mrb_state *mrb, mrb_value self) {
mrb_value block;
@@ -134,46 +238,67 @@ static mrb_value element_text_on_click(mrb_state *mrb, mrb_value self) {
return self;
}
DEF_RB(
ElementRect,
({
app::element_pool.release(id);
}),
({
mrb_value shape_val;
mrb_int color;
mrb_value kwargs;
mrb_get_args(mrb, "Hi|H", &shape_val, &color, &kwargs);
static void ElementRect_free(mrb_state *mrb, void *ptr) {
UNUSED(mrb);
int id = ((Wrapper *)ptr)->id;
app::element_pool.release(id);
delete (Wrapper *)ptr;
}
float x = 0, y = 0, w = 0, h = 0;
if (!mrb_nil_p(shape_val)) {
HASH_FLOAT(shape_val, x, x);
HASH_FLOAT(shape_val, y, y);
HASH_FLOAT(shape_val, w, w);
HASH_FLOAT(shape_val, h, h);
}
static const struct mrb_data_type ElementRect_type = {
"ElementRect", ElementRect_free
};
float z = 0;
if (!mrb_nil_p(kwargs))
HASH_FLOAT(kwargs, z, z);
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);
mrb_data_init(self, nullptr, &ElementRect_type);
Wrapper *s = new Wrapper();
Vec2<float> position = {x, y};
Vec2<float> shape = {w, h};
mrb_value shape_val;
mrb_int color;
mrb_value kwargs;
mrb_get_args(mrb, "Hi|H", &shape_val, &color, &kwargs);
app::ERect *element = new app::ERect(
shape,
{(uint8_t)((color >> 24) & 0xFF),
(uint8_t)((color >> 16) & 0xFF),
(uint8_t)((color >> 8) & 0xFF),
(uint8_t)(color & 0xFF)}
);
element->position = position;
element->z = z;
float x = 0, y = 0, w = 0, h = 0;
if (!mrb_nil_p(shape_val)) {
HASH_FLOAT(shape_val, x, x);
HASH_FLOAT(shape_val, y, y);
HASH_FLOAT(shape_val, w, w);
HASH_FLOAT(shape_val, h, h);
}
s->id = app::element_pool.acquire(element);
app::element_pool.use(s->id);
})
)
float z = 0;
if (!mrb_nil_p(kwargs))
HASH_FLOAT(kwargs, z, z);
Vec2<float> position = {x, y};
Vec2<float> shape = {w, h};
app::ERect *element = new app::ERect(
shape,
{(uint8_t)((color >> 24) & 0xFF),
(uint8_t)((color >> 16) & 0xFF),
(uint8_t)((color >> 8) & 0xFF),
(uint8_t)(color & 0xFF)}
);
element->position = position;
element->z = z;
s->id = app::element_pool.acquire(element);
app::element_pool.use(s->id);
mrb_data_init(self, s, &ElementRect_type);
return self;
}
inline int get_id_ElementRect(mrb_state *mrb, mrb_value self) {
Wrapper *wrapper;
Data_Get_Struct(mrb, self, &ElementRect_type, wrapper);
return wrapper->id;
}
static mrb_value element_rect_on_click(mrb_state *mrb, mrb_value self) {
mrb_value block;
@@ -201,52 +326,79 @@ static mrb_value element_rect_color_set(mrb_state *mrb, mrb_value self) {
static mrb_value element_rect_color_get(mrb_state *mrb, mrb_value self) {
int id = get_id_ElementRect(mrb, self);
app::ERect *element = (app::ERect *)app::element_pool[id];
uint32_t color = ((uint32_t)element->color.r << 24)
| ((uint32_t)element->color.g << 16)
| ((uint32_t)element->color.b << 8)
| (uint32_t)element->color.a;
uint32_t color =
((uint32_t)element->color.r << 24) | ((uint32_t)element->color.g << 16)
| ((uint32_t)element->color.b << 8) | (uint32_t)element->color.a;
return mrb_fixnum_value(color);
}
DEF_RB(
ElementImage,
({
app::element_pool.release(id);
}),
({
mrb_value animation_val;
mrb_value kwargs;
mrb_get_args(mrb, "o|H", &animation_val, &kwargs);
static void ElementImage_free(mrb_state *mrb, void *ptr) {
UNUSED(mrb);
int id = ((Wrapper *)ptr)->id;
app::element_pool.release(id);
delete (Wrapper *)ptr;
}
if (!mrb_obj_is_kind_of(mrb, animation_val, mrb_class_get(mrb, "Animation"))) {
mrb_raise(mrb, mrb_class_get(mrb, "Exception"), "Expected an Animation object");
return mrb_nil_value();
}
static const struct mrb_data_type ElementImage_type = {
"ElementImage", ElementImage_free
};
float x = 0;
float y = 0;
float z = 0;
bool click_through = false;
if (!mrb_nil_p(kwargs)) {
mrb_value pos_hash = HASH_GET(kwargs, position);
HASH_FLOAT(pos_hash, x, x);
HASH_FLOAT(pos_hash, y, y);
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);
mrb_data_init(self, nullptr, &ElementImage_type);
Wrapper *s = new Wrapper();
HASH_FLOAT(kwargs, z, z);
HASH_BOOL(kwargs, click_through, click_through);
}
mrb_value animation_val;
mrb_value kwargs;
mrb_get_args(mrb, "o|H", &animation_val, &kwargs);
if (!mrb_obj_is_kind_of(
mrb,
animation_val,
mrb_class_get(mrb, "Animation")
)) {
mrb_raise(
mrb,
mrb_class_get(mrb, "Exception"),
"Expected an Animation object"
);
return mrb_nil_value();
}
int id = get_id_Animation(mrb, animation_val);
float x = 0;
float y = 0;
float z = 0;
bool click_through = false;
if (!mrb_nil_p(kwargs)) {
mrb_value pos_hash = HASH_GET(kwargs, position);
HASH_FLOAT(pos_hash, x, x);
HASH_FLOAT(pos_hash, y, y);
app::EImage *element = new app::EImage(id);
element->position = {x, y};
element->z = z;
element->click_through = click_through;
HASH_FLOAT(kwargs, z, z);
HASH_BOOL(kwargs, click_through, click_through);
}
s->id = app::element_pool.acquire(element);
app::element_pool.use(s->id);
})
)
int id = get_id_Animation(mrb, animation_val);
app::EImage *element = new app::EImage(id);
element->position = {x, y};
element->z = z;
element->click_through = click_through;
s->id = app::element_pool.acquire(element);
app::element_pool.use(s->id);
mrb_data_init(self, s, &ElementImage_type);
return self;
}
inline int get_id_ElementImage(mrb_state *mrb, mrb_value self) {
Wrapper *wrapper;
Data_Get_Struct(mrb, self, &ElementImage_type, wrapper);
return wrapper->id;
}
static mrb_value element_image_on_click(mrb_state *mrb, mrb_value self) {
mrb_value block;
@@ -257,17 +409,36 @@ static mrb_value element_image_on_click(mrb_state *mrb, mrb_value self) {
return self;
}
DEF_RB(
Scene,
({
app::scene_pool.release(id);
}),
({
app::Scene *loading_scene = new app::Scene{};
s->id = app::scene_pool.acquire(loading_scene);
app::scene_pool.use(s->id);
})
)
static void Scene_free(mrb_state *mrb, void *ptr) {
UNUSED(mrb);
int id = ((Wrapper *)ptr)->id;
app::scene_pool.release(id);
delete (Wrapper *)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);
mrb_data_init(self, nullptr, &Scene_type);
Wrapper *s = new Wrapper();
app::Scene *loading_scene = new app::Scene{};
s->id = app::scene_pool.acquire(loading_scene);
app::scene_pool.use(s->id);
mrb_data_init(self, s, &Scene_type);
return self;
}
inline int get_id_Scene(mrb_state *mrb, mrb_value self) {
Wrapper *wrapper;
Data_Get_Struct(mrb, self, &Scene_type, wrapper);
return wrapper->id;
}
static mrb_value scene_add_element(mrb_state *mrb, mrb_value self) {
mrb_value element_val;
@@ -278,24 +449,34 @@ static mrb_value scene_add_element(mrb_state *mrb, mrb_value self) {
&& !mrb_obj_is_kind_of(mrb, element_val, mrb_class_get(mrb, "ElementRect"))
&& !mrb_obj_is_kind_of(mrb, element_val, mrb_class_get(mrb, "ElementImage"))
) {
mrb_raise(mrb, mrb_class_get(mrb, "Exception"), "Expected an ElementText, ElementRect, or ElementImage object");
mrb_raise(
mrb,
mrb_class_get(mrb, "Exception"),
"Expected an ElementText, ElementRect, or ElementImage object"
);
return mrb_nil_value();
}
int id = get_id_Scene(mrb, self);
app::Scene *scene = app::scene_pool[id];
// int element_id = get_id_Element(mrb, element_val);
int element_id;
if (mrb_obj_is_kind_of(mrb, element_val, mrb_class_get(mrb, "ElementText"))) {
element_id = get_id_ElementText(mrb, element_val);
} else if (mrb_obj_is_kind_of(mrb, element_val, mrb_class_get(mrb, "ElementRect"))) {
} else if (
mrb_obj_is_kind_of(mrb, element_val, mrb_class_get(mrb, "ElementRect"))
) {
element_id = get_id_ElementRect(mrb, element_val);
} else if (mrb_obj_is_kind_of(mrb, element_val, mrb_class_get(mrb, "ElementImage"))) {
} else if (
mrb_obj_is_kind_of(mrb, element_val, mrb_class_get(mrb, "ElementImage"))
) {
element_id = get_id_ElementImage(mrb, element_val);
} else {
mrb_raise(mrb, mrb_class_get(mrb, "Exception"), "Expected an ElementText, ElementRect, or ElementImage object");
mrb_raise(
mrb,
mrb_class_get(mrb, "Exception"),
"Expected an ElementText, ElementRect, or ElementImage object"
);
return mrb_nil_value();
}
@@ -313,7 +494,11 @@ static mrb_value scene_delete_element(mrb_state *mrb, mrb_value self) {
&& !mrb_obj_is_kind_of(mrb, element_val, mrb_class_get(mrb, "ElementRect"))
&& !mrb_obj_is_kind_of(mrb, element_val, mrb_class_get(mrb, "ElementImage"))
) {
mrb_raise(mrb, mrb_class_get(mrb, "Exception"), "Expected an ElementText, ElementRect, or ElementImage object");
mrb_raise(
mrb,
mrb_class_get(mrb, "Exception"),
"Expected an ElementText, ElementRect, or ElementImage object"
);
return mrb_nil_value();
}
@@ -323,12 +508,20 @@ static mrb_value scene_delete_element(mrb_state *mrb, mrb_value self) {
int element_id;
if (mrb_obj_is_kind_of(mrb, element_val, mrb_class_get(mrb, "ElementText"))) {
element_id = get_id_ElementText(mrb, element_val);
} else if (mrb_obj_is_kind_of(mrb, element_val, mrb_class_get(mrb, "ElementRect"))) {
} else if (
mrb_obj_is_kind_of(mrb, element_val, mrb_class_get(mrb, "ElementRect"))
) {
element_id = get_id_ElementRect(mrb, element_val);
} else if (mrb_obj_is_kind_of(mrb, element_val, mrb_class_get(mrb, "ElementImage"))) {
} else if (
mrb_obj_is_kind_of(mrb, element_val, mrb_class_get(mrb, "ElementImage"))
) {
element_id = get_id_ElementImage(mrb, element_val);
} else {
mrb_raise(mrb, mrb_class_get(mrb, "Exception"), "Expected an ElementText, ElementRect, or ElementImage object");
mrb_raise(
mrb,
mrb_class_get(mrb, "Exception"),
"Expected an ElementText, ElementRect, or ElementImage object"
);
return mrb_nil_value();
}
@@ -430,40 +623,15 @@ inline void setup() {
DEF_CLASS(Animation, MRB_ARGS_REQ(1) | MRB_ARGS_OPT(1));
DEF_CLASS(ElementText, MRB_ARGS_REQ(2) | MRB_ARGS_OPT(1));
ADD_METHOD(
ElementText,
"on_click",
element_text_on_click,
MRB_ARGS_BLOCK()
);
ADD_METHOD(ElementText, "on_click", element_text_on_click, MRB_ARGS_BLOCK());
DEF_CLASS(ElementRect, MRB_ARGS_REQ(2) | MRB_ARGS_OPT(1));
ADD_METHOD(
ElementRect,
"on_click",
element_rect_on_click,
MRB_ARGS_BLOCK()
);
ADD_METHOD(
ElementRect,
"color=",
element_rect_color_set,
MRB_ARGS_REQ(1)
);
ADD_METHOD(
ElementRect,
"color",
element_rect_color_get,
MRB_ARGS_NONE()
);
ADD_METHOD(ElementRect, "on_click", element_rect_on_click, MRB_ARGS_BLOCK());
ADD_METHOD(ElementRect, "color=", element_rect_color_set, MRB_ARGS_REQ(1));
ADD_METHOD(ElementRect, "color", element_rect_color_get, MRB_ARGS_NONE());
DEF_CLASS(ElementImage, MRB_ARGS_REQ(1) | MRB_ARGS_OPT(1));
ADD_METHOD(
ElementImage,
"on_click",
element_image_on_click,
MRB_ARGS_BLOCK()
);
ADD_METHOD(ElementImage, "on_click", element_image_on_click, MRB_ARGS_BLOCK());
DEF_CLASS(Scene, MRB_ARGS_NONE());
ADD_METHOD(Scene, "<<", scene_add_element, MRB_ARGS_REQ(1));