## Store core

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

### Usage

    ---- Basic Use
        -- At the most basic level this allows for the naming of locations to store in the global table, the second feature is that you are
        -- able to listen for updates of this value, which means that when ever the set function is called it will trigger the update callback.

        -- 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.

        -- This will register a new location called 'scenario.difficulty'
        -- note that setting a start value is optional and we could take nil to mean normal
        Store.register('scenario.difficulty',function(value)
            game.print('The scenario difficulty has be set to: '..value)
        end)

        -- 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.difficulty','hard')

        -- This will return 'hard'
        Store.get('scenario.difficulty')

    ---- Using Children
        -- One limitation of store is that all locations 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 "parent" location which has been registered
        -- 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 register every player at the start you must use
        -- the players name as the child name.

        -- This will register the location 'scenario.score' where we plan to use force names as the child
        Store.register('scenario.score',function(value,child)
            game.print(child..' now has a score of '..value)
        end)

        -- This will return nil, but will not error as children don't need to be registered
        Store.get('scenario.score','player')

        -- This will set 'player' to have a value of 10 for 'scenario.score' and trigger the game message print
        Store.set('scenario.score','player',10)

        -- This would be the similar to Store.get however this will return the names of all the children
        Store.get_children('scenario.score')

    ---- Using Sync
        -- 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
        -- syncing of values.

        -- This may be useful when you want to have a value change effect multiple instances or even if you just want a database to store values so
        -- you can sync data between map resets.

        -- This example will register the location 'statistics.total-play-time' where we plan to use plan names as the child
        -- note that the location must be the same across instances
        Store.register('statistics.total-play-time',true,function(value,child)
            game.print(child..' now has now played for '..value)
        end)

        -- Use of set and are all the same as non synced but you should include from_sync as true

    ---- Alternative method
        -- Some people may prefer to use a variable 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, uid_location will also
        -- be used if you give a nil location.

        local store_game_speed =
        Store.register(function(value)
            game.print('The game speed has been set to: '..value)
        end)

### Dependencies

utils.global
utils.event
expcore.common
utils.token

### Functions

is_registered(location) | Check for if a location is registered
uid_location() | Returns a unique name that can be used for a store
register([location][, synced][, callback]) | Registers a new location with an update callback which is triggered when the value updates
get(location[, child][, allow_unregistered=false]) | Gets the value stored at a location, this location must be registered
set(location[, child], value[, from_sync]) | Sets the value at a location, this location must be registered
clear(location[, child][, from_sync]) | Sets the value at a location to nil, this location must be registered
get_children(location) | 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

### Dependencies

# utils.global
# utils.event
# expcore.common
# utils.token

### Functions

# is_registered(location)

  Check for if a location is registered

  Parameters:
  - location : (string) the location to test for
  Returns:
  - (boolean) true if registered
# uid_location()

  Returns a unique name that can be used for a store

  Returns:
  - (string) a unique name
# register([location][, synced][, callback])

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

  Parameters:
  - location : (string) string a unique that points to the data, string used rather than token to allow migration (optional)
  - synced : (boolean) when true will output changes to a file so it can be synced (optional)
  - callback : (function) when given the callback will be automatically registered to the update of the value (optional)
  Returns:
  - (string) the location that is being used
# get(location[, child][, allow_unregistered=false])

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

  Parameters:
  - location : (string) the location to get the data from
  - child : (string) the child location if required (optional)
  - allow_unregistered : (boolean) when true no error is returned if the location is not registered (default: false)
  Returns:
  - (any) the data which was stored at the location
# set(location[, child], value[, from_sync])

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

  Parameters:
  - location : (string) the location to set the data to
  - child : (string) the child location if required (optional)
  - value : (any) the new value to set at the location, value may be reverted if there is a watch callback, cant be nil
  - from_sync : (boolean) set this true to avoid an output to the sync file (optional)
  Returns:
  - (boolean) true if it was successful
# clear(location[, child][, from_sync])

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

  Parameters:
  - location : (string) the location to set the data to
  - child : (string) the child location if required (optional)
  - from_sync : (boolean) set this true to avoid an output to the sync file (optional)
  Returns:
  - (boolean) true if it was successful
# get_children(location)

  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

  Parameters:
  - location : (string) the location to get the children of
  Returns:
  - (table) a table containing all the children names