GetElementsByType()
BlitzMax Forums/BlitzMax Programming/GetElementsByType()
| ||
Hello, I have a quite familiar object structure in my game (don't worry, example code is provided below): TElement type TPlayer extends TElement TEnemy extends TElement TBullet extends TElement TElement controls a global list with all created TElements Now I want to write a TElement method GetElementsByType:TList(typeID) to receive all elements of that type. Example: I can write a function for every extended type, like TElement.GetBullets() TElement.GetEnemies() but I would like to have a generic function where I can call every extended type without writing a function for each and every extended type. Is there a way to do this? |
| ||
Why not make GetElements an abstract method and use polymorphism? Or have I misunderstood? <edit> In fact I think I have misunderstood.... don't mind me. |
| ||
Imagine TElement is a type defined in a module. During project progress I create all kind of abstract types of TElement. Now I need to write a GetElement() function for every abstract type. Instead it would be nice and handy if TElement could have a generic GetElementByType() function. In my project, things are a little different. TElement does also have a field polLinks:TList containing links to other TElement objects. I want to be able to ask to a TPlayer instance "Which TEnemies do you have (are linked)?" or "TEnemy, give me a list of all your TBullets." I can do all this by calling GetElementsByType() GetElementsByType() will run through the polLinks list of course. |
| ||
Here is one way...SuperStrict Framework BRL.Map Import BRL.LinkedList Import BRL.StandardIO Type TElement Const TYPE_PLAYER:Int = 1 Const TYPE_ENEMY:Int = 2 Const TYPE_BULLET:Int = 3 Global golElements:TMap = New TMap Method Init() Local id:String = GetId() Local list:TList = TList(golElements.ValueForKey(id)) If Not list Then list = New TList golElements.Insert(id, list) End If list.AddLast(Self) End Method Function GetElementsByType:TList(typeId:Int) ' can return Null TList Return TList(golElements.ValueForKey(String(typeId))) End Function Method GetId:Int() Abstract End Type Type TPlayer Extends TElement Method New() Init() End Method '.. create function etc. Method GetId:Int() Return TYPE_PLAYER End Method End Type Type TEnemy Extends TElement Method New() Init() End Method '.. create function etc. Method GetId:Int() Return TYPE_ENEMY End Method End Type Type TBullet Extends TElement Method New() Init() End Method '.. create function etc. Method GetId:Int() Return TYPE_BULLET End Method End Type 'receive all bullets: Local olBullets:TList = TElement.GetElementsByType(TElement.TYPE_BULLET) If olBullets Then Print olBullets.count() End If New TBullet New TBullet olBullets = TElement.GetElementsByType(TElement.TYPE_BULLET) Print olBullets.count() If you want all types, you could implement some extra functionality in GetElementsByType(). One advantage to this, is that your type lists are already built, so access of those is faster. It depends what information you need more often. |
| ||
I would consider sending a string and do a select/case on it to check which object to extract from the list. Not elegant but might be good enough for now and then revisit if you have to. <edit>... or use a tmap :) |
| ||
Nice example Brucey! Thanks. I'll experiment a little with TMaps. |
| ||
Brucey, Based on your example code I was able to make exactly what I need. Thanks again! |