diff --git a/docs/addons/Advanced-Start.html b/docs/addons/Advanced-Start.html index 17a11fd8..d5f1bc3d 100644 --- a/docs/addons/Advanced-Start.html +++ b/docs/addons/Advanced-Start.html @@ -348,7 +348,7 @@ generated by LDoc diff --git a/docs/addons/Chat-Popups.html b/docs/addons/Chat-Popups.html index ec447b0d..ea439bd3 100644 --- a/docs/addons/Chat-Popups.html +++ b/docs/addons/Chat-Popups.html @@ -349,7 +349,7 @@ generated by LDoc diff --git a/docs/addons/Chat-Reply.html b/docs/addons/Chat-Reply.html index 227a2701..eae91d5e 100644 --- a/docs/addons/Chat-Reply.html +++ b/docs/addons/Chat-Reply.html @@ -376,7 +376,7 @@ generated by LDoc diff --git a/docs/addons/Compilatron.html b/docs/addons/Compilatron.html index dc49b78b..04c36e4c 100644 --- a/docs/addons/Compilatron.html +++ b/docs/addons/Compilatron.html @@ -585,7 +585,7 @@ generated by LDoc diff --git a/docs/addons/Damage-Popups.html b/docs/addons/Damage-Popups.html index c5d5f078..c72338fe 100644 --- a/docs/addons/Damage-Popups.html +++ b/docs/addons/Damage-Popups.html @@ -349,7 +349,7 @@ generated by LDoc diff --git a/docs/addons/Death-Logger.html b/docs/addons/Death-Logger.html index 71cc9bde..49d07665 100644 --- a/docs/addons/Death-Logger.html +++ b/docs/addons/Death-Logger.html @@ -404,7 +404,7 @@ generated by LDoc diff --git a/docs/addons/Discord-Alerts.html b/docs/addons/Discord-Alerts.html index 27d0af48..1ea9565d 100644 --- a/docs/addons/Discord-Alerts.html +++ b/docs/addons/Discord-Alerts.html @@ -460,7 +460,7 @@ generated by LDoc diff --git a/docs/addons/Player-Colours.html b/docs/addons/Player-Colours.html index 7d67adeb..1d4b5b81 100644 --- a/docs/addons/Player-Colours.html +++ b/docs/addons/Player-Colours.html @@ -404,7 +404,7 @@ generated by LDoc diff --git a/docs/addons/Pollution-Grading.html b/docs/addons/Pollution-Grading.html index d488a111..bbeed3d3 100644 --- a/docs/addons/Pollution-Grading.html +++ b/docs/addons/Pollution-Grading.html @@ -320,7 +320,7 @@ generated by LDoc diff --git a/docs/addons/Scorched-Earth.html b/docs/addons/Scorched-Earth.html index 55bea826..5ad78aaf 100644 --- a/docs/addons/Scorched-Earth.html +++ b/docs/addons/Scorched-Earth.html @@ -404,7 +404,7 @@ generated by LDoc diff --git a/docs/addons/Spawn-Area.html b/docs/addons/Spawn-Area.html index 13dfba39..9101a4df 100644 --- a/docs/addons/Spawn-Area.html +++ b/docs/addons/Spawn-Area.html @@ -376,7 +376,7 @@ generated by LDoc diff --git a/docs/commands/Admin-Chat.html b/docs/commands/Admin-Chat.html index 731be00d..f5aba74f 100644 --- a/docs/commands/Admin-Chat.html +++ b/docs/commands/Admin-Chat.html @@ -388,7 +388,7 @@ generated by LDoc diff --git a/docs/commands/Bonus.html b/docs/commands/Bonus.html index d49279c2..16cb2030 100644 --- a/docs/commands/Bonus.html +++ b/docs/commands/Bonus.html @@ -500,7 +500,7 @@ generated by LDoc diff --git a/docs/commands/Cheat-Mode.html b/docs/commands/Cheat-Mode.html index accc40eb..5ff916a9 100644 --- a/docs/commands/Cheat-Mode.html +++ b/docs/commands/Cheat-Mode.html @@ -361,7 +361,7 @@ generated by LDoc diff --git a/docs/commands/Clear-Inventory.html b/docs/commands/Clear-Inventory.html index e20883e3..e1d7aa45 100644 --- a/docs/commands/Clear-Inventory.html +++ b/docs/commands/Clear-Inventory.html @@ -388,7 +388,7 @@ generated by LDoc diff --git a/docs/commands/Debug.html b/docs/commands/Debug.html index af847b74..27478810 100644 --- a/docs/commands/Debug.html +++ b/docs/commands/Debug.html @@ -365,7 +365,7 @@ generated by LDoc diff --git a/docs/commands/Find.html b/docs/commands/Find.html index fc61f8cf..1646f87f 100644 --- a/docs/commands/Find.html +++ b/docs/commands/Find.html @@ -360,7 +360,7 @@ generated by LDoc diff --git a/docs/commands/Help.html b/docs/commands/Help.html index c5d73042..80fcb656 100644 --- a/docs/commands/Help.html +++ b/docs/commands/Help.html @@ -404,7 +404,7 @@ generated by LDoc diff --git a/docs/commands/Home.html b/docs/commands/Home.html index 05da9559..364a5c55 100644 --- a/docs/commands/Home.html +++ b/docs/commands/Home.html @@ -458,7 +458,7 @@ generated by LDoc diff --git a/docs/commands/Interface.html b/docs/commands/Interface.html index bc2e0590..99a8bb88 100644 --- a/docs/commands/Interface.html +++ b/docs/commands/Interface.html @@ -416,7 +416,7 @@ generated by LDoc diff --git a/docs/commands/Jail.html b/docs/commands/Jail.html index 6ff4802e..23cffe1c 100644 --- a/docs/commands/Jail.html +++ b/docs/commands/Jail.html @@ -611,7 +611,7 @@ generated by LDoc diff --git a/docs/commands/Kill.html b/docs/commands/Kill.html index a16c18b0..c826849c 100644 --- a/docs/commands/Kill.html +++ b/docs/commands/Kill.html @@ -389,7 +389,7 @@ generated by LDoc diff --git a/docs/commands/Me.html b/docs/commands/Me.html index 2f8cb3f4..f8b3edd3 100644 --- a/docs/commands/Me.html +++ b/docs/commands/Me.html @@ -360,7 +360,7 @@ generated by LDoc diff --git a/docs/commands/Rainbow.html b/docs/commands/Rainbow.html index 83127954..0ee93a13 100644 --- a/docs/commands/Rainbow.html +++ b/docs/commands/Rainbow.html @@ -388,7 +388,7 @@ generated by LDoc diff --git a/docs/commands/Repair.html b/docs/commands/Repair.html index dfc8fde0..edcba43f 100644 --- a/docs/commands/Repair.html +++ b/docs/commands/Repair.html @@ -321,7 +321,7 @@ generated by LDoc diff --git a/docs/commands/Reports.html b/docs/commands/Reports.html index bb852d95..8133f2be 100644 --- a/docs/commands/Reports.html +++ b/docs/commands/Reports.html @@ -585,7 +585,7 @@ generated by LDoc diff --git a/docs/commands/Roles.html b/docs/commands/Roles.html index 338a0c5e..acef4c67 100644 --- a/docs/commands/Roles.html +++ b/docs/commands/Roles.html @@ -557,7 +557,7 @@ generated by LDoc diff --git a/docs/commands/Spawn.html b/docs/commands/Spawn.html index 9eba8a8f..15b2d030 100644 --- a/docs/commands/Spawn.html +++ b/docs/commands/Spawn.html @@ -389,7 +389,7 @@ generated by LDoc diff --git a/docs/commands/Tag.html b/docs/commands/Tag.html index b8609e4a..fb491132 100644 --- a/docs/commands/Tag.html +++ b/docs/commands/Tag.html @@ -443,7 +443,7 @@ generated by LDoc diff --git a/docs/commands/Teleport.html b/docs/commands/Teleport.html index eeed3aa0..6df0414b 100644 --- a/docs/commands/Teleport.html +++ b/docs/commands/Teleport.html @@ -484,7 +484,7 @@ generated by LDoc diff --git a/docs/commands/Warnings.html b/docs/commands/Warnings.html index 337f8b93..7707c52f 100644 --- a/docs/commands/Warnings.html +++ b/docs/commands/Warnings.html @@ -569,7 +569,7 @@ generated by LDoc diff --git a/docs/configs/Advanced-Start.html b/docs/configs/Advanced-Start.html index 72c02f54..2093a884 100644 --- a/docs/configs/Advanced-Start.html +++ b/docs/configs/Advanced-Start.html @@ -506,7 +506,7 @@ generated by LDoc diff --git a/docs/configs/Bonuses.html b/docs/configs/Bonuses.html index 31d8e33c..d1d1b3de 100644 --- a/docs/configs/Bonuses.html +++ b/docs/configs/Bonuses.html @@ -237,7 +237,7 @@ generated by LDoc diff --git a/docs/configs/Chat-Reply.html b/docs/configs/Chat-Reply.html index da119978..efd7832f 100644 --- a/docs/configs/Chat-Reply.html +++ b/docs/configs/Chat-Reply.html @@ -485,7 +485,7 @@ generated by LDoc diff --git a/docs/configs/Commands-Auth-Admin.html b/docs/configs/Commands-Auth-Admin.html index fa578e05..3bb2e8f8 100644 --- a/docs/configs/Commands-Auth-Admin.html +++ b/docs/configs/Commands-Auth-Admin.html @@ -294,7 +294,7 @@ generated by LDoc diff --git a/docs/configs/Commands-Auth-Roles.html b/docs/configs/Commands-Auth-Roles.html index 2e83f8aa..c7edeb96 100644 --- a/docs/configs/Commands-Auth-Roles.html +++ b/docs/configs/Commands-Auth-Roles.html @@ -320,7 +320,7 @@ generated by LDoc diff --git a/docs/configs/Commands-Auth-Runtime-Disable.html b/docs/configs/Commands-Auth-Runtime-Disable.html index e908fa8c..700296b0 100644 --- a/docs/configs/Commands-Auth-Runtime-Disable.html +++ b/docs/configs/Commands-Auth-Runtime-Disable.html @@ -442,7 +442,7 @@ generated by LDoc diff --git a/docs/configs/Commands-Parse-Roles.html b/docs/configs/Commands-Parse-Roles.html index 3206b122..f60715ed 100644 --- a/docs/configs/Commands-Parse-Roles.html +++ b/docs/configs/Commands-Parse-Roles.html @@ -354,7 +354,7 @@ generated by LDoc diff --git a/docs/configs/Commands-Parse.html b/docs/configs/Commands-Parse.html index 14f65272..6b32d0a1 100644 --- a/docs/configs/Commands-Parse.html +++ b/docs/configs/Commands-Parse.html @@ -338,7 +338,7 @@ see ./expcore/commands.lua for more details

