Fixed stores in gui

This commit is contained in:
Cooldude2606
2019-10-15 22:37:48 +01:00
parent 258ca8dbde
commit 3b5c69cfd1
103 changed files with 213 additions and 243 deletions

View File

@@ -105,7 +105,7 @@ Gui.classes.checkbox = Checkbox
Checkbox._prototype_radiobutton:on_store_update(callback) --- Registers a handler for when the stored value updates
Checkbox._prototype_radiobutton:add_as_option(option_set,option_name) --- Adds this radiobutton to be an option in the given option set (only one can be true at a time)
Checkbox.new_option_set(name,callback,categorize) --- Registers a new option set that can be linked to radiobuttons (only one can be true at a time)
Checkbox.new_option_set(callback,categorize) --- Registers a new option set that can be linked to radiobuttons (only one can be true at a time)
Checkbox.draw_option_set(name,element) --- Draws all radiobuttons that are part of an option set at once (Gui.draw will not work)
Checkbox.reset_radiobutton(element,exclude,recursive) --- Sets all radiobuttons in a element to false (unless excluded) and can act recursively

View File

@@ -74,14 +74,12 @@ local Checkbox = {
_prototype_checkbox=Prototype.extend{
on_element_update = Prototype.event,
on_store_update = Prototype.event,
add_store = Prototype.store(false,store_update),
add_sync_store = Prototype.store(true,store_update)
add_store = Prototype.store(store_update)
},
_prototype_radiobutton=Prototype.extend{
on_element_update = Prototype.event,
on_store_update = Prototype.event,
add_store = Prototype.store(false,store_update),
add_sync_store = Prototype.store(true,store_update)
add_store = Prototype.store(store_update)
}
}
@@ -96,8 +94,7 @@ function Checkbox.new_checkbox(name)
self:on_draw(function(player,element)
if self.store then
local category = self.categorize and self.categorize(element) or nil
local state = self:get_store(category,true)
local state = self:get_store(element,true)
if state then element.state = true end
end
end)
@@ -107,13 +104,11 @@ function Checkbox.new_checkbox(name)
if self.option_set then
local value = Checkbox.option_sets[self.option_set][element.name]
local category = self.categorize and self.categorize(element)
self:set_store(category,value)
self:set_store(element,value)
elseif self.store then
local value = element.state
local category = self.categorize and self.categorize(element)
self:set_store(category,value)
self:set_store(element,value)
else
self:raise_event('on_element_update',event.player,element,element.state)
@@ -175,15 +170,15 @@ function Checkbox._prototype_radiobutton:set_store(category,value,internal)
end
--- Registers a new option set that can be linked to radiobuttons (only one can be true at a time)
-- @tparam string name the name of the option set, must be unique
-- @tparam function callback the update callback when the value of the option set changes
-- callback param - value string - the new selected option for this option set
-- callback param - category string - the category that updated if categorize was used
-- @tparam function categorize the function used to convert an element into a string
-- @treturn string the name of this option set to be passed to add_as_option
function Checkbox.new_option_set(name,callback,categorize)
function Checkbox.new_option_set(callback,categorize)
local name = Store.register(categorize)
Store.register(name,function(value,category)
Store.watch(name,function(value,category)
local options = Checkbox.option_sets[name]
for opt_name,define_name in pairs(options) do
if Gui.defines[define_name] then

View File

@@ -47,8 +47,7 @@ local Dropdown = {
_prototype=Prototype.extend{
on_element_update = Prototype.event,
on_store_update = Prototype.event,
add_store = Prototype.store(false,store_update),
add_sync_store = Prototype.store(true,store_update)
add_store = Prototype.store(store_update)
}
}
@@ -71,8 +70,7 @@ function Dropdown.new_dropdown(name)
end
if self.store then
local category = self.categorize and self.categorize(element) or nil
local value = self:get_store(category)
local value = self:get_store(element)
if value then Dropdown.select_value(element,value) end
end
end)
@@ -82,8 +80,7 @@ function Dropdown.new_dropdown(name)
local value = Dropdown.get_selected_value(element)
if self.store then
local category = self.categorize and self.categorize(element) or value
self:set_store(category,value)
self:set_store(element,value)
else
local player = event.player

View File

@@ -37,8 +37,7 @@ local ElemButton = {
_prototype=Prototype.extend{
on_element_update = Prototype.event,
on_store_update = Prototype.event,
add_store = Prototype.store(false,store_update),
add_sync_store = Prototype.store(true,store_update)
add_store = Prototype.store(store_update)
}
}
@@ -56,8 +55,7 @@ function ElemButton.new_elem_button(name)
end
if self.store then
local category = self.categorize and self.categorize(element) or nil
local value = self:get_store(category)
local value = self:get_store(element)
if value then element.elem_value = value end
end
end)
@@ -67,8 +65,7 @@ function ElemButton.new_elem_button(name)
local value = element.elem_value
if self.store then
local category = self.categorize and self.categorize(element) or value
self:set_store(category,value)
self:set_store(element,value)
else
self:raise_event('on_element_update',event.player,element,value)

