Thread Tools Display Modes
03/01/14, 05:59 PM   #1
zork
 
zork's Avatar
AddOn Author - Click to view addons
Join Date: Feb 2014
Posts: 29
ZO_ObjectPool

I have not wrapped my head around the ZO_ObjectPool yet.

Here is a snippet of code from zo_objectpool.lua. Not sure if that has been updated yet. (aug 2013)

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

Pawkette used it in LootDrop. Maybe he/she knows and can enlighten us.

Last edited by zork : 03/01/14 at 06:02 PM.
  Reply With Quote
03/01/14, 06:02 PM   #2
Pawkette
 
Pawkette's Avatar
AddOn Author - Click to view addons
Join Date: Mar 2014
Posts: 20
What would you like to know about it?
  Reply With Quote
03/01/14, 06:26 PM   #3
zork
 
zork's Avatar
AddOn Author - Click to view addons
Join Date: Feb 2014
Posts: 29
Well I'm currently trying to understand the concept behind it.

As far as I can tell...the pool has functions to create and reset objects. On a certain event you accuire a new object and on a second event you release objects that you don't need anymore.

Maybe you could just describe the concept of LootDrop in general.

An item drops, you create a new object in the pool. After a certain time you release that object. That is how I understand it atm.
  Reply With Quote
03/01/14, 06:34 PM   #4
Pawkette
 
Pawkette's Avatar
AddOn Author - Click to view addons
Join Date: Mar 2014
Posts: 20
Precisely that, the real concept behind ZO_ObjectPool is that you have a number of generic objects that you don't want to instantiate any time they're needed. So, ZO_ObjectPool will create an object, and when you release that object it goes back into a pool - never garbage collected. The next time you need an object, it asks that pool if any are sitting around unused and gives you that unused object instead of instantiating a new one.

It's a lot of fancy code to basically represent:

Lua Code:
  1. local in_use = {}
  2. local unused = {}
  3.  
  4. function GetNew()
  5.   if ( #unused ) then
  6.     return unused[ 1 ]
  7.   else
  8.      -- create new object
  9.   end
  10. end
  11.  
  12. function Release( object )
  13.   --remove from in_use
  14.   table.insert( unused, object )
  15. end
  16.  
  17. local obj = GetNew()
  18. table.insert( in_use, obj )
  19. obj:DoStuff()
  20. Release( obj )

Last edited by Pawkette : 03/01/14 at 06:37 PM.
  Reply With Quote
03/01/14, 10:30 PM   #5
Seerah
Fishing Trainer
 
Seerah's Avatar
WoWInterface Super Mod
AddOn Author - Click to view addons
Join Date: Feb 2014
Posts: 648
I'm using it in a buff addon I'm currently working on. Here's a (very) trimmed down version.

Lua Code:
  1. local pool
  2.  
  3. local function CreateBuff(pool)
  4.      --create a new control frame
  5.      local buff = ZO_ObjectPool_CreateControl("MyBuffTemplate", pool, parentFrame)
  6.      --do other stuff with buff object
  7.  
  8.      --return it for use
  9.      return buff
  10. end
  11.  
  12. local function RemoveBuff(control)
  13.      --do stuff when you don't need a frame anymore
  14.      control:SetHidden(true)
  15. end
  16.  
  17. local function UpdateBuffs()
  18.      local myBuff
  19.      for i = 1, GetNumBuffs("player") do
  20.           --if a control with this id # doesn't exist yet, create it, otherwise just return the one we have
  21.           myBuff = pool:AcquireObject(i)
  22.           --do more stuff with myBuff
  23.      end
  24. end
  25.  
  26. local function Initialize()
  27.      --create a new pool to get my controls from
  28.      pool = ZO_ObjectPool:New(CreateBuff, RemoveBuff)
  29.      EVENT_MANAGER:RegisterForEvent("MyAddon", EVENT_EFFECT_CHANGED, UpdateBuffs)
  30. end
  31.  
  32. EVENT_MANAGER:RegisterForEvent("MyAddon", EVENT_ADD_ON_LOADED, function(event, addon)
  33.      if addon == "MyAddon" then
  34.           Initialize()
  35.      end
  36. end)
  Reply With Quote
03/02/14, 05:26 AM   #6
zork
 
zork's Avatar
AddOn Author - Click to view addons
Join Date: Feb 2014
Posts: 29
Thank you both.
  Reply With Quote

ESOUI » Developer Discussions » General Authoring Discussion » ZO_ObjectPool


Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

vB code is On
Smilies are On
[IMG] code is On
HTML code is Off