PDA

View Full Version : Class Instance Storage... Bad Idea?


TomMalufe
12-16-2009, 04:09 PM
So, I get kind of bored sometimes at work and today I had an idea for global access to a particular class' instances.
package
{
import flash.display.Sprite;

public class PlayAround extends Sprite
{
public static var instances:Vector.<PlayAround> = new Vector.<PlayAround>();

public function PlayAround()
{
PlayAround.instances.push(this);
}
}
}
I guess it's kind of similar to the idea of Singulars in a way...

Anyways, I have no particular use for this idea, but I was wondering if anyone else had any opinion on it. You think it would be a bad idea? I would probably consider it a bad practice myself... but an interesting idea all the same.

I wonder what it could be used for.

ASWC
12-16-2009, 04:19 PM
Nothing wrong with that, I've done it a couple of time for easy access.

TomMalufe
12-16-2009, 04:23 PM
I would assume you would have to be careful to avoid memory leaks though... Maybe have a destory function as well that removes itself from the instances Vector.

ASWC
12-16-2009, 04:49 PM
you could implement an easy factory type of pattern with this. You'll have a getInstance type of function that returns either an inactive object from the Vector (so you reuse an object) or returns a new one thus avoiding creating new object if you don't need to. Of course that would mean the object should be able to be reset.

TomMalufe
12-16-2009, 06:35 PM
Ah good thinking. I haven't used Object pooling enough in real projects. I've done a few experiments with the intention of trying new techniques I've learned and in those cases I have.

Hmmm... I like it. Thanks.

Edit:
So, here's how I see it now.
package
{
import flash.display.Sprite;

public class PlayAround extends Sprite
{
public static var instances:Vector.<PlayAround> = new Vector.<PlayAround>();
public static function getInstance():PlayAround
{
var inst:PlayAround;
if(PlayAround.instances.length > 0)
{
inst = PlayAround.instances.pop();
inst.init();
}
else
{
inst = new PlayAround();
}
return inst;
}

public function PlayAround()
{
this.init();
}

public function init():void
{
/**
* add Event Listeners (and maybe set property values)
**/
}

public function destructor():void
{
/**
* remove Event Listeners (and maybe reset property values)
**/
PlayAround.instances.push(this);
}
}
}
These are all public methods, but I feel like they are safe enough left exposed as they are.

Now if only I had a project where I was allowed to develop for Flash Player 10... stink'n corporate projects. I guess this would work just as well with an Array instead of a Vector, but it wouldn't feel as good to me.

ASWC
12-16-2009, 06:55 PM
in a real factory type the array or vector would only contain unused object but here we could still do the same by giving our object a state variable (typically a boolean) and when in your application you get rid of one object you set its state to false (like let's say isActive:Boolean). Then in the getInstance method you run a loop to check if any object has a isActive set to fasle and return it.

TomMalufe
12-16-2009, 07:24 PM
But wouldn't it be less efficient to have to loop through the whole Vector (or most of it) each time you want to get an instance? The way I have it set up above the instances Vector only contains dead/inactive instances and the rest have to be stored outside of the class. This way I can just grab the one off the top if there is any to be had. Also, I can forgo the whole pool if I please by not using the getInstance/destructor methods (which gives me a little flexibility on how [if] I reuse the class later).

ASWC
12-16-2009, 08:19 PM
Yes I missed the way you implemented that. Yes that looks very good. You could have why not a vector for active object and one for inactive. ;)

-Ev-
12-18-2009, 03:03 PM
Yah, object pooling is a good use for the static Array/Vector. I've used a similar method when I have a class in which a specific action on any instance of the class should trigger an action on the rest. The action method rips through the Array/Vector and modifies the others.

Greg SS
12-23-2009, 02:06 AM
Something cobbled up in a jiffy, not tested/compiled/debuged in anyway, just something I thought of in the moment. Tell me what you think of it.



import flash.display.Sprite;
import flash.utils.Dictionary;

public class PooledSprite extends Sprite
{
private static var pool:Array;
private static var tail:int = 0;

private var listeners:Dictionary;

public static function get instance():PooledSprite
{
if(!pool) pool = new Array();
if(tail == pool.length){
pool[tail] = new PooledSprite();
}
pool[tail].addEventListener(Event.REMOVED_FROM_STAGE, destroy);
tail++;
return pool[tail - 1];
}

public function PooledSprite():void
{
listeners = new Dictionary();
}

public function destroy():void
{
var type:String;
for(type in listeners){
removeEventListener(type, listeners[type]);
delete listeners[type];
}

pool[tail] = this;
tail--;
}

override public function
addEventListener(type:String, listener:Function, useCapture:Boolean = false, priority:int = 0, useWeakReference:Boolean = false):void
{
if(listeners[type] != null){
removeEventListener(type, listener);
delete listeners[type];
}
listeners[type] = listener;
super.addEventListener(type, listener, useCapture, priority, useWeakReference);
}

}

FEK315
12-23-2009, 05:24 AM
well, I actually understand a little of this. :D