383 lines
8.2 KiB
Plaintext
383 lines
8.2 KiB
Plaintext
ReusableObject = class("ReusableObject")
|
|
|
|
-- factory begin
|
|
if not ReusableObject.ReusableObject_Inited then
|
|
ReusableObject.pool = TablePool.new()
|
|
|
|
ReusableObject.ReusableObject_Inited = true
|
|
end
|
|
|
|
-- NOTE -->
|
|
-- Must call self:CreateData() before FIRST call self:SetData(k, v), PushBackData,GetDataLength
|
|
-- Must call self:CreateWeakData() before FIRST call self:SetWeakData(k, v), PushBackWeakData, GetWeakDataLength
|
|
-- self:SetData(k, v) v must not be reueable object
|
|
-- self:SetWeakData(k, v) v must be reueable object
|
|
-- NOTE --<
|
|
|
|
-- DON'T call
|
|
|
|
local pool = ReusableObject.pool
|
|
|
|
local tempArray = {}
|
|
|
|
function ReusableObject.LogPools()
|
|
pool:Log()
|
|
end
|
|
|
|
local instanceID = 0
|
|
local function NewInstance()
|
|
instanceID = instanceID + 1
|
|
return instanceID
|
|
end
|
|
|
|
local function DoCreate( Cls )
|
|
return Cls.new()
|
|
end
|
|
|
|
function ReusableObject.Create( Cls, asArray, args )
|
|
-- 1.
|
|
local obj = pool:RemoveOrCreate(Cls, DoCreate)
|
|
-- 2.
|
|
obj.instanceID = NewInstance()
|
|
-- 3.
|
|
obj:Construct(asArray, args)
|
|
|
|
return obj
|
|
end
|
|
|
|
function ReusableObject.Destroy(obj)
|
|
-- 1.
|
|
if not obj:Alive() then
|
|
LogUtility.ErrorFormat("Destroy not reused obj: {0}", obj)
|
|
return
|
|
end
|
|
-- 2.
|
|
obj:Deconstruct()
|
|
-- 4.
|
|
if not pool:Add(obj.class, obj) and nil ~= obj.Finalize then
|
|
obj:Finalize()
|
|
end
|
|
end
|
|
-- factory end
|
|
|
|
function ReusableObject:ctor()
|
|
self._alive = true
|
|
end
|
|
|
|
function ReusableObject:Alive()
|
|
return self._alive
|
|
end
|
|
|
|
function ReusableObject:GetData(k)
|
|
return self._data[k]
|
|
end
|
|
|
|
function ReusableObject:SetData(k, v)
|
|
Debug_AssertFormat((type(v) ~= "table" or nil == v.Construct), "SetData({0}, {1}) v is reusable object", k, v)
|
|
self._data[k] = v
|
|
end
|
|
|
|
-- for array
|
|
function ReusableObject:PushBackData(v)
|
|
Debug_Assert(self._dataAsArray, "PushBackData Just For Data As Array!!!")
|
|
Debug_AssertFormat((type(v) ~= "table" or nil == v.Construct), "PushBackData({0}, {1}) v is reusable object", k, v)
|
|
TableUtility.ArrayPushBack(self._data, v)
|
|
end
|
|
-- for array
|
|
function ReusableObject:RemoveData(i)
|
|
Debug_Assert(self._dataAsArray, "RemoveData Just For Data As Array!!!")
|
|
table.remove(self._data, i)
|
|
end
|
|
-- for array
|
|
function ReusableObject:GetDataLength()
|
|
Debug_Assert(self._dataAsArray, "GetDataLength Just For Data As Array!!!")
|
|
return #self._data
|
|
end
|
|
|
|
function ReusableObject:CreateData()
|
|
if nil ~= self._data then
|
|
return
|
|
end
|
|
if self._dataAsArray then
|
|
self._data = ReusableTable.CreateArray()
|
|
else
|
|
self._data = ReusableTable.CreateTable()
|
|
end
|
|
end
|
|
|
|
function ReusableObject:DestroyData()
|
|
if nil == self._data then
|
|
return
|
|
end
|
|
if self._dataAsArray then
|
|
ReusableTable.DestroyArray(self._data)
|
|
else
|
|
ReusableTable.DestroyTable(self._data)
|
|
end
|
|
self._data = nil
|
|
end
|
|
|
|
function ReusableObject:ClearData()
|
|
if nil == self._data then
|
|
return
|
|
end
|
|
if self._dataAsArray then
|
|
TableUtility.ArrayClear(self._data)
|
|
else
|
|
TableUtility.TableClear(self._data)
|
|
end
|
|
end
|
|
|
|
function ReusableObject:ClearDataByDeleter(deleter)
|
|
if nil == self._data then
|
|
return
|
|
end
|
|
if self._dataAsArray then
|
|
TableUtility.ArrayClearByDeleter(self._data, deleter)
|
|
else
|
|
TableUtility.TableClearByDeleter(self._data, deleter)
|
|
end
|
|
end
|
|
|
|
-- observer target begin
|
|
|
|
-- DON'T call
|
|
function ReusableObject:RegisterWeakObserver(obj)
|
|
Debug_AssertFormat(nil ~= obj.ObserverDestroyed, "obj({0}) don't have function: ObserverDestroyed", obj)
|
|
if nil == self._weakObserver then
|
|
self._weakObserver = ReusableTable.CreateArray()
|
|
end
|
|
TableUtility.ArrayPushBack(self._weakObserver, obj)
|
|
end
|
|
|
|
-- DON'T call
|
|
function ReusableObject:UnregisterWeakObserver(obj)
|
|
if nil ~= self._weakObserver then
|
|
TableUtility.ArrayRemove(self._weakObserver, obj)
|
|
end
|
|
end
|
|
|
|
-- DON'T call
|
|
function ReusableObject:ClearWeakObserver()
|
|
if nil == self._weakObserver then
|
|
return
|
|
end
|
|
-- 1.
|
|
local observers = self._weakObserver
|
|
self._weakObserver = nil
|
|
|
|
-- 2.
|
|
for i=1, #observers do
|
|
observers[i]:ObserverDestroyed(self) -- TODO outside call
|
|
end
|
|
ReusableTable.DestroyArray(observers)
|
|
end
|
|
|
|
function ReusableObject:NotifyObserver(args)
|
|
if nil == self._weakObserver then
|
|
return
|
|
end
|
|
-- 1.
|
|
TableUtility.ArrayShallowCopy(tempArray, self._weakObserver)
|
|
-- 2.
|
|
for i=1, #tempArray do
|
|
if nil ~= tempArray[i].ObserverEvent then
|
|
tempArray[i]:ObserverEvent(self, args)
|
|
end
|
|
end
|
|
TableUtility.ArrayClear(tempArray)
|
|
end
|
|
-- observer target end
|
|
|
|
-- observer begin
|
|
|
|
-- DON'T call
|
|
function ReusableObject:ObserverDestroyed(obj)
|
|
if nil == self._weakData then
|
|
return
|
|
end
|
|
if self._dataAsArray then
|
|
local a = self._weakData
|
|
if 0 < #a then
|
|
for k=1, #a do
|
|
local v = a[k]
|
|
if v == obj then
|
|
TableUtility.ArrayPushBack(tempArray, k)
|
|
end
|
|
end
|
|
if 0 < #tempArray then
|
|
for i=#tempArray,1,-1 do
|
|
local k = tempArray[i]
|
|
table.remove(a, k)
|
|
self:OnObserverDestroyed(k, obj) -- TODO outside call
|
|
end
|
|
end
|
|
end
|
|
else
|
|
local t = self._weakData
|
|
for k,v in pairs(t) do
|
|
if v == obj then
|
|
TableUtility.ArrayPushBack(tempArray, k)
|
|
end
|
|
end
|
|
if 0 < #tempArray then
|
|
for i=1,#tempArray do
|
|
local k = tempArray[i]
|
|
t[k] = nil
|
|
self:OnObserverDestroyed(k, obj) -- TODO outside call
|
|
end
|
|
end
|
|
end
|
|
TableUtility.ArrayClear(tempArray)
|
|
end
|
|
-- observer end
|
|
|
|
function ReusableObject:GetWeakData(k)
|
|
if nil == self._weakData then
|
|
return nil
|
|
end
|
|
return self._weakData[k]
|
|
end
|
|
|
|
function ReusableObject:SetWeakData(k, v)
|
|
-- 1.
|
|
local oldV = self._weakData[k]
|
|
if oldV == v then
|
|
return
|
|
end
|
|
self._weakData[k] = v
|
|
|
|
-- 2.
|
|
if nil ~= oldV then
|
|
oldV:UnregisterWeakObserver(self) -- TODO outside call
|
|
end
|
|
|
|
if nil ~= v then
|
|
v:RegisterWeakObserver(self) -- TODO outside call
|
|
end
|
|
end
|
|
|
|
function ReusableObject:FindWeakData(v)
|
|
if self._dataAsArray then
|
|
return TableUtility.ArrayFindIndex(self._weakData, v)
|
|
else
|
|
return TableUtility.TableFindKey(self._weakData, v)
|
|
end
|
|
end
|
|
|
|
-- for array
|
|
function ReusableObject:PushBackWeakData(v)
|
|
Debug_Assert(self._dataAsArray, "PushBackWeakData Just For Data As Array!!!")
|
|
TableUtility.ArrayPushBack(self._weakData, v)
|
|
v:RegisterWeakObserver(self) -- TODO outside call
|
|
end
|
|
-- for array
|
|
function ReusableObject:RemoveWeakData(i)
|
|
Debug_Assert(self._dataAsArray, "RemoveWeakData Just For Data As Array!!!")
|
|
table.remove(self._weakData, i)
|
|
end
|
|
-- for array
|
|
function ReusableObject:GetWeakDataLength()
|
|
Debug_Assert(self._dataAsArray, "GetDataLength Just For Data As Array!!!")
|
|
return #self._weakData
|
|
end
|
|
|
|
function ReusableObject:CreateWeakData()
|
|
if nil ~= self._weakData then
|
|
return
|
|
end
|
|
if self._dataAsArray then
|
|
self._weakData = ReusableTable.CreateArray()
|
|
else
|
|
self._weakData = ReusableTable.CreateTable()
|
|
end
|
|
end
|
|
|
|
function ReusableObject:DoClearWeakData()
|
|
local temp = self._weakData
|
|
self._weakData = nil
|
|
if self._dataAsArray then
|
|
for i=1, #temp do
|
|
temp[i]:UnregisterWeakObserver(self) -- TODO outside call
|
|
end
|
|
else
|
|
for k,v in pairs(temp) do
|
|
v:UnregisterWeakObserver(self) -- TODO outside call
|
|
end
|
|
end
|
|
self._weakData = temp
|
|
end
|
|
|
|
function ReusableObject:DestroyWeakData()
|
|
if nil == self._weakData then
|
|
return
|
|
end
|
|
|
|
self:DoClearWeakData()
|
|
|
|
if self._dataAsArray then
|
|
ReusableTable.DestroyArray(self._weakData)
|
|
else
|
|
ReusableTable.DestroyTable(self._weakData)
|
|
end
|
|
self._weakData = nil
|
|
end
|
|
|
|
function ReusableObject:ClearWeakData()
|
|
if nil == self._weakData then
|
|
return
|
|
end
|
|
|
|
self:DoClearWeakData()
|
|
|
|
if self._dataAsArray then
|
|
TableUtility.ArrayClear(self._weakData)
|
|
else
|
|
TableUtility.TableClear(self._weakData)
|
|
end
|
|
end
|
|
|
|
function ReusableObject:ClearWeakDataByDeleter(deleter)
|
|
if nil == self._weakData then
|
|
return
|
|
end
|
|
|
|
self:DoClearWeakData()
|
|
|
|
if self._dataAsArray then
|
|
TableUtility.ArrayClearByDeleter(self._weakData, deleter)
|
|
else
|
|
TableUtility.TableClearByDeleter(self._weakData, deleter)
|
|
end
|
|
end
|
|
|
|
-- DON'T call
|
|
function ReusableObject:Construct(asArray, args)
|
|
self._alive = true
|
|
self._dataAsArray = asArray
|
|
self:DoConstruct(asArray, args) -- TODO outside call
|
|
end
|
|
|
|
-- DON'T call
|
|
function ReusableObject:Deconstruct()
|
|
self:ClearWeakObserver()
|
|
self:DoDeconstruct(self._dataAsArray) -- TODO outside call
|
|
self:DestroyData()
|
|
self:DestroyWeakData()
|
|
self._dataAsArray = nil
|
|
self._alive = false
|
|
end
|
|
|
|
-- virtual begin
|
|
function ReusableObject:DoConstruct(asArray, args)
|
|
end
|
|
|
|
function ReusableObject:DoDeconstruct(asArray)
|
|
end
|
|
|
|
function ReusableObject:Finalize()
|
|
end
|
|
|
|
function ReusableObject:OnObserverDestroyed(k, obj)
|
|
end
|
|
-- virtual end |