View File

@@ -64,8 +64,7 @@ local ProgressBar = {
_prototype=Prototype.extend{
on_complete = Prototype.event,
on_store_complete = Prototype.event,
add_store = Prototype.store(false,store_update),
add_sync_store = Prototype.store(true,store_update)
add_store = Prototype.store(store_update)
}
}
@@ -194,11 +193,10 @@ function ProgressBar.new_progressbar(name)
self:on_draw(function(player,element,maximum)
if self.store then
local category = self.categorize and self.categorize(element) or nil
local value = self:get_store(category)
local value = self:get_store(element)
if not value then
value = self.count_down and 1 or 0
self:set_store(category,value)
self:set_store(element,value)
end
element.value = value
@@ -350,8 +348,7 @@ function ProgressBar._prototype:reset_element(element)
if not element or not element.valid then return end
local value = self.count_down and 1 or 0
if self.store then
local category = self.categorize and self.categorize(element) or value
self:set_store(category,value)
self:set_store(element,value)
else
element.value = value
end

View File

@@ -61,8 +61,7 @@ local Slider = {
_prototype=Prototype.extend{
on_element_update = Prototype.event,
on_store_update = Prototype.event,
add_store = Prototype.store(false,store_update),
add_sync_store = Prototype.store(true,store_update)
add_store = Prototype.store(store_update)
}
}
@@ -88,8 +87,7 @@ function Slider.new_slider(name)
element.set_slider_minimum_maximum(min,max)
if self.store then
local category = self.categorize and self.categorize(element) or nil
local value = self:get_store(category)
local value = self:get_store(element)
if value then element.slider_value = value end
end
@@ -103,8 +101,7 @@ function Slider.new_slider(name)
local value = element.slider_value
if self.store then
local category = self.categorize and self.categorize(element) or value
self:set_store(category,value)
self:set_store(element,value)
else
event_call(self,element,value)
@@ -144,8 +141,7 @@ function Slider._prototype:draw_label(element)
local value = 0
if self.store then
local category = self.categorize and self.categorize(element) or value
value = self:get_store(category) or 0
value = self:get_store(element) or 0
end
local new_element = element.add{

View File

@@ -40,14 +40,12 @@ local Text = {
_prototype_field=Prototype.extend{
on_element_update = Prototype.event,
on_store_update = Prototype.event,
add_store = Prototype.store(false,store_update),
add_sync_store = Prototype.store(true,store_update)
add_store = Prototype.store(store_update)
},
_prototype_box=Prototype.extend{
on_element_update = Prototype.event,
on_store_update = Prototype.event,
add_store = Prototype.store(false,store_update),
add_sync_store = Prototype.store(true,store_update)
add_store = Prototype.store(store_update)
}
}
@@ -73,8 +71,7 @@ function Text.new_text_field(name)
end
if self.store then
local category = self.categorize and self.categorize(element) or nil
local value = self:get_store(category)
local value = self:get_store(element)
if value then element.text = value end
end
end)
@@ -84,8 +81,7 @@ function Text.new_text_field(name)
local value = element.text
if self.store then
local category = self.categorize and self.categorize(element) or value
self:set_store(category,value)
self:set_store(element,value)
else
self:raise_event('on_element_update',event.player,element,value)

View File

@@ -15,10 +15,10 @@
the caption of all of them at once; this is where this module comes it.
First you must register the way that the instances are stored and under what name, using Instances.register you will give the
name of the collective group of instances followed by an optional categorise function which allows variants to be stored under one
name of the collective group of instances followed by an optional serializer function which allows variants to be stored under one
name (like one for each force or player)
-- categorise works in the same way as store categorise
-- serializer works in the same way as store serializer
-- so the function will world here but no value is stored only gui elements
Instances.register('score',Gui.categorize_by_force)
@@ -34,7 +34,7 @@
element.caption = 0
end)
Note that if you don't give a categorise function then you don't need to give a category when getting the elements.
Note that if you don't give a serializer function then you don't need to give a category when getting the elements.
>>>> Using unregistered instance groups
When using a registered group and the functions that go with them it is much simpler to use and more importantly includes error checking
@@ -72,9 +72,9 @@
end) -- gets all instances and sets the element caption to 0
>>>> Functions
Instances.has_categories(name) --- Returns if a instance group has a categorise function; must be registered
Instances.has_categories(name) --- Returns if a instance group has a serializer function; must be registered
Instances.is_registered(name) --- Returns if the given name is a registered instance group
Instances.register(name,categorise) --- Registers the name of an instance group to allow for storing element instances
Instances.register(name,serializer) --- Registers the name of an instance group to allow for storing element instances
Instances.add_element(name,element) --- Adds an element to the instance group under the correct category; must be registered
Instances.get_elements_raw(name,category) --- Gets all element instances without first removing any invalid ones; used internally and must be registered
@@ -86,46 +86,46 @@
local Global = require 'utils.global' --- @dep utils.global
local Instances = {
categorise={},
serializer={},
data={}
}
Global.register(Instances.data,function(tbl)
Instances.data = tbl
end)
--- Returns if a instance group has a categorise function; must be registered
--- Returns if a instance group has a serializer function; must be registered
-- @tparam string name the name of the instance group
-- @treturn boolean true if there is a categorise function
-- @treturn boolean true if there is a serializer function
function Instances.has_categories(name)
return type(Instances.categorise[name]) == 'function'
return type(Instances.serializer[name]) == 'function'
end
--- Returns if the given name is a registered instance group
-- @tparam string name the name of the instance group you are testing
-- @treturn boolean true if the name is registered
function Instances.is_registered(name)
return Instances.categorise[name] ~= nil
return Instances.serializer[name] ~= nil
end
--- Registers the name of an instance group to allow for storing element instances
-- @tparam string name the name of the instance group; must to unique
-- @tparam[opt] function categorise function used to turn the element into a string
-- categorise param - element LuaGuiElement - the gui element to be turned into a string
-- categorise return - string - the category that the element will be added to like the player's name or force's name
-- @tparam[opt] function serializer function used to turn the element into a string
-- serializer param - element LuaGuiElement - the gui element to be turned into a string
-- serializer return - string - the category that the element will be added to like the player's name or force's name
-- @treturn string the name that was added so it can be used as a variable
function Instances.register(name,categorise)
function Instances.register(name,serializer)
if _LIFECYCLE ~= _STAGE.control then
return error('Can only be called during the control stage', 2)
end
if Instances.categorise[name] then
if Instances.serializer[name] then
return error('Instances for '..name..' already exist.',2)
end
categorise = type(categorise) == 'function' and categorise or true
serializer = type(serializer) == 'function' and serializer or true
Instances.data[name] = {}
Instances.categorise[name] = categorise
Instances.serializer[name] = serializer
return name
end
@@ -134,12 +134,12 @@ end
-- @tparam string name the name of the instance group to add the element to
-- @tparam LuaGuiElement element the element to add the the instance group
function Instances.add_element(name,element)
if not Instances.categorise[name] then
if not Instances.serializer[name] then
return error('Invalid name for instance group: '..name,2)
end
if Instances.has_categories(name) then
local category = Instances.categorise[name](element)
local category = Instances.serializer[name](element)
if not Instances.data[name][category] then Instances.data[name][category] = {} end
table.insert(Instances.data[name][category],element)
else
@@ -149,10 +149,10 @@ end
--- Gets all element instances without first removing any invalid ones; used internally and must be registered
-- @tparam string name the name of the instance group to get the instances of
-- @tparam[opt] string category the category to get the instance from, not needed when no categorise function
-- @tparam[opt] string category the category to get the instance from, not needed when no serializer function
-- @treturn table the table of element instances of which some may be invalid
function Instances.get_elements_raw(name,category)
if not Instances.categorise[name] then
if not Instances.serializer[name] then
return error('Invalid name for instance group: '..name,2)
end
@@ -165,24 +165,24 @@ end
--- Gets all valid element instances and has the option of running a callback on those that are valid
-- @tparam string name the name of the instance group to get the instances of
-- @tparam[opt] string category the category to get the instances of, not needed when no categorise function
-- @tparam[opt] string category the category to get the instances of, not needed when no serializer function
-- @tparam[opt] function callback when given the callback will be ran on all valid elements
-- callback param - element LuaGuiElement - the current valid element
-- @treturn table the table of element instances with all invalid ones removed
function Instances.get_valid_elements(name,category,callback)
if not Instances.categorise[name] then
if not Instances.serializer[name] then
return error('Invalid 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)
local serializer = 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)
if serializer and callback then callback(element)
elseif category then category(element) end
end
end

