[OOP] Mother-of-all-objects with children (TList)

BlitzMax Forums/BlitzMax Programming/[OOP] Mother-of-all-objects with children (TList)

pappavis(Posted 2006) [#1]
I am struggling with a OOP concept of father-child relations in BliztMax. All of this must be done in a OOP way.

For the purpose of portability the code must be strict adhering to C#/Java conventions. The only way i think thats possible is to have a father-child relation, with one object being the father of all other objects (using a TList).

Anyone who has done a bit of M$ Excel programming will know what i talk about. In Excel you instantiae an Excel Appinstance, then add worksheeets to it, and worksheets have rows, cells etc. So in a way one can trace from one worksheet to another by object model, for example to retrieve data from one sheet to another or to compare values etc etc.

Basically what i want to do (for a game) is:
* Instantiate a Father object which has as only a TList property.
* Add all other objects to Father (ships, missiles, starfield).

My problem is: i need some help on doing it.

Here is a practical example:
1. Instantiate Father object.
2. Instantiate a TMain object.
3. Add the object to Father.
4. Do a TMain.GetTheShowOnTheRoad() method.

The idea is then that a alien (object) can have a bullet (object), which is all ofcourse to be traced back right to Father. Also, alien could add powerup, and powerup can add defenceshield object. Ultimitley defenceshield belongs to alien. In this OOP way i could remove defenceshield then add it to player ship. You get what i mean?

Does any1 have a small example for me?? I'd really appreciate your help!

Is this way of doing working with father-child too complicated? I wanna make a basic framework which will bebefit in the long run. Whats your opinion?

here is an example of what i try to do:
Strict

Local objStart:TMain = New TMain;
objStart.Main();


'#Region  AppInstance moeder van alle Objecten
Type TAppInstance
	Global AppInstance:TList;
End Type
'#EndRegion 

'#Region  TMain
Type TMain Extends TAppInstance
	Global objGameObjectsList:TList;
	Global ScreenWidth:Int;
	Global ScreenHeight:Int;
	
	Method Main()
		ShowMouse();
                objGameObjectsList = new TList();

		Local objMain:TMain = New TMain;
		Local intSterretjeTeller:Int;

                Local objAlien1:TAlien = new TAlien;
                objGameObjectsList.AddLast(objAlien1)
	End Method		
End Type



Is the above coorect to implement the M$ Excel-objectmodel idea? TIA!


JoshK(Posted 2006) [#2]
Type thing
field parent:thing
field children:tList=new tList
EndType

Function CreateThing(parent:thing=null)
t:thing=new thing
t.parent=parent
if parent
parent.children.addlast t
endif
return t
EndFunction


Jim Teeuwen(Posted 2006) [#3]
Im using the same in my current OpenGL project.

Each Entity has a Parent and a Tlist of Children. That way you can find any entity through a child/parent relationship.

Keep in mind though that TList does not allow Indexing like an array. so doing World.Stuffs[1].Name. will not work.
You will have to create a GetChild() method that loops through the children and searches for the child you want by index or name.

Type World
  global Origin:Entity '// Pointer to the very topmost Entity

  Method New()
   if( Origin = null ) then  Origin = new Entity;
  End Method
End type


type Entity
  Field Parent:Entity;
  Field Children:TList;
  Field Name:String;

  Method New()
    Parent = null;
    Children = new TList;
    Name = "";
  End Method

  Function Create:Entity( parent:Entity = null, name:string = "" )
   Local e:Entity = new Entity

   if( parent <> null ) then
     e.SetParent( parent );
   end if
   e.Name = name;
   return e;
  End Function

  Method AddChild( child:Entity )
     If( Not Children.Contains( child ) ) Then
       child.Parent = Self;
       Children.AddFirst( child );
     End If
  End Method
  Method RemoveChild( child:Entity )
    If( Children.Contains( child ) ) Then
        child.Parent = null;
        Children.Remove( child );
    End If
  End Method
  Method IsChild( e:Entity )
    return Children.Contains( e );
  End Method
  Method SetParent( p:entity )
    '// we allready have a parent?
    if( Parent <> null) then
      Parent.RemoveChild( Self );
    end if

    Parent = p;
    Parent.AddChild( Self );
  End Method
  Method GetChild:Entity( index:int )
   if( index < 0 Or index >= Children.Count() ) then
     '// Index is out of Bounds.
     return null;
   end if
   return Entity( Children.ValueAtIndex( index ) );
  end method
  
end type

local world:World = new World;
local A:Entity = Entity.Create( world.Origin, "A" );
local B:Entity = Entity.Create( A, "B" );
Local C:Entity = Entity.Create( B, "C" );

'// print Enity C's name using parent/child relationship
Print( world.Origin.GetChild(0).GetChild(0).GetChild(0).Name );



That should give you an idea of how it works with TLists.
You can make it easier on yourself by using static Array's instead of TLists. It will make the Indexing easier, but extending the Array's when a new Child is added is a pain.
The above should suit you fine.

It is important that you dont assign a parent to an entity by simply doing :myEntity.Parent = OtherEntity;
If you do this, you will not have updated the parent's child lists. So make sure you use myEntity.SetParent( .. ) method to do so.

Note: there may be some small bugs, as I didnt test this code in Bmx. But the idea should work.


Jim Teeuwen(Posted 2006) [#4]
And another thing.
If you ever get to do 3D stuff and you happen to store/link your Mesh data directly to an Object of type Entity, then I would suggest to also keep a Global List of all Entities; Next to the parent/child structure.

This will be needed to sort the entities' By drawing order.
Just looping through them from the Origin and iterate through each child will cause problems when you are trying to render them to the screen. As some Entities way down in the chain may be required to render Before an entity somewhere High up the chain (Z-ordering and all that).

But this isnt really related to your problem so i'll shut up now :)


Red Ocktober(Posted 2006) [#5]
forgive me for budding in... and i'm not gonna pretend to understand exactly everything it is that you are trying to accomplish here, but from what little i did read, it appears to me that you are approaching this a lil inside out... or backend first... whatever...

i would define a linked list class as a base class, then derive the game object class from that... this way, everything in the game would be capable of linking to it's parent and children automatically...

if you can... take a look at pages 710 and 714 of OpenGL Game Programming by Hawkins, Aste, LaMotthe...

this sort of relationship and structure is clearly explained in a few really brief paragraphs...

good luck...

--Mike


JoshK(Posted 2006) [#6]
You only to z-order your objects that have a material applied to them that uses a blend mode.


Cajun17(Posted 2006) [#7]
I'm not sure if it's exactly what youre looking for but...
http://www.blitzbasic.com/Community/posts.php?topic=59589

Maybe it'll give you an idea or 2.