Type Dependencies

BlitzMax Forums/BlitzMax Beginners Area/Type Dependencies

z80jim(Posted 2005) [#1]
In a platform game I am working on I have an array to hold the tiles for the board. I also have a Type Player to define the characters that run around the board. The problem is several of the methods in my Player type need to access the array to determine collisions and board interactions. But the array is defined outside the Type so the Type does not compile.

What is the cleanest way to have my Player Type know about the array? I know I could pass the array in as a parameter to my Player methods but I don't like that.

Should I define a pointer field in my Player Type and initialize it to my actual array when I instantiate a player?

I guess what it comes down to is how do I reference a Global variable or object in a Type definition.


tonyg(Posted 2005) [#2]
Have you got any example code?


z80jim(Posted 2005) [#3]
No sample code. Currently I'm doing it with little or no OOP so I'm basically using a bunch of global data and functions. Will re-do it once I get a better handle on how to structure my types and such.


Warpy(Posted 2005) [#4]
if the array's a Global you should be able to get to it from inside a Type...


Grey Alien(Posted 2005) [#5]
If you dson't want the array to be global (easiest) I'd make a pointer to it in the type an initialise it early on.


FlameDuck(Posted 2005) [#6]
I know I could pass the array in as a parameter to my Player methods but I don't like that.
Why not? That sounds like a perfectly suitable solution to me...


z80jim(Posted 2005) [#7]
if the array's a Global you should be able to get to it from inside a Type...

Well my Type is in a separate file so it won't build because it doesn't know the array. I think there is a way to define the array as EXTERN or something. Haven't looked into it. I like my types to be as independent as possible though.

If you dson't want the array to be global (easiest) I'd make a pointer to it in the type an initialise it early on.

That is the way I am tending to go although I haven't worked with BM pointers and such yet. I like it though. Objective C uses that approach a lot.

I know I could pass the array in as a parameter to my Player methods but I don't like that.

Why not? That sounds like a perfectly suitable solution to me...

I only like to pass parameters to a method if I will be calling the method with different values for the parameters. In this case I would be passing the same array every time. The fact that the method will always operate on the same array should be built into the method .


skidracer(Posted 2005) [#8]
I guess what it comes down to is how do I reference a Global variable or object in a Type definition


It sounds more like you are trying to access an array defined in another file and has nothing to do with the fact you are inside a type.

If you are using import switch to include so effectively the compiler sees the whole project as one large file


or if you must use imports, add an import board.bmx line at the top of your player.bmx file. Import does not mean the file get's compiled twice just that the importer gets access to the stuff declared in the import file, eg:

game.bmx
import board.bmx
import player.bmx

player.bmx
import board.bmx

is perfectly ok and now your player.bmx routines can see the global arrays defined in board

the only problem with import vs include is you can not have board.bmx importing player.bmx as this creates a "cyclic depndency"


Qweeg(Posted 2005) [#9]
I think I had a similar issue to this - but it may just be my dodgy coding (actually this is the most likely :) )

I have a user defined type and one of its fields is another user defined type. The types are in different files and all files are Includes in the main game file. Probably easier to see in the code. Here is the first type and in SHIP.BMX:

'Enemy Ship - extends TypShip.  This is abstract so cannot be created itself.
Type typEnemyShip Extends TypShip abstract
	Field tAttackPattern:typAttackPattern
	Field varSplineTime:Float = 0.0
	Field intCurrentSpline:Int = 0
	Field intKillPoints:Int
EndType


'Enemy Spinner - extends TypEnemyShip
Type TypEnemySpinner Extends typEnemyShip
...
... some methods
...
endtype

The enemy spinner has a field of type typAttackPattern. The attack pattern type is in a seperate file ATTACKPATTERN.BMX thus:

Type typAttackPattern

	Field intEnemyCount:Int
	Field intAttackSpeed:Int
	Field tMotionPath:typMotionPath[5]

EndType

Global tSpinnerPattern1:typAttackPattern = New typAttackPattern
tSpinnerPattern1.intAttackSpeed = 100
tSpinnerPattern1.intEnemyCount = 1

For Local i:Int = 0 To 4
	tSpinnerPattern1.tMotionPath[i] = arrSpinnerPath1[i]
Next


In the first file SHIP.BMX 10 enemy spinners are initialised thus:

Global arrEnemySpinner:TypEnemySpinner[10] 'create 10 enemy spinners

For Local i:Int = 0 To 9
	arrEnemySpinner[i] = New TypEnemySpinner
	arrEnemySpinner[i].Initialise()
	arrEnemySpinner[i].tAttackPattern = tSpinnerPattern1
Next

but this fails in the compiler on the line:
arrEnemySpinner[i].tAttackPattern = tSpinnerPattern1

However if I move initialisation of the 10 spinners to the ATTACKPATTERN.BMX file then everything is fine - but it has to be after the line:

Global tSpinnerPattern1:typAttackPattern = New typAttackPattern

I guess it makes sense that you can't assign the SpinnerPattern1 as it has yet to be initialise - so I guess maybe the order that files are included is relevant. It's just that in the past this has never seemed to be a problem - everything just seems to get resolved be the compiler provided I use includes for all the files.

Anyway it's not really a problem - I just moved my declarations out to a seperate file together an everything is hunky dory, just thought it might be relevant.


FlameDuck(Posted 2005) [#10]
I only like to pass parameters to a method if I will be calling the method with different values for the parameters. In this case I would be passing the same array every time. The fact that the method will always operate on the same array should be built into the method .
In that case you need a "Singleton".
Strict

Type SingletonExample Final
	Global myInstance:SingletonExample

	Method New()
		If myInstance <> Null
			RuntimeError "Singleton creation error"
		EndIf
	EndMethod 

	Function getInstance:SingletonExample()
		If myInstance = Null
			myInstance = New SingletonExample
		EndIf
		Return myInstance
	EndFunction
EndType
It's not a "true" singleton (since BlitzMAX doesn't allow for Private constructors, meaning you can (in theory) instantiate more than one Singleton), but it works similar enough to one. To use it,use "SingletonExample.getInstance()" and you'll have access to any public fields or methods included in the singleton object.