generated by LDoc diff --git a/docs/configs/Compilatron.html b/docs/configs/Compilatron.html index 2d0f47b4..b0250bf1 100644 --- a/docs/configs/Compilatron.html +++ b/docs/configs/Compilatron.html @@ -354,7 +354,7 @@ generated by LDoc diff --git a/docs/configs/Death-Logger.html b/docs/configs/Death-Logger.html index f03d13cd..24401358 100644 --- a/docs/configs/Death-Logger.html +++ b/docs/configs/Death-Logger.html @@ -416,7 +416,7 @@ generated by LDoc diff --git a/docs/configs/Discord-Alerts.html b/docs/configs/Discord-Alerts.html index e7cc6d8b..5605e456 100644 --- a/docs/configs/Discord-Alerts.html +++ b/docs/configs/Discord-Alerts.html @@ -237,7 +237,7 @@ generated by LDoc diff --git a/docs/configs/File-Loader.html b/docs/configs/File-Loader.html index 25d76c3b..5c96dd17 100644 --- a/docs/configs/File-Loader.html +++ b/docs/configs/File-Loader.html @@ -240,7 +240,7 @@ generated by LDoc diff --git a/docs/configs/Permission-Groups.html b/docs/configs/Permission-Groups.html index 5798d322..ec4ad401 100644 --- a/docs/configs/Permission-Groups.html +++ b/docs/configs/Permission-Groups.html @@ -295,7 +295,7 @@ generated by LDoc diff --git a/docs/configs/Player-List.html b/docs/configs/Player-List.html index 28764dd5..8647bdec 100644 --- a/docs/configs/Player-List.html +++ b/docs/configs/Player-List.html @@ -812,7 +812,7 @@ generated by LDoc diff --git a/docs/configs/Pollution-Grading.html b/docs/configs/Pollution-Grading.html index 3f407af5..e2ca1dd2 100644 --- a/docs/configs/Pollution-Grading.html +++ b/docs/configs/Pollution-Grading.html @@ -384,7 +384,7 @@ generated by LDoc diff --git a/docs/configs/Popup-Messages.html b/docs/configs/Popup-Messages.html index e217cb89..7b7bcbad 100644 --- a/docs/configs/Popup-Messages.html +++ b/docs/configs/Popup-Messages.html @@ -414,7 +414,7 @@ generated by LDoc diff --git a/docs/configs/Preset-Player-Colours.html b/docs/configs/Preset-Player-Colours.html index 6ded0dd1..63d439f7 100644 --- a/docs/configs/Preset-Player-Colours.html +++ b/docs/configs/Preset-Player-Colours.html @@ -324,7 +324,7 @@ generated by LDoc diff --git a/docs/configs/Repair.html b/docs/configs/Repair.html index 04430dd7..f154803c 100644 --- a/docs/configs/Repair.html +++ b/docs/configs/Repair.html @@ -414,7 +414,7 @@ generated by LDoc diff --git a/docs/configs/Rockets.html b/docs/configs/Rockets.html index 2a142796..e31f17da 100644 --- a/docs/configs/Rockets.html +++ b/docs/configs/Rockets.html @@ -834,7 +834,7 @@ generated by LDoc diff --git a/docs/configs/Roles.html b/docs/configs/Roles.html index 3fbacb0e..494d46dc 100644 --- a/docs/configs/Roles.html +++ b/docs/configs/Roles.html @@ -292,7 +292,7 @@ generated by LDoc diff --git a/docs/configs/Science.html b/docs/configs/Science.html index 873dbf53..e9bd1687 100644 --- a/docs/configs/Science.html +++ b/docs/configs/Science.html @@ -354,7 +354,7 @@ generated by LDoc diff --git a/docs/configs/Scorched-Earth.html b/docs/configs/Scorched-Earth.html index 5f2f2131..497d5afe 100644 --- a/docs/configs/Scorched-Earth.html +++ b/docs/configs/Scorched-Earth.html @@ -388,7 +388,7 @@ generated by LDoc diff --git a/docs/configs/Spawn-Area.html b/docs/configs/Spawn-Area.html index ebefadb6..c11ea36c 100644 --- a/docs/configs/Spawn-Area.html +++ b/docs/configs/Spawn-Area.html @@ -744,7 +744,7 @@ generated by LDoc diff --git a/docs/configs/Tasks.html b/docs/configs/Tasks.html index 2ea51a33..9e8aedf0 100644 --- a/docs/configs/Tasks.html +++ b/docs/configs/Tasks.html @@ -384,7 +384,7 @@ generated by LDoc diff --git a/docs/configs/Warnings.html b/docs/configs/Warnings.html index 1971da7d..f1623c82 100644 --- a/docs/configs/Warnings.html +++ b/docs/configs/Warnings.html @@ -355,7 +355,7 @@ generated by LDoc diff --git a/docs/configs/Warps.html b/docs/configs/Warps.html index c90c3b4f..220ac9f0 100644 --- a/docs/configs/Warps.html +++ b/docs/configs/Warps.html @@ -684,7 +684,7 @@ generated by LDoc diff --git a/docs/control/Jail.html b/docs/control/Jail.html index 8b2073fa..7f57692c 100644 --- a/docs/control/Jail.html +++ b/docs/control/Jail.html @@ -1208,7 +1208,7 @@ generated by LDoc diff --git a/docs/control/Production.html b/docs/control/Production.html index cfc5135f..f1113092 100644 --- a/docs/control/Production.html +++ b/docs/control/Production.html @@ -1329,7 +1329,7 @@ generated by LDoc diff --git a/docs/control/Reports.html b/docs/control/Reports.html index 02a29320..d8897523 100644 --- a/docs/control/Reports.html +++ b/docs/control/Reports.html @@ -1110,7 +1110,7 @@ generated by LDoc diff --git a/docs/control/Rockets.html b/docs/control/Rockets.html index 4cd079d7..4b9966cb 100644 --- a/docs/control/Rockets.html +++ b/docs/control/Rockets.html @@ -984,7 +984,7 @@ generated by LDoc diff --git a/docs/control/Tasks.html b/docs/control/Tasks.html index 0a82275c..fbe012aa 100644 --- a/docs/control/Tasks.html +++ b/docs/control/Tasks.html @@ -1039,7 +1039,7 @@ generated by LDoc diff --git a/docs/control/Warnings.html b/docs/control/Warnings.html index cca92779..f0d8a48d 100644 --- a/docs/control/Warnings.html +++ b/docs/control/Warnings.html @@ -1465,7 +1465,7 @@ generated by LDoc diff --git a/docs/control/Warps.html b/docs/control/Warps.html index 4af6171d..8eaa202f 100644 --- a/docs/control/Warps.html +++ b/docs/control/Warps.html @@ -1413,7 +1413,7 @@ generated by LDoc diff --git a/docs/core/Commands.html b/docs/core/Commands.html index b6e82a2c..5f50cb52 100644 --- a/docs/core/Commands.html +++ b/docs/core/Commands.html @@ -1972,7 +1972,7 @@ generated by LDoc diff --git a/docs/core/Common-Library.html b/docs/core/Common-Library.html index ee9e8780..df42a599 100644 --- a/docs/core/Common-Library.html +++ b/docs/core/Common-Library.html @@ -2746,7 +2746,7 @@ Common.table_insert(tbl,50,tbl2) generated by LDoc diff --git a/docs/core/Gui.html b/docs/core/Gui.html index 6533ff0e..cc538320 100644 --- a/docs/core/Gui.html +++ b/docs/core/Gui.html @@ -10987,7 +10987,7 @@ generated by LDoc diff --git a/docs/core/Permissions-Groups.html b/docs/core/Permissions-Groups.html index cffa89f8..690c75dd 100644 --- a/docs/core/Permissions-Groups.html +++ b/docs/core/Permissions-Groups.html @@ -1432,7 +1432,7 @@ generated by LDoc diff --git a/docs/core/Roles.html b/docs/core/Roles.html index 3187a4f7..3ac81e42 100644 --- a/docs/core/Roles.html +++ b/docs/core/Roles.html @@ -3152,7 +3152,7 @@ generated by LDoc diff --git a/docs/core/Store.html b/docs/core/Store.html index 97eda35f..63185182 100644 --- a/docs/core/Store.html +++ b/docs/core/Store.html @@ -42,7 +42,10 @@

