You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

461 lines
16 KiB

5 years ago
--========================================================--
-- Scorpio SavedVariable Manager --
-- --
-- Author : kurapica125@outlook.com --
-- Create Date : 2016/12/20 --
--========================================================--
--========================================================--
Scorpio "Scorpio.SVManager" "2.0.0"
--========================================================--
__Sealed__() __SuperObject__(false):AsInheritable()
local SVProxy = class (function(_ENV)
local _RawData = {}
local _Manager = {}
local _Default = {}
local clone = Toolset.clone
local function copydefault(tar, default, clonefunc)
if type(tar) ~= "table" then tar = {} end
if default then
for k, v in pairs(default) do
local ty = type(v)
if ty == "table" then
tar[k] = copydefault(tar[k], v)
elseif tar[k] == nil then
if ty == "function" and clonefunc then
tar[k] = v
else
if ty == "function" then
v = v()
ty = type(v)
end
if ty == "table" then
tar[k] = copydefault(tar[k], v)
elseif ty == "string" or ty == "boolean" or ty == "number" then
tar[k] = v
end
end
end
end
end
return tar
end
----------------------------------------------
-- Method --
----------------------------------------------
--- Gets the clone data
function GetData(self)
return clone(_RawData[self], true)
end
--- Wipes and Sets the new data
__Arguments__{ Table }
function SetData(self, data)
copydefault(wipe(_RawData[self]), data)
copydefault(_RawData[self], _Default[self])
end
--- Sets the default value for the account saved variable
__Arguments__{ NEString + Number, Table }
function SetDefault(self, key, default)
local sDefault = _Default[self]
sDefault[key] = copydefault(sDefault[key], default, true)
for p, d in pairs(_Default) do
if d == sDefault then
_RawData[p][key]= copydefault(_RawData[p][key], default)
end
end
end
__Arguments__{ Table }
function SetDefault(self, default)
local sDefault = _Default[self]
copydefault(sDefault, default, true)
for p, d in pairs(_Default) do
if d == sDefault then
copydefault(_RawData[p], default)
end
end
end
--- Reset the saved variable with default
function Reset(self)
copydefault(wipe(_RawData[self]), _Default[self])
end
--- Reset all saved variable proxies with the same default
function ResetAll(self)
local sDefault = _Default[self]
for p, d in pairs(_Default) do
if d == sDefault then p:Reset() end
end
end
----------------------------------------------
-- Constructor --
----------------------------------------------
__Arguments__{ Table, Table/nil }
function __ctor(self, data, default)
_RawData[self] = data
_Manager[data] = self
_Default[self] = default or {}
if default then copydefault(data, default) end
end
__Arguments__{ NEString, Table/nil }
function __ctor(self, name, default)
local data = _G[name]
if not data then
data = {}
_G[name] = data
end
_RawData[self] = data
_Manager[data] = self
_Default[self] = default or {}
if default then copydefault(data, default) end
end
__Arguments__{ Table, Any * 0 }
function __exist(_, data)
return _Manager[data]
end
__Arguments__{ NEString, Any * 0 }
function __exist(_, name)
return _Manager[_G[name]]
end
----------------------------------------------
-- Meta-method --
----------------------------------------------
function __index(self, key)
return _RawData[self][key]
end
function __newindex(self, key, value)
_RawData[self][key] = value
end
end)
--- The saved variables mananger
__Sealed__() class "SVManager" (function(_ENV)
inherit (SVProxy)
local _Root = {}
----------------------------------------------
-- SVCharManager --
----------------------------------------------
__Sealed__() class "SVCharManager" (function(_ENV)
inherit (SVProxy)
if Scorpio.IsRetail then
----------------------------------------------
-- SVSpecManager --
----------------------------------------------
__Sealed__() class "SVSpecManager" (function(_ENV)
inherit (SVProxy)
----------------------------------------------
-- SVWarModeManager --
----------------------------------------------
__Sealed__() class "SVWarModeManager" (function(_ENV)
inherit (SVProxy)
local _RTDefault = {}
----------------------------------------------
-- Constructor --
----------------------------------------------
__Arguments__{ Table + NEString, SVProxy/nil }
function __ctor(self, sv, root)
if root then
root = _Root[root] or root
_RTDefault[root]= _RTDefault[root] or {}
super(self, sv, _RTDefault[root])
else
super(self, sv)
end
end
end)
local WarMode_PVE = WarMode.PVE
local WarMode_PVP = WarMode.PVP
local IsWarModeDesired = C_PvP.IsWarModeDesired
local _CurrentWarMode = WarMode.PVE
local _DBModeMap = {}
local _RTDefault = {}
----------------------------------------------
-- Method --
----------------------------------------------
function GetData(self)
local modes = self.__ScorpioModes
self.__ScorpioModes = nil
local data = super.GetData(self)
self.__ScorpioModes = modes
return data
end
__Arguments__{ Table }
function SetData(self, data)
local modes = self.__ScorpioModes
self.__ScorpioModes = nil
super.SetData(self, data)
self.__ScorpioModes = modes
end
--- Reset current specialization saved variable with default
function Reset(self)
local modes = self.__ScorpioModes
super.Reset(self)
self.__ScorpioModes = modes
end
----------------------------------------------
-- Property --
----------------------------------------------
--- The char's specialization saved variable
property "WarMode" {
get = function(self)
local cmode = IsWarModeDesired() and WarMode_PVP or WarMode_PVE
if _CurrentWarMode ~= cmode then
_CurrentWarMode = cmode
wipe(_DBModeMap)
end
local mode = _DBModeMap[self]
if not mode then
self.__ScorpioModes = self.__ScorpioModes or {}
self.__ScorpioModes[_CurrentWarMode]= self.__ScorpioModes[_CurrentWarMode] or {}
mode = SVWarModeManager(self.__ScorpioModes[_CurrentWarMode], self)
_DBModeMap[self]= mode
end
return mode
end
}
--- The specialization sv mananger
__Indexer__(WarMode)
property "WarModes" {
get = function(self, index)
local modes = self.__ScorpioModes
local mode = modes and modes[index]
return mode and SVWarModeManager(mode, self)
end,
}
----------------------------------------------
-- Constructor --
----------------------------------------------
__Arguments__{ Table + NEString, SVProxy/nil }
function __ctor(self, sv, root)
if root then
root = _Root[root] or root
_Root[self] = root
_RTDefault[root]= _RTDefault[root] or {}
super(self, sv, _RTDefault[root])
else
super(self, sv)
end
end
end)
local _CurrentSpec = 1
local _DBSpecMap = {}
----------------------------------------------
-- Property --
----------------------------------------------
--- The char's specialization saved variable
property "Spec" {
get = function(self)
local nowSpec = GetSpecialization() or 1
if _CurrentSpec ~= nowSpec then
_CurrentSpec = nowSpec
wipe(_DBSpecMap)
end
local spec = _DBSpecMap[self]
if not spec then
self.__ScorpioSpecs = self.__ScorpioSpecs or {}
self.__ScorpioSpecs[_CurrentSpec] = self.__ScorpioSpecs[_CurrentSpec] or {}
spec = SVSpecManager(self.__ScorpioSpecs[_CurrentSpec], self)
_DBSpecMap[self] = spec
end
return spec
end
}
--- The specialization sv mananger
__Indexer__(Number)
property "Specs" {
get = function(self, index)
local specs = self.__ScorpioSpecs
local spec = specs and specs[index]
return spec and SVSpecManager(spec, self)
end,
}
end
local _RTDefault = {}
----------------------------------------------
-- Method --
----------------------------------------------
function GetData(self)
local specs = self.__ScorpioSpecs
self.__ScorpioSpecs = nil
local data = super.GetData(self)
self.__ScorpioSpecs = specs
return data
end
__Arguments__{ Table }
function SetData(self, data)
local specs = self.__ScorpioSpecs
self.__ScorpioSpecs = nil
super.SetData(self, data)
self.__ScorpioSpecs = specs
end
--- Reset the character saved variable with default
function Reset(self)
local specs = self.__ScorpioSpecs
super.Reset(self)
self.__ScorpioSpecs = specs
end
----------------------------------------------
-- Constructor --
----------------------------------------------
__Arguments__{ Table + NEString, SVProxy/nil }
function __ctor(self, sv, root)
if root then
root = _Root[root] or root
_Root[self] = root
_RTDefault[root]= _RTDefault[root] or {}
super(self, sv, _RTDefault[root])
else
super(self, sv)
end
end
end)
local _DBCharMap = {}
local yield = coroutine.yield
----------------------------------------------
-- Method --
----------------------------------------------
--- Get saved characters
__Iterator__()
function GetCharacters(self)
local chars = self.__ScorpioChars
if chars then for name in pairs(chars) do yield(name) end end
end
function GetData(self)
local chars = self.__ScorpioChars
self.__ScorpioChars = nil
local data = super.GetData(self)
self.__ScorpioChars = chars
return data
end
__Arguments__{ Table }
function SetData(self, data)
local chars = self.__ScorpioChars
self.__ScorpioChars = nil
super.SetData(self, data)
self.__ScorpioChars = chars
end
--- Reset the account saved variable with default
function Reset(self)
local chars = self.__ScorpioChars
super.Reset(self)
self.__ScorpioChars = chars
end
----------------------------------------------
-- Property --
----------------------------------------------
--- The char's saved variable
property "Char" {
get = function(self)
local char = _DBCharMap[self]
if not char then
local name = GetRealmName() .. "-" .. UnitName("player")
-- Char data should saved in the account data
self.__ScorpioChars = self.__ScorpioChars or {}
self.__ScorpioChars[name] = self.__ScorpioChars[name] or {}
char = SVCharManager(self.__ScorpioChars[name], self)
_DBCharMap[self]= char
end
return char
end,
}
--- The chars saved variable access
__Indexer__(NEString)
property "Chars" {
get = function(self, name)
local chars = self.__ScorpioChars
local char = chars and chars[name]
return char and SVCharManager(char, self)
end,
}
----------------------------------------------
-- Constructor --
----------------------------------------------
__Arguments__{ NEString, NEString/nil }
function __ctor(self, sv, svchar)
super(self, sv)
if svchar then
_DBCharMap[self] = SVCharManager(svchar, self)
end
end
end)