#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(); mrb_float width, height; mrb_value kwargs; mrb_get_args(mrb, "ff|H", &width, &height, &kwargs); bool pixel_art = false; if (!mrb_nil_p(kwargs)) HASH_BOOL(kwargs, pixel_art, pixel_art); s->id = window.create_image({(float)width, (float)height}, pixel_art); mrb_data_init(self, s, &Image_type); return self; } mrb_value image_load(mrb_state *mrb, mrb_value) { 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); uint64_t id = window.load_image(path, pixel_art); return definitions::wrap(definitions::bindings.Image, id); } 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); } mrb_value image_update(mrb_state *mrb, mrb_value self) { Wrapper *wrapper = (Wrapper *)DATA_PTR(self); uint64_t id = wrapper->id; mrb_float x, y, width, height; char *new_content; mrb_int length; mrb_get_args(mrb, "ffffs", &x, &y, &width, &height, &new_content, &length); bool success = window.update_image( id, Rect::from( {(float)x, (float)y}, {(float)width, (float)height} ), new_content, (uint32_t)length ); return mrb_bool_value(success); } } // namespace namespace definitions { void register_image() { DEF_CLASS(Image, MRB_ARGS_REQ(2) | MRB_ARGS_OPT(1)); ADD_CLASS_METHOD(Image, "load", image_load, MRB_ARGS_REQ(2) | 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()); ADD_METHOD(Image, "update", image_update, MRB_ARGS_REQ(5)); bindings.Image = {Image_class, &Image_type}; } } // namespace definitions