Sections

@@ -203,7 +206,10 @@

Jump to Section

@@ -224,7 +230,7 @@

Store core

Core Module - Store - - Adds an easy way to store and watch for updates to a value

+- Used to store and watch for updates for values in the global table

@@ -232,48 +238,6 @@ -

Usage

-

--- The data store module is designed to be an alterative way to store data in the global table
--- each piece of data is stored at a location and optional key of that location
--- it is recomented that you use a local varible to store the location
-local scenario_difficuly = Store.uid_location()
-local team_scores = 'team-scores'
-
--- Setting and getting data is then as simple as
--- note that when storing a table you must use Store.update
-Store.set(scenario_difficuly,'Hard')
-Store.set(team_scores,game.player.force.name,20)
-
-Store.get(scenario_difficuly) -- returns 'Hard'
-Store.get(team_scores,game.player.force.name) -- returns 20
-
-Store.update(team_scores,game.player.force.name,function(value,key)
-    return value + 10 -- add 10 to the score
-end)
-
--- The reason for using stores over global is the abilty to watch for updates
--- for stores to work you must register them, often at the end of the file
-Store.register(scenario_difficuly,function(value)
-    game.print('Scenario difficulty has been set to: '..value)
-end)
-
-Store.register(team_scores,function(value,key)
-    game.print('Team '..key..' now has a score of '..value)
-end)
-
--- This can be very powerful when working with data that can be changed for a number of locations
--- with this module you can enable any location to output its changes to a file
--- say we wanted team scores to be synced across servers or between saves
--- although you will need to set up a method of storing the data outside the game
-Store.register(team_scores,true,function(value,key)
-    game.print('Team '..key..' now has a score of '..value)
-end)
-
--- If you want multiple handlers on one store location then you can register to the raw event
-Event.add(Store.events.on_value_changed,function(event)
-    game.print('Store '..event.location..'/'..event.key..' was updated to: '..event.value)
-end)
@@ -286,61 +250,84 @@ Store.register(team_scores,function(value,key) - utils.global - - utils.event - - expcore.common - - - utils.token - -

Functions

+

Tables

- - + - - + + + +
register([location][, synced=false][, callback])Registers a new location with an update callback which is triggered when the value updatesserializers
get(location[, key])Gets the value stored at a location, this location must be registeredwatchers
+ + +

Fields

+ + + + + + + +
uid
+ + +

Store Setup

+ + + + + + - - + + - - + + + + +
validate(store[, key][, error_stack=1])An error checking and serializing function for checking store uids and keys, note key is not required
set(location[, key], value[, from_sync=false][, from_internal=false])Sets the value at a location, this location must be registeredregister([serializer])Required to create new stores and register an serializer to a store, serializer not required
update(location[, key][, update_callback])Allows for updating a value based on the current value; only valid way to change tables in a storewatch(store, watcher)Register a watch function to a store that is called when the value in the store is changed, triggers for any key
+ + +

Store Data Management

+ + + + + + - - + + - - + + - - + + - - + + - - + +
get(store[, key])Used to retrive the current data that is stored, key is optional depending on if you are using them
update_all(location[, update_callback])Allows for updating all values at a location based on the current value; only valid way to change tables in a storeclear(store[, key])Used to clear the data in a store, will trigger any watchers, key is optional depending on if you are using them
clear(location[, key][, from_sync=false])Sets the value at a location to nil, this location must be registeredset(store[, key], value)Used to set the data in a store, will trigger any watchers, key is optional depending on if you are using them
get_keys(location)Gets all non nil keys at a location, keys can be added and removed during runtime -this is similar to Store.get but will always return a table even if it is emptyupdate(store[, key], updater)Used to update the data in a store, use this with tables, will trigger any watchers, key is optional depending on if you are using them
is_registered(location)Check for if a location is registeredmap(store, updater)Used to update all values that are in a store, similar to Store.update but acts on all keys at once, will trigger watchers for every key present
uid_location()Returns a unique name that can be used for a storetrigger(store[, key][, value])Used to trigger any watchers that are on this store, the key and value are passed to the watcher functions
@@ -354,31 +341,6 @@ this is similar to Store.get but will always return a table even if it is empty<
- # - utils.global -
-
-
-
- - - - - - - - - - - - - - - -
-
-
-
# utils.event
@@ -401,16 +363,21 @@ this is similar to Store.get but will always return a table even if it is empty< + +

Tables

+
- # - expcore.common + # + serializers
+

+

array of the serializers that stores are using, key is store uids

@@ -429,13 +396,15 @@ this is similar to Store.get but will always return a table even if it is empty<
- # - utils.token + # + watchers
+

+

array of watchers that stores will trigger, key is store uids

@@ -452,23 +421,20 @@ this is similar to Store.get but will always return a table even if it is empty<
-

Functions

+

Fields

- # - register([location][, synced=false][, callback]) + # + uid
-

Registers a new location with an update callback which is triggered when the value updates

-

- Parameters:
    @@ -476,51 +442,15 @@ this is similar to Store.get but will always return a table even if it is empty< -
  • +
  • - location + uid : - (string) - string a unique that points to the data, string used rather than token to allow migration + the current highest uid that is being used, will not increase during runtime - (optional) -
  • - - - - - -
  • - - synced - - : - - (boolean) - - when true will output changes to a file so it can be synced - - (default: false) -
  • - - - - - -
  • - - callback - - : - - (function) - - when given the callback will be automatically registered to the update of the value - - (optional)
  • @@ -529,13 +459,6 @@ this is similar to Store.get but will always return a table even if it is empty< - Returns: -
      -
    • - (string) - the location that is being used -
    • -
    @@ -543,28 +466,23 @@ this is similar to Store.get but will always return a table even if it is empty< - Usage: -
    -- Registering a new store location
    -local store_id = Store.register()
    -
    -- Registering a new store location, with custom update callback
    -local store_id = Store.uid_location()
    -Store.register(store_id,function(value,key)
    -    game.print('Store '..store_id..'/'..key..' was updated to: '..value)
    -end)
+
+

Store Setup

+
- # - get(location[, key]) + # + validate(store[, key][, error_stack=1])
-

Gets the value stored at a location, this location must be registered

+

An error checking and serializing function for checking store uids and keys, note key is not required

@@ -578,13 +496,13 @@ Store.register(store_id,function(value,key)
  • - location + store : - (string) + (number) - the location to get the data from + the uid of the store that you want to check is valid
  • @@ -598,9 +516,268 @@ Store.register(store_id,function(value,key) : - (string) + (string or any) - the key location if used + the key that you want to serialize or check is a string + + (optional) + + + + + + +
  • + + error_stack + + : + + (number) + + the position in the stack relative to the current function (1) to raise this error on + + (default: 1) +
  • + + + + + + + + Returns: +
      +
    • + (string) + if key is given and a serializer is registered, or key was already a string, then the key is returned +
    • +
    + + + + + + + + Usage: +
    -- Registering a new store and checking that it is valid
    +-- New store will use player names as the keys
    +local player_scores = Store.register(function(player)
    +    return player.name
    +end)
    +
    +-- player_scores is a valid store and key will be your player name
    +local key = Store.validate(player_scores,game.player)
    + + +
    +
    +
    +
    + # + register([serializer]) +
    +
    +
    +
    + +

    Required to create new stores and register an serializer to a store, serializer not required

    +

    + + + Parameters: + +
      + + + + + +
    • + + serializer + + : + + (function) + + the function used to convert non string keys into strings to be used in the store + + (optional) +
    • + + +
    + + + + + Returns: +
      +
    • + (number) + the uid for the new store that you have created, use this as the first param to all other functions +
    • +
    + + + + + + + + Usage: +
    -- Creating a store with no serializer
    +local scenario_diffculty = Store.register()
    +
    -- Creating a store which can take LuaPlayer
    +local player_scores = Store.register(function(player)
    +    return player.name
    +end)
    + + +
    +
    +
    +
    + # + watch(store, watcher) +
    +
    +
    +
    + +

    Register a watch function to a store that is called when the value in the store is changed, triggers for any key

    +

    + + + Parameters: + +
      + + + + + +
    • + + store + + : + + (number) + + the uid of the store that you want to watch for changes to + +
    • + + + + + +
    • + + watcher + + : + + (function) + + the function that will be called when there is a change to the store + +
    • + + +
    + + + + + + + + + + + + Usage: +
    -- Printing the changed value to all players, no keys
    +-- Register the new store, we are not using keys so we dont need a serializer
    +local scenario_diffculty = Store.register()
    +
    +-- Register the watcher so that when we change the value the message is printed
    +Store.watch(scenario_diffculty,function(value)
    +    game.print('The scenario diffculty has been set to '..value)
    +end)
    +
    +-- Set a new value for the diffculty and see that it has printed to the game
    +Store.set(scenario_diffculty,'hard')
    +
    -- Printing the changed value to all players, with keys
    +-- Register the new store, we are not using player names as the keys so it would be useful to accept LuaPlayer objects
    +local player_scores = Store.register(function(player)
    +    return player.name
    +end)
    +
    +-- Register the watcher so that when we change the value the message is printed
    +Store.watch(player_scores,function(value,key)
    +    game.print(key..' now has a score of '..value)
    +end)
    +
    +-- Set a new value for your score and see that it has printed to the game
    +Store.set(player_scores,game.player,10)
    + + +
    +
    +

    Store Data Management

    +
    +
    +
    +
    + # + get(store[, key]) +
    +
    +
    +
    + +

    Used to retrive the current data that is stored, key is optional depending on if you are using them

    +

    + + + Parameters: + +
      + + + + + +
    • + + store + + : + + (number) + + the uid of the store that you want to get the value from + +
    • + + + + + +
    • + + key + + : + + (string or any) + + the key that you want to get the value of, must be a string unless you have a serializer (optional)
    • @@ -615,7 +792,7 @@ Store.register(store_id,function(value,key)
      • (any) - the data which was stored at the location + the data that is stored
      @@ -626,23 +803,37 @@ Store.register(store_id,function(value,key) Usage: -
      -- Getting the data at a store location
      -local data = Store.get(store_id_no_keys)
      -local data = Store.get(store_id_with_keys,'key_one')
      +
      -- Getting the value of a store with no keys
      +-- Register the new store, we are not using keys so we dont need a serializer
      +local scenario_diffculty = Store.register()
      +
      +-- Get the current diffculty for the scenario
      +local diffculty = Store.get(scenario_diffculty)
      +
      -- Getting the data from a store with keys
      +-- Register the new store, we are not using player names as the keys so it would be useful to accept LuaPlayer objects
      +local player_scores = Store.register(function(player)
      +    return player.name
      +end)
      +
      +-- Get your current score
      +local my_score = Store.get(player_scores,game.player)
      +
      +-- Get all scores
      +lcoal scores = Store.get(player_scores)
    - # - set(location[, key], value[, from_sync=false][, from_internal=false]) + # + clear(store[, key])
    -

    Sets the value at a location, this location must be registered

    +

    Used to clear the data in a store, will trigger any watchers, key is optional depending on if you are using them

    @@ -656,13 +847,13 @@ Store.register(store_id,function(value,key)
  • - location + store : - (string) + (number) - the location to set the data to + the uid of the store that you want to clear
  • @@ -676,9 +867,94 @@ Store.register(store_id,function(value,key) : - (string) + (string or any) - the key location if used + the key that you want to clear, must be a string unless you have a serializer + + (optional) + + + + + + + + + + + + + + + + Usage: +
    -- Clear a store which does not use keys
    +-- Register the new store, we are not using keys so we dont need a serializer
    +local scenario_diffculty = Store.register()
    +
    +-- Clear the scenario diffculty
    +Store.clear(scenario_diffculty)
    +
    -- Clear data that is in a store with keys
    +-- Register the new store, we are not using player names as the keys so it would be useful to accept LuaPlayer objects
    +local player_scores = Store.register(function(player)
    +    return player.name
    +end)
    +
    +-- Clear your score
    +Store.clear(player_scores,game.player)
    +
    +-- Clear all scores
    +Store.clear(player_scores)
    + + +
    +
    +
    +
    + # + set(store[, key], value) +
    +
    +
    +
    + +

    Used to set the data in a store, will trigger any watchers, key is optional depending on if you are using them

    +

    + + + Parameters: + +
      + + + + + +
    • + + store + + : + + (number) + + the uid of the store that you want to set + +
    • + + + + + +
    • + + key + + : + + (string or any) + + the key that you want to set, must be a string unless you have a serializer (optional)
    • @@ -695,57 +971,16 @@ Store.register(store_id,function(value,key) (any) - the new value to set at the location, value may be reverted if there is a watch callback, cant be nil + the value that you want to set - - - -
    • - - from_sync - - : - - (boolean) - - set this true to avoid an output to the sync file - - (default: false) -
    • - - - - - -
    • - - from_internal - - : - - (boolean) - - set this true to add one to the error stack offset - - (default: false) -
    • - -
    - Returns: -
      -
    • - (boolean) - true if it was successful -
    • -
    @@ -754,9 +989,26 @@ Store.register(store_id,function(value,key) Usage: -
    -- Setting the data at a store location
    -Store.set(store_id_no_keys,'Hello, World!')
    -Store.set(store_id_with_keys,'key_one','Hello, World!')
    +
    -- Setting a store which does not use keys
    +-- Register the new store, we are not using keys so we dont need a serializer
    +local scenario_diffculty = Store.register()
    +
    +-- Set the new scenario diffculty
    +Store.set(scenario_diffculty,'hard')
    +
    -- Set data in a store with keys
    +-- Register the new store, we are not using player names as the keys so it would be useful to accept LuaPlayer objects
    +local player_scores = Store.register(function(player)
    +    return player.name
    +end)
    +
    +-- Set your current score
    +Store.set(player_scores,game.player,10)
    +
    +-- Set all scores, note this might not have much use
    +Store.set(player_scores,{
    +    [game.player.name] = 10,
    +    ['SomeOtherPlayer'] = 0
    +})
    @@ -764,13 +1016,13 @@ Store.set(store_id_with_keys,'key_one',
    # - update(location[, key][, update_callback]) + update(store[, key], updater)
    -

    Allows for updating a value based on the current value; only valid way to change tables in a store

    +

    Used to update the data in a store, use this with tables, will trigger any watchers, key is optional depending on if you are using them

    @@ -784,13 +1036,13 @@ Store.set(store_id_with_keys,'key_one', - location + store : - (string) + (number) - the location to set the data to + the uid of the store that you want to update @@ -804,9 +1056,9 @@ Store.set(store_id_with_keys,'key_one',string) + (string or any) - the key location if required + the key that you want to update, must be a string unless you have a serializer (optional) @@ -817,15 +1069,14 @@ Store.set(store_id_with_keys,'key_one', - update_callback + updater : (function) - the function called to update the value stored, rtn value to set new value + the function which is called to make changes to the value, such as changing table keys, if a value is returned it will replace the current value in the store - (optional) @@ -842,19 +1093,34 @@ Store.set(store_id_with_keys,'key_one',-- Updating a value stored at a location -Store.update(store_id_no_keys,function(value) - return value + 1 -end) -Store.update(store_id_with_keys,'key_one',function(value) +
    -- Incrementing a global score
    +-- Because we are only going to have one score so we will not need keys or a serializer
    +local game_score = Store.register()
    +
    +-- Setting a default value
    +Store.set(game_score,0)
    +
    +-- We now will update the game score by one, we return the value so that it is set as the new value in the store
    +Store.update(game_score,function(value)
         return value + 1
     end)
    -
    -- Updating a table stored at a location
    -Store.update(store_id_no_keys,function(value)
    -    value.ctn = value.ctn + 1
    +    
    -- Updating keys in a table of data
    +-- Register the new store, we are not using player names as the keys so it would be useful to accept LuaPlayer objects
    +local player_data = Store.register(function(player)
    +    return player.name
     end)
    -Store.update(store_id_with_keys,'key_one',function(value)
    -    value.ctn = value.ctn + 1
    +
    +-- Setting a default value for your player, used to show the table structure
    +Store.set(player_data,game.player,{
    +    group = 'Admin',
    +    role = 'Owner',
    +    show_group_config = false
    +})
    +
    +-- Updating the show_group_config key in your player data, note that it would be harder to call set every time
    +-- We do not need to return anything in this case as we are not replacing all the data
    +Store.update(player_data,game.player,function(data)
    +    data.show_group_config = not data.show_group_config
     end)
    @@ -862,14 +1128,14 @@ Store.update(store_id_with_keys,'key_one',
    - # - update_all(location[, update_callback]) + # + map(store, updater)
    -

    Allows for updating all values at a location based on the current value; only valid way to change tables in a store

    +

    Used to update all values that are in a store, similar to Store.update but acts on all keys at once, will trigger watchers for every key present

    @@ -883,13 +1149,13 @@ Store.update(store_id_with_keys,'key_one', - location + store : - (string) + (number) - the location to set the data to + the uid of the store that you want to map @@ -899,15 +1165,14 @@ Store.update(store_id_with_keys,'key_one', - update_callback + updater : (function) - the function called to update the value stored + the function that is called on every key in this store - (optional) @@ -924,13 +1189,24 @@ Store.update(store_id_with_keys,'key_one', Usage: -
    -- Updating all values at a location
    -Store.update(store_id_with_keys,function(value)
    -    return value + 1
    -end)
    -
    -- Updating all tables at a location
    -Store.update(store_id_with_keys,function(value)
    -    value.ctn = value.ctn + 1
    +    
    -- Updating keys in a table of data
    +-- Register the new store, we are not using player names as the keys so it would be useful to accept LuaPlayer objects
    +local player_data = Store.register(function(player)
    +    return player.name
    +end)
    +
    +-- Setting a default value for your player, used to show the table structure
    +Store.set(player_data,game.player,{
    +    group = 'Admin',
    +    role = 'Owner',
    +    show_group_config = false
    +})
    +
    +-- Updating the show_group_config key for all players, note that it would be harder to call set every time
    +-- We do not need to return anything in this case as we are not replacing all the data
    +-- We also have access to the current key being updated if needed
    +Store.map(player_data,function(data,key)
    +    data.show_group_config = not data.show_group_config
     end)
    @@ -938,14 +1214,14 @@ Store.update(store_id_with_keys,'key_one',
    - # - clear(location[, key][, from_sync=false]) + # + trigger(store[, key][, value])
    -

    Sets the value at a location to nil, this location must be registered

    +

    Used to trigger any watchers that are on this store, the key and value are passed to the watcher functions

    @@ -959,13 +1235,13 @@ Store.update(store_id_with_keys,'key_one', - location + store : - (string) + (number) - the location to set the data to + the uid of the store that you want to trigger @@ -979,9 +1255,9 @@ Store.update(store_id_with_keys,'key_one', : - (string) + (string or any) - the key location if used + the key that you want to trigger, must be a string unless you have a serializer (optional) @@ -992,15 +1268,15 @@ Store.update(store_id_with_keys,'key_one', - from_sync + value : - (boolean) + (any) - set this true to avoid an output to the sync file + the new value that is at this key or store, passed directly to the watcher - (default: false) + (optional) @@ -1009,13 +1285,6 @@ Store.update(store_id_with_keys,'key_one', - Returns: -
      -
    • - (boolean) - true if it was successful -
    • -
    @@ -1024,167 +1293,13 @@ Store.update(store_id_with_keys,'key_one', Usage: -
    -- Clear the data at a location
    -Store.clear(store_id_no_keys)
    -Store.clear(store_id_with_keys,'key_one')
    - +
    -- Triggering a manule call of the watchers
    +-- The type of store we use does not really matter for this as long as you pass it what you watchers are expecting
    +local scenario_diffculty = Store.register()
     
    -    
    -
    -
    -
    - # - get_keys(location) -
    -
    -
    -
    - -

    Gets all non nil keys at a location, keys can be added and removed during runtime -this is similar to Store.get but will always return a table even if it is empty

    -

    - - - Parameters: - -
      - - - - - -
    • - - location - - : - - (string) - - the location to get the keys of - -
    • - - -
    - - - - - Returns: -
      -
    • - (table) - a table containing all the keys names -
    • -
    - - - - - - - - Usage: -
    -- Get all keys at a store location
    -local keys = Store.get_keys(store_id_with_keys)
    - - -
    -
    -
    -
    - # - is_registered(location) -
    -
    -
    -
    - -

    Check for if a location is registered

    -

    - - - Parameters: - -
      - - - - - -
    • - - location - - : - - (string) - - the location to test for - -
    • - - -
    - - - - - Returns: -
      -
    • - (boolean) - true if registered -
    • -
    - - - - - - - - Usage: -
    -- Check that a store is registered
    -local registerd = Store.is_registered(store_id)
    - - -
    -
    -
    -
    - # - uid_location() -
    -
    -
    -
    - -

    Returns a unique name that can be used for a store

    -

    - - - - - - Returns: -
      -
    • - (string) - a unique name -
    • -
    - - - - - - - - Usage: -
    -- Get a new unique store id
    -local store_id = Store.uid_location()
    +-- Trigger the watchers with a fake change of diffculty +-- This is mostly used internally but it can be useful in other cases +Store.trigger(scenario_diffculty,nil,'normal')
    @@ -1203,7 +1318,7 @@ this is similar to Store.get but will always return a table even if it is empty< generated by LDoc
    diff --git a/docs/core/Sudo.html b/docs/core/Sudo.html index 53d24d08..effd3f71 100644 --- a/docs/core/Sudo.html +++ b/docs/core/Sudo.html @@ -544,7 +544,7 @@ generated by LDoc diff --git a/docs/guis/Player-List.html b/docs/guis/Player-List.html index 5d601cbe..ca132f1d 100644 --- a/docs/guis/Player-List.html +++ b/docs/guis/Player-List.html @@ -626,7 +626,7 @@ generated by LDoc diff --git a/docs/guis/Rocket-Info.html b/docs/guis/Rocket-Info.html index e3d10a38..9f1c0cce 100644 --- a/docs/guis/Rocket-Info.html +++ b/docs/guis/Rocket-Info.html @@ -629,7 +629,7 @@ generated by LDoc diff --git a/docs/guis/Science-Info.html b/docs/guis/Science-Info.html index 59dc47ca..b268e806 100644 --- a/docs/guis/Science-Info.html +++ b/docs/guis/Science-Info.html @@ -449,7 +449,7 @@ generated by LDoc diff --git a/docs/guis/Task-List.html b/docs/guis/Task-List.html index a97b0a3e..6411c61b 100644 --- a/docs/guis/Task-List.html +++ b/docs/guis/Task-List.html @@ -632,7 +632,7 @@ generated by LDoc diff --git a/docs/guis/Warps-List.html b/docs/guis/Warps-List.html index 75ae9c1d..3f796e43 100644 --- a/docs/guis/Warps-List.html +++ b/docs/guis/Warps-List.html @@ -837,7 +837,7 @@ generated by LDoc diff --git a/docs/index.html b/docs/index.html index 6466ea5d..bd823be3 100644 --- a/docs/index.html +++ b/docs/index.html @@ -75,7 +75,7 @@ Store Core Module - Store - - Adds an easy way to store and watch for updates to a value +- Used to store and watch for updates for values in the global table Sudo @@ -514,7 +514,7 @@ see ./expcore/commands.lua for more details generated by LDoc diff --git a/docs/modules/control.html b/docs/modules/control.html index 88f0ccce..895e3c7c 100644 --- a/docs/modules/control.html +++ b/docs/modules/control.html @@ -351,7 +351,7 @@ generated by LDoc diff --git a/docs/modules/utils.alien_evolution_progress.html b/docs/modules/utils.alien_evolution_progress.html index c377d74b..296ac275 100644 --- a/docs/modules/utils.alien_evolution_progress.html +++ b/docs/modules/utils.alien_evolution_progress.html @@ -419,7 +419,7 @@ fraction will decide a chance to spawn. 1 alien for 2 spawner's will have 50% on generated by LDoc diff --git a/docs/modules/utils.core.html b/docs/modules/utils.core.html index 3378c6d3..acf43435 100644 --- a/docs/modules/utils.core.html +++ b/docs/modules/utils.core.html @@ -1164,7 +1164,7 @@ generated by LDoc diff --git a/docs/modules/utils.debug.html b/docs/modules/utils.debug.html index b00a200b..ace05e78 100644 --- a/docs/modules/utils.debug.html +++ b/docs/modules/utils.debug.html @@ -654,7 +654,7 @@ generated by LDoc diff --git a/docs/modules/utils.dump_env.html b/docs/modules/utils.dump_env.html index e4dc2c92..ca8addbe 100644 --- a/docs/modules/utils.dump_env.html +++ b/docs/modules/utils.dump_env.html @@ -323,7 +323,7 @@ generated by LDoc diff --git a/docs/modules/utils.event.html b/docs/modules/utils.event.html index 62b58139..1102c0ef 100644 --- a/docs/modules/utils.event.html +++ b/docs/modules/utils.event.html @@ -1292,7 +1292,7 @@ generated by LDoc diff --git a/docs/modules/utils.event_core.html b/docs/modules/utils.event_core.html index 64b7e446..b400b006 100644 --- a/docs/modules/utils.event_core.html +++ b/docs/modules/utils.event_core.html @@ -434,7 +434,7 @@ generated by LDoc diff --git a/docs/modules/utils.math.html b/docs/modules/utils.math.html index 56d4d37f..2a81a956 100644 --- a/docs/modules/utils.math.html +++ b/docs/modules/utils.math.html @@ -353,7 +353,7 @@ generated by LDoc diff --git a/docs/modules/utils.recipe_locker.html b/docs/modules/utils.recipe_locker.html index 3f85b13d..58a5fe01 100644 --- a/docs/modules/utils.recipe_locker.html +++ b/docs/modules/utils.recipe_locker.html @@ -441,7 +441,7 @@ generated by LDoc diff --git a/docs/modules/utils.state_machine.html b/docs/modules/utils.state_machine.html index 98f7bcd5..e500cb0e 100644 --- a/docs/modules/utils.state_machine.html +++ b/docs/modules/utils.state_machine.html @@ -752,7 +752,7 @@ generated by LDoc diff --git a/docs/modules/utils.table.html b/docs/modules/utils.table.html index 3cbf7778..21f063b7 100644 --- a/docs/modules/utils.table.html +++ b/docs/modules/utils.table.html @@ -1418,7 +1418,7 @@ generated by LDoc diff --git a/docs/modules/utils.task.html b/docs/modules/utils.task.html index 00472a97..fc166fba 100644 --- a/docs/modules/utils.task.html +++ b/docs/modules/utils.task.html @@ -651,7 +651,7 @@ generated by LDoc diff --git a/docs/modules/utils.timestamp.html b/docs/modules/utils.timestamp.html index 99473b65..14b2f39f 100644 --- a/docs/modules/utils.timestamp.html +++ b/docs/modules/utils.timestamp.html @@ -442,7 +442,7 @@ generated by LDoc diff --git a/docs/topics/license.html b/docs/topics/license.html index e28db313..679b74e8 100644 --- a/docs/topics/license.html +++ b/docs/topics/license.html @@ -789,7 +789,7 @@ Public License instead of this License. But first, please read generated by LDoc diff --git a/docs/topics/readme.md.html b/docs/topics/readme.md.html index cc1c1178..44bd3397 100644 --- a/docs/topics/readme.md.html +++ b/docs/topics/readme.md.html @@ -333,7 +333,7 @@ generated by LDoc diff --git a/expcore/store.lua b/expcore/store.lua index 5d3f80ce..86cbf043 100644 --- a/expcore/store.lua +++ b/expcore/store.lua @@ -1,351 +1,432 @@ --[[-- Core Module - Store - - Adds an easy way to store and watch for updates to a value - @core Store - @alias Store - - @usage --- The data store module is designed to be an alterative way to store data in the global table --- each piece of data is stored at a location and optional key of that location --- it is recomented that you use a local varible to store the location -local scenario_difficuly = Store.uid_location() -local team_scores = 'team-scores' - --- Setting and getting data is then as simple as --- note that when storing a table you must use Store.update -Store.set(scenario_difficuly,'Hard') -Store.set(team_scores,game.player.force.name,20) - -Store.get(scenario_difficuly) -- returns 'Hard' -Store.get(team_scores,game.player.force.name) -- returns 20 - -Store.update(team_scores,game.player.force.name,function(value,key) - return value + 10 -- add 10 to the score -end) - --- The reason for using stores over global is the abilty to watch for updates --- for stores to work you must register them, often at the end of the file -Store.register(scenario_difficuly,function(value) - game.print('Scenario difficulty has been set to: '..value) -end) - -Store.register(team_scores,function(value,key) - game.print('Team '..key..' now has a score of '..value) -end) - --- This can be very powerful when working with data that can be changed for a number of locations --- with this module you can enable any location to output its changes to a file --- say we wanted team scores to be synced across servers or between saves --- although you will need to set up a method of storing the data outside the game -Store.register(team_scores,true,function(value,key) - game.print('Team '..key..' now has a score of '..value) -end) - --- If you want multiple handlers on one store location then you can register to the raw event -Event.add(Store.events.on_value_changed,function(event) - game.print('Store '..event.location..'/'..event.key..' was updated to: '..event.value) -end) +- Used to store and watch for updates for values in the global table +@core Store +@alias Store ]] -local Global = require 'utils.global' --- @dep utils.global local Event = require 'utils.event' --- @dep utils.event -local table_keys,write_json,get_file_path = ext_require('expcore.common','table_keys','write_json','get_file_path') --- @dep expcore.common -local Token = require 'utils.token' --- @dep utils.token local Store = { - registered={}, - synced={}, - callbacks={}, - events = { - on_value_changed=script.generate_event_name() - } + --- @field uid the current highest uid that is being used, will not increase during runtime + uid = 0, + --- @table serializers array of the serializers that stores are using, key is store uids + serializers = {}, + --- @table watchers array of watchers that stores will trigger, key is store uids + watchers = {} } -local store_data = {} -Global.register(Store.data,function(tbl) - store_data = tbl +-- All data is stored in global.data_store and is accessed here with data_store +local data_store = {} +global.data_store = {} +Event.on_load(function() + data_store = global.data_store end) -local function error_not_table(value) - if type(value) ~= 'table' then - error('Location is not a table can not use key locations',3) +--- Store Setup. +-- @section setup + +--[[-- An error checking and serializing function for checking store uids and keys, note key is not required +@tparam number store the uid of the store that you want to check is valid +@tparam[opt] ?string|any key the key that you want to serialize or check is a string +@tparam[opt=1] number error_stack the position in the stack relative to the current function (1) to raise this error on +@treturn string if key is given and a serializer is registered, or key was already a string, then the key is returned + +@usage-- Registering a new store and checking that it is valid +-- New store will use player names as the keys +local player_scores = Store.register(function(player) + return player.name +end) + +-- player_scores is a valid store and key will be your player name +local key = Store.validate(player_scores,game.player) + +]] +function Store.validate(store,key,error_stack) + error_stack = error_stack or 1 + + if not type(store) == 'number' then + -- Store is not a number and so if not valid + error('Store uid given is not a number; recived type '..type(store),error_stack+1) + elseif store > Store.uid then + -- Store is a number but it is out of range, ie larger than the current highest uid + error('Store uid is out of range; recived '..tostring(store),error_stack+1) + elseif key ~= nil and type(key) ~= 'string' and Store.serializers[store] == nil then + -- Key is present but is not a string and there is no serializer registered + error('Store key is not a string and no serializer has been registered; recived '..type(key),error_stack+1) + elseif key ~= nil then + -- Key is present and so it is serialized and returned + local serializer = Store.serializers[store] + if type(key) ~= 'string' then + local success, key = pcall(serializer,key) + + if not success then + -- Serializer casued an error while serializing the key + error('Store watcher casued an error: '..key,error_stack+1) + elseif type(key) ~= 'string' then + -- Serializer was successful but failed to return a string value + error('Store key serializer did not return a string; recived type '..type(key),error_stack+1) + end + end + + return key end + end ---[[-- Registers a new location with an update callback which is triggered when the value updates -@tparam[opt] string location string a unique that points to the data, string used rather than token to allow migration -@tparam[opt=false] boolean synced when true will output changes to a file so it can be synced -@tparam[opt] function callback when given the callback will be automatically registered to the update of the value -@treturn string the location that is being used -@usage-- Registering a new store location -local store_id = Store.register() -@usage-- Registering a new store location, with custom update callback -local store_id = Store.uid_location() -Store.register(store_id,function(value,key) - game.print('Store '..store_id..'/'..key..' was updated to: '..value) +--[[-- Required to create new stores and register an serializer to a store, serializer not required +@tparam[opt] function serializer the function used to convert non string keys into strings to be used in the store +@treturn number the uid for the new store that you have created, use this as the first param to all other functions + +@usage-- Creating a store with no serializer +local scenario_diffculty = Store.register() + +@usage-- Creating a store which can take LuaPlayer +local player_scores = Store.register(function(player) + return player.name end) + ]] -function Store.register(location,synced,callback) +function Store.register(serializer) if _LIFECYCLE ~= _STAGE.control then - return error('Can only be called during the control stage', 2) + -- Only allow this function to be called during the control stage + error('Store can not be registered durring runtime', 2) end - if type(location) ~= 'string' then - callback = synced - synced = location + -- Increment the uid counter + local uid = Store.uid + 1 + Store.uid = uid + + -- Register the serializer if given + if serializer then + Store.serializers[uid] = serializer 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 '..location..' is already registered by '..Store.registered[location], 2) - end - - Store.registered[location] = get_file_path(1) - Store.synced[location] = synced and true or nil - Store.callbacks[location] = callback or nil - - return location + -- Return the new uid + return uid end ---[[-- Gets the value stored at a location, this location must be registered -@tparam string location the location to get the data from -@tparam[opt] string key the key location if used -@treturn any the data which was stored at the location -@usage-- Getting the data at a store location -local data = Store.get(store_id_no_keys) -local data = Store.get(store_id_with_keys,'key_one') +--[[-- Register a watch function to a store that is called when the value in the store is changed, triggers for any key +@tparam number store the uid of the store that you want to watch for changes to +@tparam function watcher the function that will be called when there is a change to the store + +@usage-- Printing the changed value to all players, no keys +-- Register the new store, we are not using keys so we dont need a serializer +local scenario_diffculty = Store.register() + +-- Register the watcher so that when we change the value the message is printed +Store.watch(scenario_diffculty,function(value) + game.print('The scenario diffculty has been set to '..value) +end) + +-- Set a new value for the diffculty and see that it has printed to the game +Store.set(scenario_diffculty,'hard') + +@usage-- Printing the changed value to all players, with keys +-- Register the new store, we are not using player names as the keys so it would be useful to accept LuaPlayer objects +local player_scores = Store.register(function(player) + return player.name +end) + +-- Register the watcher so that when we change the value the message is printed +Store.watch(player_scores,function(value,key) + game.print(key..' now has a score of '..value) +end) + +-- Set a new value for your score and see that it has printed to the game +Store.set(player_scores,game.player,10) + ]] -function Store.get(location,key) - if not Store.registered[location] then - return error('Location is not registered', 2) +function Store.watch(store,watcher) + Store.validate(store,nil,2) + + -- Add the watchers table if it does not exist + local watchers = Store.watchers[store] + if not watchers then + watchers = {} + Store.watchers[store] = watchers end - local data = store_data[location] - if key and data then - error_not_table(data) + -- Append the new watcher function + watchers[#watchers+1] = watcher +end + +--- Store Data Management. +-- @section data + +--[[-- Used to retrive the current data that is stored, key is optional depending on if you are using them +@tparam number store the uid of the store that you want to get the value from +@tparam[opt] ?string|any key the key that you want to get the value of, must be a string unless you have a serializer +@treturn any the data that is stored + +@usage-- Getting the value of a store with no keys +-- Register the new store, we are not using keys so we dont need a serializer +local scenario_diffculty = Store.register() + +-- Get the current diffculty for the scenario +local diffculty = Store.get(scenario_diffculty) + +@usage-- Getting the data from a store with keys +-- Register the new store, we are not using player names as the keys so it would be useful to accept LuaPlayer objects +local player_scores = Store.register(function(player) + return player.name +end) + +-- Get your current score +local my_score = Store.get(player_scores,game.player) + +-- Get all scores +lcoal scores = Store.get(player_scores) + +]] +function Store.get(store,key) + key = Store.validate(store,key,2) + + -- Get the data from the data store + local data = data_store[store] + if key then return data[key] end + -- Return all data if there is no key return data end ---[[-- Sets the value at a location, this location must be registered -@tparam string location the location to set the data to -@tparam[opt] string key the key location if used -@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=false] boolean from_sync set this true to avoid an output to the sync file -@tparam[opt=false] boolean from_internal set this true to add one to the error stack offset -@treturn boolean true if it was successful -@usage-- Setting the data at a store location -Store.set(store_id_no_keys,'Hello, World!') -Store.set(store_id_with_keys,'key_one','Hello, World!') +--[[-- Used to clear the data in a store, will trigger any watchers, key is optional depending on if you are using them +@tparam number store the uid of the store that you want to clear +@tparam[opt] ?string|any key the key that you want to clear, must be a string unless you have a serializer + +@usage-- Clear a store which does not use keys +-- Register the new store, we are not using keys so we dont need a serializer +local scenario_diffculty = Store.register() + +-- Clear the scenario diffculty +Store.clear(scenario_diffculty) + +@usage-- Clear data that is in a store with keys +-- Register the new store, we are not using player names as the keys so it would be useful to accept LuaPlayer objects +local player_scores = Store.register(function(player) + return player.name +end) + +-- Clear your score +Store.clear(player_scores,game.player) + +-- Clear all scores +Store.clear(player_scores) + ]] -function Store.set(location,key,value,from_sync,from_internal) - if not Store.registered[location] then - return error('Location is not registered', from_internal and 3 or 2) +function Store.clear(store,key) + key = Store.validate(store,key,2) + + -- Check if there is a key being used + if key then + data_store[store][key] = nil + else + data_store[store] = nil end + -- Trigger any watch functions + Store.trigger(store,key,nil) +end + +--[[-- Used to set the data in a store, will trigger any watchers, key is optional depending on if you are using them +@tparam number store the uid of the store that you want to set +@tparam[opt] ?string|any key the key that you want to set, must be a string unless you have a serializer +@tparam any value the value that you want to set + +@usage-- Setting a store which does not use keys +-- Register the new store, we are not using keys so we dont need a serializer +local scenario_diffculty = Store.register() + +-- Set the new scenario diffculty +Store.set(scenario_diffculty,'hard') + +@usage-- Set data in a store with keys +-- Register the new store, we are not using player names as the keys so it would be useful to accept LuaPlayer objects +local player_scores = Store.register(function(player) + return player.name +end) + +-- Set your current score +Store.set(player_scores,game.player,10) + +-- Set all scores, note this might not have much use +Store.set(player_scores,{ + [game.player.name] = 10, + ['SomeOtherPlayer'] = 0 +}) + +]] +function Store.set(store,key,value) + -- Allow for key to be optional if value == nil then value = key key = nil end + -- Check the store is valid + key = Store.validate(store,key,2) + + -- If there is a key being used then the store must be a able if key then - local data = store_data[location] - if not data then - data = {} - store_data[location] = data + if type(data_store[store]) ~= 'table' then + data_store[store] = {_value = data_store[store]} end - error_not_table(data) - data[key] = value + data_store[store][key] = value else - store_data[location] = value + data_store[store] = value end - script.raise_event(Store.events.on_value_changed,{ - tick=game.tick, - location=location, - key=key, - value=value, - from_sync=from_sync or false - }) - - return true + -- Trigger any watchers + Store.trigger(store,key,value) end ---[[-- Allows for updating a value based on the current value; only valid way to change tables in a store -@tparam string location the location to set the data to -@tparam[opt] string key the key location if required -@tparam[opt] function update_callback the function called to update the value stored, rtn value to set new value -@usage-- Updating a value stored at a location -Store.update(store_id_no_keys,function(value) - return value + 1 -end) -Store.update(store_id_with_keys,'key_one',function(value) - return value + 1 -end) -@usage-- Updating a table stored at a location -Store.update(store_id_no_keys,function(value) - value.ctn = value.ctn + 1 -end) -Store.update(store_id_with_keys,'key_one',function(value) - value.ctn = value.ctn + 1 -end) -]] -function Store.update(location,key,update_callback,...) - local value = Store.get(location,key) +--[[-- Used to update the data in a store, use this with tables, will trigger any watchers, key is optional depending on if you are using them +@tparam number store the uid of the store that you want to update +@tparam[opt] ?string|any key the key that you want to update, must be a string unless you have a serializer +@tparam function updater the function which is called to make changes to the value, such as changing table keys, if a value is returned it will replace the current value in the store - local args - if type(key) == 'function' then - args = {update_callback,...} - update_callback = key +@usage-- Incrementing a global score +-- Because we are only going to have one score so we will not need keys or a serializer +local game_score = Store.register() + +-- Setting a default value +Store.set(game_score,0) + +-- We now will update the game score by one, we return the value so that it is set as the new value in the store +Store.update(game_score,function(value) + return value + 1 +end) + +@usage-- Updating keys in a table of data +-- Register the new store, we are not using player names as the keys so it would be useful to accept LuaPlayer objects +local player_data = Store.register(function(player) + return player.name +end) + +-- Setting a default value for your player, used to show the table structure +Store.set(player_data,game.player,{ + group = 'Admin', + role = 'Owner', + show_group_config = false +}) + +-- Updating the show_group_config key in your player data, note that it would be harder to call set every time +-- We do not need to return anything in this case as we are not replacing all the data +Store.update(player_data,game.player,function(data) + data.show_group_config = not data.show_group_config +end) + +]] +function Store.update(store,key,updater) + -- Allow for key to be nil + if updater == nil then + updater = key key = nil end - local rtn - if update_callback and type(update_callback) == 'function' then - if args then - rtn = update_callback(value,key,unpack(args)) - else - rtn = update_callback(value,key,...) - end - end - - if rtn then - Store.set(location,key,rtn,nil,true) - else - script.raise_event(Store.events.on_value_changed,{ - tick=game.tick, - location=location, - key=key, - value=value, - from_sync=false - }) - end - -end - ---[[-- Allows for updating all values at a location based on the current value; only valid way to change tables in a store -@tparam string location the location to set the data to -@tparam[opt] function update_callback the function called to update the value stored -@usage-- Updating all values at a location -Store.update(store_id_with_keys,function(value) - return value + 1 -end) -@usage-- Updating all tables at a location -Store.update(store_id_with_keys,function(value) - value.ctn = value.ctn + 1 -end) -]] -function Store.update_all(location,update_callback,...) - local data = Store.get(location) - - error_not_table(data) - - for key,value in pairs(data) do - local rtn - if update_callback and type(update_callback) == 'function' then - rtn = update_callback(value,key,...) - end - - if rtn then - Store.set(location,key,rtn,nil,true) - else - script.raise_event(Store.events.on_value_changed,{ - tick=game.tick, - location=location, - key=key, - value=value, - from_sync=false - }) - end - end - -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 key the key location if used -@tparam[opt=false] boolean from_sync set this true to avoid an output to the sync file -@treturn boolean true if it was successful -@usage-- Clear the data at a location -Store.clear(store_id_no_keys) -Store.clear(store_id_with_keys,'key_one') -]] -function Store.clear(location,key,from_sync) - if not Store.callbacks[location] then - return error('Location is not registered', 2) - end + -- Check the store is valid + key = Store.validate(store,key,2) + local value + -- If a key is used then the store must be a table if key then - local data = store_data[location] - if not data then return end - error_not_table(data) - data[key] = nil + if type(data_store[store]) ~= 'table' then + data_store[store] = {_value = data_store[store]} + end + + -- Call the updater and if it returns a value then set this value + local rtn = updater(data_store[store][key]) + if rtn then + data_store[store][key] = rtn + end + value = data_store[store][key] + else - store_data[location] = nil + -- Call the updater and if it returns a value then set this value + local rtn = updater(data_store[store]) + if rtn then + data_store[store] = rtn + end + value = data_store[store] + end - script.raise_event(Store.events.on_value_changed,{ - tick=game.tick, - location=location, - key=key, - from_sync=from_sync or false - }) - - return true + -- Trigger any watchers + Store.trigger(store,key,value) end ---[[-- Gets all non nil keys at a location, keys can be added and removed during runtime -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 keys of -@treturn table a table containing all the keys names -@usage-- Get all keys at a store location -local keys = Store.get_keys(store_id_with_keys) -]] -function Store.get_keys(location) - local data = Store.get(location) - return type(data) == 'table' and table_keys(data) or {} -end +--[[-- Used to update all values that are in a store, similar to Store.update but acts on all keys at once, will trigger watchers for every key present +@tparam number store the uid of the store that you want to map +@tparam function updater the function that is called on every key in this store ---[[-- Check for if a location is registered -@tparam string location the location to test for -@treturn boolean true if registered -@usage-- Check that a store is registered -local registerd = Store.is_registered(store_id) -]] -function Store.is_registered(location) - return Store.registered[location] -end - ---[[-- Returns a unique name that can be used for a store -@treturn string a unique name -@usage-- Get a new unique store id -local store_id = Store.uid_location() -]] -function Store.uid_location() - return tostring(Token.uid()) -end - --- Handles syncing -Event.add(Store.events.on_value_changed,function(event) - if Store.callbacks[event.location] then - Store.callbacks[event.location](event.value,event.key) - end - - if not event.from_sync and Store.synced[event.location] then - write_json('log/store.log',{ - tick=event.tick, - location=event.location, - key=event.key, - value=event.value, - }) - end +@usage-- Updating keys in a table of data +-- Register the new store, we are not using player names as the keys so it would be useful to accept LuaPlayer objects +local player_data = Store.register(function(player) + return player.name end) +-- Setting a default value for your player, used to show the table structure +Store.set(player_data,game.player,{ + group = 'Admin', + role = 'Owner', + show_group_config = false +}) + +-- Updating the show_group_config key for all players, note that it would be harder to call set every time +-- We do not need to return anything in this case as we are not replacing all the data +-- We also have access to the current key being updated if needed +Store.map(player_data,function(data,key) + data.show_group_config = not data.show_group_config +end) + +]] +function Store.map(store,updater) + Store.validate(store,nil,2) + + -- Get all that data in the store and check its a table + local data = data_store[store] + if not type(data) == 'table' then + return + end + + -- Loop over all the keys and call the updater, setting value if returned, and calling watcher functions + for key,value in pairs(data) do + local rtn = updater(value,key) + if rtn then + data[key] = rtn + end + Store.trigger(store,key,data[key]) + end +end + +--[[-- Used to trigger any watchers that are on this store, the key and value are passed to the watcher functions +@tparam number store the uid of the store that you want to trigger +@tparam[opt] ?string|any key the key that you want to trigger, must be a string unless you have a serializer +@tparam[opt] any value the new value that is at this key or store, passed directly to the watcher + +@usage-- Triggering a manule call of the watchers +-- The type of store we use does not really matter for this as long as you pass it what you watchers are expecting +local scenario_diffculty = Store.register() + +-- Trigger the watchers with a fake change of diffculty +-- This is mostly used internally but it can be useful in other cases +Store.trigger(scenario_diffculty,nil,'normal') + +]] +function Store.trigger(store,key,value) + key = Store.validate(store,key,2) + + -- Get the watchers and then loop over them + local watchers = Store.watchers[store] + for _,watcher in pairs(watchers) do + local success, err = pcall(watcher,value,key) + if not success then + error('Store watcher casued an error: '..err) + end + end +end + +-- Module return return Store \ No newline at end of file