@@ -138,6 +138,50 @@ local function DeleteInstanceInfoData(inst, info)
138138 end
139139end
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+
141185function X .IsUserSettingsAvailable ()
142186 return DATABASE_CONNECTION_ESTABLISHED
143187end
@@ -229,6 +273,32 @@ function X.ReleaseUserSettingsDB()
229273end
230274
231275function 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
349419-- {schema} tOption.xSchema 数据类型约束对象,通过 Schema 库生成
350420-- {boolean} tOption.bDataSet 是否为配置项组(如用户多套自定义偏好),配置项组在读写时需要额外传入一个组下配置项唯一键值(即多套自定义偏好中某一项的名字)
351421-- {table} tOption.tDataSetDefaultValue 数据默认值(仅当 bDataSet 为真时生效,用于设置配置项组不同默认值)
422+ -- {boolean} tOption.bPersistImmediatelyOnChange 是否在变更时立即持久化到文件,默认为 true,为 false 时变更会缓存在内存中等待系统空闲时写入
352423function 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