Skip to content

Commit

Permalink
v3.1.1
Browse files Browse the repository at this point in the history
  • Loading branch information
noahrepublic committed Mar 23, 2024
1 parent 2f29d38 commit 2715069
Show file tree
Hide file tree
Showing 4 changed files with 172 additions and 1 deletion.
6 changes: 6 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,12 @@
# DataKeep

## [version 3.1.1](https://github.com/noahrepublic/DataKeep/releases/tag/v3.1.1): 03/17/2024

### Fixed
- LoadCount not incrementing

### Added
- Class implementation to Usage docs

## [version 3.1.0](https://github.com/noahrepublic/DataKeep/releases/tag/v3.1.0): 03/17/2024

Expand Down
164 changes: 164 additions & 0 deletions docs/Usage.md
Original file line number Diff line number Diff line change
Expand Up @@ -83,3 +83,167 @@ end)
# Class Approach

For more experienced developers I personally opt in to create a service that returns a "Player" OOP class that holds it own cleaner and a Keep inside.

Note: "attributes" and "leaderstats" are folders in the script parent which contains numbervalues/stringvalues/boolvalues

```lua

--> Services

local Players = game:GetService("Players")
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local ServerStorage = game:GetService("ServerStorage")

--> Includes

local Packages = ReplicatedStorage.Packages

local require = require(Packages.Loader).load(script)

local Maid = require("Maid")

local ServerPackages = ServerStorage.Packages

local DataKeep = require(ServerPackages.DataKeep)

local DataTemplate = require(script.Parent.DataTemplate)

--> Module Definition

local Player = {}
Player.__index = Player

--> Variables

local keepStore = DataKeep.GetStore("PlayerData", DataTemplate):awaitValue()

keepStore.validate = function(data)
for key in data do
local dataTempVersion = DataTemplate[key]

if typeof(data[key]) ~= typeof(dataTempVersion) then
return false,
`Invalid type for key {key}, expected {typeof(dataTempVersion)}, got {typeof(key)}, value {data[key]}`
end
end

return true
end
--> Private Functions

local function initKeep(playerClass, keep)
local player = playerClass.Player

-- attributes & leaderstats

local attributes = Instance.new("Folder")
attributes.Name = "attributes"
attributes.Parent = player

local leaderstats = Instance.new("Folder")
leaderstats.Name = "leaderstats"
leaderstats.Parent = player

local function bindData(value, parent) -- leaderstats or attributes
local doesExist = keep.Data[value.Name]

if not doesExist then
return
end

value = value:Clone()

value.Value = keep.Data[value.Name]

value:GetPropertyChangedSignal("Value"):Connect(function() -- should clean on value destroy
keep.Data[value.Name] = value.Value
end)

value.Parent = parent

playerClass._keys[value.Name] = value
end

-- "attributes" and "leaderstats" are folders in the script parent which contains numbervalues/stringvalues/boolvalues

for _, attribute in ipairs(script.Parent.attributes:GetChildren()) do
bindData(attribute, attributes)
end

for _, leaderstat in ipairs(script.Parent.leaderstats:GetChildren()) do
bindData(leaderstat, leaderstats)
end

-- listen for globals
end

local function loadKeep(playerClass)
local player = playerClass.Player

local keep = keepStore:LoadKeep("Player_" .. player.UserId)

keep:andThen(function(dataKeep)
if dataKeep == nil then
player:Kick("Data locked")
end
-- add userids

dataKeep:Reconcile()

dataKeep.Releasing:Connect(function(releaseState) -- no clean needed-- datakeep releases internals
releaseState
:andThen(function()
player:Kick("Session released")
end)
:catch(function(err)
warn(err)
end)
end)

if not player:IsDescendantOf(Players) then
playerClass:Destroy()
return
end

initKeep(playerClass, dataKeep)
end)

return keep -- so they can attach to the promise
end

--> Constructor

function Player.new(player)
local self = setmetatable({
Player = player,

Maid = Maid.new(),

Keep = {},

_keys = {}, -- stored attribute/leaderstats keys for changing to automatically change the datakeep. **MUST USE THESE FOR ANY ATTRIBUTES/LEADERSTATS BINDED**
}, Player)

self.Keep = loadKeep(self)

return self
end

function Player:GetKey(keyName: string)
return self._keys[keyName]
end

function Player:GetData(key: string)
local keep = self.Keep:awaitValue()

return keep.Data[key]
end

function Player:Destroy()
-- do cleaning, this should generally include releasing the keep
end

--> Public Methods

return Player
```
1 change: 1 addition & 0 deletions src/Keep.lua
Original file line number Diff line number Diff line change
Expand Up @@ -458,6 +458,7 @@ local function transformUpdate(keep: Keep, newestData: KeepStruct, release: bool

keep._last_save = os.clock()
newestData.MetaData.ForceLoad = keep.MetaData.ForceLoad
newestData.MetaData.LoadCount = keep.MetaData.LoadCount

return newestData, newestData.UserIds
end
Expand Down
2 changes: 1 addition & 1 deletion wally.toml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
[package]
name = "noahrepublic/datakeep"
description = "The final data saving solution you need"
version = "3.1.0"
version = "3.1.1"
license = "MIT"
authors = ["noahrepublic"]
registry = "https://github.com/UpliftGames/wally-index"
Expand Down

0 comments on commit 2715069

Please sign in to comment.