Access types and variables from another BMX file

BlitzMax Forums/BlitzMax Beginners Area/Access types and variables from another BMX file

Ravl(Posted 2012) [#1]
Ok, first I have to tell you I just bought BlitzMax after playing a while with the trial version. I used C# until now if someones is interested in that.
I searched the forums about my problem and I read some tutorials but I do not find the response.

Here it is the problem:
- I created a file: hiddenObject.bmx, another one scene.bmx and of course game.bmx which is the main one.

- hiddenObject.bmx has a type (let's say is my class for Hidden Objects) and I want to access objects from my other 'class': "scene.bmx". but I am not able to do that.

In my game.bmx I included "hiddenObject.bmx" and "scene.bmx"

[game.bmx]
Import "hiddenObject.bmx"
Import "scene.bmx"

Global myScene:TScene
Global tmpObjectIndex:Int = 0
Global ho:THiddenObject[]

myScene = New TScene

ho = New THiddenObject[40]
For x = 0 To 39
	ho[x] = New THiddenObject	
Next

myScene.Init()


[hiddenObject.bmx]
Type THiddenObject
	Field Image:TImage
	Field X:Int
    	Field Y:Int
	Field Name:String
	Field ImageName:String

    	Method Draw()

	End Method    
	
	Method Update() 
	
	End Method
End Type


[scene.bmx]
Type TScene
	Field backgroundImage:TImage
		
	
	Method Init()

	End Method
	
	Method LoadScene()
                    'here, I would like to access my ho objects
                     ho[0].Name = "ball"
                    'etc
	End Method		
EndType



Yasha(Posted 2012) [#2]
That's because scene.bmx hasn't imported hiddenObject.bmx, and therefore the definitions are invisible at the point of use (the fact that both TScene and THiddenObject are both made visible to game.bmx is irrelevant to what happens within those files). The simplest way to fix this is to simply Import "hiddenObject.bmx" in scene.bmx.

Names are not visible in BlitzMax without being explicitly made visible (unlike C# where, if I recall correctly, you can just refer to your classes in other files as long as they're all linked together at use-time, since this is handled by some .NET magic later). There are two main ways to do this:

-- the traditional way, using Include: this literally pastes your files together as though they were one file. It has slightly different rules from C's #include, so it's safer to use, but there is no equivalent concept to .h files so everything can only be declared once. This is less easy to organise but very simple as it guarantees everything is in the same namespace.

-- using Import will build each source file as a separate .o file (they form a kind of mini-module when built this way). A module is completely closed and self-contained unless it is Imported: it is invisible to the rest of the program until you ask for it. Import has two other notable quirks:

---- Imports can't be recursive: A cannot depend on B which also imports A again. You need to restructure code designed in this way, because modules have to be able to compile in a linear order (a circular dependency would need to half-compile one file, then the second to finish the first one, then back to the second...).

---- Because Imports are "closed until opened", you can hide part of the contents of one from anything that imports it with Private (this is nothing like C#'s private keyword). Anything appearing below the line with the Private directive will not be visible in files that import your class (if you used Include, this wouldn't have any effect because the compiler sees only one file). You can also use this to create a poor-man's-version of C# private by having an abstract interface class extended by a private implementation class.


...basically, you have to import something in order to use it, and it has to be imported into every place that uses it. Since TScene and THiddenObject are only imported together after they're defined, that doesn't help, and TScene needs its own import of THiddenObject.


Ravl(Posted 2012) [#3]
Thanks man.

For this little test I made something like this:
[game]
Import "scene.bmx"


initScene()
Print ho[0].objectName


[hiddenobject]
Type THiddenObject
	Field objectName:String
	Field objectPosX:Int
	Field objectPosY:Int
End Type


[scene]
Import "hiddenobject.bmx"

Global ho:THiddenObject[]

Function initScene()
	ho = New THiddenObject[40]
	
	For x = 0 To 39
		ho[x] = New THiddenObject	
	Next
	
	ho[0].objectName= "Object 1"
	ho[1].objectName= "Object 2"
	ho[2].objectName= "Object 3"
End Function


This way I can access the ho objects created in the scene file from my game file.

Anyway is this the best practice?

I mean is there a sample or tutorial I should read before starting codding a whole casual game?