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.
315 lines
12 KiB
315 lines
12 KiB
--===========================================================================--
|
|
-- --
|
|
-- System.Collections.Proxy --
|
|
-- --
|
|
--===========================================================================--
|
|
|
|
--===========================================================================--
|
|
-- Author : kurapica125@outlook.com --
|
|
-- URL : http://github.com/kurapica/PLoop --
|
|
-- Create Date : 2016/02/28 --
|
|
-- Update Date : 2018/05/12 --
|
|
-- Version : 1.1.0 --
|
|
--===========================================================================--
|
|
|
|
PLoop(function(_ENV)
|
|
import "System.Serialization"
|
|
|
|
--- The safe dictionary, it'll create the object as proxy to the real table
|
|
__Sealed__() __Serializable__() __Arguments__{ AnyType, AnyType }( Any, Any )
|
|
__NoNilValue__(false):AsInheritable() __NoRawSet__(false):AsInheritable()
|
|
class "System.Collections.Proxy" (function (_ENV, keytype, valtype)
|
|
extend "IDictionary" "ISerializable"
|
|
|
|
local RAW_HOLDER = {}
|
|
|
|
export {
|
|
ipairs = ipairs,
|
|
pairs = pairs,
|
|
GetErrorMessage = Struct.GetErrorMessage,
|
|
yield = coroutine.yield,
|
|
|
|
List[keytype], List[valtype]
|
|
}
|
|
|
|
if keytype ~= Any then
|
|
export { kvalid = getmetatable(keytype).ValidateValue, rawset = rawset }
|
|
end
|
|
|
|
if valtype ~= Any then
|
|
export { vvalid = getmetatable(valtype).ValidateValue, rawset = rawset }
|
|
end
|
|
|
|
-----------------------------------------------------------
|
|
-- serialization --
|
|
-----------------------------------------------------------
|
|
function Serialize(self, info)
|
|
local key = {}
|
|
local val = {}
|
|
local idx = 1
|
|
for k, v in self:GetIterator() do
|
|
key[idx]= k
|
|
val[idx]= v
|
|
idx = idx + 1
|
|
end
|
|
|
|
info:SetValue(1, List[keytype](key))
|
|
info:SetValue(2, List[valtype](val))
|
|
end
|
|
|
|
__Arguments__{ SerializationInfo }
|
|
function __new(_, info)
|
|
local key = info:GetValue(1, List[keytype])
|
|
local val = info:GetValue(2, List[valtype])
|
|
|
|
return this(_, key, val)
|
|
end
|
|
|
|
-----------------------------------------------------------
|
|
-- method --
|
|
-----------------------------------------------------------
|
|
function GetIterator(self)
|
|
return pairs(self[RAW_HOLDER])
|
|
end
|
|
|
|
--- Update the dictionary
|
|
if keytype == Any and valtype == Any then
|
|
__Arguments__{ RawTable }
|
|
function Update(self, dict)
|
|
for k, v in pairs(dict) do self[RAW_HOLDER][k] = v end
|
|
return self
|
|
end
|
|
|
|
__Arguments__{ IDictionary }
|
|
function Update(self, dict)
|
|
for k, v in dict:GetIterator() do self[RAW_HOLDER][k] = v end
|
|
return self
|
|
end
|
|
|
|
__Arguments__{ Callable, System.Any/nil, System.Any/nil }
|
|
function Update(self, iter, obj, idx)
|
|
for k, v in iter, obj, idx do self[RAW_HOLDER][k] = v end
|
|
return self
|
|
end
|
|
elseif keytype == Any and valtype ~= Any then
|
|
__Arguments__{ RawTable }
|
|
function Update(self, dict)
|
|
for k, v in pairs(dict) do
|
|
local ret, msg = vvalid(valtype, v, true)
|
|
if not msg then
|
|
self[RAW_HOLDER][k] = v
|
|
end
|
|
end
|
|
return self
|
|
end
|
|
|
|
__Arguments__{ IDictionary }
|
|
function Update(self, dict)
|
|
for k, v in dict:GetIterator() do
|
|
local ret, msg = vvalid(valtype, v, true)
|
|
if not msg then
|
|
self[RAW_HOLDER][k] = v
|
|
end
|
|
end
|
|
return self
|
|
end
|
|
|
|
__Arguments__{ Callable, System.Any/nil, System.Any/nil }
|
|
function Update(self, iter, obj, idx)
|
|
for k, v in iter, obj, idx do
|
|
local ret, msg = vvalid(valtype, v, true)
|
|
if not msg then
|
|
self[RAW_HOLDER][k] = v
|
|
end
|
|
end
|
|
return self
|
|
end
|
|
elseif keytype ~= Any and valtype == Any then
|
|
__Arguments__{ RawTable }
|
|
function Update(self, dict)
|
|
for k, v in pairs(dict) do
|
|
local ret, msg = kvalid(keytype, k, true)
|
|
if not msg then
|
|
self[RAW_HOLDER][k] = v
|
|
end
|
|
end
|
|
return self
|
|
end
|
|
|
|
__Arguments__{ IDictionary }
|
|
function Update(self, dict)
|
|
for k, v in dict:GetIterator() do
|
|
local ret, msg = kvalid(keytype, k, true)
|
|
if not msg then
|
|
self[RAW_HOLDER][k] = v
|
|
end
|
|
end
|
|
return self
|
|
end
|
|
|
|
__Arguments__{ Callable, System.Any/nil, System.Any/nil }
|
|
function Update(self, iter, obj, idx)
|
|
for k, v in iter, obj, idx do
|
|
local ret, msg = kvalid(keytype, k, true)
|
|
if not msg then
|
|
self[RAW_HOLDER][k] = v
|
|
end
|
|
end
|
|
return self
|
|
end
|
|
else
|
|
__Arguments__{ RawTable }
|
|
function Update(self, dict)
|
|
for k, v in pairs(dict) do
|
|
local ret, msg = kvalid(keytype, k, true)
|
|
if not msg then
|
|
ret, msg = vvalid(valtype, v, true)
|
|
if not msg then
|
|
self[RAW_HOLDER][k] = v
|
|
end
|
|
end
|
|
end
|
|
return self
|
|
end
|
|
|
|
__Arguments__{ IDictionary }
|
|
function Update(self, dict)
|
|
for k, v in dict:GetIterator() do
|
|
local ret, msg = kvalid(keytype, k, true)
|
|
if not msg then
|
|
ret, msg = vvalid(valtype, v, true)
|
|
if not msg then
|
|
self[RAW_HOLDER][k] = v
|
|
end
|
|
end
|
|
end
|
|
return self
|
|
end
|
|
|
|
__Arguments__{ Callable, System.Any/nil, System.Any/nil }
|
|
function Update(self, iter, obj, idx)
|
|
for k, v in iter, obj, idx do
|
|
local ret, msg = kvalid(keytype, k, true)
|
|
if not msg then
|
|
ret, msg = vvalid(valtype, v, true)
|
|
if not msg then
|
|
self[RAW_HOLDER][k] = v
|
|
end
|
|
end
|
|
end
|
|
return self
|
|
end
|
|
end
|
|
|
|
-----------------------------------------------------------
|
|
-- property --
|
|
-----------------------------------------------------------
|
|
--- Gets or sets the value associated with the specified key
|
|
__Indexer__(keytype ~= Any and keytype or nil)
|
|
property "Item" {
|
|
get = function(self, key)
|
|
return self[RAW_HOLDER][key]
|
|
end,
|
|
set = function(self, key, value)
|
|
self[RAW_HOLDER][key] = value
|
|
end,
|
|
type = valtype ~= Any and valtype or nil,
|
|
}
|
|
|
|
-----------------------------------------------------------
|
|
-- constructor --
|
|
-----------------------------------------------------------
|
|
__Arguments__{ }
|
|
function __new() return { [RAW_HOLDER] = {} } end
|
|
|
|
__Arguments__{ RawTable }
|
|
function __new(_, dict) return { [RAW_HOLDER] = dict }, true end
|
|
|
|
__Arguments__{ RawTable + IList, RawTable + IList }
|
|
function __new(_, lstKey, lstValue)
|
|
local dict = {}
|
|
local iter, o, idx, value = (lstValue.GetIterator or ipairs)(lstValue)
|
|
for _, key in (lstValue.GetIterator or ipairs)(lstKey) do
|
|
idx, value = iter(o, idx)
|
|
if idx then
|
|
dict[key] = value
|
|
else
|
|
break
|
|
end
|
|
end
|
|
return { [RAW_HOLDER] = dict }, true
|
|
end
|
|
|
|
__Arguments__{ RawTable + IList, Any }
|
|
function __new(_, lstKey, value)
|
|
local dict = {}
|
|
for _, key in (lstKey.GetIterator or ipairs)(lstKey) do
|
|
dict[key] = value
|
|
end
|
|
return { [RAW_HOLDER] = dict }, true
|
|
end
|
|
|
|
__Arguments__{ IDictionary }
|
|
function __new(_, dict)
|
|
local dict = {}
|
|
for key, value in dict:GetIterator() do
|
|
dict[key] = value
|
|
end
|
|
return { [RAW_HOLDER] = dict }, true
|
|
end
|
|
|
|
__Arguments__{ Callable, Any/nil, Any/nil }
|
|
function __new(_, iter, obj, idx)
|
|
local dict = {}
|
|
for key, value in iter, obj, idx do
|
|
dict[key] = value
|
|
end
|
|
return { [RAW_HOLDER] = dict }, true
|
|
end
|
|
|
|
if keytype ~= Any and valtype ~= Any then
|
|
function __ctor(self)
|
|
local msg
|
|
for k, v in self:GetIterator() do
|
|
k, msg = kvalid(keytype, k)
|
|
if msg then throw(GetErrorMessage(msg, "field")) end
|
|
|
|
v, msg = vvalid(valtype, v)
|
|
if msg then throw(GetErrorMessage(msg, "value")) end
|
|
self[k]= v
|
|
end
|
|
end
|
|
elseif keytype ~= Any then
|
|
function __ctor(self)
|
|
local msg
|
|
for k, v in self:GetIterator() do
|
|
k, msg = kvalid(keytype, k)
|
|
if msg then throw(GetErrorMessage(msg, "field")) end
|
|
end
|
|
end
|
|
elseif valtype ~= Any then
|
|
function __ctor(self)
|
|
local msg
|
|
for k, v in self:GetIterator() do
|
|
v, msg = vvalid(valtype, v)
|
|
if msg then throw(GetErrorMessage(msg, "value")) end
|
|
self[k]= v
|
|
end
|
|
end
|
|
end
|
|
|
|
-----------------------------------------------------------
|
|
-- meta-method --
|
|
-----------------------------------------------------------
|
|
if keytype ~= Any or valtype ~= Any then
|
|
__Arguments__{ keytype, valtype }
|
|
end
|
|
function __newindex(self, key, val)
|
|
self[RAW_HOLDER][key]= val
|
|
end
|
|
|
|
function __index(self, key)
|
|
return self[RAW_HOLDER][key]
|
|
end
|
|
end)
|
|
end)
|
|
|