chore: split monolithic header to proper program files, add vec2 ruby class to proxy element position etc., other cleanup

This commit is contained in:
2026-06-01 22:13:50 +01:00
parent 872d878ddc
commit dcb8b46245
21 changed files with 3153 additions and 2037 deletions
+187
View File
@@ -0,0 +1,187 @@
#include "bindings/definitions.h"
#include "window/window.h"
namespace {
void Animation_free(mrb_state *mrb, void *ptr) {
UNUSED(mrb);
uint64_t id = ((Wrapper *)ptr)->id;
animation_pool.release(id);
delete (Wrapper *)ptr;
}
const struct mrb_data_type Animation_type = {
"Animation", Animation_free
};
mrb_value Animation_init(mrb_state *mrb, mrb_value self) {
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<uint64_t> 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, definitions::bindings.Image.cls)) {
mrb_raise(
mrb,
mrb_class_get(mrb, "Exception"),
"Expected an array of Image objects"
);
return mrb_nil_value();
}
Wrapper *image_wrapper = (Wrapper *)DATA_PTR(frame_val);
uint64_t frame_id = image_wrapper->id;
image_pool.use(frame_id);
frame_ids.push_back(frame_id);
}
Animation *animation = new Animation{frame_ids, fps};
s->id = animation_pool.acquire(animation);
animation_pool.use(s->id);
mrb_data_init(self, s, &Animation_type);
return self;
}
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, definitions::bindings.Image.cls)) {
mrb_raise(
mrb,
mrb_class_get(mrb, "Exception"),
"Expected an Image object"
);
return mrb_nil_value();
}
Wrapper *image_wrapper = (Wrapper *)DATA_PTR(image_val);
uint64_t frame_id = image_wrapper->id;
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 definitions::wrap(definitions::bindings.Animation, s->id);
}
mrb_value animation_equal(mrb_state *mrb, mrb_value self) {
mrb_value other;
mrb_get_args(mrb, "o", &other);
if (!mrb_obj_is_kind_of(mrb, other, definitions::bindings.Animation.cls))
return mrb_false_value();
Wrapper *self_wrapper = (Wrapper *)DATA_PTR(self);
uint64_t id_self = self_wrapper->id;
Wrapper *other_wrapper = (Wrapper *)DATA_PTR(other);
uint64_t id_other = other_wrapper->id;
return mrb_bool_value(id_self == id_other);
}
mrb_value animation_hash(mrb_state *, mrb_value self) {
Wrapper *wrapper = (Wrapper *)DATA_PTR(self);
return mrb_fixnum_value(wrapper->id);
}
mrb_value animation_frames_set(mrb_state *mrb, mrb_value self) {
const mrb_value *frames_val;
mrb_int frames_len;
mrb_get_args(mrb, "a", &frames_val, &frames_len);
Wrapper *self_wrapper = (Wrapper *)DATA_PTR(self);
uint64_t id = self_wrapper->id;
Animation *animation = animation_pool[id];
std::vector<uint64_t> new_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, definitions::bindings.Image.cls)) {
mrb_raise(
mrb,
mrb_class_get(mrb, "Exception"),
"Expected an array of Image objects"
);
return mrb_nil_value();
}
Wrapper *image_wrapper = (Wrapper *)DATA_PTR(frame_val);
uint64_t frame_id = image_wrapper->id;
image_pool.use(frame_id);
new_frame_ids.push_back(frame_id);
}
// Release old frames
for (uint64_t frame_id : animation->frames)
image_pool.release(frame_id);
animation->frames = std::move(new_frame_ids);
return mrb_nil_value();
}
mrb_value animation_frames_get(mrb_state *mrb, mrb_value self) {
Wrapper *self_wrapper = (Wrapper *)DATA_PTR(self);
uint64_t id = self_wrapper->id;
Animation *animation = animation_pool[id];
mrb_value frames_array = mrb_ary_new_capa(mrb, animation->frames.size());
for (uint64_t frame_id : animation->frames) {
image_pool.use(frame_id);
mrb_value frame_obj = definitions::wrap(definitions::bindings.Image, frame_id);
mrb_ary_push(mrb, frames_array, frame_obj);
}
return frames_array;
}
mrb_value animation_fps_set(mrb_state *mrb, mrb_value self) {
mrb_float fps;
mrb_get_args(mrb, "f", &fps);
Wrapper *self_wrapper = (Wrapper *)DATA_PTR(self);
uint64_t id = self_wrapper->id;
Animation *animation = animation_pool[id];
animation->frame_rate = fps;
return mrb_nil_value();
}
mrb_value animation_fps_get(mrb_state *mrb, mrb_value self) {
Wrapper *self_wrapper = (Wrapper *)DATA_PTR(self);
uint64_t id = self_wrapper->id;
Animation *animation = animation_pool[id];
return mrb_float_value(mrb, animation->frame_rate);
}
} // namespace
namespace definitions {
void register_animation() {
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());
ADD_METHOD(Animation, "fps=", animation_fps_set, MRB_ARGS_REQ(1));
ADD_METHOD(Animation, "fps", animation_fps_get, MRB_ARGS_NONE());
ADD_METHOD(Animation, "frames=", animation_frames_set, MRB_ARGS_REQ(1));
ADD_METHOD(Animation, "frames", animation_frames_get, MRB_ARGS_NONE());
bindings.Animation = {Animation_class, &Animation_type};
}
} // namespace definitions
+206
View File
@@ -0,0 +1,206 @@
#include "app/app.h"
#include "bindings/definitions.h"
namespace {
mrb_value app_run(mrb_state *mrb, mrb_value) {
mrb_int width, height;
mrb_value options_hash;
char *title = nullptr;
mrb_get_args(mrb, "iiz|H", &width, &height, &title, &options_hash);
app_ = new app::App({(float)width, (float)height}, title);
float fps = 60;
if (!mrb_nil_p(options_hash))
HASH_FLOAT(options_hash, fps, fps);
app_->set_fps(fps);
return mrb_nil_value();
}
mrb_value app_fps_get(mrb_state *mrb, mrb_value) {
return mrb_float_value(mrb, app_->get_fps());
}
mrb_value app_fps_set(mrb_state *mrb, mrb_value) {
mrb_float fps;
mrb_get_args(mrb, "f", &fps);
app_->set_fps(fps);
return mrb_nil_value();
}
mrb_value app_start(mrb_state *mrb, mrb_value) {
mrb_value scene_val;
mrb_get_args(mrb, "o", &scene_val);
if (!mrb_obj_is_kind_of(mrb, scene_val, mrb_class_get(mrb, "Scene"))) {
mrb_raise(mrb, mrb_class_get(mrb, "Exception"), "Expected a Scene object");
return mrb_nil_value();
}
Wrapper *scene_wrapper = (Wrapper *)DATA_PTR(scene_val);
uint64_t id = scene_wrapper->id;
app_->switch_to_scene(id);
app_->loop();
return mrb_nil_value();
}
mrb_value app_current_scene(mrb_state *, mrb_value) {
uint64_t id = app_->current_scene_id;
if (id == UINT64_MAX)
return mrb_nil_value();
app::scene_pool.use(id);
return definitions::wrap(definitions::bindings.Scene, id);
}
mrb_value app_on_update(mrb_state *mrb, mrb_value) {
mrb_value block;
mrb_get_args(mrb, "&", &block);
app_->update.set_proc(block);
return mrb_nil_value();
}
mrb_value app_switch_to(mrb_state *mrb, mrb_value) {
mrb_value scene_val;
mrb_get_args(mrb, "o", &scene_val);
if (!mrb_obj_is_kind_of(mrb, scene_val, mrb_class_get(mrb, "Scene"))) {
mrb_raise(mrb, mrb_class_get(mrb, "Exception"), "Expected a Scene object");
return mrb_nil_value();
}
Wrapper *scene_wrapper = (Wrapper *)DATA_PTR(scene_val);
uint64_t id = scene_wrapper->id;
app_->switch_to_scene(id);
return mrb_nil_value();
}
mrb_value app_localize(mrb_state *mrb, mrb_value) {
mrb_sym lang_sym, key_sym;
char *text;
mrb_get_args(mrb, "nnz", &lang_sym, &key_sym, &text);
auto lang = Localization::lang_from_sym(mrb, lang_sym);
const char *key_name = mrb_sym2name(mrb, key_sym);
auto it = Localization::localization_key_map.find(key_name);
Localization::Key key_id;
if (it == Localization::localization_key_map.end()) {
key_id = (Localization::Key)Localization::localization_key_map.size();
Localization::localization_key_map[key_name] = key_id;
} else {
key_id = it->second;
}
Localization::set(lang, key_id, text);
return mrb_nil_value();
}
mrb_value app_language_set(mrb_state *mrb, mrb_value) {
mrb_sym lang_sym;
mrb_get_args(mrb, "n", &lang_sym);
Localization::current_language = Localization::lang_from_sym(mrb, lang_sym);
return mrb_nil_value();
}
mrb_value app_language_get(mrb_state *mrb, mrb_value) {
return mrb_symbol_value(Localization::lang_to_sym(mrb, Localization::current_language));
}
mrb_value app_mouse_position(mrb_state *mrb, mrb_value) {
Vec2<float> mouse_pos = app_->mouse_position;
mrb_value result = mrb_hash_new(mrb);
HASH_SET(result, x, mrb_float_value(mrb, mouse_pos.x));
HASH_SET(result, y, mrb_float_value(mrb, mouse_pos.y));
return result;
}
mrb_value app_is_down(mrb_state *mrb, mrb_value) {
mrb_sym key_sym;
mrb_get_args(mrb, "n", &key_sym);
std::string key_name = mrb_sym2name(mrb, key_sym);
Key key = get_key(key_name);
return mrb_bool_value(app_->down_keys[key]);
}
mrb_value app_is_pressed(mrb_state *mrb, mrb_value) {
mrb_sym key_sym;
mrb_get_args(mrb, "n", &key_sym);
std::string key_name = mrb_sym2name(mrb, key_sym);
Key key = get_key(key_name);
for (Key pressed_key : app_->pressed_keys)
if (pressed_key == key)
return mrb_bool_value(true);
return mrb_bool_value(false);
}
mrb_value app_is_released(mrb_state *mrb, mrb_value) {
mrb_sym key_sym;
mrb_get_args(mrb, "n", &key_sym);
std::string key_name = mrb_sym2name(mrb, key_sym);
Key key = get_key(key_name);
for (Key released_key : app_->released_keys)
if (released_key == key)
return mrb_bool_value(true);
return mrb_bool_value(false);
}
mrb_value app_map_key(mrb_state *mrb, mrb_value) {
mrb_sym key_sym;
mrb_sym action_sym;
mrb_get_args(mrb, "nn", &key_sym, &action_sym);
std::string key_name = mrb_sym2name(mrb, key_sym);
std::string action_name = mrb_sym2name(mrb, action_sym);
set_action_mapping(action_name, key_name);
return mrb_nil_value();
}
mrb_value app_scroll(mrb_state *mrb, mrb_value) {
Vec2<float> scroll = app_->scroll;
mrb_value result = mrb_hash_new(mrb);
HASH_SET(result, x, mrb_float_value(mrb, scroll.x));
HASH_SET(result, y, mrb_float_value(mrb, scroll.y));
return result;
}
mrb_value app_text_input(mrb_state *mrb, mrb_value) {
return mrb_str_new_cstr(mrb, app_->text.c_str());
}
mrb_value app_exit(mrb_state *, mrb_value) {
app_->exit();
return mrb_nil_value();
}
} // namespace
namespace definitions {
void register_app() {
DEF_MODULE(App);
ADD_MODULE_METHOD(App, "run", app_run, MRB_ARGS_REQ(3) | MRB_ARGS_OPT(1));
ADD_MODULE_METHOD(App, "start", app_start, MRB_ARGS_REQ(1));
ADD_MODULE_METHOD(App, "switch_to", app_switch_to, MRB_ARGS_REQ(1));
ADD_MODULE_METHOD(App, "scene", app_current_scene, MRB_ARGS_NONE());
ADD_MODULE_METHOD(App, "update", app_on_update, MRB_ARGS_BLOCK());
ADD_MODULE_METHOD(App, "fps=", app_fps_set, MRB_ARGS_REQ(1));
ADD_MODULE_METHOD(App, "fps", app_fps_get, MRB_ARGS_NONE());
ADD_MODULE_METHOD(App, "localize", app_localize, MRB_ARGS_REQ(3));
ADD_MODULE_METHOD(App, "language=", app_language_set, MRB_ARGS_REQ(1));
ADD_MODULE_METHOD(App, "language", app_language_get, MRB_ARGS_NONE());
ADD_MODULE_METHOD(App, "mouse_position", app_mouse_position, MRB_ARGS_NONE());
ADD_MODULE_METHOD(App, "down?", app_is_down, MRB_ARGS_REQ(1));
ADD_MODULE_METHOD(App, "pressed?", app_is_pressed, MRB_ARGS_REQ(1));
ADD_MODULE_METHOD(App, "released?", app_is_released, MRB_ARGS_REQ(1));
ADD_MODULE_METHOD(App, "map_key", app_map_key, MRB_ARGS_REQ(2));
ADD_MODULE_METHOD(App, "scroll", app_scroll, MRB_ARGS_NONE());
ADD_MODULE_METHOD(App, "text_input", app_text_input, MRB_ARGS_NONE());
ADD_MODULE_METHOD(App, "exit!", app_exit, MRB_ARGS_NONE());
}
} // namespace definitions
+326
View File
@@ -0,0 +1,326 @@
#include "app/app.h"
#include "bindings/definitions.h"
namespace {
void ElementImage_free(mrb_state *mrb, void *ptr) {
UNUSED(mrb);
uint64_t id = ((Wrapper *)ptr)->id;
app::element_pool.release(id);
delete (Wrapper *)ptr;
}
const struct mrb_data_type ElementImage_type = {
"ElementImage",
ElementImage_free
};
mrb_value ElementImage_init(mrb_state *mrb, mrb_value self) {
Wrapper *old = (Wrapper *)DATA_PTR(self);
if (old)
mrb_free(mrb, old);
mrb_data_init(self, nullptr, &ElementImage_type);
Wrapper *s = new Wrapper();
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,
definitions::bindings.Animation.cls
)) {
mrb_raise(
mrb,
mrb_class_get(mrb, "Exception"),
"Expected an Animation object"
);
return mrb_nil_value();
}
float x = 0, y = 0, z = 0, rotation = 0;
float scale_x = 1, scale_y = 1, alpha = 1, pivot_x = 0.5, pivot_y = 0.5;
mrb_sym click_mode_sym = sym_block;
if (!mrb_nil_p(kwargs)) {
mrb_value pos_hash = HASH_GET(kwargs, position);
if (!mrb_nil_p(pos_hash)) {
HASH_FLOAT(pos_hash, x, x);
HASH_FLOAT(pos_hash, y, y);
}
mrb_value scale_hash = HASH_GET(kwargs, scale);
if (!mrb_nil_p(scale_hash)) {
HASH_FLOAT(scale_hash, x, scale_x);
HASH_FLOAT(scale_hash, y, scale_y);
}
mrb_value pivot_hash = HASH_GET(kwargs, pivot);
if (!mrb_nil_p(pivot_hash)) {
HASH_FLOAT(pivot_hash, x, pivot_x);
HASH_FLOAT(pivot_hash, y, pivot_y);
}
HASH_FLOAT(kwargs, z, z);
HASH_FLOAT(kwargs, rotation, rotation);
HASH_FLOAT(kwargs, alpha, alpha);
mrb_value v = HASH_GET(kwargs, click_mode);
if (!mrb_nil_p(v)) {
click_mode_sym = mrb_symbol(v);
}
}
Wrapper *animation_wrapper = (Wrapper *)DATA_PTR(animation_val);
uint64_t id = animation_wrapper->id;
animation_pool.use(id);
app::EImage *element = new app::EImage(id);
element->position = {x, y};
element->scale = {scale_x, scale_y};
element->rotation = rotation;
element->pivot = {pivot_x, pivot_y};
element->alpha = alpha;
element->z = z;
std::string click_mode = mrb_sym2name(mrb, click_mode_sym);
if (click_mode == "pass")
element->click_mode = ClickMode::PASS;
else if (click_mode == "block")
element->click_mode = ClickMode::BLOCK;
else if (click_mode == "ignore")
element->click_mode = ClickMode::IGNORE;
s->id = app::element_pool.acquire(element);
app::element_pool.use(s->id);
mrb_data_init(self, s, &ElementImage_type);
return self;
}
mrb_value element_image_on_click(mrb_state *mrb, mrb_value self) {
mrb_value block;
mrb_get_args(mrb, "&", &block);
Wrapper *wrapper = (Wrapper *)DATA_PTR(self);
uint64_t id = wrapper->id;
app::Element *element = app::element_pool[id];
element->on_click.set_proc(block);
return self;
}
mrb_value element_image_equal(mrb_state *mrb, mrb_value self) {
mrb_value other;
mrb_get_args(mrb, "o", &other);
if (!mrb_obj_is_kind_of(mrb, other, definitions::bindings.ElementImage.cls))
return mrb_false_value();
Wrapper *wrapper_self = (Wrapper *)DATA_PTR(self);
Wrapper *wrapper_other = (Wrapper *)DATA_PTR(other);
return mrb_bool_value(wrapper_self->id == wrapper_other->id);
}
mrb_value element_image_inspect(mrb_state *mrb, mrb_value self) {
Wrapper *wrapper = (Wrapper *)DATA_PTR(self);
uint64_t id = wrapper->id;
app::EImage *element = (app::EImage *)app::element_pool[id];
std::string str = "#<ElementImage:0x"
+ std::format("0x{:016x}", id)
+ " animation_id=0x"
+ std::format("{:016x}", element->animation_id)
+ ">";
return mrb_str_new_cstr(mrb, str.c_str());
}
mrb_value element_image_hash(mrb_state *, mrb_value self) {
Wrapper *wrapper = (Wrapper *)DATA_PTR(self);
return mrb_fixnum_value(wrapper->id);
}
mrb_value element_image_animation_set(mrb_state *mrb, mrb_value self) {
mrb_value animation;
mrb_get_args(mrb, "o", &animation);
if (!mrb_obj_is_kind_of(
mrb,
animation,
definitions::bindings.Animation.cls
)) {
mrb_raise(
mrb,
mrb_class_get(mrb, "Exception"),
"Expected an Animation object"
);
return mrb_nil_value();
}
Wrapper *animation_wrapper = (Wrapper *)DATA_PTR(animation);
uint64_t animation_id = animation_wrapper->id;
Wrapper *wrapper = (Wrapper *)DATA_PTR(self);
uint64_t id = wrapper->id;
app::EImage *element = (app::EImage *)app::element_pool[id];
animation_pool.use(animation_id);
animation_pool.release(element->animation_id);
element->animation_id = animation_id;
return self;
}
mrb_value element_image_animation_get(mrb_state *, mrb_value self) {
Wrapper *wrapper = (Wrapper *)DATA_PTR(self);
uint64_t id = wrapper->id;
app::EImage *element = (app::EImage *)app::element_pool[id];
uint64_t animation_id = element->animation_id;
if (animation_id == UINT64_MAX)
return mrb_nil_value();
animation_pool.use(animation_id);
return definitions::wrap(definitions::bindings.Animation, animation_id);
}
mrb_value element_image_position_get(mrb_state *, mrb_value self) {
Wrapper *wrapper = (Wrapper *)DATA_PTR(self);
uint64_t id = wrapper->id;
app::EImage *element = (app::EImage *)app::element_pool[id];
return definitions::Vec2_wrap(id, &element->position);
}
mrb_value element_image_rotation_get(mrb_state *mrb, mrb_value self) {
Wrapper *wrapper = (Wrapper *)DATA_PTR(self);
uint64_t id = wrapper->id;
app::EImage *element = (app::EImage *)app::element_pool[id];
return mrb_float_value(mrb, element->rotation);
}
mrb_value element_image_rotation_set(mrb_state *mrb, mrb_value self) {
mrb_float rotation;
mrb_get_args(mrb, "f", &rotation);
Wrapper *wrapper = (Wrapper *)DATA_PTR(self);
uint64_t id = wrapper->id;
app::EImage *element = (app::EImage *)app::element_pool[id];
element->rotation = rotation;
return mrb_nil_value();
}
mrb_value element_image_pivot_get(mrb_state *, mrb_value self) {
Wrapper *wrapper = (Wrapper *)DATA_PTR(self);
uint64_t id = wrapper->id;
app::EImage *element = (app::EImage *)app::element_pool[id];
return definitions::Vec2_wrap(id, &element->pivot);
}
mrb_value element_image_scale_get(mrb_state *, mrb_value self) {
Wrapper *wrapper = (Wrapper *)DATA_PTR(self);
uint64_t id = wrapper->id;
app::EImage *element = (app::EImage *)app::element_pool[id];
return definitions::Vec2_wrap(id, &element->scale);
}
mrb_value element_image_alpha_get(mrb_state *mrb, mrb_value self) {
Wrapper *wrapper = (Wrapper *)DATA_PTR(self);
uint64_t id = wrapper->id;
app::EImage *element = (app::EImage *)app::element_pool[id];
return mrb_float_value(mrb, element->alpha);
}
mrb_value element_image_alpha_set(mrb_state *mrb, mrb_value self) {
mrb_float alpha;
mrb_get_args(mrb, "f", &alpha);
Wrapper *wrapper = (Wrapper *)DATA_PTR(self);
uint64_t id = wrapper->id;
app::EImage *element = (app::EImage *)app::element_pool[id];
element->alpha = alpha;
return mrb_nil_value();
}
mrb_value element_image_z_get(mrb_state *mrb, mrb_value self) {
Wrapper *wrapper = (Wrapper *)DATA_PTR(self);
uint64_t id = wrapper->id;
app::EImage *element = (app::EImage *)app::element_pool[id];
return mrb_float_value(mrb, element->z);
}
mrb_value element_image_z_set(mrb_state *mrb, mrb_value self) {
mrb_float z;
mrb_get_args(mrb, "f", &z);
Wrapper *wrapper = (Wrapper *)DATA_PTR(self);
uint64_t id = wrapper->id;
app::EImage *element = (app::EImage *)app::element_pool[id];
element->z = z;
return mrb_nil_value();
}
mrb_value element_image_click_mode_get(mrb_state *mrb, mrb_value self) {
Wrapper *wrapper = (Wrapper *)DATA_PTR(self);
uint64_t id = wrapper->id;
app::EImage *element = (app::EImage *)app::element_pool[id];
std::string click_mode_str;
switch (element->click_mode) {
case ClickMode::PASS:
click_mode_str = "pass";
break;
case ClickMode::BLOCK:
click_mode_str = "block";
break;
case ClickMode::IGNORE:
click_mode_str = "ignore";
break;
}
return mrb_symbol_value(mrb_intern_cstr(mrb, click_mode_str.c_str()));
}
mrb_value element_image_click_mode_set(mrb_state *mrb, mrb_value self) {
mrb_sym click_mode_sym;
mrb_get_args(mrb, "n", &click_mode_sym);
Wrapper *wrapper = (Wrapper *)DATA_PTR(self);
uint64_t id = wrapper->id;
app::EImage *element = (app::EImage *)app::element_pool[id];
std::string click_mode = mrb_sym2name(mrb, click_mode_sym);
if (click_mode == "pass")
element->click_mode = ClickMode::PASS;
else if (click_mode == "block")
element->click_mode = ClickMode::BLOCK;
else if (click_mode == "ignore")
element->click_mode = ClickMode::IGNORE;
return mrb_nil_value();
}
} // namespace
namespace definitions {
void register_element_image() {
DEF_CLASS(ElementImage, MRB_ARGS_REQ(1) | MRB_ARGS_OPT(1));
ADD_METHOD(ElementImage, "click", element_image_on_click, MRB_ARGS_BLOCK());
ADD_METHOD(ElementImage, "==", element_image_equal, MRB_ARGS_REQ(1));
ADD_METHOD(ElementImage, "eql?", element_image_equal, MRB_ARGS_REQ(1));
ADD_METHOD(ElementImage, "inspect", element_image_inspect, MRB_ARGS_NONE());
ADD_METHOD(ElementImage, "to_s", element_image_inspect, MRB_ARGS_NONE());
ADD_METHOD(ElementImage, "hash", element_image_hash, MRB_ARGS_NONE());
ADD_METHOD(ElementImage, "animation=", element_image_animation_set, MRB_ARGS_REQ(1));
ADD_METHOD(ElementImage, "animation", element_image_animation_get, MRB_ARGS_NONE());
ADD_METHOD(ElementImage, "position", element_image_position_get, MRB_ARGS_NONE());
ADD_METHOD(ElementImage, "scale", element_image_scale_get, MRB_ARGS_NONE());
ADD_METHOD(ElementImage, "rotation=", element_image_rotation_set, MRB_ARGS_REQ(1));
ADD_METHOD(ElementImage, "rotation", element_image_rotation_get, MRB_ARGS_NONE());
ADD_METHOD(ElementImage, "pivot", element_image_pivot_get, MRB_ARGS_NONE());
ADD_METHOD(ElementImage, "alpha=", element_image_alpha_set, MRB_ARGS_REQ(1));
ADD_METHOD(ElementImage, "alpha", element_image_alpha_get, MRB_ARGS_NONE());
ADD_METHOD(ElementImage, "z=", element_image_z_set, MRB_ARGS_REQ(1));
ADD_METHOD(ElementImage, "z", element_image_z_get, MRB_ARGS_NONE());
ADD_METHOD(ElementImage, "click_mode=", element_image_click_mode_set, MRB_ARGS_REQ(1));
ADD_METHOD(ElementImage, "click_mode", element_image_click_mode_get, MRB_ARGS_NONE());
bindings.ElementImage = {ElementImage_class, &ElementImage_type};
}
} // namespace definitions
+349
View File
@@ -0,0 +1,349 @@
#include "app/app.h"
#include "bindings/definitions.h"
namespace {
void ElementRect_free(mrb_state *mrb, void *ptr) {
UNUSED(mrb);
uint64_t id = ((Wrapper *)ptr)->id;
app::element_pool.release(id);
delete (Wrapper *)ptr;
}
const struct mrb_data_type ElementRect_type = {
"ElementRect",
ElementRect_free
};
mrb_value ElementRect_init(mrb_state *mrb, mrb_value self) {
Wrapper *old = (Wrapper *)DATA_PTR(self);
if (old)
mrb_free(mrb, old);
mrb_data_init(self, nullptr, &ElementRect_type);
Wrapper *s = new Wrapper();
mrb_float w, h;
mrb_int color_i = 0xFFFFFF;
mrb_value kwargs;
mrb_get_args(mrb, "ffi|H", &w, &h, &color_i, &kwargs);
float x = 0, y = 0, z = 0, rotation = 0;
float scale_x = 1, scale_y = 1, alpha = 1, pivot_x = 0.5, pivot_y = 0.5;
mrb_sym click_mode_sym = sym_block;
if (!mrb_nil_p(kwargs)) {
mrb_value pos_hash = HASH_GET(kwargs, position);
if (!mrb_nil_p(pos_hash)) {
HASH_FLOAT(pos_hash, x, x);
HASH_FLOAT(pos_hash, y, y);
}
mrb_value scale_hash = HASH_GET(kwargs, scale);
if (!mrb_nil_p(scale_hash)) {
HASH_FLOAT(scale_hash, x, scale_x);
HASH_FLOAT(scale_hash, y, scale_y);
}
mrb_value pivot_hash = HASH_GET(kwargs, pivot);
if (!mrb_nil_p(pivot_hash)) {
HASH_FLOAT(pivot_hash, x, pivot_x);
HASH_FLOAT(pivot_hash, y, pivot_y);
}
HASH_FLOAT(kwargs, z, z);
HASH_FLOAT(kwargs, rotation, rotation);
HASH_FLOAT(kwargs, alpha, alpha);
mrb_value v = HASH_GET(kwargs, click_mode);
if (!mrb_nil_p(v)) {
click_mode_sym = mrb_symbol(v);
}
}
Vec2<float> shape = {(float)w, (float)h};
Color color = {
(uint8_t)((color_i >> 16) & 0xFF),
(uint8_t)((color_i >> 8) & 0xFF),
(uint8_t)((color_i) & 0xFF)
};
app::ERect *element = new app::ERect(
shape,
color
);
element->position = {x, y};
element->scale = {scale_x, scale_y};
element->rotation = rotation;
element->pivot = {pivot_x, pivot_y};
element->alpha = alpha;
element->z = z;
std::string click_mode = mrb_sym2name(mrb, click_mode_sym);
if (click_mode == "pass")
element->click_mode = ClickMode::PASS;
else if (click_mode == "block")
element->click_mode = ClickMode::BLOCK;
else if (click_mode == "ignore")
element->click_mode = ClickMode::IGNORE;
s->id = app::element_pool.acquire(element);
app::element_pool.use(s->id);
mrb_data_init(self, s, &ElementRect_type);
return self;
}
mrb_value element_rect_on_click(mrb_state *mrb, mrb_value self) {
mrb_value block;
mrb_get_args(mrb, "&", &block);
Wrapper *wrapper = (Wrapper *)DATA_PTR(self);
uint64_t id = wrapper->id;
app::Element *element = app::element_pool[id];
element->on_click.set_proc(block);
return self;
}
mrb_value element_rect_width_set(mrb_state *mrb, mrb_value self) {
mrb_float width;
mrb_get_args(mrb, "f", &width);
Wrapper *wrapper = (Wrapper *)DATA_PTR(self);
uint64_t id = wrapper->id;
app::ERect *element = (app::ERect *)app::element_pool[id];
element->shape.x = width;
return mrb_nil_value();
}
mrb_value element_rect_width_get(mrb_state *mrb, mrb_value self) {
Wrapper *wrapper = (Wrapper *)DATA_PTR(self);
uint64_t id = wrapper->id;
app::ERect *element = (app::ERect *)app::element_pool[id];
return mrb_float_value(mrb, element->shape.x);
}
mrb_value element_rect_height_set(mrb_state *mrb, mrb_value self) {
mrb_float height;
mrb_get_args(mrb, "f", &height);
Wrapper *wrapper = (Wrapper *)DATA_PTR(self);
uint64_t id = wrapper->id;
app::ERect *element = (app::ERect *)app::element_pool[id];
element->shape.y = height;
return mrb_nil_value();
}
mrb_value element_rect_height_get(mrb_state *mrb, mrb_value self) {
Wrapper *wrapper = (Wrapper *)DATA_PTR(self);
uint64_t id = wrapper->id;
app::ERect *element = (app::ERect *)app::element_pool[id];
return mrb_float_value(mrb, element->shape.y);
}
mrb_value element_rect_color_set(mrb_state *mrb, mrb_value self) {
mrb_value color_val;
mrb_get_args(mrb, "o", &color_val);
Wrapper *wrapper = (Wrapper *)DATA_PTR(self);
uint64_t id = wrapper->id;
app::ERect *element = (app::ERect *)app::element_pool[id];
element->color = {
(uint8_t)((mrb_fixnum(color_val) >> 16) & 0xFF),
(uint8_t)((mrb_fixnum(color_val) >> 8) & 0xFF),
(uint8_t)((mrb_fixnum(color_val)) & 0xFF)
};
return self;
}
mrb_value element_rect_color_get(mrb_state *, mrb_value self) {
Wrapper *wrapper = (Wrapper *)DATA_PTR(self);
uint64_t id = wrapper->id;
app::ERect *element = (app::ERect *)app::element_pool[id];
uint32_t color =
((uint32_t)element->color.r << 16) | ((uint32_t)element->color.g << 8)
| ((uint32_t)element->color.b);
return mrb_fixnum_value(color);
}
mrb_value element_rect_equal(mrb_state *mrb, mrb_value self) {
mrb_value other;
mrb_get_args(mrb, "o", &other);
if (!mrb_obj_is_kind_of(mrb, other, definitions::bindings.ElementRect.cls))
return mrb_false_value();
Wrapper *wrapper_self = (Wrapper *)DATA_PTR(self);
Wrapper *wrapper_other = (Wrapper *)DATA_PTR(other);
uint64_t id_self = wrapper_self->id;
uint64_t id_other = wrapper_other->id;
return mrb_bool_value(id_self == id_other);
}
mrb_value element_rect_inspect(mrb_state *mrb, mrb_value self) {
Wrapper *wrapper = (Wrapper *)DATA_PTR(self);
uint64_t id = wrapper->id;
app::ERect *element = (app::ERect *)app::element_pool[id];
std::string str = "#<ElementRect:0x"
+ std::format("0x{:016x}", id)
+ " width=" + std::format("{}", element->shape.x)
+ " height=" + std::format("{}", element->shape.y)
+ ">";
return mrb_str_new_cstr(mrb, str.c_str());
}
mrb_value element_rect_hash(mrb_state *, mrb_value self) {
Wrapper *wrapper = (Wrapper *)DATA_PTR(self);
uint64_t id = wrapper->id;
return mrb_fixnum_value(id);
}
mrb_value element_rect_position_get(mrb_state *, mrb_value self) {
Wrapper *wrapper = (Wrapper *)DATA_PTR(self);
uint64_t id = wrapper->id;
app::ERect *element = (app::ERect *)app::element_pool[id];
return definitions::Vec2_wrap(id, &element->position);
}
mrb_value element_rect_rotation_get(mrb_state *mrb, mrb_value self) {
Wrapper *wrapper = (Wrapper *)DATA_PTR(self);
uint64_t id = wrapper->id;
app::ERect *element = (app::ERect *)app::element_pool[id];
return mrb_float_value(mrb, element->rotation);
}
mrb_value element_rect_rotation_set(mrb_state *mrb, mrb_value self) {
mrb_float rotation;
mrb_get_args(mrb, "f", &rotation);
Wrapper *wrapper = (Wrapper *)DATA_PTR(self);
uint64_t id = wrapper->id;
app::ERect *element = (app::ERect *)app::element_pool[id];
element->rotation = rotation;
return mrb_nil_value();
}
mrb_value element_rect_pivot_get(mrb_state *, mrb_value self) {
Wrapper *wrapper = (Wrapper *)DATA_PTR(self);
uint64_t id = wrapper->id;
app::ERect *element = (app::ERect *)app::element_pool[id];
return definitions::Vec2_wrap(id, &element->pivot);
}
mrb_value element_rect_scale_get(mrb_state *, mrb_value self) {
Wrapper *wrapper = (Wrapper *)DATA_PTR(self);
uint64_t id = wrapper->id;
app::ERect *element = (app::ERect *)app::element_pool[id];
return definitions::Vec2_wrap(id, &element->scale);
}
mrb_value element_rect_alpha_get(mrb_state *mrb, mrb_value self) {
Wrapper *wrapper = (Wrapper *)DATA_PTR(self);
uint64_t id = wrapper->id;
app::ERect *element = (app::ERect *)app::element_pool[id];
return mrb_float_value(mrb, element->alpha);
}
mrb_value element_rect_alpha_set(mrb_state *mrb, mrb_value self) {
mrb_float alpha;
mrb_get_args(mrb, "f", &alpha);
Wrapper *wrapper = (Wrapper *)DATA_PTR(self);
uint64_t id = wrapper->id;
app::ERect *element = (app::ERect *)app::element_pool[id];
element->alpha = alpha;
return mrb_nil_value();
}
mrb_value element_rect_z_get(mrb_state *mrb, mrb_value self) {
Wrapper *wrapper = (Wrapper *)DATA_PTR(self);
uint64_t id = wrapper->id;
app::ERect *element = (app::ERect *)app::element_pool[id];
return mrb_float_value(mrb, element->z);
}
mrb_value element_rect_z_set(mrb_state *mrb, mrb_value self) {
mrb_float z;
mrb_get_args(mrb, "f", &z);
Wrapper *wrapper = (Wrapper *)DATA_PTR(self);
uint64_t id = wrapper->id;
app::ERect *element = (app::ERect *)app::element_pool[id];
element->z = z;
return mrb_nil_value();
}
mrb_value element_rect_click_mode_get(mrb_state *mrb, mrb_value self) {
Wrapper *wrapper = (Wrapper *)DATA_PTR(self);
uint64_t id = wrapper->id;
app::ERect *element = (app::ERect *)app::element_pool[id];
std::string click_mode_str;
switch (element->click_mode) {
case ClickMode::PASS:
click_mode_str = "pass";
break;
case ClickMode::BLOCK:
click_mode_str = "block";
break;
case ClickMode::IGNORE:
click_mode_str = "ignore";
break;
}
return mrb_symbol_value(mrb_intern_cstr(mrb, click_mode_str.c_str()));
}
mrb_value element_rect_click_mode_set(mrb_state *mrb, mrb_value self) {
mrb_sym click_mode_sym;
mrb_get_args(mrb, "n", &click_mode_sym);
Wrapper *wrapper = (Wrapper *)DATA_PTR(self);
uint64_t id = wrapper->id;
app::ERect *element = (app::ERect *)app::element_pool[id];
std::string click_mode = mrb_sym2name(mrb, click_mode_sym);
if (click_mode == "pass")
element->click_mode = ClickMode::PASS;
else if (click_mode == "block")
element->click_mode = ClickMode::BLOCK;
else if (click_mode == "ignore")
element->click_mode = ClickMode::IGNORE;
return mrb_nil_value();
}
} // namespace
namespace definitions {
void register_element_rect() {
DEF_CLASS(ElementRect, MRB_ARGS_REQ(3) | MRB_ARGS_OPT(1));
ADD_METHOD(ElementRect, "==", element_rect_equal, MRB_ARGS_REQ(1));
ADD_METHOD(ElementRect, "eql?", element_rect_equal, MRB_ARGS_REQ(1));
ADD_METHOD(ElementRect, "inspect", element_rect_inspect, MRB_ARGS_NONE());
ADD_METHOD(ElementRect, "to_s", element_rect_inspect, MRB_ARGS_NONE());
ADD_METHOD(ElementRect, "hash", element_rect_hash, MRB_ARGS_NONE());
ADD_METHOD(ElementRect, "click", element_rect_on_click, MRB_ARGS_BLOCK());
ADD_METHOD(ElementRect, "width=", element_rect_width_set, MRB_ARGS_REQ(1));
ADD_METHOD(ElementRect, "width", element_rect_width_get, MRB_ARGS_NONE());
ADD_METHOD(ElementRect, "height=", element_rect_height_set, MRB_ARGS_REQ(1));
ADD_METHOD(ElementRect, "height", element_rect_height_get, MRB_ARGS_NONE());
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, "position", element_rect_position_get, MRB_ARGS_NONE());
ADD_METHOD(ElementRect, "scale", element_rect_scale_get, MRB_ARGS_NONE());
ADD_METHOD(ElementRect, "rotation=", element_rect_rotation_set, MRB_ARGS_REQ(1));
ADD_METHOD(ElementRect, "rotation", element_rect_rotation_get, MRB_ARGS_NONE());
ADD_METHOD(ElementRect, "pivot", element_rect_pivot_get, MRB_ARGS_NONE());
ADD_METHOD(ElementRect, "alpha=", element_rect_alpha_set, MRB_ARGS_REQ(1));
ADD_METHOD(ElementRect, "alpha", element_rect_alpha_get, MRB_ARGS_NONE());
ADD_METHOD(ElementRect, "z=", element_rect_z_set, MRB_ARGS_REQ(1));
ADD_METHOD(ElementRect, "z", element_rect_z_get, MRB_ARGS_NONE());
ADD_METHOD(ElementRect, "click_mode=", element_rect_click_mode_set, MRB_ARGS_REQ(1));
ADD_METHOD(ElementRect, "click_mode", element_rect_click_mode_get, MRB_ARGS_NONE());
bindings.ElementRect = {ElementRect_class, &ElementRect_type};
}
} // namespace definitions
+411
View File
@@ -0,0 +1,411 @@
#include "app/app.h"
#include "bindings/definitions.h"
namespace {
void ElementText_free(mrb_state *mrb, void *ptr) {
UNUSED(mrb);
uint64_t id = ((Wrapper *)ptr)->id;
app::element_pool.release(id);
delete (Wrapper *)ptr;
}
const struct mrb_data_type ElementText_type = {
"ElementText", ElementText_free
};
mrb_value ElementText_init(mrb_state *mrb, mrb_value self) {
Wrapper *old = (Wrapper *)DATA_PTR(self);
if (old)
mrb_free(mrb, old);
mrb_data_init(self, nullptr, &ElementText_type);
Wrapper *s = new Wrapper();
mrb_sym key;
mrb_value font_val;
mrb_int color_i = 0xFFFFFF;
mrb_value t_args;
mrb_value kwargs;
mrb_get_args(mrb, "noi|HH", &key, &font_val, &color_i, &t_args, &kwargs);
auto key_id = Localization::key_from_sym(mrb, key);
if (!mrb_obj_is_kind_of(mrb, font_val, definitions::bindings.Font.cls)) {
mrb_raise(mrb, mrb_class_get(mrb, "Exception"), "Expected a Font object");
return mrb_nil_value();
}
float x = 0, y = 0, z = 0, rotation = 0;
float scale_x = 1, scale_y = 1, alpha = 1;
float pivot_x = 0.5, pivot_y = 0.5;
mrb_sym click_mode_sym = sym_block;
if (!mrb_nil_p(kwargs)) {
mrb_value pos_hash = HASH_GET(kwargs, position);
if (!mrb_nil_p(pos_hash)) {
HASH_FLOAT(pos_hash, x, x);
HASH_FLOAT(pos_hash, y, y);
}
mrb_value scale_hash = HASH_GET(kwargs, scale);
if (!mrb_nil_p(scale_hash)) {
HASH_FLOAT(scale_hash, x, scale_x);
HASH_FLOAT(scale_hash, y, scale_y);
}
mrb_value pivot_hash = HASH_GET(kwargs, pivot);
if (!mrb_nil_p(pivot_hash)) {
HASH_FLOAT(pivot_hash, x, pivot_x);
HASH_FLOAT(pivot_hash, y, pivot_y);
}
HASH_FLOAT(kwargs, z, z);
HASH_FLOAT(kwargs, rotation, rotation);
HASH_FLOAT(kwargs, alpha, alpha);
mrb_value v = HASH_GET(kwargs, click_mode);
if (!mrb_nil_p(v)) {
click_mode_sym = mrb_symbol(v);
}
}
Wrapper *font_wrapper = (Wrapper *)DATA_PTR(font_val);
uint64_t id = font_wrapper->id;
font_pool.use(id);
Color color = {
(uint8_t)((color_i >> 16) & 0xFF),
(uint8_t)((color_i >> 8) & 0xFF),
(uint8_t)((color_i) & 0xFF)
};
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;
element->pivot = {pivot_x, pivot_y};
element->alpha = alpha;
element->z = z;
std::string click_mode = mrb_sym2name(mrb, click_mode_sym);
if (click_mode == "pass")
element->click_mode = ClickMode::PASS;
else if (click_mode == "block")
element->click_mode = ClickMode::BLOCK;
else if (click_mode == "ignore")
element->click_mode = ClickMode::IGNORE;
s->id = app::element_pool.acquire(element);
app::element_pool.use(s->id);
mrb_data_init(self, s, &ElementText_type);
return self;
}
mrb_value element_text_on_click(mrb_state *mrb, mrb_value self) {
mrb_value block;
mrb_get_args(mrb, "&", &block);
Wrapper *wrapper = (Wrapper *)DATA_PTR(self);
uint64_t id = wrapper->id;
app::Element *element = app::element_pool[id];
element->on_click.set_proc(block);
return self;
}
mrb_value element_text_equal(mrb_state *mrb, mrb_value self) {
mrb_value other;
mrb_get_args(mrb, "o", &other);
if (!mrb_obj_is_kind_of(mrb, other, definitions::bindings.ElementText.cls))
return mrb_false_value();
Wrapper *self_wrapper = (Wrapper *)DATA_PTR(self);
Wrapper *other_wrapper = (Wrapper *)DATA_PTR(other);
return mrb_bool_value(self_wrapper->id == other_wrapper->id);
}
mrb_value element_text_inspect(mrb_state *mrb, mrb_value self) {
Wrapper *wrapper = (Wrapper *)DATA_PTR(self);
uint64_t id = wrapper->id;
app::EText *element = (app::EText *)app::element_pool[id];
std::string str = "#<ElementText:0x"
+ std::format("0x{:016x}", id)
+ " key=:" + Localization::get_key_name(element->key)
+ " font_id=" + std::format("0x{:016x}", element->font_id)
+ ">";
return mrb_str_new_cstr(mrb, str.c_str());
}
mrb_value element_text_to_s(mrb_state *mrb, mrb_value self) {
Wrapper *wrapper = (Wrapper *)DATA_PTR(self);
uint64_t id = wrapper->id;
app::EText *element = (app::EText *)app::element_pool[id];
std::string localized_text = Localization::get(element->key, element->params);
return mrb_str_new_cstr(mrb, localized_text.c_str());
}
mrb_value element_text_hash(mrb_state *, mrb_value self) {
Wrapper *wrapper = (Wrapper *)DATA_PTR(self);
return mrb_fixnum_value(wrapper->id);
}
mrb_value element_text_key_get(mrb_state *mrb, mrb_value self) {
Wrapper *wrapper = (Wrapper *)DATA_PTR(self);
uint64_t id = wrapper->id;
app::EText *element = (app::EText *)app::element_pool[id];
return mrb_symbol_value(Localization::lang_to_sym(mrb, element->key));
}
mrb_value element_text_key_set(mrb_state *mrb, mrb_value self) {
mrb_sym key_sym;
mrb_get_args(mrb, "n", &key_sym);
Wrapper *wrapper = (Wrapper *)DATA_PTR(self);
uint64_t id = wrapper->id;
app::EText *element = (app::EText *)app::element_pool[id];
element->key = Localization::lang_from_sym(mrb, key_sym);
return mrb_nil_value();
}
mrb_value element_text_font_get(mrb_state *, mrb_value self) {
Wrapper *wrapper = (Wrapper *)DATA_PTR(self);
uint64_t id = wrapper->id;
app::EText *element = (app::EText *)app::element_pool[id];
if (element->font_id == UINT64_MAX)
return mrb_nil_value();
font_pool.use(element->font_id);
return wrap(definitions::bindings.Font, element->font_id);
}
mrb_value element_text_params(mrb_state *, mrb_value self) {
Wrapper *wrapper = (Wrapper *)DATA_PTR(self);
uint64_t id = wrapper->id;
app::element_pool.use(id);
return wrap(definitions::bindings.Params, id);
}
mrb_value element_text_font_set(mrb_state *mrb, mrb_value self) {
mrb_value font_val;
mrb_get_args(mrb, "o", &font_val);
if (!mrb_obj_is_kind_of(mrb, font_val, definitions::bindings.Font.cls)) {
mrb_raise(mrb, mrb_class_get(mrb, "Exception"), "Expected a Font object");
return mrb_nil_value();
}
Wrapper *font_wrapper = (Wrapper *)DATA_PTR(font_val);
uint64_t font_id = font_wrapper->id;
Wrapper *self_wrapper = (Wrapper *)DATA_PTR(self);
uint64_t id = self_wrapper->id;
app::EText *element = (app::EText *)app::element_pool[id];
if (element->font_id != UINT64_MAX)
font_pool.release(element->font_id);
element->font_id = font_id;
font_pool.use(font_id);
return mrb_nil_value();
}
mrb_value element_text_color_get(mrb_state *, mrb_value self) {
Wrapper *wrapper = (Wrapper *)DATA_PTR(self);
uint64_t id = wrapper->id;
app::EText *element = (app::EText *)app::element_pool[id];
return mrb_fixnum_value(
(element->color.r << 16) | (element->color.g << 8) | (element->color.b)
);
}
mrb_value element_text_color_set(mrb_state *mrb, mrb_value self) {
mrb_int color_val;
mrb_get_args(mrb, "i", &color_val);
Wrapper *wrapper = (Wrapper *)DATA_PTR(self);
uint64_t id = wrapper->id;
app::EText *element = (app::EText *)app::element_pool[id];
element->color = {
(uint8_t)((color_val >> 16) & 0xFF),
(uint8_t)((color_val >> 8) & 0xFF),
(uint8_t)((color_val) & 0xFF)
};
return mrb_nil_value();
}
mrb_value element_text_position_get(mrb_state *, mrb_value self) {
Wrapper *wrapper = (Wrapper *)DATA_PTR(self);
uint64_t id = wrapper->id;
app::EText *element = (app::EText *)app::element_pool[id];
return definitions::Vec2_wrap(id, &element->position);
}
mrb_value element_text_rotation_get(mrb_state *mrb, mrb_value self) {
Wrapper *wrapper = (Wrapper *)DATA_PTR(self);
uint64_t id = wrapper->id;
app::EText *element = (app::EText *)app::element_pool[id];
return mrb_float_value(mrb, element->rotation);
}
mrb_value element_text_rotation_set(mrb_state *mrb, mrb_value self) {
mrb_float rotation;
mrb_get_args(mrb, "f", &rotation);
Wrapper *wrapper = (Wrapper *)DATA_PTR(self);
uint64_t id = wrapper->id;
app::EText *element = (app::EText *)app::element_pool[id];
element->rotation = rotation;
return mrb_nil_value();
}
mrb_value element_text_pivot_get(mrb_state *, mrb_value self) {
Wrapper *wrapper = (Wrapper *)DATA_PTR(self);
uint64_t id = wrapper->id;
app::EText *element = (app::EText *)app::element_pool[id];
return definitions::Vec2_wrap(id, &element->pivot);
}
mrb_value element_text_scale_get(mrb_state *, mrb_value self) {
Wrapper *wrapper = (Wrapper *)DATA_PTR(self);
uint64_t id = wrapper->id;
app::EText *element = (app::EText *)app::element_pool[id];
return definitions::Vec2_wrap(id, &element->scale);
}
mrb_value element_text_alpha_get(mrb_state *mrb, mrb_value self) {
Wrapper *wrapper = (Wrapper *)DATA_PTR(self);
uint64_t id = wrapper->id;
app::EText *element = (app::EText *)app::element_pool[id];
return mrb_float_value(mrb, element->alpha);
}
mrb_value element_text_alpha_set(mrb_state *mrb, mrb_value self) {
mrb_float alpha;
mrb_get_args(mrb, "f", &alpha);
Wrapper *wrapper = (Wrapper *)DATA_PTR(self);
uint64_t id = wrapper->id;
app::EText *element = (app::EText *)app::element_pool[id];
element->alpha = alpha;
return mrb_nil_value();
}
mrb_value element_text_z_get(mrb_state *mrb, mrb_value self) {
Wrapper *wrapper = (Wrapper *)DATA_PTR(self);
uint64_t id = wrapper->id;
app::EText *element = (app::EText *)app::element_pool[id];
return mrb_float_value(mrb, element->z);
}
mrb_value element_text_z_set(mrb_state *mrb, mrb_value self) {
mrb_float z;
mrb_get_args(mrb, "f", &z);
Wrapper *wrapper = (Wrapper *)DATA_PTR(self);
uint64_t id = wrapper->id;
app::EText *element = (app::EText *)app::element_pool[id];
element->z = z;
return mrb_nil_value();
}
mrb_value element_text_click_mode_get(mrb_state *mrb, mrb_value self) {
Wrapper *wrapper = (Wrapper *)DATA_PTR(self);
uint64_t id = wrapper->id;
app::EText *element = (app::EText *)app::element_pool[id];
std::string click_mode_str;
switch (element->click_mode) {
case ClickMode::PASS:
click_mode_str = "pass";
break;
case ClickMode::BLOCK:
click_mode_str = "block";
break;
case ClickMode::IGNORE:
click_mode_str = "ignore";
break;
}
return mrb_symbol_value(mrb_intern_cstr(mrb, click_mode_str.c_str()));
}
mrb_value element_text_click_mode_set(mrb_state *mrb, mrb_value self) {
mrb_sym click_mode_sym;
mrb_get_args(mrb, "n", &click_mode_sym);
Wrapper *wrapper = (Wrapper *)DATA_PTR(self);
uint64_t id = wrapper->id;
app::EText *element = (app::EText *)app::element_pool[id];
std::string click_mode_str = mrb_sym2name(mrb, click_mode_sym);
if (click_mode_str == "pass")
element->click_mode = ClickMode::PASS;
else if (click_mode_str == "block")
element->click_mode = ClickMode::BLOCK;
else if (click_mode_str == "ignore")
element->click_mode = ClickMode::IGNORE;
return mrb_nil_value();
}
mrb_value element_text_width(mrb_state *mrb, mrb_value self) {
Wrapper *wrapper = (Wrapper *)DATA_PTR(self);
uint64_t id = wrapper->id;
app::EText *element = (app::EText *)app::element_pool[id];
return mrb_float_value(mrb, element->size().x);
}
mrb_value element_text_height(mrb_state *mrb, mrb_value self) {
Wrapper *wrapper = (Wrapper *)DATA_PTR(self);
uint64_t id = wrapper->id;
app::EText *element = (app::EText *)app::element_pool[id];
return mrb_float_value(mrb, element->size().y);
}
} // namespace
namespace definitions {
void register_element_text() {
DEF_CLASS(ElementText, MRB_ARGS_REQ(3) | MRB_ARGS_OPT(2));
ADD_METHOD(ElementText, "==", element_text_equal, MRB_ARGS_REQ(1));
ADD_METHOD(ElementText, "eql?", element_text_equal, MRB_ARGS_REQ(1));
ADD_METHOD(ElementText, "inspect", element_text_inspect, MRB_ARGS_NONE());
ADD_METHOD(ElementText, "hash", element_text_hash, MRB_ARGS_NONE());
ADD_METHOD(ElementText, "click", element_text_on_click, MRB_ARGS_BLOCK());
ADD_METHOD(ElementText, "to_s", element_text_to_s, MRB_ARGS_NONE());
ADD_METHOD(ElementText, "key=", element_text_key_set, MRB_ARGS_REQ(1));
ADD_METHOD(ElementText, "key", element_text_key_get, MRB_ARGS_NONE());
ADD_METHOD(ElementText, "color=", element_text_color_set, MRB_ARGS_REQ(1));
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());
ADD_METHOD(ElementText, "params", element_text_params, MRB_ARGS_NONE());
ADD_METHOD(ElementText, "position", element_text_position_get, MRB_ARGS_NONE());
ADD_METHOD(ElementText, "scale", element_text_scale_get, MRB_ARGS_NONE());
ADD_METHOD(ElementText, "rotation=", element_text_rotation_set, MRB_ARGS_REQ(1));
ADD_METHOD(ElementText, "rotation", element_text_rotation_get, MRB_ARGS_NONE());
ADD_METHOD(ElementText, "pivot", element_text_pivot_get, MRB_ARGS_NONE());
ADD_METHOD(ElementText, "alpha=", element_text_alpha_set, MRB_ARGS_REQ(1));
ADD_METHOD(ElementText, "alpha", element_text_alpha_get, MRB_ARGS_NONE());
ADD_METHOD(ElementText, "z=", element_text_z_set, MRB_ARGS_REQ(1));
ADD_METHOD(ElementText, "z", element_text_z_get, MRB_ARGS_NONE());
ADD_METHOD(ElementText, "click_mode=", element_text_click_mode_set, MRB_ARGS_REQ(1));
ADD_METHOD(ElementText, "click_mode", element_text_click_mode_get, MRB_ARGS_NONE());
ADD_METHOD(ElementText, "width", element_text_width, MRB_ARGS_NONE());
ADD_METHOD(ElementText, "height", element_text_height, MRB_ARGS_NONE());
bindings.ElementText = {ElementText_class, &ElementText_type};
}
} // namespace definitions
+72
View File
@@ -0,0 +1,72 @@
#include "bindings/definitions.h"
#include "window/window.h"
namespace {
void Font_free(mrb_state *mrb, void *ptr) {
UNUSED(mrb);
uint64_t id = ((Wrapper *)ptr)->id;
font_pool.release(id);
delete (Wrapper *)ptr;
}
const struct mrb_data_type Font_type = {"Font", Font_free};
mrb_value Font_init(mrb_state *mrb, mrb_value self) {
Wrapper *old = (Wrapper *)DATA_PTR(self);
if (old)
mrb_free(mrb, old);
mrb_data_init(self, nullptr, &Font_type);
Wrapper *s = new Wrapper();
char *path;
mrb_int size;
mrb_value kwargs;
mrb_get_args(mrb, "zi|H", &path, &size, &kwargs);
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);
mrb_data_init(self, s, &Font_type);
return self;
}
mrb_value font_equal(mrb_state *mrb, mrb_value self) {
mrb_value other;
mrb_get_args(mrb, "o", &other);
if (!mrb_obj_is_kind_of(mrb, other, definitions::bindings.Font.cls))
return mrb_false_value();
Wrapper *wrapper = (Wrapper *)DATA_PTR(self);
uint64_t id_self = wrapper->id;
Wrapper *other_wrapper = (Wrapper *)DATA_PTR(other);
uint64_t id_other = other_wrapper->id;
return mrb_bool_value(id_self == id_other);
}
mrb_value font_hash(mrb_state *, mrb_value self) {
Wrapper *wrapper = (Wrapper *)DATA_PTR(self);
return mrb_fixnum_value(wrapper->id);
}
} // namespace
namespace definitions {
void register_font() {
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));
ADD_METHOD(Font, "hash", font_hash, MRB_ARGS_NONE());
bindings.Font = {Font_class, &Font_type};
}
} // namespace definitions
+78
View File
@@ -0,0 +1,78 @@
#include "bindings/definitions.h"
#include "window/window.h"
namespace {
void Image_free(mrb_state *mrb, void *ptr) {
UNUSED(mrb);
uint64_t id = ((Wrapper *)ptr)->id;
image_pool.release(id);
delete (Wrapper *)ptr;
}
const struct mrb_data_type Image_type = {"Image", Image_free};
mrb_value Image_init(mrb_state *mrb, mrb_value self) {
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);
bool pixel_art = false;
if (!mrb_nil_p(kwargs))
HASH_BOOL(kwargs, pixel_art, pixel_art);
s->id = window.load_image(path, pixel_art);
mrb_data_init(self, s, &Image_type);
return self;
}
mrb_value image_equal(mrb_state *mrb, mrb_value self) {
mrb_value other;
mrb_get_args(mrb, "o", &other);
if (!mrb_obj_is_kind_of(mrb, other, definitions::bindings.Image.cls))
return mrb_false_value();
Wrapper *wrapper = (Wrapper *)DATA_PTR(self);
uint64_t id_self = wrapper->id;
Wrapper *other_wrapper = (Wrapper *)DATA_PTR(other);
uint64_t id_other = other_wrapper->id;
return mrb_bool_value(id_self == id_other);
}
mrb_value image_hash(mrb_state *, mrb_value self) {
Wrapper *wrapper = (Wrapper *)DATA_PTR(self);
return mrb_fixnum_value(wrapper->id);
}
mrb_value image_width(mrb_state *mrb, mrb_value self) {
Wrapper *wrapper = (Wrapper *)DATA_PTR(self);
uint64_t id = wrapper->id;
return mrb_float_value(mrb, window.get_image_size(id).x);
}
mrb_value image_height(mrb_state *mrb, mrb_value self) {
Wrapper *wrapper = (Wrapper *)DATA_PTR(self);
uint64_t id = wrapper->id;
return mrb_float_value(mrb, window.get_image_size(id).y);
}
} // namespace
namespace definitions {
void register_image() {
DEF_CLASS(Image, MRB_ARGS_REQ(1) | MRB_ARGS_OPT(1));
ADD_METHOD(Image, "==", image_equal, MRB_ARGS_REQ(1));
ADD_METHOD(Image, "eql?", image_equal, MRB_ARGS_REQ(1));
ADD_METHOD(Image, "hash", image_hash, MRB_ARGS_NONE());
ADD_METHOD(Image, "width", image_width, MRB_ARGS_NONE());
ADD_METHOD(Image, "height", image_height, MRB_ARGS_NONE());
bindings.Image = {Image_class, &Image_type};
}
} // namespace definitions
+68
View File
@@ -0,0 +1,68 @@
#include "app/app.h"
#include "bindings/definitions.h"
namespace {
void Params_free(mrb_state *mrb, void *ptr) {
UNUSED(mrb);
uint64_t id = ((Wrapper *)ptr)->id;
app::element_pool.release(id);
delete (Wrapper *)ptr;
}
const struct mrb_data_type Params_type = {"Params", Params_free};
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);
app::element_pool.use(id);
s->id = id;
mrb_data_init(self, s, &Params_type);
return self;
}
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());
}
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));
element->reload_text();
return mrb_nil_value();
}
} // namespace
namespace definitions {
void register_params() {
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));
bindings.Params = {Params_class, &Params_type};
}
} // namespace definitions
+199
View File
@@ -0,0 +1,199 @@
#include "app/app.h"
#include "bindings/definitions.h"
namespace {
void Scene_free(mrb_state *mrb, void *ptr) {
UNUSED(mrb);
uint64_t id = ((Wrapper *)ptr)->id;
app::scene_pool.release(id);
delete (Wrapper *)ptr;
}
const struct mrb_data_type Scene_type = {"Scene", Scene_free};
mrb_value Scene_init(mrb_state *mrb, mrb_value self) {
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;
}
mrb_value scene_add_element(mrb_state *mrb, mrb_value self) {
mrb_value element_val;
mrb_get_args(mrb, "o", &element_val);
if (
!mrb_obj_is_kind_of(mrb, element_val, definitions::bindings.ElementText.cls)
&& !mrb_obj_is_kind_of(mrb, element_val, definitions::bindings.ElementRect.cls)
&& !mrb_obj_is_kind_of(mrb, element_val, definitions::bindings.ElementImage.cls)
) {
mrb_raise(
mrb,
mrb_class_get(mrb, "Exception"),
"Expected an ElementText, ElementRect, or ElementImage object"
);
return mrb_nil_value();
}
Wrapper *wrapper = (Wrapper *)DATA_PTR(self);
app::Scene *scene = app::scene_pool[wrapper->id];
Wrapper *element_wrapper = (Wrapper *)DATA_PTR(element_val);
scene->add_element(element_wrapper->id);
return self;
}
mrb_value scene_delete_element(mrb_state *mrb, mrb_value self) {
mrb_value element_val;
mrb_get_args(mrb, "o", &element_val);
if (
!mrb_obj_is_kind_of(mrb, element_val, definitions::bindings.ElementText.cls)
&& !mrb_obj_is_kind_of(mrb, element_val, definitions::bindings.ElementRect.cls)
&& !mrb_obj_is_kind_of(mrb, element_val, definitions::bindings.ElementImage.cls)
) {
mrb_raise(
mrb,
mrb_class_get(mrb, "Exception"),
"Expected an ElementText, ElementRect, or ElementImage object"
);
return mrb_nil_value();
}
Wrapper *wrapper = (Wrapper *)DATA_PTR(self);
app::Scene *scene = app::scene_pool[wrapper->id];
Wrapper *element_wrapper = (Wrapper *)DATA_PTR(element_val);
scene->delete_element(element_wrapper->id);
return self;
}
mrb_value scene_on_update(mrb_state *mrb, mrb_value self) {
mrb_value block;
mrb_get_args(mrb, "&", &block);
Wrapper *wrapper = (Wrapper *)DATA_PTR(self);
app::Scene *scene = app::scene_pool[wrapper->id];
scene->update.set_proc(block);
return self;
}
mrb_value scene_elements_at(mrb_state *mrb, mrb_value self) {
mrb_value position_val;
mrb_get_args(mrb, "o", &position_val);
float x = 0, y = 0;
HASH_FLOAT(position_val, x, x);
HASH_FLOAT(position_val, y, y);
Vec2<float> position = {x, y};
Wrapper *wrapper = (Wrapper *)DATA_PTR(self);
app::Scene *scene = app::scene_pool[wrapper->id];
std::vector<uint64_t> element_ids = scene->elements_at(position);
mrb_value result = mrb_ary_new_capa(mrb, element_ids.size());
for (uint64_t element_id : element_ids) {
app::Element *element = app::element_pool[element_id];
app::element_pool.use(element_id);
if (element->type == Type::TEXT) {
mrb_value obj = definitions::wrap(definitions::bindings.ElementText, element_id);
mrb_ary_push(mrb, result, obj);
} else if (element->type == Type::RECT) {
mrb_value obj = definitions::wrap(definitions::bindings.ElementRect, element_id);
mrb_ary_push(mrb, result, obj);
} else if (element->type == Type::IMAGE) {
mrb_value obj = definitions::wrap(definitions::bindings.ElementImage, element_id);
mrb_ary_push(mrb, result, obj);
} else {
continue;
}
}
return result;
}
mrb_value scene_elements(mrb_state *mrb, mrb_value self) {
Wrapper *wrapper = (Wrapper *)DATA_PTR(self);
app::Scene *scene = app::scene_pool[wrapper->id];
std::vector<uint64_t> element_ids = scene->element_ids;
mrb_value result = mrb_ary_new_capa(mrb, element_ids.size());
for (uint64_t element_id : element_ids) {
app::Element *element = app::element_pool[element_id];
app::element_pool.use(element_id);
if (element->type == Type::TEXT) {
mrb_value obj = definitions::wrap(definitions::bindings.ElementText, element_id);
mrb_ary_push(mrb, result, obj);
} else if (element->type == Type::RECT) {
mrb_value obj = definitions::wrap(definitions::bindings.ElementRect, element_id);
mrb_ary_push(mrb, result, obj);
} else if (element->type == Type::IMAGE) {
mrb_value obj = definitions::wrap(definitions::bindings.ElementImage, element_id);
mrb_ary_push(mrb, result, obj);
} else {
continue;
}
}
return result;
}
mrb_value scene_equal(mrb_state *mrb, mrb_value self) {
mrb_value other;
mrb_get_args(mrb, "o", &other);
if (!mrb_obj_is_kind_of(mrb, other, definitions::bindings.Scene.cls))
return mrb_false_value();
Wrapper *self_wrapper = (Wrapper *)DATA_PTR(self);
uint64_t id_self = self_wrapper->id;
Wrapper *other_wrapper = (Wrapper *)DATA_PTR(other);
uint64_t id_other = other_wrapper->id;
return mrb_bool_value(id_self == id_other);
}
mrb_value scene_inspect(mrb_state *mrb, mrb_value self) {
Wrapper *wrapper = (Wrapper *)DATA_PTR(self);
uint64_t id = wrapper->id;
return mrb_str_new_cstr(mrb, ("#<Scene:" + std::to_string(id) + ">").c_str());
}
mrb_value scene_hash(mrb_state *, mrb_value self) {
Wrapper *wrapper = (Wrapper *)DATA_PTR(self);
uint64_t id = wrapper->id;
return mrb_fixnum_value(id);
}
} // namespace
namespace definitions {
void register_scene() {
DEF_CLASS(Scene, MRB_ARGS_NONE());
ADD_METHOD(Scene, "==", scene_equal, MRB_ARGS_REQ(1));
ADD_METHOD(Scene, "eql?", scene_equal, MRB_ARGS_REQ(1));
ADD_METHOD(Scene, "inspect", scene_inspect, MRB_ARGS_NONE());
ADD_METHOD(Scene, "to_s", scene_inspect, MRB_ARGS_NONE());
ADD_METHOD(Scene, "hash", scene_hash, MRB_ARGS_NONE());
ADD_METHOD(Scene, "<<", scene_add_element, MRB_ARGS_REQ(1));
ADD_METHOD(Scene, "delete", scene_delete_element, MRB_ARGS_REQ(1));
ADD_METHOD(Scene, "remove", scene_delete_element, MRB_ARGS_REQ(1));
ADD_METHOD(Scene, "update", scene_on_update, MRB_ARGS_BLOCK());
ADD_METHOD(Scene, "elements_at", scene_elements_at, MRB_ARGS_REQ(1));
ADD_METHOD(Scene, "elements", scene_elements, MRB_ARGS_NONE());
bindings.Scene = {Scene_class, &Scene_type};
}
} // namespace definitions
+90
View File
@@ -0,0 +1,90 @@
#include "app/app.h"
#include "bindings/definitions.h"
namespace {
struct Vec2Wrapper : public Wrapper {
Vec2<float> *vec;
};
void Vec2_free(mrb_state *mrb, void *ptr) {
UNUSED(mrb);
uint64_t id = ((Wrapper *)ptr)->id;
app::element_pool.release(id);
delete (Wrapper *)ptr;
}
const struct mrb_data_type Vec2_type = {"Vec2", Vec2_free};
mrb_value Vec2_init(mrb_state *mrb, mrb_value self) {
Wrapper *old = (Wrapper *)DATA_PTR(self);
if (old)
mrb_free(mrb, old);
mrb_data_init(self, nullptr, &Vec2_type);
Vec2Wrapper *s = new Vec2Wrapper();
mrb_int id;
mrb_get_args(mrb, "i", &id);
app::element_pool.use(id);
s->id = id;
s->vec = &((app::EText *)app::element_pool[id])->position;
mrb_data_init(self, s, &Vec2_type);
return self;
}
mrb_value vec2_x(mrb_state *mrb, mrb_value self) {
Vec2Wrapper *s = (Vec2Wrapper *)DATA_PTR(self);
return mrb_float_value(mrb, s->vec->x);
}
mrb_value vec2_y(mrb_state *mrb, mrb_value self) {
Vec2Wrapper *s = (Vec2Wrapper *)DATA_PTR(self);
return mrb_float_value(mrb, s->vec->y);
}
mrb_value vec2_x_set(mrb_state *mrb, mrb_value self) {
mrb_float x;
mrb_get_args(mrb, "f", &x);
Vec2Wrapper *s = (Vec2Wrapper *)DATA_PTR(self);
s->vec->x = (float)x;
return mrb_nil_value();
}
mrb_value vec2_y_set(mrb_state *mrb, mrb_value self) {
mrb_float y;
mrb_get_args(mrb, "f", &y);
Vec2Wrapper *s = (Vec2Wrapper *)DATA_PTR(self);
s->vec->y = (float)y;
return mrb_nil_value();
}
} // namespace
namespace definitions {
void register_vec2() {
DEF_CLASS(Vec2, MRB_ARGS_REQ(2));
ADD_METHOD(Vec2, "x", vec2_x, MRB_ARGS_NONE());
ADD_METHOD(Vec2, "y", vec2_y, MRB_ARGS_NONE());
ADD_METHOD(Vec2, "x=", vec2_x_set, MRB_ARGS_REQ(1));
ADD_METHOD(Vec2, "y=", vec2_y_set, MRB_ARGS_REQ(1));
bindings.Vec2 = {Vec2_class, &Vec2_type};
}
mrb_value Vec2_wrap(uint64_t id, Vec2<float> *vec) {
RBasic *obj_b = mrb_obj_alloc(Ruby::mrb, MRB_TT_DATA, bindings.Vec2.cls);
mrb_value obj = mrb_obj_value(obj_b);
Vec2Wrapper *w = new Vec2Wrapper();
app::element_pool.use(id);
w->id = id;
w->vec = vec;
mrb_data_init(obj, w, &Vec2_type);
return obj;
}
} // namespace definitions
+1 -1
View File
@@ -1,4 +1,4 @@
#include "binding/definitions.h"
#include "bindings/definitions.h"
int main(int argc, char *argv[]) {
Ruby::load_mgems();