diff --git a/include/app/app.h b/include/app/app.h index d1bacd4..c4b7b68 100644 --- a/include/app/app.h +++ b/include/app/app.h @@ -169,10 +169,9 @@ struct Scene { } } - void update_scene(uint64_t delta_time) { + void update_scene(mrb_value dt_val) { if (mrb_nil_p(update.proc)) return; - mrb_value dt_val = mrb_float_value(Ruby::mrb, delta_time / 1e9); update.call(1, &dt_val); } @@ -200,6 +199,8 @@ struct Scene { } else if (e->click_mode == ClickMode::BLOCK) { result.push_back(*it); break; + } else { + continue; } } } @@ -240,6 +241,7 @@ struct App { std::vector released_keys; Vec2 scroll = {0, 0}; std::string text = ""; + Ruby::Block update; void exit() { running = false; @@ -335,7 +337,12 @@ struct App { } } - scene->update_scene(dt); + int ai = mrb_gc_arena_save(Ruby::mrb); + mrb_value dt_val = mrb_float_value(Ruby::mrb, dt / 1e9); + update.call(1, &dt_val); + scene->update_scene(dt_val); + mrb_gc_arena_restore(Ruby::mrb, ai); + scene->render(window, window.get_time()); window.render(); diff --git a/include/binding/definitions.h b/include/binding/definitions.h index 56115fd..cb16c0f 100644 --- a/include/binding/definitions.h +++ b/include/binding/definitions.h @@ -1629,6 +1629,22 @@ static mrb_value app_start(mrb_state *mrb, mrb_value) { return mrb_nil_value(); } +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); +} + +static 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(); +} + static mrb_value app_switch_to(mrb_state *mrb, mrb_value) { mrb_value scene_val; mrb_get_args(mrb, "o", &scene_val); @@ -1772,7 +1788,7 @@ inline void setup() { 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, "on_click", element_text_on_click, MRB_ARGS_BLOCK()); + 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()); @@ -1807,7 +1823,7 @@ inline void setup() { 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, "on_click", element_rect_on_click, MRB_ARGS_BLOCK()); + 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)); @@ -1830,7 +1846,7 @@ inline void setup() { ADD_METHOD(ElementRect, "click_mode", element_rect_click_mode_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, "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()); @@ -1862,7 +1878,7 @@ inline void setup() { 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, "on_update", scene_on_update, MRB_ARGS_BLOCK()); + 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()); @@ -1870,6 +1886,8 @@ inline void setup() { 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)); diff --git a/samples/button.rb b/samples/button.rb index 2570367..4f2d972 100644 --- a/samples/button.rb +++ b/samples/button.rb @@ -12,19 +12,32 @@ bg_animation = Animation.new [bg_image1, bg_image2], fps: 5 App.language = :en App.localize(:en, :btn_text, "Click %{name}!") -text = ElementText.new :btn_text, default_font, 0xFFFF00, {name: "Me"}, position: {x: 50, y: 50}, z: 1, click_mode: :pass, alpha: 1 +text = ElementText.new :btn_text, default_font, 0xFFFF00, {name: "Me"}, position: {x: 50, y: 50}, z: 1, click_mode: :block, alpha: 1 -rect = ElementRect.new 100, 25, 0xFF0000, position: {x: 50, y: 50}, z: 0, rotation: 60, scale: { x: 1, y: 1 }, alpha: 0.4 +rect = ElementRect.new 100, 25, 0xFF0000, position: {x: 50, y: 50}, z: 0, rotation: 60, scale: { x: 1, y: 1 }, alpha: 0.8, click_mode: :block image_element = ElementImage.new bg_animation, position: {x: 0, y: 0}, z: -1, click_mode: :ignore, alpha: 1 pp text, rect, image_element -rect.on_click do +end_scene = Scene.new +end_scene << rect + +text.click do + App.switch_to end_scene +end + +image_element.click do + pp "Image clicked" +end + +rect.click do + pp "Rect clicked", rect.color.to_s(16) + rect.color = rect.color == 0xFF0000 ? 0x00FF00 : 0xFF0000 - main_scene << text unless main_scene.elements.include?(text) + text.params[:name] = text.params[:name] == "Me" ? "You" : "Me" @@ -37,7 +50,7 @@ start = Time.now c_ = 0.0 c_c = 0 -main_scene.on_update do |delta_time| +App.update do |delta_time| c_ += delta_time c_c += 1 @@ -45,7 +58,7 @@ main_scene.on_update do |delta_time| # commented out to avoid spamming the console, but you can uncomment to see the delta time being printed every frame # runs at 60fps, so you should see around 16-17ms being printed - el = main_scene.elements_at(App.mouse_position) + el = App.scene.elements_at(App.mouse_position) pp App.text_input if App.text_input != "" @@ -68,8 +81,6 @@ main_scene << text main_scene << rect main_scene << image_element -main_scene.delete(text) - App.start main_scene time = Time.now - start diff --git a/writeup/analysis.md b/writeup/analysis.md index 1462576..3220faf 100644 --- a/writeup/analysis.md +++ b/writeup/analysis.md @@ -260,6 +260,8 @@ extra: - network interface, with a lib to work with rack backends (and generic socket api) - persistence store - rng helpers +- tweening system +- layout system ## Embedded scripting language choice.