Skip to content

Commit

Permalink
Fix type bind_save_part -> bind_save_state, fix default autosave timer
Browse files Browse the repository at this point in the history
  • Loading branch information
Insality committed Aug 29, 2024
1 parent 96daf04 commit e23600d
Show file tree
Hide file tree
Showing 5 changed files with 47 additions and 32 deletions.
22 changes: 15 additions & 7 deletions API_REFERENCE.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@

- [Saver Functions](#saver-functions)
- [saver.init](#saverinit)
- [saver.bind_save_part](#saverbind_save_part)
- [saver.bind_save_state](#saverbind_save_state)
- [saver.save_game_state](#saversave_game_state)
- [saver.load_game_state](#saverload_game_state)
- [saver.get_game_state](#saverget_game_state)
Expand Down Expand Up @@ -55,18 +55,18 @@ This function loads the game state from a file and starts the autosave timer. If
saver.init()
```

**saver.bind_save_part**
**saver.bind_save_state**
---
```lua
saver.bind_save_part(key_id, table_reference)
saver.bind_save_state(table_key_id, table_reference)
```

This function binds a table reference to a part of the game state. When the game state is saved, the table reference will be saved as part of the game state.
This function binds a table reference as a part of the game state. When the game state is saved, the all table references will be saved to the game state.

This is a main function to use to save your game state. You can bind multiple tables to different parts of the game state. After binding, the `table_reference` will be changed by the saved data.

- **Parameters:**
- `key_id`: The table key to set the value for.
- `table_key_id`: The table key to set the value for.
- `table_reference`: The table reference to bind to the game state.

- **Usage Example:**
Expand All @@ -77,7 +77,7 @@ local game_state = {
money = 100
}

saver.bind_save_part("game", game_state)
saver.bind_save_state("game", game_state)

-- If we have previously saved game state, the game_state will be changed to the saved data
print(game_state.level) -- 5 (if it was saved as before)
Expand Down Expand Up @@ -378,7 +378,7 @@ local migrations = {

saver.set_migrations(migrations)
saver.init()
saver.bind_save_part("game", game_state)
saver.bind_save_state("game", game_state)
saver.apply_migrations()
```

Expand Down Expand Up @@ -463,6 +463,14 @@ print(project_folder)

The Storage module provides several functions to work with key-value storage:

Before using the storage module, you `saver.init()` should be called to initialize the storage data.

To start using the module in your project, you first need to import it. This can be done with the following line of code:

```lua
local storage = require("saver.storage")
```

**storage.set**
---
```lua
Expand Down
6 changes: 3 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ This configuration section for `game.project` defines various settings:

Defold Saver uses the following core concepts:
- **Auto-Save**: Automatically save data at regular intervals. It used as a default save method. This allows you to specify the data you want to keep in the save file and the library will handle the rest.
- **Save State**: A Save state contains a set of table references in the save file. You can bind multiple save states. Bindings is done by the `saver.bind_save_part(id, table_reference)` function. When you bind the table to save state and previous data was saved, the save data will override values in your reference table. So usually you should bind the default table from module or your game data on game loader step.
- **Save State**: A Save state contains a set of table references in the save file. You can bind multiple save states. Bindings is done by the `saver.bind_save_state(id, table_reference)` function. When you bind the table to save state and previous data was saved, the save data will override values in your reference table. So usually you should bind the default table from module or your game data on game loader step.
- **Migration**: Migrations are used to update the save data if required. Migration is a just list of functions that will be applied to the save data if the migration version in save is less than the migrations count. You can set migrations by `saver.set_migrations` function before `saver.init` and apply them by `saver.apply_migrations` function after.
- **Storage**: Storage is a simple key-value storage that can be utilized in many ways and you don't want to make a separate save state for it. You can set and get values by `storage.set` and `storage.get` functions.

Expand All @@ -83,7 +83,7 @@ local game_data = {

function init(self)
saver.init()
saver.bind_save_part("game", game_data)
saver.bind_save_state("game", game_data)

-- Now we can change game_data content and it will be saved automatically via autosave
game_data.score = game_data.score + 1
Expand All @@ -100,7 +100,7 @@ end

```lua
saver.init()
saver.bind_save_part(part_id, table_reference)
saver.bind_save_state(table_key_id, table_reference)
saver.save_game_state()
saver.load_game_state()
saver.set_game_state(state)
Expand Down
10 changes: 5 additions & 5 deletions USE_CASES.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ local game_data = {

function init(self)
saver.init()
saver.bind_save_part("game", game_data)
saver.bind_save_state("game", game_data)
end
```

Expand Down Expand Up @@ -47,7 +47,7 @@ You can use `saver.get_game_state()` to get the current game state. It will retu
```lua
function init(self)
saver.init()
saver.bind_save_part("game", game_data)
saver.bind_save_state("game", game_data)

-- Inspect the game state
pprint(saver.get_game_state())
Expand Down Expand Up @@ -79,7 +79,7 @@ local my_library = require("my_library")

function init(self)
saver.init()
saver.bind_save_part("my_library", my_library.state)
saver.bind_save_state("my_library", my_library.state)

-- After bind save state, you can use your library functions
-- The state will be loaded from the save file and will be saved automatically
Expand Down Expand Up @@ -115,8 +115,8 @@ local migrations = {
function init(data)
saver.set_migrations(migrations)
saver.init()
saver.bind_save_part("game", game_data)
saver.bind_save_part("settings", settings_data)
saver.bind_save_state("game", game_data)
saver.bind_save_state("settings", settings_data)

-- We need to call `set_migrations` before `init` to correct
-- tracking of current migration version
Expand Down
23 changes: 12 additions & 11 deletions saver/saver.lua
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,11 @@ local migrations = require("saver.migrations")
local saver_internal = require("saver.saver_internal")

local PROJECT_NAME = sys.get_config_string("project.title")
local DIRECTORY_PATH = sys.get_config_string("saver.save_folder", PROJECT_NAME)
local SAVE_NAME = sys.get_config_string("saver.save_name", "game")
local SAVER_KEY = sys.get_config_string("saver.saver_key", "saver")
local STORAGE_KEY = sys.get_config_string("saver.storage_key", "storage")
local DEFAULT_AUTOSAVE_TIMER = sys.get_config_int("saver.autosave_timer", 0)
local DEFAULT_AUTOSAVE_TIMER = sys.get_config_int("saver.autosave_timer", 3)


---@class saver
Expand Down Expand Up @@ -135,23 +136,23 @@ end


---Load and override the table_reference. The reference on the table keeps the same
---@param key_id string The save state id to save
---@param table_key_id string The save state id to save
---@param table_reference table The save state table
---@return table The table_reference
function M.bind_save_state(key_id, table_reference)
function M.bind_save_state(table_key_id, table_reference)
local save_table = M.get_game_state()
assert(save_table, "Add save part should be called after init")

-- Add the save part if it doesn't exist
if not save_table[key_id] then
save_table[key_id] = table_reference
if not save_table[table_key_id] then
save_table[table_key_id] = table_reference
return table_reference
end

-- Override the save part if it exists
-- Values from previous save part will be copied to the new save part
local prev_reference = save_table[key_id]
save_table[key_id] = table_reference
local prev_reference = save_table[table_key_id]
save_table[table_key_id] = table_reference
saver_internal.override(prev_reference, table_reference)

return table_reference
Expand Down Expand Up @@ -207,14 +208,14 @@ function M.delete_file_by_name(filename)
end


---Get the save path in the save directory
---@param filename string
---@return string
---This function returns the absolute path to the game save folder. If a file name is provided, the path to the file in the game save folder is returned. Filename supports subfolders.
---@param filename string @The name of the file to get the path for. Can contain subfolders.
---@return string @The absolute path to the game save folder, or the path to the file in the game save folder if a file name is provided.
function M.get_save_path(filename)
assert(filename, "Can't get save path without filename")

-- If filename contains "/" extract subfolder to the dir_name
local directory_path = PROJECT_NAME
local directory_path = DIRECTORY_PATH
if filename:find("/") then
local splitted = saver_internal.split(filename, "/")
filename = splitted[#splitted]
Expand Down
18 changes: 12 additions & 6 deletions saver/storage.lua
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,8 @@ function M.get_number(name, default_value)

local value = M.get(name, default_value)
if type(value) == TYPE_NUMBER then
return value --[[@as number]]
---@cast value number
return value
end
return default_value
end
Expand All @@ -62,7 +63,8 @@ function M.get_string(name, default_value)

local value = M.get(name, default_value)
if type(value) == TYPE_STRING then
return value --[[@as string]]
---@cast value string
return value
end
return default_value
end
Expand All @@ -77,7 +79,8 @@ function M.get_boolean(name, default_value)

local value = M.get(name, default_value)
if type(value) == TYPE_BOOLEAN then
return value --[[@as boolean]]
---@cast value boolean
return value
end
return default_value
end
Expand All @@ -91,17 +94,20 @@ function M.set(id, value)
local v = M.state.storage[id] or {}

if type(value) == TYPE_STRING then
v.s_value = value --[[@as string]]
---@cast value string
v.s_value = value
v.i_value = nil
v.b_value = nil
end
if type(value) == TYPE_NUMBER then
v.i_value = value --[[@as number]]
---@cast value number
v.i_value = value
v.s_value = nil
v.b_value = nil
end
if type(value) == TYPE_BOOLEAN then
v.b_value = value --[[@as boolean]]
---@cast value boolean
v.b_value = value
v.s_value = nil
v.i_value = nil
end
Expand Down

0 comments on commit e23600d

Please sign in to comment.