Skip to content

Commit 7f46250

Browse files
committed
feat: 用户配置项增加 bPersistImmediatelyOnChange 标记用于延迟存储
1 parent 8073220 commit 7f46250

File tree

1 file changed

+139
-26
lines changed

1 file changed

+139
-26
lines changed

Boilerplate_!Base/src/lib/Storage.UserSettings.lua

Lines changed: 139 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -138,6 +138,50 @@ local function DeleteInstanceInfoData(inst, info)
138138
end
139139
end
140140

141+
-- 统一处理配置项存盘逻辑
142+
---@param inst table 数据库实例
143+
---@param info table 配置项信息
144+
---@param szDataSetKey string|number DataSet 键值(可选,仅当配置项为 DataSet 类型时使用)
145+
---@param xValue any 要保存的值
146+
---@param bDelete boolean 是否为删除操作
147+
local function FlushSettingsData(inst, info, szDataSetKey, xValue, bDelete)
148+
if info.bDataSet then
149+
-- 处理 DataSet 类型的数据
150+
if bDelete then
151+
-- 删除 DataSet 中的某个键
152+
local res = GetInstanceInfoData(inst, info)
153+
if X.IsTable(res) and res.v == info.szVersion and X.IsTable(res.d) then
154+
res.d[szDataSetKey] = nil
155+
if X.IsEmpty(res.d) then
156+
DeleteInstanceInfoData(inst, info)
157+
else
158+
SetInstanceInfoData(inst, info, res.d, info.szVersion)
159+
end
160+
else
161+
DeleteInstanceInfoData(inst, info)
162+
end
163+
else
164+
-- 设置 DataSet 中的某个键
165+
local res = GetInstanceInfoData(inst, info)
166+
local dataToSave
167+
if X.IsTable(res) and res.v == info.szVersion and X.IsTable(res.d) then
168+
res.d[szDataSetKey] = xValue
169+
dataToSave = res.d
170+
else
171+
dataToSave = { [szDataSetKey] = xValue }
172+
end
173+
SetInstanceInfoData(inst, info, dataToSave, info.szVersion)
174+
end
175+
else
176+
-- 处理普通数据
177+
if bDelete then
178+
DeleteInstanceInfoData(inst, info)
179+
else
180+
SetInstanceInfoData(inst, info, xValue, info.szVersion)
181+
end
182+
end
183+
end
184+
141185
function X.IsUserSettingsAvailable()
142186
return DATABASE_CONNECTION_ESTABLISHED
143187
end
@@ -229,6 +273,32 @@ function X.ReleaseUserSettingsDB()
229273
end
230274

