Type-problem aargh!

Blitz3D Forums/Blitz3D Programming/Type-problem aargh!

njesper(Posted 2003) [#1]
Hi there,

I have two different types: .player, and .enemy, and I want to be able to use the same function for controlling either .player or .enemy.

example: (theoretical)
type player
field gfx
end type

type enemy
field gfx
end type

e.enemy = new enemy
p.player = new player

function movePerson(person)
positionEntity person\gfx,10,10,10
end function

...And then I want to say something like:
movePerson(e.enemy) or movePerson(p.player)
But this is not possible!!!
Isn't there a way to solve this so that I can use the same function for more than one type of type (hehe..)??

Best regards,
Jesper Colding - Jørgensen


Warren(Posted 2003) [#2]
Not really. You're asking for overloaded functions and after the last bruhaha over that I don't think you want to go there.

Object Orientation is a four letter word around here.


sswift(Posted 2003) [#3]
There is a way to solve it, and I used the method in my GUI system.

Type GUI_Object
   Field ObjectType
   Field ObjectHandle
EndType


ObjectType is a number which defines which type the object is.
ObjectHandle is a pointer to that type.


This is how I create a new object:

ThisGUIObject.GUI_Object = New GUI_Object
ThisText.GUI_Text = New GUI_Text

ThisGUIObject\ObjectType = GUI_OBJECTTYPE_TEXT
ThisGUIObject\ObjectHandle = Handle(ThisText)


Note how ObjectType is set to a constant that tells it that the pointer converted to an int and stored in ObjectHandle is of type TEXT.

And this is a function which returns the entity stored in any one of my types:

Function GUI_GetObjectEntity(ThisGUIObject.GUI_Object)

	ObjectType   = ThisGUIObject\ObjectType
	ObjectHandle = ThisGUIObject\ObjectHandle
	
	Select ObjectType
	
		Case GUI_OBJECTTYPE_DATABAR
		
			ThisDataBar.GUI_DataBar	= Object.GUI_DataBar(ObjectHandle)
			Avatar = ThisDataBar\Avatar
	
		Case GUI_OBJECTTYPE_DATAARC
		
			ThisDataArc.GUI_DataArc	= Object.GUI_DataArc(ObjectHandle)
			Avatar = ThisDataArc\Avatar

		Case GUI_OBJECTTYPE_TEXT
		
			ThisText.GUI_Text = Object.GUI_Text(ObjectHandle)
			Avatar = ThisText\Avatar

		Case GUI_OBJECTTYPE_SPRITE
		
			ThisSprite.GUI_Sprite = Object.GUI_Sprite(ObjectHandle)
			Avatar = ThisSprite\Avatar

	End Select


	Return Avatar
	
End Function


Some of my functions, like "set value" need a case statement in them like this to handle the different object types. Others however, like a function to position the object, just call this function for whatever object is passed to them and then operate on the entity.


It's not perfect but it does allow me to have one set of funcitons to position and set the properties of any GUI object, without having to have all properties that all objects may use contained in one huge type.

Of course, is it worthwhile to muck up your code in this way just so that you don't have one huge type that encapsulates all possible objects? I dunno. It saves ram of course, but most games will have so few objects that it's not even remotely worth concerning yourself about. The types are a little cleaner, but the rest of the code tends to be more difficult to understand because of all the case statements.

And just having all the objects in one type would not get rid of all case statements, because a databar and a dataarc both need different code to execute when their appearance changes, because their meshes are constructed differently. So you'll still have some case statements in there.

All in all, I'm not convinced it was worthwhile to do. It took more time to implement, is more prone to bugs, and doesn't result in simpler, more easily maintained code.

But it made me feel good to get it working at the time anyhow.

The only situation where I could truly reccomend this is a VERY large and complex project, perferably one with more than one programmer working on the same code. For 90% of Blitz games I just don't think there's a significant benefit to using this method... if any benefit at all.


Who was John Galt?(Posted 2003) [#4]
Another way (I know not exactly what you're after, but it's simple)


type player
field gfx
end type

type enemy
field gfx
end type

e.enemy = new enemy
p.player = new player

movegfx(e\gfx)
movegfx(p\gfx)

function movegfx(gfxhandle)
positionEntity gfxhandle,10,10,10
end function


njesper(Posted 2003) [#5]
sswift, Thanks for your detailed solution, actually I have tried something similar, but just got sooo tired of all those damn CASE-lists, that made med think: so I really save time doing it like that?, anyways thanks for your help.

Odfex, I have been thinking about it, and I think I go for your solution, but then there is the risk of having to derrive alot of type-"fields" before sending them to a function. On the other hand, making the functions "stupid", by not containing any type-code, can also have its benefits. Well, Thank you very much.

Thanks guys,

Best regards, Jesper


_Skully(Posted 2003) [#6]
Well, if they have common components you can break them apart into three types:

Type Player
field gfx
field o.obj
end type

Type Enemy
field gfx
field o.obj
end type

Type obj
field x#,dx#
field y#,dy#
end type

This way for movement and the like you just pass the "obj" to the function rather than what the object is


njesper(Posted 2003) [#7]
_skully, could you please show how you would create a player then? I mean how do you then access the o.obj? I do not think you can write: Player\o\x#,dx# for example..
else, please prove me wrong :-)

Best regards,
JEsper


njesper(Posted 2003) [#8]
_skully,

Correction, correction, I DID find out the syntax.
Thanks for your solution to the problem.

Best regards, Jesper