From ec8042864703f9ce6cc9b0cf528e6a8528104b89 Mon Sep 17 00:00:00 2001 From: Vas Crabb Date: Wed, 25 Nov 2020 19:18:26 +1100 Subject: Fairly significant overhaul of Lua engine and some cleanup. The things that were previously called device iterators are not iterators in the C++ sense of the word. This is confusing for newcomers. These have been renamed to be device enumerators. Several Lua methods and properties that previously returned tables now return lightweight wrappers for the underlying objects. This means creating them is a lot faster, but you can't modify them, and the performance characteristics of different operations varies. The render manager's target list uses 1-based indexing to be more like idiomatic Lua. It's now possible to create a device enumerator on any device, and then get subdevices (or sibling devices) using a relative tag. Much more render/layout functionality has been exposed to Lua. Layout scripts now have access to the layout file and can directly set the state of an item with no bindings, or register callbacks to obtain state. Some things that were previously methods are now read-only properties. Layout files are no longer required to supply a "name". This was problematic because the same layout file could be loaded for multiple instances of the same device, and each instance of the layout file should use the correct inputs (and in the future outputs) for the device instance it's associated with. This should also fix video output with MSVC builds by avoiding delegates that return things that don't fit in a register. --- src/emu/render.h | 66 ++++++++++++++++++++++++++++++++++++++++++++------------ 1 file changed, 52 insertions(+), 14 deletions(-) (limited to 'src/emu/render.h') diff --git a/src/emu/render.h b/src/emu/render.h index 3dc7376957c..e24893033c6 100644 --- a/src/emu/render.h +++ b/src/emu/render.h @@ -176,7 +176,7 @@ namespace emu::render::detail { struct bounds_step { - constexpr render_bounds get() const { return bounds; } + void get(render_bounds &result) const { result = bounds; } int state; render_bounds bounds; @@ -186,7 +186,7 @@ using bounds_vector = std::vector; struct color_step { - constexpr render_color get() const { return color; } + void get(render_color &result) const { result = color; } int state; render_color color; @@ -735,6 +735,10 @@ public: friend class layout_view; public: + using state_delegate = delegate; + using bounds_delegate = delegate; + using color_delegate = delegate; + // construction/destruction item( view_environment &env, @@ -746,12 +750,13 @@ public: ~item(); // getters + std::string const &id() const { return m_id; } layout_element *element() const { return m_element; } screen_device *screen() { return m_screen; } bool bounds_animated() const { return m_bounds.size() > 1U; } bool color_animated() const { return m_color.size() > 1U; } - render_bounds bounds() const { return m_get_bounds(); } - render_color color() const { return m_get_color(); } + render_bounds bounds() const { render_bounds result; m_get_bounds(result); return result; } + render_color color() const { render_color result; m_get_color(result); return result; } int blend_mode() const { return m_blend_mode; } u32 visibility_mask() const { return m_visibility_mask; } int orientation() const { return m_orientation; } @@ -766,24 +771,35 @@ public: int element_state() const { return m_get_elem_state(); } int animation_state() const { return m_get_anim_state(); } + // set state + void set_state(int state) { m_elem_state = state; } + + // set handlers + void set_element_state_callback(state_delegate &&handler); + void set_animation_state_callback(state_delegate &&handler); + void set_bounds_callback(bounds_delegate &&handler); + void set_color_callback(color_delegate &&handler); + // resolve tags, if any void resolve_tags(); private: using bounds_vector = emu::render::detail::bounds_vector; using color_vector = emu::render::detail::color_vector; - using state_delegate = delegate; - using bounds_delegate = delegate; - using color_delegate = delegate; + state_delegate default_get_elem_state(); + state_delegate default_get_anim_state(); + bounds_delegate default_get_bounds(); + color_delegate default_get_color(); + int get_state() const; int get_output() const; int get_input_raw() const; int get_input_field_cached() const; int get_input_field_conditional() const; int get_anim_output() const; int get_anim_input() const; - render_bounds get_interpolated_bounds() const; - render_color get_interpolated_color() const; + void get_interpolated_bounds(render_bounds &result) const; + void get_interpolated_color(render_color &result) const; static layout_element *find_element(view_environment &env, util::xml::data_node const &itemnode, element_map &elemmap); static bounds_vector make_bounds(view_environment &env, util::xml::data_node const &itemnode, layout_group::transform const &trans); @@ -804,26 +820,28 @@ public: output_finder<> m_output; // associated output output_finder<> m_animoutput; // associated output for animation if different ioport_port * m_animinput_port; // input port used for animation + int m_elem_state; // element state used in absence of bindings ioport_value const m_animmask; // mask for animation state u8 const m_animshift; // shift for animation state ioport_port * m_input_port; // input port of this item ioport_field const * m_input_field; // input port field of this item ioport_value const m_input_mask; // input mask of this item u8 const m_input_shift; // input mask rightshift for raw (trailing 0s) - bool const m_input_raw; // get raw data from input port bool m_clickthrough; // should click pass through to lower elements screen_device * m_screen; // pointer to screen - int m_orientation; // orientation of this item + int const m_orientation; // orientation of this item bounds_vector m_bounds; // bounds of the item color_vector const m_color; // color of the item int m_blend_mode; // blending mode to use when drawing u32 m_visibility_mask; // combined mask of parent visibility groups // cold items + std::string const m_id; // optional unique item identifier std::string const m_input_tag; // input tag of this item std::string const m_animinput_tag; // tag of input port for animation state bounds_vector const m_rawbounds; // raw (original) bounds of the item bool const m_have_output; // whether we actually have an output + bool const m_input_raw; // get raw data from input port bool const m_have_animoutput; // whether we actually have an output for animation bool const m_has_clickthrough; // whether clickthrough was explicitly configured }; @@ -893,9 +911,11 @@ public: ~layout_view(); // getters + item *get_item(std::string const &id); item_list &items() { return m_items; } bool has_screen(screen_device &screen); const std::string &name() const { return m_name; } + const std::string &unqualified_name() const { return m_unqualified_name; } size_t visible_screen_count() const { return m_screens.size(); } float effective_aspect() const { return m_effaspect; } const render_bounds &bounds() const { return m_bounds; } @@ -920,6 +940,12 @@ public: private: struct layer_lists; + using item_id_map = std::unordered_map< + std::reference_wrapper, + item &, + std::hash, + std::equal_to >; + // add items, recursing for groups void add_items( layer_lists &layers, @@ -937,7 +963,6 @@ private: static std::string make_name(layout_environment &env, util::xml::data_node const &viewnode); // internal state - std::string m_name; // name of the layout float m_effaspect; // X/Y of the layout in current configuration render_bounds m_bounds; // computed bounds of the view in current configuration item_list m_items; // list of layout items @@ -949,6 +974,9 @@ private: screen_ref_vector m_screens; // list screens visible in current configuration // cold items + std::string m_name; // display name for the view + std::string m_unqualified_name; // the name exactly as specified in the layout file + item_id_map m_items_by_id; // items with non-empty ID indexed by ID visibility_toggle_vector m_vistoggles; // collections of items that can be shown/hidden render_bounds m_expbounds; // explicit bounds of the view u32 m_defvismask; // default visibility mask @@ -966,16 +994,24 @@ public: using element_map = std::unordered_map; using group_map = std::unordered_map; using view_list = std::list; + using resolve_tags_delegate = delegate; // construction/destruction layout_file(device_t &device, util::xml::data_node const &rootnode, char const *searchpath, char const *dirname); ~layout_file(); // getters + device_t &device() const { return m_device; } element_map const &elements() const { return m_elemmap; } view_list &views() { return m_viewlist; } view_list const &views() const { return m_viewlist; } + // resolve tags, if any + void resolve_tags(); + + // set handlers + void set_resolve_tags_callback(resolve_tags_delegate &&handler); + private: using environment = emu::render::detail::layout_environment; @@ -988,8 +1024,10 @@ private: bool init); // internal state - element_map m_elemmap; // list of shared layout elements - view_list m_viewlist; // list of views + device_t & m_device; // device that caused file to be loaded + element_map m_elemmap; // list of shared layout elements + view_list m_viewlist; // list of views + resolve_tags_delegate m_resolve_tags; // additional actions after resolving tags }; // ======================> render_target -- cgit v1.2.3