231275
function X.FlushUserSettingsDB()
276+
-- 遍历 DATA_CACHE 查找需要 flush 的数据
277+
for szKey, cache in pairs(DATA_CACHE) do
278+
local info = USER_SETTINGS_INFO[szKey]
279+
if info then
280+
local inst = DATABASE_INSTANCE[info.ePathType]
281+
if inst then
282+
if cache.bDataSet then
283+
-- 处理 DataSet 类型的数据
284+
for szDataSetKey, dataSetCache in pairs(cache.tDataSet) do
285+
if dataSetCache.bFlushRequired then
286+
FlushSettingsData(inst, info, szDataSetKey, dataSetCache.xValue, dataSetCache.bDeleted)
287+
-- 清除 flush 标记
288+
dataSetCache.bFlushRequired = nil
289+
end
290+
end
291+
else
292+
-- 处理普通数据
293+
if cache.bFlushRequired then
294+
FlushSettingsData(inst, info, nil, cache.xValue, cache.bDeleted)
295+
-- 清除 flush 标记
296+
cache.bFlushRequired = nil
297+
end
298+
end
299+
end
300+
end
301+
end
232302
-- for _, ePathType in ipairs(DATABASE_TYPE_LIST) do
233303
-- local inst = DATABASE_INSTANCE[ePathType]
234304
-- if inst then
@@ -349,8 +419,9 @@ end
349419
-- {schema} tOption.xSchema 数据类型约束对象,通过 Schema 库生成
350420
-- {boolean} tOption.bDataSet 是否为配置项组(如用户多套自定义偏好),配置项组在读写时需要额外传入一个组下配置项唯一键值(即多套自定义偏好中某一项的名字)
351421
-- {table} tOption.tDataSetDefaultValue 数据默认值(仅当 bDataSet 为真时生效,用于设置配置项组不同默认值)
422+
-- {boolean} tOption.bPersistImmediatelyOnChange 是否在变更时立即持久化到文件,默认为 true,为 false 时变更会缓存在内存中等待系统空闲时写入
352423
function X.RegisterUserSettings(szKey, tOption)
353-
local ePathType, szDataKey, bUserData, bNoExport, szGroup, szLabel, szDescription, szVersion, szRestriction, xDefaultValue, xSchema, bDataSet, tDataSetDefaultValue, eDefaultLocationOverride
424+
local ePathType, szDataKey, bUserData, bNoExport, szGroup, szLabel, szDescription, szVersion, szRestriction, xDefaultValue, xSchema, bDataSet, tDataSetDefaultValue, eDefaultLocationOverride, bPersistImmediatelyOnChange
354425
if X.IsTable(tOption) then
355426
ePathType = tOption.ePathType
356427
szDataKey = tOption.szDataKey
@@ -366,6 +437,7 @@ function X.RegisterUserSettings(szKey, tOption)
366437
bDataSet = tOption.bDataSet
367438
tDataSetDefaultValue = tOption.tDataSetDefaultValue
368439
eDefaultLocationOverride = tOption.eDefaultLocationOverride
440+
bPersistImmediatelyOnChange = tOption.bPersistImmediatelyOnChange
369441
end
370442
if not ePathType then
371443
ePathType = X.PATH_TYPE.ROLE
@@ -376,6 +448,9 @@ function X.RegisterUserSettings(szKey, tOption)
376448
if not szVersion then
377449
szVersion = ''
378450
end
451+
if X.IsNil(bPersistImmediatelyOnChange) then
452+
bPersistImmediatelyOnChange = true
453+
end
379454
if not X.IsString(szKey) or szKey == '' then
380455
assert(false, 'RegisterUserSettings KEY(' .. X.EncodeLUAData(szKey) .. '): `Key` should be a non-empty string value.')
381456
end
@@ -441,6 +516,7 @@ function X.RegisterUserSettings(szKey, tOption)
441516
bDataSet = bDataSet,
442517
tDataSetDefaultValue = tDataSetDefaultValue,
443518
eDefaultLocationOverride = eDefaultLocationOverride,
519+
bPersistImmediatelyOnChange = bPersistImmediatelyOnChange,
444520
}
445521
setmetatable(tInfo, {
446522
__index = function(t, k)
@@ -533,7 +609,13 @@ function X.GetUserSettings(szKey, ...)
533609
or nil
534610
end
535611
if X.IsTable(cache) and cache.bValue then
536-
res, bData, bCache = cache.xValue, true, true
612+
-- 从缓存获取数据,如果标记为删除则返回默认值
613+
if cache.bDeleted then
614+
-- 数据被删除但还没有 flush,直接返回默认值
615+
bData, bCache = false, true
616+
else
617+
res, bData, bCache = cache.xValue, true, true
618+
end
537619
end
538620
-- 未命中缓存,从数据库读取
539621
if not bCache then
@@ -581,12 +663,14 @@ function X.GetUserSettings(szKey, ...)
581663
bValue = true,
582664
xValue = res,
583665
xRawValue = X.Clone(res),
666+
bDeleted = false,
584667
}
585668
else
586669
DATA_CACHE[szKey] = {
587670
bValue = true,
588671
xValue = res,
589672
xRawValue = X.Clone(res),
673+
bDeleted = false,
590674
}
591675
end
592676
end
@@ -645,20 +729,33 @@ function X.SetUserSettings(szKey, ...)
645729
end
646730
-- 写数据库
647731
if info.bDataSet then
648-
local res = GetInstanceInfoData(inst, info)
649-
if X.IsTable(res) and res.v == info.szVersion and X.IsTable(res.d) then
650-
res.d[szDataSetKey] = xValue
651-
xValue = res.d
652-
else
653-
xValue = { [szDataSetKey] = xValue }
654-
end
655-
if X.IsTable(DATA_CACHE[szKey]) and DATA_CACHE[szKey].bDataSet then
656-
DATA_CACHE[szKey].tDataSet[szDataSetKey] = nil
732+
-- 更新缓存
733+
if not DATA_CACHE[szKey] then
734+
DATA_CACHE[szKey] = { bDataSet = true, tDataSet = {} }
735+
end
736+
DATA_CACHE[szKey].tDataSet[szDataSetKey] = {
737+
bValue = true,
738+
xValue = X.Clone(xValue),
739+
xRawValue = X.Clone(xValue),
740+
bFlushRequired = not info.bPersistImmediatelyOnChange,
741+
bDeleted = false,
742+
}
743+
if info.bPersistImmediatelyOnChange then
744+
FlushSettingsData(inst, info, szDataSetKey, xValue, false)
657745
end
658746
else
659-
DATA_CACHE[szKey] = nil
747+
-- 更新缓存
748+
DATA_CACHE[szKey] = {
749+
bValue = true,
750+
xValue = X.Clone(xValue),
751+
xRawValue = X.Clone(xValue),
752+
bFlushRequired = not info.bPersistImmediatelyOnChange,
753+
bDeleted = false,
754+
}
755+
if info.bPersistImmediatelyOnChange then
756+
FlushSettingsData(inst, info, nil, xValue, false)
757+
end
660758
end
661-
SetInstanceInfoData(inst, info, xValue, info.szVersion)
662759
-- if info.bUserData then
663760
-- inst.bUserDataDBCommit = true
664761
-- else
@@ -715,24 +812,40 @@ function X.ResetUserSettings(szKey, ...)
715812
end
716813
-- 写数据库
717814
if info.bDataSet then
718-
local res = GetInstanceInfoData(inst, info)
719-
if X.IsTable(res) and res.v == info.szVersion and X.IsTable(res.d) and szDataSetKey then
720-
res.d[szDataSetKey] = nil
721-
if X.IsEmpty(res.d) then
722-
DeleteInstanceInfoData(inst, info)
723-
else
724-
SetInstanceInfoData(inst, info, res.d, info.szVersion)
725-
end
726-
if DATA_CACHE[szKey] and DATA_CACHE[szKey].bDataSet then
727-
DATA_CACHE[szKey].tDataSet[szDataSetKey] = nil
815+
-- 更新缓存
816+
if not DATA_CACHE[szKey] then
817+
DATA_CACHE[szKey] = { bDataSet = true, tDataSet = {} }
818+
end
819+
if szDataSetKey then
820+
DATA_CACHE[szKey].tDataSet[szDataSetKey] = {
821+
bValue = true,
822+
xValue = nil,
823+
xRawValue = nil,
824+
bFlushRequired = not info.bPersistImmediatelyOnChange,
825+
bDeleted = true,
826+
}
827+
if info.bPersistImmediatelyOnChange then
828+
FlushSettingsData(inst, info, szDataSetKey, nil, true)
728829
end
729830
else
730-
DeleteInstanceInfoData(inst, info)
831+
-- 重置整个 DataSet
731832
DATA_CACHE[szKey] = nil
833+
if info.bPersistImmediatelyOnChange then
834+
FlushSettingsData(inst, info, nil, nil, true)
835+
end
732836
end
733837
else
734-
DeleteInstanceInfoData(inst, info)
735-
DATA_CACHE[szKey] = nil
838+
-- 更新缓存
839+
DATA_CACHE[szKey] = {
840+
bValue = true,
841+
xValue = nil,
842+
xRawValue = nil,
843+
bFlushRequired = not info.bPersistImmediatelyOnChange,
844+
bDeleted = true,
845+
}
846+
if info.bPersistImmediatelyOnChange then
847+
FlushSettingsData(inst, info, nil, nil, true)
848+
end
736849
end
737850
-- if info.bUserData then
738851
-- inst.bUserDataDBCommit = true

0 commit comments

Comments
 (0)