Back to Home

ESO Lua File v100032

libraries/utility/zo_objectpool.lua

[◄ back to folders ]
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
--[[
A generic pool to contain "active" and "free" objects. Active objects
are typically objects which:
1. Have a relatively high construction cost
2. Are not lightweight enough to create many of them at once
3. Tend to be reused as dynamic elements of a larger container.
The pool should "rapidly" reach a high-water mark of contained objects
which should flow between active and free states on a regular basis.
Ideal uses of the ZO_ObjectPool would be to contain objects such as:
1. Scrolling combat text
2. Tracked quests
3. Buff icons
The pools are not intended to be used to track a dynamic set of
contained objects whose membership grows to a predetermined size.
As such, do NOT use the pool to track:
1. Chat filters
2. Inventory slots
3. Action buttons (unless creating something like AutoBar)
A common usage pattern is instantiating templated controls. To facilitate this
without bloating your own code you should use ZO_ObjectPool_CreateControl which has
been written here as a convenience. It creates a control named "template"..id where
id is an arbitrary value that will not conflict with other generated id's.
If your system depends on having well-known names for controls, you should not use the
convenience function.
--]]
ZO_ObjectPool = ZO_Object:Subclass()
function ZO_ObjectPool:New(factoryFunctionOrObjectClass, resetFunction)
    local pool = ZO_Object.New(self)
        
    if factoryFunctionOrObjectClass then
        pool.m_Active   = {}
        pool.m_Free     = {}
        if type(factoryFunctionOrObjectClass) == "function" then
            pool.m_Factory  = factoryFunctionOrObjectClass   -- Signature: function(ZO_ObjectPool)
        else
            pool.m_Factory = function(pool) return factoryFunctionOrObjectClass:New(pool) end
        end
        
        pool.m_Reset    = resetFunction     -- Signature: function(objectBeingReset)
        pool.m_NextFree = 1                 -- Just in case the user would like the pool to generate object keys.
        pool.m_NextControlId = 0            -- Just in case the user would like the pool to generate id-based control suffixes
    end
    
    return pool
end
function ZO_ObjectPool:GetNextFree()
    local freeKey, object = next(self.m_Free)
    if freeKey == nil or object == nil then
        local nextPotentialFree = self.m_NextFree
        self.m_NextFree = self.m_NextFree + 1
        return nextPotentialFree, nil
    end
    return freeKey, object
end
function ZO_ObjectPool:GetNextControlId()
    self.m_NextControlId = self.m_NextControlId + 1
    return self.m_NextControlId
end
function ZO_ObjectPool:GetTotalObjectCount()
end
function ZO_ObjectPool:GetActiveObjectCount()
    return NonContiguousCount(self.m_Active)
end
function ZO_ObjectPool:HasActiveObjects()
    return next(self.m_Active) ~= nil
end
function ZO_ObjectPool:GetActiveObjects()
    return self.m_Active
end
function ZO_ObjectPool:GetActiveObject(objectKey)
    return self.m_Active[objectKey]
end
function ZO_ObjectPool:ActiveObjectIterator(filterFunctions)
    return ZO_FilteredNonContiguousTableIterator(self.m_Active, filterFunctions)
end
function ZO_ObjectPool:GetFreeObjectCount()
    return NonContiguousCount(self.m_Free)
end
function ZO_ObjectPool:ActiveAndFreeObjectIterator(filterFunctions)
    local objects = {}
    ZO_CombineNonContiguousTables(objects, self.m_Active, self.m_Free)
    return ZO_FilteredNonContiguousTableIterator(objects, filterFunctions)
end
end
function ZO_ObjectPool:AcquireObject(objectKey)
    -- If the object referred to by this key is already
    -- active there is very little work to do...just return it.
    if((objectKey ~= nil) and (self.m_Active[objectKey] ~= nil))
    then
        return self.m_Active[objectKey], objectKey
    end
    
    local object = nil
    
    -- If we know the key that we want, use that object first, otherwise just return the first object from the free pool
    -- A nil objectKey means that the caller doesn't care about tracking unique keys for these objects, or that the keys
    -- the system uses can't directly be used to look up the data. Just manage them with pool-generated id's
    if(objectKey == nil)
    then
        objectKey, object = self:GetNextFree()
    else
        object = self.m_Free[objectKey]
    end
    --
    -- If the object is valid it was reclaimed from the free list, otherwise it needs to be created.
    -- Creation uses the m_Factory member which receives this pool as its only argument.
    -- Either way, after this, object must be non-nil
    --
    if(object)
    then
        self.m_Free[objectKey] = nil
    else        
        object = self:m_Factory(objectKey)
    end
           
    self.m_Active[objectKey] = object
    if self.customAcquireBehavior then
        self.customAcquireBehavior(object, objectKey)
    end
        
    return object, objectKey
end
function ZO_ObjectPool:ReleaseObject(objectKey)
    local object = self.m_Active[objectKey]
    
    if(object)
    then
        if(self.m_Reset)
        then
            self.m_Reset(object, self)
        end
        
        self.m_Active[objectKey] = nil
        self.m_Free[objectKey] = object
    end
end
function ZO_ObjectPool:ReleaseAllObjects()
    for k, v in pairs(self.m_Active)
    do
        if(self.m_Reset)
        then
            self.m_Reset(v, self)
        end
        
        self.m_Free[k] = v
    end
    
    self.m_Active = {}
end
function ZO_ObjectPool:DestroyFreeObject(objectKey, destroyFunction)
     local object = self.m_Free[objectKey]
     destroyFunction(object)
     self.m_Free[objectKey] = nil
end
function ZO_ObjectPool:DestroyAllFreeObjects(destroyFunction)
    for k, object in pairs(self.m_Free) do
        destroyFunction(object)
    end
    self.m_Free = {}
end
function ZO_ObjectPool_CreateControl(templateName, objectPool, parentControl)
    return CreateControlFromVirtual(templateName, parentControl, templateName, objectPool:GetNextControlId())
end
function ZO_ObjectPool_CreateNamedControl(name, templateName, objectPool, parentControl)
    return CreateControlFromVirtual(name, parentControl, templateName, objectPool:GetNextControlId())
end
    control:SetHidden(true)
end