2
-- A factory allows for simple object pooling; that is,
3
-- reusing object instances instead of creating them and deleting
4
-- them as needed. This approach saves CPU and memory.
6
-- Be careful of accidentally adding an instance to a view twice.
7
-- This will manifest itself as the sprite moving twice as fast, for
8
-- example, each time it is recycled. The easiest way to avoid this
9
-- problem is for the object to add itself to the view in its onNew
10
-- handler, since that will only be called once.
12
-- If you only want a certain number of instances of a class ever
13
-- created, first call preload() to create as many instances as you want,
14
-- then freeze() to prevent any new instances from being created.
15
-- If a factory is ever asked to make a new instance of a frozen class
16
-- but none are available for recycling, it returns nil.
19
-- Called not on the factory, but the object is creates whenever
20
-- it is either initially created or recycled via create().
25
Factory = Class:extend{
26
-- private property: objects ready to be recycled, stored by prototype
29
-- private property: tracks which pools cannot be added to, stored by prototype.
33
-- Creates a fresh object, either by reusing a previously
34
-- recycled one or creating a new instance. If the object has
35
-- a revive method, it calls it.
38
-- prototype - <Class> object
39
-- props - table of properties to mix into the class
44
create = function (self, prototype, props)
48
assert(prototype.instanceOf and prototype:instanceOf(Class), 'asked to create something that isn\'t a class')
51
if self._recycled[prototype] and #self._recycled[prototype] > 0 then
52
newObj = table.remove(self._recycled[prototype])
53
if props then newObj:mixin(props) end
55
-- create a new instance if we're allowed to
57
if not self._frozen[prototype] then
58
newObj = prototype:new(props)
64
if newObj.revive then newObj:revive() end
65
if newObj.onReset then newObj:onReset() end
70
-- Marks an object as ready to be recycled. If the object
71
-- has a die method, then this function it.
74
-- object - object to recycle
79
recycle = function (self, object)
80
if not self._recycled[object.prototype] then
81
self._recycled[object.prototype] = {}
84
table.insert(self._recycled[object.prototype], object)
86
if object.die then object:die() end
90
-- Preloads the factory with a certain number of instances of a class.
93
-- prototype - class object
94
-- count - number of objects to create
99
preload = function (self, prototype, count)
100
if not self._recycled[prototype] then
101
self._recycled[prototype] = {}
107
table.insert(self._recycled[prototype], prototype:new())
112
-- Prevents any new instances of a class from being created via create().
115
-- prototype - class object
120
freeze = function (self, prototype)
121
self._frozen[prototype] = true
125
-- Allows new instances of a class to be created via create().
128
-- prototype - class object
133
unfreeze = function (self, prototype)
134
self._frozen[prototype] = false