diff --git a/expcore/Gui/core.lua b/expcore/Gui/core.lua index 6e4e9a3e..011bf283 100644 --- a/expcore/Gui/core.lua +++ b/expcore/Gui/core.lua @@ -152,17 +152,13 @@ ]] local Gui = require 'utils.gui' local Game = require 'utils.game' -local Global = require 'utils.global' local Store = require 'expcore.store' +local Instances = require 'expcore.gui.instances' Gui._prototype = {} -- Stores the base prototype of all element defines Gui.classes = {} -- Stores the class definations used to create element defines Gui.defines = {} -- Stores the indivdual element definations Gui.names = {} -- Stores debug names to link to gui uids -Gui.instances = {} -- Stores runtime data of all active instances of an element define -Global.register(Gui.instances,function(tbl) - Gui.instances = tbl -end) --- Used internally to create new prototypes for element defines -- @tparam tbl table a table that will have functions added to it @@ -211,24 +207,18 @@ function Gui._store_factory(callback) self.store = Store.uid_location() self.categorize = categorize - Gui.instances[self.name]={} + + Instances.register(self.name,self.categorize) Store.register(self.store,function(value,category) if self.events.on_store_update then self.events.on_store_update(value,category) end - local instances = Gui.get_instances(self,category) - if instances then - - for k,element in pairs(instances) do - if element and element.valid then - callback(self,element,value) - else - instances[k] = nil - end - end - + if Instances.is_registered(self.name) then + Instances.apply_to_elements(self.name,category,function(element) + callback(self,element,value) + end) end end) @@ -256,24 +246,18 @@ function Gui._sync_store_factory(callback) self.store = location self.categorize = categorize - Gui.instances[self.name]={} + + Instances.register(self.name,self.categorize) Store.register_synced(self.store,function(value,category) if self.events.on_store_update then self.events.on_store_update(value,category) end - local instances = Gui.get_instances(self,category) - if instances then - - for k,element in pairs(instances) do - if element and element.valid then - callback(self,element,value) - else - instances[k] = nil - end - end - + if Instances.is_registered(self.name) then + Instances.apply_to_elements(self,category,function(element) + callback(self,element,value) + end) end end) @@ -380,12 +364,8 @@ function Gui._prototype:draw_to(element) new_element.enabled = self.post_authenticator(player,self.name) end - if self.store then - local category = self.categorize and self.categorize(element) or nil - local instances = Gui.get_instances(self,category) - if instances then - table.insert(instances,new_element) - end + if Instances.is_registered(self.name) then + Instances.add_element(self.name,new_element) end if self.post_draw then self.post_draw(new_element) end @@ -442,24 +422,6 @@ function Gui.get_define(name,internal) return define end ---- Gets all instances of the element define, mostly internal use and note invalid elements may be present in the return --- @tparam name string the uid or debug name for the define to get the instances for --- @tparam[opt] category string the category to get the instances for --- @treturn table a table of LuaGuiElements that might be invalid which belong to this define -function Gui.get_instances(name,category) - local define = Gui.get_define(name,true) - if not Gui.instances[define.name] then return end - - local instances = Gui.instances[define.name] - if define.categorize then - if not instances[category] then instances[category] = {} end - return instances[category] - - end - - return instances -end - --- Gets the value that is stored for a given element define, category needed if categorize function used -- @tparam name ?string|table the uid, debug name or define for the element define to get -- @tparam[opt] category string the category to get the value for diff --git a/expcore/Gui/instances.lua b/expcore/Gui/instances.lua new file mode 100644 index 00000000..72532a4b --- /dev/null +++ b/expcore/Gui/instances.lua @@ -0,0 +1,117 @@ +--- This file is a breakout from core which forcues on instance management of defines +local Global = require 'utils.global' + +local Instances = { + categorise={}, + data={} +} +Global.register(Instances.data,function(tbl) + Instances.data = tbl +end) + +function Instances.has_categories(name) + return type(Instances.categorise[name]) == 'function' +end + +function Instances.is_registered(name) + return Instances.categorise[name] ~= nil +end + +function Instances.register(name,categorise) + if _LIFECYCLE ~= _STAGE.control then + return error('Can only be called during the control stage', 2) + end + + if Instances.categorise[name] then + return error('Instances for '..name..' already exist.',2) + end + + categorise = type(categorise) == 'function' and categorise or true + + Instances.data[name] = {} + Instances.categorise[name] = categorise + + return name +end + +function Instances.add_element(name,element) + if not Instances.categorise[name] then + return error('Inavlid name for instance group: '..name,2) + end + + if Instances.has_categories(name) then + local category = Instances.categorise[name](element) + if not Instances.data[name][category] then Instances.data[name][category] = {} end + table.insert(Instances.data[name][category],element) + else + table.insert(Instances.data[name],element) + end +end + +function Instances.get_elements_raw(name,category) + if not Instances.categorise[name] then + return error('Inavlid name for instance group: '..name,2) + end + + if Instances.has_categories(name) then + return Instances.data[name][category] or {} + else + return Instances.data[name] + end +end + +function Instances.get_valid_elements(name,category,callback) + if not Instances.categorise[name] then + return error('Inavlid name for instance group: '..name,2) + end + + category = category or callback + local elements = Instances.get_elements_raw(name,category) + local categorise = Instances.has_categories(name) + + for key,element in pairs(elements) do + if not element or not element.valid then + elements[key] = nil + else + if categorise and callback then callback(element) + elseif category then category(element) end + end + end + + return elements +end +Instances.get_elements = Instances.get_valid_elements +Instances.apply_to_elements = Instances.get_valid_elements + +function Instances.unregistered_add_element(name,categorise,element) + if not Instances.data[name] then Instances.data[name] = {} end + if type(categorise) == 'function' then + local category = categorise(element) + if not Instances.data[name][category] then Instances.data[name][category] = {} end + table.insert(Instances.data[name][category],element) + else + table.insert(Instances.data[name],element) + end +end + +function Instances.unregistered_get_elements(name,category,callback) + local elements = Instances.data[name] + if category then + elements = Instances.data[name][category] + end + + if not elements then return {} end + + for key,element in pairs(elements) do + if not element or not element.valid then + elements[key] = nil + else + if callback then callback(element) end + end + end + + return elements +end +Instances.unregistered_apply_to_elements = Instances.runtime_get_elements + +return Instances \ No newline at end of file diff --git a/expcore/Gui/slider.lua b/expcore/Gui/slider.lua index adf1b2c8..eb1ba17a 100644 --- a/expcore/Gui/slider.lua +++ b/expcore/Gui/slider.lua @@ -13,47 +13,9 @@ Other functions present from expcore.gui.core ]] local Gui = require './core' +local Instances = require './instances' local Game = require 'utils.game' ---- Gets the active lables for a define --- @tparam define table the define to get the labels for --- @tparam element LuaGuiElement the element that will be used to get the category --- @treturn table the table of active instances for the slider lables -local function get_labels(define,element) - local function cat(e) - return e.player_index - end - - local name = define.name..'-label' - if not Gui.instances[name] then return end - - local categorize = define.categorize or not define.store and cat - local category = categorize and categorize(element) or nil - local instances = Gui.get_instances({ - name=name, - categorize=categorize - },category) - - return instances -end - ---- Gets and updates the label values --- @tparam define table the define to get the labels for --- @tparam element LuaGuiElement the element that will be used to get the category -local function update_lables(define,element) - local instances = get_labels(define,element) - local value = element.slider_value - if instances then - for k,instance in pairs(instances) do - if instance and instance.valid then - instance.caption = tostring(math.round(value,2)) - else - instances[k]=nil - end - end - end -end - --- Event call for on_value_changed and store update -- @tparam define table the define that this is acting on -- @tparam element LuaGuiElement the element that triggered the event @@ -69,7 +31,14 @@ local function event_call(define,element,value) define.events.on_element_update(player,element,value,percent) end - update_lables(define,element) + local category = player.name + if define.categorize then + category = define.categorize(element) + end + + Instances.unregistered_get_elements(define.name..'-label',category,function(label) + label.caption = tostring(math.round(value,2)) + end) end --- Store call for store update @@ -183,10 +152,9 @@ function Slider._prototype:draw_label(element) caption=tostring(math.round(value,2)) } - if not Gui.instances[name] then Gui.instances[name] = {} end + local categorise = self.categorise or Gui.player_store - local labels = get_labels(self,element) - table.insert(labels,new_element) + Instances.unregistered_add_element(name,categorise,new_element) return new_element end diff --git a/expcore/gui.lua b/expcore/gui.lua index 73618784..12af5c47 100644 --- a/expcore/gui.lua +++ b/expcore/gui.lua @@ -36,6 +36,13 @@ local Gui = require('./gui/core') Gui.toggle_visible(element) --- Will toggle the visiblity of an element ]] +local Instances = require('./gui/instances') +Gui.new_instance_group = Instances.registers +Gui.get_instances = Instances.get_elements +Gui.add_instance = Instances.get_elements +Gui.update_instances = Instances.apply_to_elements +Gui.classes.instances = Instances + local Button = require('./gui/buttons') Gui.new_button = Button.new_button Gui.classes.button = Button