How to access type from outside of module ???

BlitzMax Forums/BlitzMax Programming/How to access type from outside of module ???

skn3(Posted 2004) [#1]
Man this is really doing my head in now. I am importing a module into "source A". In that imported module, I am importing a bmx file which contains a type.

If I try and reference that type from "source A" it can't find the type.

What I want to know, how is it that the blitz types like TLIST and TPIXMAP, are accessable yet my type isn't. I checked the public/private commands but they don't mention anything regarding types.

I am guessing that a module imported from an imported module is not visible to the original source ? In which case, that sucks a bit.


PowerPC603(Posted 2004) [#2]
I'm hitting myself on the head too with this one.
My guess would be to Import the type also in "source A".

For what I understand, it seems you have to Import that type in each bmx-file that uses it.

I saw this in the "AStar"-sample, which is part of the samples that come with BMax.
There the "CallBack"-type is Imported twice in the same project, once inside the main-program and secondly in another Imported file.

Or use the Include-command (like I do).
But this recompiles all source-code again, even when only 1 file has changed.


Hotcakes(Posted 2004) [#3]
Also, all code will be Included twice, so you're likely to get Type clashes.

Yes, the Import to both sources method PowerPC described is the right one. That let's Max know which sources should see what Types and since the code only gets included once it's very efficient.


FlameDuck(Posted 2004) [#4]
I am guessing that a module imported from an imported module is not visible to the original source ? In which case, that sucks a bit.
Why? If you need this, you need to rethink your design, as you'll have an alarmingly high coupling (thus your code will be much harder to maintain).


Warren(Posted 2004) [#5]
"Rethink your design" is a lousy answer.


FlameDuck(Posted 2004) [#6]
"Rethink your design" is a lousy answer.
Really? They don't use an itterative method at Epic? I'm surprised Epic gets it perfectly right the first time, considering no-one else in the world does.

The other possible answer is "write a wrapper function". But you'll have to rethink your design anyway when you start refactoring.


Bot Builder(Posted 2004) [#7]
For modules you import another module. This will not include the source code twice. When writing modules, it is a way to state your module's dependancies.


skn3(Posted 2004) [#8]
Perhaps if the docs actualy explained the behaviour of the commands. This is what the docs say about import...
Import declarations from a module or source file
(that is it nothing more, nothing less)
If they actualy explained what happens when you import a file, it might be easier for people to understand what is going on.

That brief and totaly unhelpful sentance tells you nothing of what will and will not happen when you use import. (Aside from "import declarations" :P)

Why? If you need this, you need to rethink your design, as you'll have an alarmingly high coupling (thus your code will be much harder to maintain).

You know you dont always have to try and come up with the "smart" answer. It isn't that much of a stretch (without any knowledge of how the import command works in bmax) to expect modules imported from an import to be accessable. Now with the aid of the more helpful answers from people on this thread, I know otherwise.


PowerPC603(Posted 2004) [#9]
So, if you had 10 sourcecode files (file1.bmx, file2.bmx, ...) and each file needs a function that stored in yet another file (file11.bmx), then all 10 files should Import "File11.bmx"?

If your main file (Main.bmx) Imports all 10 files (file1.bmx ... file10.bmx) and doesn't use that function by itself, then there's no need to Import file11.bmx in the main file?

So should this be the correct way of using Import?
Don't mind the simple functions and methods, it's just an example if I get the idea for using Import correctly.
Only 3 files used, instead of 10:
' File1.bmx
	Import "MyPrint.bmx"

	Type Blah1 
		Method New()
			MyPrint("I'm stupid")
		End Method
	End Type

' File2.bmx
	Import "MyPrint.bmx"

	Type Blah2
		Method New()
			MyPrint("I'm crazy")
		End Method
	End Type

' File3.bmx
	Import "MyPrint.bmx"

	Type Blah3
		Method New()
			MyPrint("I'm still an idiot")
		End Method
	End Type

' MyPrint.bmx
	Function MyPrint(TempText$)
		Print TempText$
	End Function

' Main.bmx
	Import "File1.bmx"
	Import "File2.bmx"
	Import "File3.bmx"

	NewBlah1:Blah1 = New Blah1
	NewBlah2:Blah2 = New Blah2
	NewBlah3:Blah3 = New Blah3


Is this correct?

The main file doesn't call the function "MyPrint" directly, so it doesn't have to Import it?


Dreamora(Posted 2004) [#10]
there is some stuff in the sources ( especially the brl modules ) that is nowhere explained in any of the helpfiles:

1) Import imports a precompiled module where you can use everything that is exported

=> How do we actually export anything
that is the point where only the brl sources help you, using a way which I was quite surprised

2) Some C++ programmers here might alreay have spotted it, but you will find "private" and "public" in the brl module sources! private means not exported, while public means exported


public

type test

 method bla()
  print "blabla"
 endmethod
endtype

private

type test1
 method bla()
  print "blablubb"
 endmethod
endtype



haven't tested it as I am not at dev system, but if you include this source test will be accessable while test1 only exist for internal purposes ...


skn3(Posted 2004) [#11]
Types don't work with private/public. Only functions, constants or globals.


Dreamora(Posted 2004) [#12]
Sorry but BlitzMax thinks something else
( put a private in front of the tlist type declaration and recompiled this module -> TList will not known anymore )

the only thing you can not do is use private and public within types, that is forbidden. but outside of types it works as expected with implementation "hidding"

[edit]

just a small sample


this is allowed


private
type test
 field name:string
endtype


while this is not allowed and will lead to a compiler error

type test
 private
  field name:string
 public
  method print_name()
   print name
  endmethod
endtype



Warren(Posted 2004) [#13]
I think he means you can't put public/private inside of a type declaration. I tried it, and you can't. Kind of renders them pointless.


skn3(Posted 2004) [#14]
From the docs..
Private makes a constant, global variable or function only accessible from within the current source file.

Public makes a constant, global variable or function accessible from outside the current source file (default).



Dreamora(Posted 2004) [#15]
Not pointless
but makes life harder than needed, there you're right.

You still can private the type and create an extended type that includes the stuff you want to have exported, so something like a type implementation that is hidden and a type "interface" for other users ( i know, stupid word but couldn't think of another usefull one )


FlameDuck(Posted 2004) [#16]
You know you dont always have to try and come up with the "smart" answer.
You know, I don't.

It isn't that much of a stretch (without any knowledge of how the import command works in bmax) to expect modules imported from an import to be accessable.
Certainly that depends on your background? Anyone familiar with say, Java or C# would not expect this behavior.

What did you think was the main difference between import and include? Or did you think they where interchangable?

I tried it, and you can't. Kind of renders them pointless.
Well not entirely pointless, but certainly much less useful.

You still can private the type and create an extended type that includes the stuff you want to have exported
That's actually quite clever, and might just work...


marksibly(Posted 2004) [#17]
Hey, relax everyone!

I don't fully understand the original question (or maybe the follow-ups have just confused me). Is this to do with developing your own module? eg...

'----- mod/mystuff.mod/mymod.mod/mymod.bmx -----

Module MyStuff.MyMod

Import BRL.Basic 'etc...modules must manually import what they need.

Import "mytypes.bmx"

'----- mod/mystuff.mod/mymod.mod/mytypes.bmx -----

Type MyType
End Type

If so, then yes, any types declared in 'mytypes.bmx' will be visible to any application by default.

However, other modules will need to manually Import MyStuff.MyMod, the same way BRL.Basic is imported above.

If this is totally nothing to do with what your asking, please post some sample code along the lines of the above.

Sorry there is no Public/Private stuff in the language reference. I will add this soon to the module and project management sections. But in the meantime, don't worry about these as everything is 'public' by default.


skn3(Posted 2004) [#18]
Ok this is what I meant. If you imagine the following:
mygame.bmx
- Import Mymods.FantasticMod

Mymods.FantasticMod
- Import "types.bmx"

types.bmx
- type TheBestTypeInTheWorld
- end type

Now imagine that program structure, if you were to try and access TheBestTypeInTheWorld from mygame.bmx, it wouldn't work. At least it hasn't for me.


What did you think was the main difference between import and include? Or did you think they where interchangable?

I thought import would import the file into the parent files context. Just like if you import a texture into a texture pack maker, it will be added to the pack you are working on. Then if you access that texture pack as a whole, the imported texture is available. I understand it now, but it wasn't clear.


Dreamora(Posted 2004) [#19]
Includes: replaces the include line with the source within the file

Import: Links the compiled version of the source with the exe ( especially then needed when you get modules that don't have any source ).

skn3[ac]: Strange your sample should work. Perhaps you did something that prevents the access ... have a similar structure for a tile engine that I started to create and have no problem with accessing the imported types.

ok there is 1 possibility but I don't think you did that: Is there some field or something within your type? if not, it is removed on compile as it is useless.


skn3(Posted 2004) [#20]
Well now it seems to work ...
It was when I was having trouble with the extern problem, so well who knows o_O.


FlameDuck(Posted 2004) [#21]
I understand it now, but it wasn't clear.
I know. Which is why I think it's important to make a more obvious distinction in the documentation.