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.

122 lines
4.9 KiB

--===========================================================================--
-- --
-- System.Collections.Array --
-- --
--===========================================================================--
--===========================================================================--
-- Author : kurapica125@outlook.com --
-- URL : http://github.com/kurapica/PLoop --
-- Create Date : 2018/03/20 --
-- Update Date : 2018/03/20 --
-- Version : 1.0.0 --
--===========================================================================--
PLoop(function(_ENV)
namespace "System.Collections"
import "System.Serialization"
--- The array of objects with event control
-- @usage
-- class "A" {
-- -- Property
-- Name = { Type = String, Event = "OnNameChanged", Default = "Anonymous" };
--
-- -- Constructor
-- A = function(self, name) self.Name = name end;
-- }
--
-- -- The Array is a template class, you can specific the element class
-- ar = Array[A](A("Ann"), A("Ben"), A("Coco"))
--
-- -- You can set event handler to all objects by assign it to the array
-- function ar:OnNameChanged(new, old)
-- print( ("%s -> %s"):format(old, new) )
-- end
__ObjFuncAttr__() __SuperObject__(false) __Serializable__()
__NoRawSet__(false) __NoNilValue__(false) __Arguments__{ AnyType }( Any )
class "Array" (function(_ENV, eletype)
inherit (List[eletype])
-----------------------------------------------------------
-- helper --
-----------------------------------------------------------
local addeventlistener = function() end
export {
parseindex = Toolset.parseindex,
getErrorMessage = Struct.GetErrorMessage,
}
if Interface.Validate(eletype) or Class.Validate(eletype) then
export {
getfeature = Interface.GetFeature,
validevent = Event.Validate,
rawget = rawget,
rawset = rawset,
pairs = pairs,
tinsert = table.insert,
ARRAY_EVENT = "__PLOOP_ARRAY_EVENT",
}
export { Event }
function addeventlistener(self, obj)
local evts = rawget(self, ARRAY_EVENT)
if evts then
for k, v in pairs(evts) do
obj[k] = v
end
end
end
end
-----------------------------------------------------------
-- method --
-----------------------------------------------------------
if Interface.Validate(eletype) or Class.Validate(eletype) then
__Arguments__{ Integer, eletype }
function Insert(self, idx, obj)
tinsert(self, idx, obj)
addeventlistener(self, obj)
end
__Arguments__{ eletype }
function Insert(self, obj)
tinsert(self, obj)
addeventlistener(self, obj)
end
end
-----------------------------------------------------------
-- meta-method --
-----------------------------------------------------------
if Interface.Validate(eletype) or Class.Validate(eletype) then
__Arguments__{ String, Callable }
function __newindex(self, key, value)
local evt = getfeature(eletype, key)
if evt and validevent(evt) then
local evts = rawget(self, ARRAY_EVENT) or {}
rawset(self, ARRAY_EVENT, evts)
evts[key] = value
self:Each(key, value)
else
error("The " .. tostring(eletype) .. " don't have an event named " .. tostring(key), 2)
end
end
__Arguments__{ Number, eletype }
__newindex = rawset
else
__Arguments__{ String, Callable }
function __newindex(self, key)
error("The " .. tostring(eletype) .. " don't have an event named " .. tostring(key), 2)
end
__Arguments__{ Number, eletype }
__newindex = rawset
end
end)
end)