Hello! I have been working on my voxel terrain system and while I was thinking off how I can optimize the performance, I came up with idea of creating object pools manager.
local module = {
}
function module:New() : PoolManager
local PoolsManager = {
Pools = {
};
CanAddObjects = {
};
CreateMethods = {
};
TYPES_NULL = {
};
NewMethods = {
};
Lengths = {
};
Keys = {
}
}
function PoolsManager:CreatePool(Key,TYPE_NULL:any,CanAddObjects : boolean,NewMethod)
local Index = #self.Pools + 1
self.Lengths[Index] = 0
self.Pools[Index] = {}
self.CanAddObjects[Index] = CanAddObjects == true
self.NewMethods[Index] = NewMethod or function() return TYPE_NULL end
self.Keys[Key] = Index
self.TYPES_NULL[Index] = TYPE_NULL
return Index
end
function PoolsManager:GetIndexFromKey(Key)
return self.Keys[Key]
end
function PoolsManager:InsertObject(Index,Object)
table.insert(self.Pools[Index],Object)
self.Lengths[Index] += 1
end
function PoolsManager:PopObject(Index)
local Pool = self.Pools[Index]
local Length = self.Lengths[Index]
if (Length > 0) then
local Top = Pool[Length]
Pool[Length] = self.TYPES_NULL[Index]
self.Lengths[Index] -= 1
return Top
elseif (self.CanAddObjects[Index]) then
return self.NewMethods[Index]()
else
return self.TYPES_NULL[Index]
end
end
return PoolsManager
end
export type PoolManager = typeof(module:New())
return module
It’s a simple module, which contains a set of methods.
But let’s come to the explaining part of how these work.
-
CreatePool(Key, TYPE_NULL, CanAddObjects, NewMethod)
: This method creates a pool for objects of a specific type. It takes four arguments:
-
Key
: The key used to identify the pool. It serves as a unique identifier for the pool. -
TYPE_NULL
: The default value to be returned by thePopObject
method if the pool is empty and cannot create a new object. It represents a null value for the type. -
CanAddObjects
: A boolean value indicating whether new objects can be added to the pool when it runs out of objects. IfCanAddObjects
is set totrue
, theNewMethod
will be used to create a new object for the pool. -
NewMethod
: A function that creates a new object for the pool. IfCanAddObjects
istrue
and the pool is empty, this method will be called to generate a new object for the pool.
-
GetIndexFromKey(Key)
: This method retrieves the index of a pool based on its key. It takes one argument:
-
Key
: The key used to identify the pool.It returns the index of the pool associated with the provided key.
-
InsertObject(Index, Object)
: This method inserts an object into the specified pool. It takes two arguments:
-
Index
: The index of the pool where the object will be inserted. -
Object
: The object to be inserted into the pool.The method adds the object to the pool’s table and increments the length of the pool.
-
PopObject(Index)
: This method retrieves an object from the specified pool. It takes one argument:
-
Index
: The index of the pool from which the object will be retrieved.The method checks if the pool has any objects. If it does, the last object from the pool’s table is retrieved, the length of the pool is decremented, and the object is returned. If the pool is empty andCanAddObjects
istrue
, theNewMethod
is called to create a new object for the pool. If the pool is empty andCanAddObjects
isfalse
, theTYPE_NULL
value associated with the pool is returned.
Here is an example how to use this:
local PoolManagerModule = require(script.PoolManagerModule)
local poolManager = PoolManagerModule:New()
local Object = {}
function Object.new(value)
local obj = {
value = value
}
setmetatable(obj, { __index = Object })
return obj
end
function Object:PrintValue()
print("Value:", self.value)
end
local TYPE_NULL = Object.new(-math.huge)
local objectPoolIndex = poolManager:CreatePool("ObjectPool",TYPE_NULL, false)
-- Insert objects into the pool
for i = 1, 10 do
local obj = Object.new(i)
poolManager:InsertObject(objectPoolIndex, obj)
end
-- Retrieve objects from the pool
for i = 1, 12 do
local obj = poolManager:PopObject(objectPoolIndex)
if obj ~= TYPE_NULL then
obj:PrintValue()
else
print("No available objects in the pool.")
end
end