#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 = "#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