From c5c335d17caf996a6d0be1b4787e3c4e011c0754 Mon Sep 17 00:00:00 2001 From: Insality Date: Fri, 11 Mar 2022 20:37:18 +0200 Subject: [PATCH] Optimize component and event creation, add cache for interests, optimize scroll --- druid/base/scroll.lua | 12 ++++------ druid/component.lua | 41 ++++++++++++++------------------- druid/event.lua | 16 +++++++++++-- druid/extended/data_list.lua | 2 +- druid/system/druid_instance.lua | 9 ++++---- 5 files changed, 41 insertions(+), 39 deletions(-) diff --git a/druid/base/scroll.lua b/druid/base/scroll.lua index ec2eeb3..01fbdd4 100755 --- a/druid/base/scroll.lua +++ b/druid/base/scroll.lua @@ -140,6 +140,7 @@ function Scroll.init(self, view_node, content_node) self.druid = self:get_druid() self.view_node = self:get_node(view_node) + self.view_border = helper.get_border(self.view_node) self.content_node = self:get_node(content_node) self.view_size = vmath.mul_per_elem(gui.get_size(self.view_node), gui.get_scale(self.view_node)) @@ -419,15 +420,14 @@ function Scroll.is_node_in_view(self, node) end local node_border = helper.get_border(node, node_offset_for_view) - local view_border = helper.get_border(self.view_node) -- Check is vertical outside (Left or Right): - if node_border.z < view_border.x or node_border.x > view_border.z then + if node_border.z < self.view_border.x or node_border.x > self.view_border.z then return false end -- Check is horizontal outside (Up or Down): - if node_border.w > view_border.y or node_border.y < view_border.w then + if node_border.w > self.view_border.y or node_border.y < self.view_border.w then return false end @@ -693,12 +693,10 @@ end function Scroll._update_size(self) - local view_border = helper.get_border(self.view_node) - local content_border = helper.get_border(self.content_node) local content_size = vmath.mul_per_elem(gui.get_size(self.content_node), gui.get_scale(self.content_node)) - self.available_pos = get_border_vector(view_border - content_border, self._offset) + self.available_pos = get_border_vector(self.view_border - content_border, self._offset) self.available_size = get_size_vector(self.available_pos) self.drag.can_x = self.available_size.x > 0 and self._is_horizontal_scroll @@ -727,7 +725,7 @@ function Scroll._update_size(self) self.drag.can_y = content_size.y > self.view_size.y end - self.available_pos_extra = get_border_vector(view_border - content_border_extra, self._offset) + self.available_pos_extra = get_border_vector(self.view_border - content_border_extra, self._offset) self.available_size_extra = get_size_vector(self.available_pos_extra) self:_set_scroll_position(self.position) diff --git a/druid/component.lua b/druid/component.lua index 62266ed..e63fecf 100644 --- a/druid/component.lua +++ b/druid/component.lua @@ -12,6 +12,7 @@ local helper = require("druid.helper") local BaseComponent = class("druid.component") +local INTERESTS = {} -- Cache interests by component class in runtime local IS_AUTO_TEMPLATE = not (sys.get_config("druid.no_auto_template") == "1") @@ -270,13 +271,7 @@ end -- @tparam BaseComponent self @{BaseComponent} -- @treturn BaseComponent|nil The druid component instance or nil function BaseComponent.get_parent_component(self) - local context = self:get_context() - - if context.isInstanceOf and context:isInstanceOf(BaseComponent) then - return context - end - - return nil + return self._meta.parent end @@ -285,26 +280,27 @@ end -- @tparam table druid_instance The parent druid instance -- @tparam table context Druid context. Usually it is self of script -- @tparam table style Druid style module +-- @tparam table instance_class The component instance class -- @treturn component BaseComponent itself -- @local -function BaseComponent.setup_component(self, druid_instance, context, style) +function BaseComponent.setup_component(self, druid_instance, context, style, instance_class) self._meta = { template = "", - context = nil, + context = context, nodes = nil, style = nil, druid = druid_instance, input_enabled = true, - children = {} + children = {}, + parent = type(context) ~= "userdata" and context, + instance_class = instance_class } - self:__set_context(context) self:set_style(style) self:set_template("") - local parent = self:get_parent_component() - if parent then - parent:__add_children(self) + if self._meta.parent then + self._meta.parent:__add_children(self) end return self @@ -370,20 +366,16 @@ function BaseComponent.__tostring(self) end ---- Set current component context --- @tparam BaseComponent self @{BaseComponent} --- @tparam table context Druid context. Usually it is self of script --- @local -function BaseComponent.__set_context(self, context) - self._meta.context = context -end - - --- Get current component interests -- @tparam BaseComponent self @{BaseComponent} -- @treturn table List of component interests -- @local function BaseComponent.__get_interests(self) + local instance_class = self._meta.instance_class + if INTERESTS[instance_class] then + return INTERESTS[instance_class] + end + local interests = {} for index = 1, #BaseComponent.ALL_INTERESTS do local interest = BaseComponent.ALL_INTERESTS[index] @@ -392,7 +384,8 @@ function BaseComponent.__get_interests(self) end end - return interests + INTERESTS[instance_class] = interests + return INTERESTS[instance_class] end diff --git a/druid/event.lua b/druid/event.lua index 2500a2c..e540de8 100644 --- a/druid/event.lua +++ b/druid/event.lua @@ -13,7 +13,7 @@ local DruidEvent = class("druid.event") -- @tparam DruidEvent self @{DruidEvent} -- @tparam function initial_callback Subscribe the callback on new event, if callback exist function DruidEvent.initialize(self, initial_callback) - self._callbacks = {} + self._callbacks = nil -- initialize later if initial_callback then self:subscribe(initial_callback) @@ -29,6 +29,7 @@ function DruidEvent.subscribe(self, callback, context) assert(type(self) == "table", "You should subscribe to event with : syntax") assert(type(callback) == "function", "Callback should be function") + self._callbacks = self._callbacks or {} table.insert(self._callbacks, { callback = callback, context = context @@ -43,6 +44,10 @@ end -- @tparam function callback Callback itself -- @tparam table context Additional context as first param to callback call function DruidEvent.unsubscribe(self, callback, context) + if not self._callbacks then + return + end + for index, callback_info in ipairs(self._callbacks) do if callback_info.callback == callback and callback_info.context == context then table.remove(self._callbacks, index) @@ -56,6 +61,9 @@ end -- @tparam DruidEvent self @{DruidEvent} -- @treturn bool True if event have handlers function DruidEvent.is_exist(self) + if not self._callbacks then + return false + end return #self._callbacks > 0 end @@ -63,7 +71,7 @@ end --- Clear the all event handlers -- @tparam DruidEvent self @{DruidEvent} function DruidEvent.clear(self) - self._callbacks = {} + self._callbacks = nil end @@ -71,6 +79,10 @@ end -- @tparam DruidEvent self @{DruidEvent} -- @tparam any ... All event params function DruidEvent.trigger(self, ...) + if not self._callbacks then + return false + end + for index, callback_info in ipairs(self._callbacks) do if callback_info.context then callback_info.callback(callback_info.context, ...) diff --git a/druid/extended/data_list.lua b/druid/extended/data_list.lua index bbef209..db14b35 100644 --- a/druid/extended/data_list.lua +++ b/druid/extended/data_list.lua @@ -44,8 +44,8 @@ function DataList.init(self, scroll, grid, create_function) self.druid = self:get_druid() self.scroll = scroll self.grid = grid - self.scroll:bind_grid(grid) self.grid.style.IS_DYNAMIC_NODE_POSES = false + self.scroll:bind_grid(grid) -- Current visual elements indexes self.top_index = 1 diff --git a/druid/system/druid_instance.lua b/druid/system/druid_instance.lua index 8c291e6..dea1439 100755 --- a/druid/system/druid_instance.lua +++ b/druid/system/druid_instance.lua @@ -61,9 +61,10 @@ local data_list = require("druid.extended.data_list") local DruidInstance = class("druid.druid_instance") +local IS_NO_AUTO_INPUT = sys.get_config("druid.no_auto_input") == "1" local function input_init(self) - if self._no_auto_input then + if IS_NO_AUTO_INPUT then return end @@ -75,7 +76,7 @@ end local function input_release(self) - if self._no_auto_input then + if IS_NO_AUTO_INPUT then return end @@ -105,7 +106,7 @@ end -- Create the component itself local function create(self, instance_class) local instance = instance_class() - instance:setup_component(self, self._context, self._style) + instance:setup_component(self, self._context, self._style, instance_class) table.insert(self.components_all, instance) @@ -206,7 +207,6 @@ function DruidInstance.initialize(self, context, style) self._input_blacklist = nil self._input_whitelist = nil - self._no_auto_input = (sys.get_config("druid.no_auto_input") == "1") self.components_interest = {} self.components_all = {} @@ -239,7 +239,6 @@ function DruidInstance.new(self, component, ...) instance:init(...) end - self:log_message("Create component", { name = instance:get_name(), parent = instance:get_parent_name() }) return instance end