Skip to content

Commit

Permalink
Update chest
Browse files Browse the repository at this point in the history
  • Loading branch information
gaymeowing committed Aug 7, 2024
1 parent 2a1282a commit c92b25b
Show file tree
Hide file tree
Showing 13 changed files with 366 additions and 50 deletions.
1 change: 1 addition & 0 deletions libs/chest/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
# [Documentation](https://libs.luau.lol/chest)
40 changes: 40 additions & 0 deletions libs/chest/callbacks.luau
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
--!native

-- callbacks
-- utility for handling callbacks

local cross = require("libs/cross")

local callbacks = {}

function callbacks.SPAWN<A...>(callbacks: { { (A...) -> () } }, ...: A...)
for _, callback_info in callbacks do
cross.spawn(callback_info[1], ...)
end
end

function callbacks.CONNECTION<A...>(
callbacks: { { (A...) -> () } },
callback: (A...) -> ()
): () -> ()
local info = table.freeze({ callback })
table.insert(callbacks, info)

return function()
local index = table.find(callbacks, info)

if index then
if index ~= 1 then
local len = #callbacks
callbacks[index] = callbacks[len]
callbacks[len] = nil
else
callbacks[1] = nil
end
end
end
end

return table.freeze(callbacks)


52 changes: 22 additions & 30 deletions libs/chest/data_ops.luau
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ local function CLONE_BUFFER(buf: buffer): buffer
end

-- merges a & b into one array, eliminating duplicate values
local function merge_arrays_unique_only<V>(a: { V }, b: { V }): { V }
local function MERGE_ARRAYS_UNIQUE_ONLY<V>(a: { V }, b: { V }): { V }
local result_tbl = table.clone(a)

for _, value in b do
Expand All @@ -24,92 +24,84 @@ local function merge_arrays_unique_only<V>(a: { V }, b: { V }): { V }
return result_tbl
end

local function deepfreeze<T>(tbl: T & {}): T
local function DEEP_FREEZE<T>(tbl: T & {}): T
local tbl = tbl :: any

for index, value in tbl do
if type(value) == "table" then
tbl[index] = deepfreeze(value :: any)
tbl[index] = DEEP_FREEZE(value :: any)
end
end
return table.freeze(tbl) :: any
end

local function frozen_deepclone<T>(tbl: T & {}): T
local function FROZEN_DEEPCLONE<T>(tbl: T & {}): T
local clone = table.clone(tbl)

for index, value in clone do
if type(value) == "table" then
clone[index] = frozen_deepclone(value :: any)
clone[index] = FROZEN_DEEPCLONE(value :: any)
elseif type(value) == "buffer" then
clone[index] = CLONE_BUFFER(value)
end
end
return table.freeze(clone) :: any
end

local function deepclone<T>(tbl: T & {}): T
local function DEEPCLONE<T>(tbl: T & {}): T
local clone = table.clone(tbl)

for index, value in clone do
if type(value) == "table" then
clone[index] = deepclone(value :: any)
clone[index] = DEEPCLONE(value :: any)
elseif type(value) == "buffer" then
clone[index] = CLONE_BUFFER(value)
end
end
return clone :: any
end

local function clone_val<Value>(value: Value): Value
local function CLONE_VAL<Value>(value: Value): Value
return if type(value) == "table" then
deepclone(value)
DEEPCLONE(value)
elseif type(value) == "buffer" then
CLONE_BUFFER(value) :: any
else
value
end

local function clone_default_val<Value, Metadata>(
chest: t.Chest<Value, Metadata>,
key: string
): Value
local getter = chest.default_value_getter
return if getter then getter(key) else clone_val(chest.default_value :: any)
end

local function reconcile<T>(original: { [any]: any }, template: T & {}): T
local function RECONCILE<T>(original: { [any]: any }, template: T & {}): T
local tbl = table.clone(original)
local template = template :: any

for key, value: any in template :: {} do
local tbl_key = tbl[key]

if not tbl_key then
tbl[key] = clone_val(value)
tbl[key] = CLONE_VAL(value)
elseif type(tbl_key) == "table" and type(value) == "table" then
tbl[key] = reconcile(tbl_key, value)
tbl[key] = RECONCILE(tbl_key, value)
end
end

return tbl :: any
end

local function clone_default_val<Value, Metadata>(
local function CLONE_DEFAULT_VAL<Value, Metadata>(
chest: t.Chest<Value, Metadata>,
key: string
): Value
local getter = chest.default_value_getter
return if getter then getter(key) else clone_val(chest.default_value :: any)
return if getter then getter(key) else CLONE_VAL(chest.default_value :: any)
end

return table.freeze({
merge_arrays_unique_only = merge_arrays_unique_only,
clone_default_val = clone_default_val,
frozen_deepclone = frozen_deepclone,
clone_buf = CLONE_BUFFER,
deepfreeze = deepfreeze,
deepclone = deepclone,
clone_val = clone_val,
reconcile = reconcile,
MERGE_ARRAYS_UNIQUE_ONLY = MERGE_ARRAYS_UNIQUE_ONLY,
CLONE_DEFAULT_VAL = CLONE_DEFAULT_VAL,
FROZEN_DEEPCLONE = FROZEN_DEEPCLONE,
CLONE_BUF = CLONE_BUFFER,
DEEP_FREEZE = DEEP_FREEZE,
DEEPCLONE = DEEPCLONE,
CLONE_VAL = CLONE_VAL,
RECONCILE = RECONCILE,
})
28 changes: 28 additions & 0 deletions libs/chest/gem/base.luau
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@

-- base gem
-- class that the other gems inherit from as both classes share
-- the exact same methods for dealing w datastore versioning

-- NOTE: do when DataStore:GetVersionAtTimeAsync() is added
-- https://devforum.roblox.com/t/upcoming-changes-to-data-stores-versioning/3042258

local t = require("../types")

local basegem_proto = {} :: t.BaseGemPrototype
(basegem_proto :: any).__index = basegem_proto

basegem_proto.revert = function(gem: t.BaseGem, time: number, auto_migrate: boolean?): (boolean, string?)
local gem: t.GlobalGem | t.Gem = gem :: any
local chest = gem.chest

error("[CHEST] method not implemented, waiting for DataStore:GetVersionAtTimeAsync() to be added")
end :: any

basegem_proto.datastore_version = function(gem: t.BaseGem, time: number): (boolean, string?)
local gem: t.GlobalGem | t.Gem = gem :: any
local chest = gem.chest

error("[CHEST] method not implemented, waiting for DataStore:GetVersionAtTimeAsync() to be added")
end :: any

return table.freeze(basegem_proto)
22 changes: 22 additions & 0 deletions libs/chest/gem/get_keyinfo.luau
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
--!native

-- get keyinfo
-- function for getting the keyinfo for a gem

local t = require("../types")

local ERR_CANNOT_FIND_GEM = "[CHEST] cannot %s gem %s because it doesnt exist in chest %s"

local function GET_KEYINFO(local_gem: t.Gem, error_action: string): t.KeyInfo
local chest = local_gem.chest
local name = local_gem.name
local keyinfo = chest.local_keys[name]

if keyinfo then
return keyinfo :: any
else
error(string.format(ERR_CANNOT_FIND_GEM, error_action, name, chest.name), 2)
end
end

return GET_KEYINFO
File renamed without changes.
Loading

0 comments on commit c92b25b

Please sign in to comment.