mirror of
https://github.com/PHIDIAS0303/ExpCluster.git
synced 2025-12-31 04:51:40 +09:00
Changed store to use a single function
This commit is contained in:
@@ -1,6 +1,6 @@
|
|||||||
--- Config for the different action buttons that show on the player list
|
--- Config for the different action buttons that show on the player list
|
||||||
-- each button has the button define(s) given along side an auth function, and optional reason callback
|
-- each button has the button define(s) given along side an auth function, and optional reason callback
|
||||||
-- if a reason callback is used then Store.set_child(action_name_store,player.name,'BUTTON_NAME') should be called during on_click
|
-- if a reason callback is used then Store.set(action_name_store,player.name,'BUTTON_NAME') should be called during on_click
|
||||||
-- buttons can be removed from the gui by commenting them out of the config at the bottom of this file
|
-- buttons can be removed from the gui by commenting them out of the config at the bottom of this file
|
||||||
-- the key used for the name of the button is the permision name used by the role system
|
-- the key used for the name of the button is the permision name used by the role system
|
||||||
local Gui = require 'expcore.gui'
|
local Gui = require 'expcore.gui'
|
||||||
@@ -34,7 +34,7 @@ end
|
|||||||
|
|
||||||
-- gets the action player and a coloured name for the action to be used on
|
-- gets the action player and a coloured name for the action to be used on
|
||||||
local function get_action_player_name(player)
|
local function get_action_player_name(player)
|
||||||
local action_player_name = Store.get_child(action_player_store,player.name)
|
local action_player_name = Store.get(action_player_store,player.name)
|
||||||
local action_player = Game.get_player_from_any(action_player_name)
|
local action_player = Game.get_player_from_any(action_player_name)
|
||||||
local action_player_name_color = format_chat_player_name(action_player)
|
local action_player_name_color = format_chat_player_name(action_player)
|
||||||
return action_player,action_player_name_color
|
return action_player,action_player_name_color
|
||||||
@@ -109,7 +109,7 @@ Gui.new_button()
|
|||||||
if Reports.player_is_reported_by(action_player_name,player.name) then
|
if Reports.player_is_reported_by(action_player_name,player.name) then
|
||||||
player.print({'expcom-report.already-reported'},Colors.orange_red)
|
player.print({'expcom-report.already-reported'},Colors.orange_red)
|
||||||
else
|
else
|
||||||
Store.set_child(action_name_store,player.name,'command/report')
|
Store.set(action_name_store,player.name,'command/report')
|
||||||
end
|
end
|
||||||
end)
|
end)
|
||||||
|
|
||||||
@@ -128,7 +128,7 @@ Gui.new_button()
|
|||||||
:set_tooltip{'player-list.warn-player'}
|
:set_tooltip{'player-list.warn-player'}
|
||||||
:set_style('tool_button',tool_button_style)
|
:set_style('tool_button',tool_button_style)
|
||||||
:on_click(function(player,element)
|
:on_click(function(player,element)
|
||||||
Store.set_child(action_name_store,player.name,'command/give-warning')
|
Store.set(action_name_store,player.name,'command/give-warning')
|
||||||
end)
|
end)
|
||||||
|
|
||||||
local function warn_player_callback(player,reason)
|
local function warn_player_callback(player,reason)
|
||||||
@@ -149,7 +149,7 @@ Gui.new_button()
|
|||||||
if Roles.player_has_role(action_player_name,'Jail') then
|
if Roles.player_has_role(action_player_name,'Jail') then
|
||||||
player.print({'expcom-jail.already-jailed',action_player_name_color},Colors.orange_red)
|
player.print({'expcom-jail.already-jailed',action_player_name_color},Colors.orange_red)
|
||||||
else
|
else
|
||||||
Store.set_child(action_name_store,player.name,'command/jail')
|
Store.set(action_name_store,player.name,'command/jail')
|
||||||
end
|
end
|
||||||
end)
|
end)
|
||||||
|
|
||||||
@@ -171,7 +171,7 @@ Gui.new_button()
|
|||||||
if Roles.player_has_role(action_player_name,'Jail') then
|
if Roles.player_has_role(action_player_name,'Jail') then
|
||||||
player.print({'expcom-jail.already-banned',action_player_name_color},Colors.orange_red)
|
player.print({'expcom-jail.already-banned',action_player_name_color},Colors.orange_red)
|
||||||
else
|
else
|
||||||
Store.set_child(action_name_store,player.name,'command/temp-ban')
|
Store.set(action_name_store,player.name,'command/temp-ban')
|
||||||
end
|
end
|
||||||
end)
|
end)
|
||||||
|
|
||||||
@@ -189,7 +189,7 @@ Gui.new_button()
|
|||||||
:set_tooltip{'player-list.kick-player'}
|
:set_tooltip{'player-list.kick-player'}
|
||||||
:set_style('tool_button',tool_button_style)
|
:set_style('tool_button',tool_button_style)
|
||||||
:on_click(function(player,element)
|
:on_click(function(player,element)
|
||||||
Store.set_child(action_name_store,player.name,'command/kick')
|
Store.set(action_name_store,player.name,'command/kick')
|
||||||
end)
|
end)
|
||||||
|
|
||||||
local function kick_player_callback(player,reason)
|
local function kick_player_callback(player,reason)
|
||||||
@@ -204,7 +204,7 @@ Gui.new_button()
|
|||||||
:set_tooltip{'player-list.ban-player'}
|
:set_tooltip{'player-list.ban-player'}
|
||||||
:set_style('tool_button',tool_button_style)
|
:set_style('tool_button',tool_button_style)
|
||||||
:on_click(function(player,element)
|
:on_click(function(player,element)
|
||||||
Store.set_child(action_name_store,player.name,'command/ban')
|
Store.set(action_name_store,player.name,'command/ban')
|
||||||
end)
|
end)
|
||||||
|
|
||||||
local function ban_player_callback(player,reason)
|
local function ban_player_callback(player,reason)
|
||||||
|
|||||||
@@ -112,12 +112,12 @@ function Checkbox.new_checkbox(name)
|
|||||||
|
|
||||||
if self.option_set then
|
if self.option_set then
|
||||||
local value = Checkbox.option_sets[self.option_set][element.name]
|
local value = Checkbox.option_sets[self.option_set][element.name]
|
||||||
local category = self.categorize and self.categorize(element) or value
|
local category = self.categorize and self.categorize(element)
|
||||||
self:set_store(category,value)
|
self:set_store(category,value)
|
||||||
|
|
||||||
elseif self.store then
|
elseif self.store then
|
||||||
local value = element.state
|
local value = element.state
|
||||||
local category = self.categorize and self.categorize(element) or value
|
local category = self.categorize and self.categorize(element)
|
||||||
self:set_store(category,value)
|
self:set_store(category,value)
|
||||||
|
|
||||||
else
|
else
|
||||||
@@ -166,12 +166,7 @@ end
|
|||||||
function Checkbox._prototype_radiobutton:get_store(category,internal)
|
function Checkbox._prototype_radiobutton:get_store(category,internal)
|
||||||
if not self.store then return end
|
if not self.store then return end
|
||||||
local location = not internal and self.option_set or self.store
|
local location = not internal and self.option_set or self.store
|
||||||
|
return Store.get(location,category)
|
||||||
if self.categorize then
|
|
||||||
return Store.get_child(location,category)
|
|
||||||
else
|
|
||||||
return Store.get(location)
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|
||||||
--- Sets the stored value of the radiobutton or the option set if present
|
--- Sets the stored value of the radiobutton or the option set if present
|
||||||
@@ -182,12 +177,7 @@ end
|
|||||||
function Checkbox._prototype_radiobutton:set_store(category,value,internal)
|
function Checkbox._prototype_radiobutton:set_store(category,value,internal)
|
||||||
if not self.store then return end
|
if not self.store then return end
|
||||||
local location = not internal and self.option_set or self.store
|
local location = not internal and self.option_set or self.store
|
||||||
|
return Store.set(location,category,value)
|
||||||
if self.categorize then
|
|
||||||
return Store.set_child(location,category,value)
|
|
||||||
else
|
|
||||||
return Store.set(location,category)
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|
||||||
--- Registers a new option set that can be linked to radiobutotns (only one can be true at a time)
|
--- Registers a new option set that can be linked to radiobutotns (only one can be true at a time)
|
||||||
|
|||||||
@@ -255,7 +255,7 @@ function Gui._sync_store_factory(callback)
|
|||||||
|
|
||||||
Instances.register(self.name,self.categorize)
|
Instances.register(self.name,self.categorize)
|
||||||
|
|
||||||
Store.register_synced(self.store,function(value,category)
|
Store.register(self.store,true,function(value,category)
|
||||||
if self.events.on_store_update then
|
if self.events.on_store_update then
|
||||||
self.events.on_store_update(value,category)
|
self.events.on_store_update(value,category)
|
||||||
end
|
end
|
||||||
@@ -419,24 +419,24 @@ end
|
|||||||
-- @treturn any the value that is stored for this define
|
-- @treturn any the value that is stored for this define
|
||||||
function Gui._prototype:get_store(category)
|
function Gui._prototype:get_store(category)
|
||||||
if not self.store then return end
|
if not self.store then return end
|
||||||
if self.categorize then
|
return Store.get(self.store,category)
|
||||||
return Store.get_child(self.store,category)
|
|
||||||
else
|
|
||||||
return Store.get(self.store)
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|
||||||
--- Sets the value in this elements store, category needed if categorize function used
|
--- Sets the value in this elements store, category needed if categorize function used
|
||||||
-- @tparam string category[opt] the category to get such as player name or force name
|
-- @tparam string category[opt] the category to get such as player name or force name
|
||||||
-- @tparam boolean any value the value to set for this define, must be valid for its type ie for checkbox etc
|
-- @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
|
-- @treturn boolean true if the value was set
|
||||||
function Gui._prototype:set_store(category,value)
|
function Gui._prototype:set_store(category,value)
|
||||||
if not self.store then return end
|
if not self.store then return end
|
||||||
if self.categorize then
|
return Store.set(self.store,category,value)
|
||||||
return Store.set_child(self.store,category,value)
|
end
|
||||||
else
|
|
||||||
return Store.set(self.store,category)
|
--- Sets the value in this elements store to nil, category needed if categorize function used
|
||||||
end
|
-- @tparam[opt] string category the category to get such as player name or force name
|
||||||
|
-- @treturn boolean true if the value was set
|
||||||
|
function Gui._prototype:clear_store(category)
|
||||||
|
if not self.store then return end
|
||||||
|
return Store.clear(self.store,category)
|
||||||
end
|
end
|
||||||
|
|
||||||
--- Gets an element define give the uid, debug name or a copy of the element define
|
--- Gets an element define give the uid, debug name or a copy of the element define
|
||||||
|
|||||||
@@ -250,8 +250,7 @@ local function change_value_prototype(self,amount,category,filter)
|
|||||||
|
|
||||||
local function reset_store()
|
local function reset_store()
|
||||||
local value = self.count_down and 1 or 0
|
local value = self.count_down and 1 or 0
|
||||||
local _category = category or value
|
self:set_store(category,value)
|
||||||
self:set_store(_category,value)
|
|
||||||
end
|
end
|
||||||
|
|
||||||
if self.store then
|
if self.store then
|
||||||
@@ -261,15 +260,13 @@ local function change_value_prototype(self,amount,category,filter)
|
|||||||
|
|
||||||
if self.count_down and new_value <= 0
|
if self.count_down and new_value <= 0
|
||||||
or not self.count_down and new_value >= 1 then
|
or not self.count_down and new_value >= 1 then
|
||||||
self:set_store(category)
|
self:clear_store(category)
|
||||||
|
|
||||||
if self.events.on_store_complete then
|
if self.events.on_store_complete then
|
||||||
category = category or reset_store
|
|
||||||
self.events.on_store_complete(category,reset_store)
|
self.events.on_store_complete(category,reset_store)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
category = category or new_value
|
|
||||||
self:set_store(category,new_value)
|
self:set_store(category,new_value)
|
||||||
|
|
||||||
return
|
return
|
||||||
|
|||||||
@@ -652,7 +652,7 @@ Event.add(defines.events.on_tick,function()
|
|||||||
progressbar_one:increment()
|
progressbar_one:increment()
|
||||||
progressbar_three:decrement()
|
progressbar_three:decrement()
|
||||||
local categories = Store.get_children(progressbar_two.store)
|
local categories = Store.get_children(progressbar_two.store)
|
||||||
for category,_ in pairs(categories) do
|
for _,category in pairs(categories) do
|
||||||
progressbar_two:increment(1,category)
|
progressbar_two:increment(1,category)
|
||||||
end
|
end
|
||||||
end)
|
end)
|
||||||
|
|||||||
@@ -7,43 +7,42 @@
|
|||||||
This may be useful when storing config values and when they get set you want to make sure it is taken care of, or maybe you want
|
This may be useful when storing config values and when they get set you want to make sure it is taken care of, or maybe you want
|
||||||
to have a value that you can trigger an update of from different places.
|
to have a value that you can trigger an update of from different places.
|
||||||
|
|
||||||
-- this will register a new location called 'scenario.dificutly' and the start value is 'normal'
|
-- this will register a new location called 'scenario.dificutly'
|
||||||
-- note that setting a start value is optional and we could take nil to mean normal
|
-- note that setting a start value is optional and we could take nil to mean normal
|
||||||
Store.register('scenario.dificutly',function(value)
|
Store.register('scenario.dificutly',function(value)
|
||||||
game.print('The scenario dificulty has be set to: '..value)
|
game.print('The scenario dificulty has be set to: '..value)
|
||||||
end,'normal')
|
end)
|
||||||
|
|
||||||
-- this will return 'normal' as we have not set the value anywhere else
|
|
||||||
Store.get('scenario.dificutly')
|
|
||||||
|
|
||||||
-- this will set the value in the store to 'hard' and will trigger the update callback which will print a message to the game
|
-- this will set the value in the store to 'hard' and will trigger the update callback which will print a message to the game
|
||||||
Store.set('scenario.dificutly','hard')
|
Store.set('scenario.dificutly','hard')
|
||||||
|
|
||||||
|
-- this will return 'hard'
|
||||||
|
Store.get('scenario.dificutly')
|
||||||
|
|
||||||
>>>> Using Children
|
>>>> Using Children
|
||||||
One limitation of store is that all lcoations must be registered to avoid desyncs, to get round this issue "children" can be used.
|
One limitation of store is that all lcoations must be registered to avoid desyncs, to get round this issue "children" can be used.
|
||||||
When you set the value of a child it does not have its own update callback so rather the "partent" location which has been registerd
|
When you set the value of a child it does not have its own update callback so rather the "parent" location which has been registerd
|
||||||
will have its update value called with a second param of the name of that child.
|
will have its update value called with a second param of the name of that child.
|
||||||
|
|
||||||
This may be useful when you want a value of each player or force and since you cant regisier every player at the start you must use
|
This may be useful when you want a value of each player or force and since you cant regisier every player at the start you must use
|
||||||
the players name as the child name.
|
the players name as the child name.
|
||||||
|
|
||||||
-- this will register the lcoation 'scenario.score' where we plan to use force names as the child
|
-- this will register the lcoation 'scenario.score' where we plan to use force names as the child
|
||||||
-- here we have not set a start value since it will be an empty location
|
|
||||||
Store.register('scenario.score',function(value,child)
|
Store.register('scenario.score',function(value,child)
|
||||||
game.print(child..' now has a score of '..value)
|
game.print(child..' now has a score of '..value)
|
||||||
end)
|
end)
|
||||||
|
|
||||||
-- this will return nil, but will not error as children dont need to be registerd
|
-- this will return nil, but will not error as children dont need to be registerd
|
||||||
Store.get_child('scenario.score','player')
|
Store.get('scenario.score','player')
|
||||||
|
|
||||||
-- this will set 'player' to have a value of 10 for 'scenario.score' and trigger the game message print
|
-- this will set 'player' to have a value of 10 for 'scenario.score' and trigger the game message print
|
||||||
Store.set_child('scenario.score','player',10)
|
Store.set('scenario.score','player',10)
|
||||||
|
|
||||||
-- this would be the same as Store.get however this will return an empty table rather than nil
|
-- this would be the silliar to Store.get however this will return the names of all the children
|
||||||
Store.get_children('scenario.score')
|
Store.get_children('scenario.score')
|
||||||
|
|
||||||
>>>> Using Sync
|
>>>> Using Sync
|
||||||
There is the option to use Store.register_synced which is the same as Store.register however you can combine this with an external script
|
There is the option to use synced values which is the same as a normal value however you can combine this with an external script
|
||||||
which can read the output from 'script-output/log/store.log' and have it send rcon commands back to the game allowing for cross instance
|
which can read the output from 'script-output/log/store.log' and have it send rcon commands back to the game allowing for cross instance
|
||||||
syncing of values.
|
syncing of values.
|
||||||
|
|
||||||
@@ -52,66 +51,51 @@
|
|||||||
|
|
||||||
-- this example will register the location 'stastics.total-play-time' where we plan to use plan names as the child
|
-- this example will register the location 'stastics.total-play-time' where we plan to use plan names as the child
|
||||||
-- note that the location must be the same across instances
|
-- note that the location must be the same across instances
|
||||||
Store.register_synced('stastics.total-play-time',function(value,child)
|
Store.register('stastics.total-play-time',true,function(value,child)
|
||||||
game.print(child..' now has now played for '..value)
|
game.print(child..' now has now played for '..value)
|
||||||
end)
|
end)
|
||||||
|
|
||||||
-- use of set,get,set_child and get_chlid are all the same as non synced
|
-- use of set and are all the same as non synced but you should include from_sync as true
|
||||||
|
|
||||||
>>>> Using a watch function
|
|
||||||
Some times the value that you want is not some made up value that you have but rather a factorio value or something similar, in order to recive
|
|
||||||
updates on these values (if the factorio api does not provide an event for it) you will need to add a watch function to update the store when the
|
|
||||||
values changes. You will want to keep these watch functions small since they run every tick.
|
|
||||||
|
|
||||||
-- this will register a location 'game.speed', note that the lcoation can be anything but we chose 'game.speed' to match what we are watching
|
|
||||||
-- also note that we do not need a start value here since it will be set on the first tick, but you may want a start value to avoid a trigger of the callback
|
|
||||||
Store.register('game.speed',function(value)
|
|
||||||
game.print('The game speed has been set to: '..value)
|
|
||||||
end)
|
|
||||||
|
|
||||||
-- this will add the watch function to the lcoation, every tick the function is ran and the value returned in compeared to the stored value
|
|
||||||
-- if the two values are different then the store is overriden and the update function is called
|
|
||||||
Store.add_watch('game.speed',function()
|
|
||||||
return game.speed
|
|
||||||
end)
|
|
||||||
|
|
||||||
>>>> Alternative method
|
>>>> Alternative method
|
||||||
Some people may prefer to use a varible rather than a string for formating reasons here is an example. Also for any times when
|
Some people may prefer to use a varible rather than a string for formating reasons here is an example. Also for any times when
|
||||||
there will be little external input Store.uid_location() can be used to generate non conflicting locations, use of register_synced will
|
there will be little external input Store.uid_location() can be used to generate non conflicting locations, uid_location will also
|
||||||
still require a name other wise there may be mirgration issuses.
|
be used if you give a nil location.
|
||||||
|
|
||||||
local store_game_speed = Store.uid_location()
|
local store_game_speed =
|
||||||
|
Store.register(function(value)
|
||||||
Store.register(store_game_speed,function(value)
|
|
||||||
game.print('The game speed has been set to: '..value)
|
game.print('The game speed has been set to: '..value)
|
||||||
end)
|
end)
|
||||||
|
|
||||||
Store.add_watch(store_game_speed,function()
|
|
||||||
return game.speed
|
|
||||||
end)
|
|
||||||
|
|
||||||
]]
|
]]
|
||||||
|
|
||||||
local Global = require 'utils.global'
|
local Global = require 'utils.global'
|
||||||
local Event = require 'utils.event'
|
local Event = require 'utils.event'
|
||||||
local write_json = ext_require('expcore.common','write_json','table_keys')
|
local table_keys,write_json = ext_require('expcore.common','table_keys','write_json')
|
||||||
local Token = require 'utils.token'
|
local Token = require 'utils.token'
|
||||||
|
|
||||||
local Store = {
|
local Store = {
|
||||||
data={},
|
data={},
|
||||||
callbacks={},
|
registered={},
|
||||||
synced={},
|
synced={},
|
||||||
watchers={}
|
callbacks={},
|
||||||
|
on_value_update=script.generate_event_name()
|
||||||
}
|
}
|
||||||
Global.register(Store.data,function(tbl)
|
Global.register(Store.data,function(tbl)
|
||||||
Store.data = tbl
|
Store.data = tbl
|
||||||
end)
|
end)
|
||||||
|
|
||||||
|
local function error_not_table(value)
|
||||||
|
if type(value) ~= 'table' then
|
||||||
|
error('Location is not a table can not use child locations',3)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
--- Check for if a lcoation is registered
|
--- Check for if a lcoation is registered
|
||||||
-- @tparam string location the location to test for
|
-- @tparam string location the location to test for
|
||||||
-- @treturn boolean true if registered
|
-- @treturn boolean true if registered
|
||||||
function Store.is_registered(location)
|
function Store.is_registered(location)
|
||||||
return not not Store.callbacks[location]
|
return Store.registered[location]
|
||||||
end
|
end
|
||||||
|
|
||||||
--- Returns a unqiue name that can be used for a store
|
--- Returns a unqiue name that can be used for a store
|
||||||
@@ -121,185 +105,143 @@ function Store.uid_location()
|
|||||||
end
|
end
|
||||||
|
|
||||||
--- Registers a new location with an update callback which is triggered when the value updates
|
--- Registers a new location with an update callback which is triggered when the value updates
|
||||||
-- @tparam string location string a unique that points to the data, string used rather than token to allow migration
|
-- @tparam[opt] string location string a unique that points to the data, string used rather than token to allow migration
|
||||||
-- @tparam function callback this callback will be called when the stored value is set to a new value
|
-- @tparam[opt] boolean synced when true will output changes to a file so it can be synced
|
||||||
-- @tparam[opt] any start_value this value will be the inital value that is stored at this location
|
-- @tparam[opt] function callback when given the callback will be automatically registered to the update of the value
|
||||||
function Store.register(location,callback,start_value)
|
-- @treturn string the lcoation that is being used
|
||||||
|
function Store.register(location,synced,callback)
|
||||||
if _LIFECYCLE ~= _STAGE.control then
|
if _LIFECYCLE ~= _STAGE.control then
|
||||||
return error('Can only be called during the control stage', 2)
|
return error('Can only be called during the control stage', 2)
|
||||||
end
|
end
|
||||||
|
|
||||||
if Store.callbacks[location] then
|
if type(location) ~= 'string' then
|
||||||
|
callback = synced
|
||||||
|
synced = location
|
||||||
|
end
|
||||||
|
|
||||||
|
if type(synced) ~= 'boolean' then
|
||||||
|
callback = synced
|
||||||
|
end
|
||||||
|
|
||||||
|
location = type(location) == 'string' and location or Store.uid_location()
|
||||||
|
|
||||||
|
if Store.registered[location] then
|
||||||
return error('Location is already registered', 2)
|
return error('Location is already registered', 2)
|
||||||
end
|
end
|
||||||
|
|
||||||
if type(callback) ~= 'function' then
|
Store.registered[location] = true
|
||||||
return error('Callback must be a function', 2)
|
Store.synced[location] = synced and true or nil
|
||||||
end
|
Store.callbacks[location] = callback or nil
|
||||||
|
|
||||||
Store.data[location] = start_value
|
|
||||||
Store.callbacks[location] = callback
|
|
||||||
|
|
||||||
return location
|
return location
|
||||||
end
|
end
|
||||||
|
|
||||||
--- Registers a new cross server synced location with an update callback, and external script is required for cross server
|
|
||||||
-- @tparam string location string a unique that points to the data, string used rather than token to allow migration
|
|
||||||
-- @tparam function callback this callback will be called when the stored value is set to a new value
|
|
||||||
-- @tparam[opt] any start_value this value will be the inital value that is stored at this location
|
|
||||||
function Store.register_synced(location,callback,start_value)
|
|
||||||
if _LIFECYCLE ~= _STAGE.control then
|
|
||||||
return error('Can only be called during the control stage', 2)
|
|
||||||
end
|
|
||||||
|
|
||||||
if Store.callbacks[location] then
|
|
||||||
return error('Location is already registered', 2)
|
|
||||||
end
|
|
||||||
|
|
||||||
if type(callback) ~= 'function' then
|
|
||||||
return error('Callback must be a function', 2)
|
|
||||||
end
|
|
||||||
|
|
||||||
Store.data[location] = start_value
|
|
||||||
Store.callbacks[location] = callback
|
|
||||||
Store.synced[location] = true
|
|
||||||
end
|
|
||||||
|
|
||||||
--- Adds a function that will be checked every tick for a change in the returned value, when the value changes it will be saved in the store
|
|
||||||
-- @tparam string location the location where the data will be saved and compeared to, must already be a registered location
|
|
||||||
-- @tparam function callback this function will be called every tick to check for a change in value
|
|
||||||
function Store.add_watch(location,callback)
|
|
||||||
if _LIFECYCLE ~= _STAGE.control then
|
|
||||||
return error('Can only be called during the control stage', 2)
|
|
||||||
end
|
|
||||||
|
|
||||||
if Store.callbacks[location] then
|
|
||||||
return error('Location is already being watched', 2)
|
|
||||||
end
|
|
||||||
|
|
||||||
if type(callback) ~= 'function' then
|
|
||||||
return error('Callback must be a function', 2)
|
|
||||||
end
|
|
||||||
|
|
||||||
Store.watchers[location] = callback
|
|
||||||
end
|
|
||||||
|
|
||||||
--- Gets the value stored at a location, this location must be registered
|
--- Gets the value stored at a location, this location must be registered
|
||||||
-- @tparam string location the location to get the data from
|
-- @tparam string location the location to get the data from
|
||||||
-- @tparam[opt=false] boolean no_error when true no error is returned if the location is not registered
|
-- @tparam[opt] string child the child location if required
|
||||||
|
-- @tparam[opt=false] boolean allow_unregistered when true no error is returned if the location is not registered
|
||||||
-- @treturn any the data which was stored at the location
|
-- @treturn any the data which was stored at the location
|
||||||
function Store.get(location,no_error)
|
function Store.get(location,child,allow_unregistered)
|
||||||
if not Store.callbacks[location] and not no_error then
|
if not Store.callbacks[location] and not allow_unregistered then
|
||||||
return error('Location is not registered', 2)
|
return error('Location is not registered', 2)
|
||||||
end
|
end
|
||||||
|
|
||||||
return Store.data[location]
|
local data = Store.data[location]
|
||||||
|
if child and data then
|
||||||
|
error_not_table(data)
|
||||||
|
return data[child]
|
||||||
|
end
|
||||||
|
|
||||||
|
return data
|
||||||
end
|
end
|
||||||
|
|
||||||
--- Sets the value at a location, this location must be registered, if server synced it will emit the change to file
|
--- Sets the value at a location, this location must be registered
|
||||||
-- @tparam string location the location to set the data to
|
-- @tparam string location the location to set the data to
|
||||||
-- @tparam any value the new value to set at the location, value may be reverted if there is a watch callback
|
-- @tparam[opt] string child the child location if required
|
||||||
|
-- @tparam any value the new value to set at the location, value may be reverted if there is a watch callback, cant be nil
|
||||||
|
-- @tparam[opt] boolean from_sync set this true to avoid an output to the sync file
|
||||||
-- @treturn boolean true if it was successful
|
-- @treturn boolean true if it was successful
|
||||||
function Store.set(location,value)
|
function Store.set(location,child,value,from_sync)
|
||||||
if not Store.callbacks[location] then
|
if not Store.callbacks[location] then
|
||||||
return error('Location is not registered', 2)
|
return error('Location is not registered', 2)
|
||||||
end
|
end
|
||||||
|
|
||||||
Store.data[location] = value
|
if child == nil or value == nil then
|
||||||
Store.callbacks[location](value)
|
value = child or value
|
||||||
|
child = nil
|
||||||
if Store.synced[location] then
|
|
||||||
write_json('log/store.log',{
|
|
||||||
location=location,
|
|
||||||
value=value
|
|
||||||
})
|
|
||||||
end
|
end
|
||||||
|
|
||||||
|
local data = Store.data
|
||||||
|
if child then
|
||||||
|
data = data[location]
|
||||||
|
if not data then
|
||||||
|
data = {}
|
||||||
|
Store.data[location] = data
|
||||||
|
end
|
||||||
|
error_not_table(data)
|
||||||
|
data[child] = value
|
||||||
|
else
|
||||||
|
data[location] = value
|
||||||
|
end
|
||||||
|
|
||||||
|
script.raise_event(Store.on_value_update,{
|
||||||
|
tick=game.tick,
|
||||||
|
location=location,
|
||||||
|
child=child,
|
||||||
|
value=value,
|
||||||
|
from_sync=from_sync
|
||||||
|
})
|
||||||
|
|
||||||
|
return true
|
||||||
|
end
|
||||||
|
|
||||||
|
--- Sets the value at a location to nil, this location must be registered
|
||||||
|
-- @tparam string location the location to set the data to
|
||||||
|
-- @tparam[opt] string child the child location if required
|
||||||
|
-- @tparam[opt] boolean from_sync set this true to avoid an output to the sync file
|
||||||
|
-- @treturn boolean true if it was successful
|
||||||
|
function Store.clear(location,child,from_sync)
|
||||||
|
if not Store.callbacks[location] then
|
||||||
|
return error('Location is not registered', 2)
|
||||||
|
end
|
||||||
|
|
||||||
|
local data = Store.data
|
||||||
|
if child then
|
||||||
|
data = data[location]
|
||||||
|
if not data then return end
|
||||||
|
error_not_table(data)
|
||||||
|
data[child] = nil
|
||||||
|
else
|
||||||
|
data[location] = nil
|
||||||
|
end
|
||||||
|
|
||||||
|
script.raise_event(Store.on_value_update,{
|
||||||
|
tick=game.tick,
|
||||||
|
location=location,
|
||||||
|
child=child,
|
||||||
|
from_sync=from_sync
|
||||||
|
})
|
||||||
|
|
||||||
return true
|
return true
|
||||||
end
|
end
|
||||||
|
|
||||||
--- Gets all non nil children at a location, children can be added and removed during runtime
|
--- Gets all non nil children at a location, children can be added and removed during runtime
|
||||||
-- this is similar to Store.get but will always return a table even if it is empty
|
-- this is similar to Store.get but will always return a table even if it is empty
|
||||||
-- @tparam string location the location to get the children of
|
-- @tparam string location the location to get the children of
|
||||||
-- @treturn table a table containg all the children and they values
|
-- @treturn table a table containg all the children names
|
||||||
function Store.get_children(location)
|
function Store.get_children(location)
|
||||||
local store = Store.get(location)
|
local data = Store.get(location)
|
||||||
|
return type(data) == 'table' and table_keys(data) or {}
|
||||||
if type(store) ~= 'table' and store ~= nil then
|
|
||||||
return error('Location has a non table value', 2)
|
|
||||||
end
|
|
||||||
|
|
||||||
return store or {}
|
|
||||||
end
|
end
|
||||||
|
|
||||||
--- Gets the value of the child to a location, children can be added and removed during runtime
|
-- Handels syncing
|
||||||
-- @tparam string location the location of which the child is located
|
Event.add(Store.on_value_update,function(event)
|
||||||
-- @tparam string child the child element to get the value of
|
if Store.callbacks[event.location] then
|
||||||
-- @treturn any the value which was stored at that location
|
Store.callbacks[event.location](event.value,event.child)
|
||||||
function Store.get_child(location,child)
|
|
||||||
local store = Store.get(location)
|
|
||||||
|
|
||||||
if type(store) ~= 'table' and store ~= nil then
|
|
||||||
return error('Location has a non table value', 2)
|
|
||||||
end
|
end
|
||||||
|
|
||||||
return store and store[child]
|
if not event.from_sync then
|
||||||
end
|
write_json('log/store.log',event)
|
||||||
|
|
||||||
--- Sets the value of the chlid to a location, children can be added and removed during runtime
|
|
||||||
-- when a child is set it will call the update handler of the parent allowing children be to added at runtime
|
|
||||||
-- this may be used when a player joins the game and the child is the players name
|
|
||||||
-- @tparam string location the location of which the child is located
|
|
||||||
-- @tparam string child the child element to set the value of
|
|
||||||
-- @tparam any value the value to set at this location
|
|
||||||
-- @treturn boolean true if it was successful
|
|
||||||
function Store.set_child(location,child,value)
|
|
||||||
local store = Store.get(location)
|
|
||||||
|
|
||||||
if type(store) ~= 'table' and store ~= nil then
|
|
||||||
return error('Location has a non table value', 2)
|
|
||||||
end
|
|
||||||
|
|
||||||
if not store then
|
|
||||||
Store.data[location] = {}
|
|
||||||
end
|
|
||||||
|
|
||||||
Store.data[location][child] = value
|
|
||||||
Store.callbacks[location](value,child)
|
|
||||||
|
|
||||||
if Store.synced[location] then
|
|
||||||
write_json('log/store.log',{
|
|
||||||
location=location,
|
|
||||||
child=child,
|
|
||||||
value=value
|
|
||||||
})
|
|
||||||
end
|
|
||||||
|
|
||||||
return true
|
|
||||||
end
|
|
||||||
|
|
||||||
-- Event handler for the watcher callbacks
|
|
||||||
Event.add(defines.events.on_tick,function()
|
|
||||||
local errors = {}
|
|
||||||
|
|
||||||
for location,callback in pairs(Store.watchers) do
|
|
||||||
local store_old = Store.data[location]
|
|
||||||
local success,store_new = pcall(callback)
|
|
||||||
|
|
||||||
if not success then
|
|
||||||
table.insert(errors,store_new)
|
|
||||||
else
|
|
||||||
if type(store_old) ~= type(store_new)
|
|
||||||
or type(store_old) == 'table' and not table.compare(store_new,store_new)
|
|
||||||
or store_old ~= store_new then
|
|
||||||
Store.data[location] = store_new
|
|
||||||
Store.callbacks[location](store_new)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
if #errors > 0 then
|
|
||||||
error(table.concat(errors,'; '))
|
|
||||||
end
|
end
|
||||||
end)
|
end)
|
||||||
|
|
||||||
|
|||||||
@@ -23,11 +23,11 @@ Gui.on_click(zoom_to_map_name,function(event)
|
|||||||
else
|
else
|
||||||
-- rmb will open settings
|
-- rmb will open settings
|
||||||
local player_name = event.player.name
|
local player_name = event.player.name
|
||||||
local old_action_player_name = Store.get_child(action_player_store,player_name)
|
local old_action_player_name = Store.get(action_player_store,player_name)
|
||||||
if action_player_name == old_action_player_name then
|
if action_player_name == old_action_player_name then
|
||||||
Store.set_child(action_player_store,player_name) -- will close if already open
|
Store.clear(action_player_store,player_name) -- will close if already open
|
||||||
else
|
else
|
||||||
Store.set_child(action_player_store,player_name,action_player_name)
|
Store.set(action_player_store,player_name,action_player_name)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end)
|
end)
|
||||||
@@ -47,11 +47,11 @@ end)
|
|||||||
end)
|
end)
|
||||||
:on_click(function(player,element)
|
:on_click(function(player,element)
|
||||||
local new_action_player_name = element.parent.name
|
local new_action_player_name = element.parent.name
|
||||||
local action_player_name = Store.get_child(action_player_store,player.name)
|
local action_player_name = Store.get(action_player_store,player.name)
|
||||||
if action_player_name == new_action_player_name then
|
if action_player_name == new_action_player_name then
|
||||||
Store.set_child(action_player_store,player.name) -- will close if already open
|
Store.clear(action_player_store,player.name) -- will close if already open
|
||||||
else
|
else
|
||||||
Store.set_child(action_player_store,player.name,element.parent.name)
|
Store.set(action_player_store,player.name,new_action_player_name)
|
||||||
end
|
end
|
||||||
end)
|
end)
|
||||||
|
|
||||||
@@ -66,8 +66,8 @@ Gui.new_button()
|
|||||||
style.width = 28
|
style.width = 28
|
||||||
end)
|
end)
|
||||||
:on_click(function(player,element)
|
:on_click(function(player,element)
|
||||||
Store.set_child(action_player_store,player.name,nil)
|
Store.clear(action_player_store,player.name)
|
||||||
Store.set_child(action_name_store,player.name,nil)
|
Store.clear(action_name_store,player.name)
|
||||||
end)
|
end)
|
||||||
|
|
||||||
--- Button used to confirm a reason
|
--- Button used to confirm a reason
|
||||||
@@ -85,8 +85,8 @@ end)
|
|||||||
local action_name = Store.get_child(action_name_store,player.name)
|
local action_name = Store.get_child(action_name_store,player.name)
|
||||||
local reason_callback = config[action_name].reason_callback
|
local reason_callback = config[action_name].reason_callback
|
||||||
reason_callback(player,reason)
|
reason_callback(player,reason)
|
||||||
Store.set_child(action_player_store,player.name,nil)
|
Store.clear(action_player_store,player.name)
|
||||||
Store.set_child(action_name_store,player.name,nil)
|
Store.clear(action_name_store,player.name)
|
||||||
element.parent.entry.text = ''
|
element.parent.entry.text = ''
|
||||||
end)
|
end)
|
||||||
|
|
||||||
@@ -157,7 +157,7 @@ local function generate_container(player,element)
|
|||||||
Gui.set_padding(reason_bar,-1,-1,3,3)
|
Gui.set_padding(reason_bar,-1,-1,3,3)
|
||||||
reason_bar.style.horizontally_stretchable = true
|
reason_bar.style.horizontally_stretchable = true
|
||||||
reason_bar.style.height = 35
|
reason_bar.style.height = 35
|
||||||
local action_name = Store.get_child(action_name_store,player.name)
|
local action_name = Store.get(action_name_store,player.name)
|
||||||
reason_bar.visible = action_name ~= nil
|
reason_bar.visible = action_name ~= nil
|
||||||
|
|
||||||
-- text entry for the reason bar
|
-- text entry for the reason bar
|
||||||
@@ -180,7 +180,7 @@ end
|
|||||||
--- Adds buttons and permission flows to the action bar
|
--- Adds buttons and permission flows to the action bar
|
||||||
local function generate_action_bar(player,element)
|
local function generate_action_bar(player,element)
|
||||||
close_action_bar(element)
|
close_action_bar(element)
|
||||||
local action_player = Store.get_child(action_player_store,player.name)
|
local action_player = Store.get(action_player_store,player.name)
|
||||||
|
|
||||||
for action_name,buttons in pairs(config) do
|
for action_name,buttons in pairs(config) do
|
||||||
local permission_flow =
|
local permission_flow =
|
||||||
@@ -212,7 +212,7 @@ local player_list_name
|
|||||||
local function update_action_bar(player)
|
local function update_action_bar(player)
|
||||||
local frame = Gui.classes.left_frames.get_frame(player_list_name,player)
|
local frame = Gui.classes.left_frames.get_frame(player_list_name,player)
|
||||||
local element = frame.container.action_bar
|
local element = frame.container.action_bar
|
||||||
local action_player_name = Store.get_child(action_player_store,player.name)
|
local action_player_name = Store.get(action_player_store,player.name)
|
||||||
|
|
||||||
if not action_player_name then
|
if not action_player_name then
|
||||||
element.visible = false
|
element.visible = false
|
||||||
@@ -220,8 +220,8 @@ local function update_action_bar(player)
|
|||||||
local action_player = Game.get_player_from_any(action_player_name)
|
local action_player = Game.get_player_from_any(action_player_name)
|
||||||
if not action_player.connected then
|
if not action_player.connected then
|
||||||
element.visible = false
|
element.visible = false
|
||||||
Store.set(action_player_store,player.name) -- clears store if player is offline
|
Store.clear(action_player_store,player.name) -- clears store if player is offline
|
||||||
Store.set_child(action_name_store,player.name)
|
Store.clear(action_name_store,player.name)
|
||||||
else
|
else
|
||||||
element.visible = true
|
element.visible = true
|
||||||
for action_name,buttons in pairs(config) do
|
for action_name,buttons in pairs(config) do
|
||||||
@@ -347,13 +347,13 @@ Store.register(action_name_store,function(value,category)
|
|||||||
local frame = Gui.classes.left_frames.get_frame(player_list_name,player)
|
local frame = Gui.classes.left_frames.get_frame(player_list_name,player)
|
||||||
local element = frame.container.reason_bar
|
local element = frame.container.reason_bar
|
||||||
if value then
|
if value then
|
||||||
local action_player_name = Store.get_child(action_player_store,category)
|
local action_player_name = Store.get(action_player_store,category)
|
||||||
local action_player = Game.get_player_from_any(action_player_name)
|
local action_player = Game.get_player_from_any(action_player_name)
|
||||||
if action_player.connected then
|
if action_player.connected then
|
||||||
element.visible = true
|
element.visible = true
|
||||||
else
|
else
|
||||||
Store.set_child(action_player_store,category) -- clears store if player is offline
|
Store.clear(action_player_store,category) -- clears store if player is offline
|
||||||
Store.set_child(action_name_store,category)
|
Store.clear(action_name_store,category)
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
element.visible = false
|
element.visible = false
|
||||||
|
|||||||
@@ -41,13 +41,13 @@ local function add_task(player,task_number)
|
|||||||
editing={[player.name]=true}
|
editing={[player.name]=true}
|
||||||
}
|
}
|
||||||
|
|
||||||
Store.set_child(task_store,task_id,'New task')
|
Store.set(task_store,task_id,'New task')
|
||||||
end
|
end
|
||||||
|
|
||||||
--- Removes all refrences to a task
|
--- Removes all refrences to a task
|
||||||
local function remove_task(task_id)
|
local function remove_task(task_id)
|
||||||
local force_name = task_details[task_id].force
|
local force_name = task_details[task_id].force
|
||||||
Store.set_child(task_store,task_id)
|
Store.clear(task_store,task_id)
|
||||||
task_details[task_id] = nil
|
task_details[task_id] = nil
|
||||||
table.remove_element(force_tasks[force_name],task_id)
|
table.remove_element(force_tasks[force_name],task_id)
|
||||||
end
|
end
|
||||||
@@ -108,7 +108,7 @@ end)
|
|||||||
details.editing[player.name] = nil
|
details.editing[player.name] = nil
|
||||||
details.last_edit_player = player.name
|
details.last_edit_player = player.name
|
||||||
details.last_edit_time = game.tick
|
details.last_edit_time = game.tick
|
||||||
Store.set_child(task_store,task_id,task)
|
Store.set(task_store,task_id,task)
|
||||||
end)
|
end)
|
||||||
|
|
||||||
--- Used to cancel any changes you made to a task
|
--- Used to cancel any changes you made to a task
|
||||||
@@ -175,7 +175,7 @@ end)
|
|||||||
>> discard_task
|
>> discard_task
|
||||||
]]
|
]]
|
||||||
function generate_task(player,element,task_id)
|
function generate_task(player,element,task_id)
|
||||||
local task = Store.get_child(task_store,task_id)
|
local task = Store.get(task_store,task_id)
|
||||||
local details = task_details[task_id]
|
local details = task_details[task_id]
|
||||||
local editing = details.editing[player.name]
|
local editing = details.editing[player.name]
|
||||||
local last_edit_player = details.last_edit_player
|
local last_edit_player = details.last_edit_player
|
||||||
|
|||||||
Reference in New Issue
Block a user