View File

@@ -27,9 +27,9 @@
Prototype:raise_event(event_name,...) --- Raises a custom event for this define, any number of params can be given
Prototype:draw_to(element,...) --- The main function for defines, when called will draw an instance of this define to the given element
Prototype:get_store(category) --- Gets the value in this elements store, category needed if categorize function used
Prototype:set_store(category,value) --- Sets the value in this elements store, category needed if categorize function used
Prototype:clear_store(category) --- Sets the value in this elements store to nil, category needed if categorize function used
Prototype:get_store(category) --- Gets the value in this elements store, category needed if serializer function used
Prototype:set_store(category,value) --- Sets the value in this elements store, category needed if serializer function used
Prototype:clear_store(category) --- Sets the value in this elements store to nil, category needed if serializer function used
]]
local Game = require 'utils.game' --- @dep utils.game
local Store = require 'expcore.store' --- @dep expcore.store
@@ -82,29 +82,22 @@ function Constructor.extend(new_prototype)
end
--- Creates a new function which adds a store to a gui define
-- @tparam boolean sync if the function should create a synced store
-- @tparam function callback the function called when needing to update the value of an element
-- @treturn function the function that will add a store for this define
function Constructor.store(sync,callback)
--- Adds a store for the define that is shared between all instances of the define in the same category, categorize is a function that returns a string
function Constructor.store(callback)
--- Adds a store for the define that is shared between all instances of the define in the same category, serializer is a function that returns a string
-- @tparam self table the gui define being acted on
-- @tparam[opt] string location a unique location identifier, when omitted a uid location will be used, use when sync is set to true
-- @tparam[opt] function categorize function used to determine the category of a LuaGuiElement, when omitted all share one single category
-- categorize param - LuaGuiElement element - the element that needs to be converted
-- categorize return - string - a deterministic string that references to a category such as player name or force name
-- @tparam[opt] function serializer function used to determine the category of a LuaGuiElement, when omitted all share one single category
-- serializer param - LuaGuiElement element - the element that needs to be converted
-- serializer return - string - a deterministic string that references to a category such as player name or force name
-- @treturn self the element define to allow chaining
return function(self,location,categorize)
return function(self,serializer)
if self.store then return end
serializer = serializer or function() return '' end
if not sync then
categorize = location
location = Store.register()
end
self.store = Store.register(serializer)
self.store = location
self.categorize = categorize
Instances.register(self.name,self.categorize)
Instances.register(self.name,serializer)
Store.watch(self.store,function(value,category)
self:raise_event('on_store_update',value,category)
@@ -274,12 +267,12 @@ function Prototype:draw_to(element,...)
Instances.add_element(self.name,new_element)
end
self:raise_event('on_draw',player,new_element)
self:raise_event('on_draw',player,new_element,...)
return new_element
end
--- Gets the value in this elements store, category needed if categorize function used
--- Gets the value in this elements store, category needed if serializer function used
-- @tparam string category[opt] the category to get such as player name or force name
-- @treturn any the value that is stored for this define
function Prototype:get_store(category)
@@ -287,7 +280,7 @@ function Prototype:get_store(category)
return Store.get(self.store,category)
end
--- Sets the value in this elements store, category needed if categorize function used
--- Sets the value in this elements store, category needed if serializer function used
-- @tparam string category[opt] the category to get such as player name or force name
-- @tparam any value the value to set for this define, must be valid for its type ie for checkbox etc
-- @treturn boolean true if the value was set
@@ -296,7 +289,7 @@ function Prototype:set_store(category,value)
return Store.set(self.store,category,value)
end
--- Sets the value in this elements store to nil, category needed if categorize function used
--- Sets the value in this elements store to nil, category needed if serializer function used
-- @tparam[opt] string category the category to get such as player name or force name
-- @treturn boolean true if the value was set
function Prototype:clear_store(category)

View File

@@ -279,7 +279,7 @@ Gui.new_radiobutton('test-radiobutton-store')
end)
local radiobutton_option_set =
Gui.new_radiobutton_option_set('gui.test.share',function(value,category)
Gui.new_radiobutton_option_set(function(value,category)
game.print('Radiobutton option set for: '..category..' is now: '..tostring(value))
end,Gui.categorize_by_player)