Question regarding import, include and multiple files
Home › Forums › TimelineFX Module › Question regarding import, include and multiple files
- This topic has 4 replies, 3 voices, and was last updated 15 years, 5 months ago by thomashaaks.
-
AuthorPosts
-
July 20, 2009 at 8:54 am #3092
thomashaaksParticipantPete,
I know it’s not completely related to the TimelineFX module but while working through the “Making a game from start to finish” tutorial a question raised:I like the approach of having a Game object that contains all required ressources and references to “global” objects (like in the tSpaceWormGame type).
You also pass the Game object into all Create methods so that each game element (like player, enemies) have a reference to their Game object and it’s contained other “global” objects.
But how would I do that if I separate the source code into several files? The SpaceWorm game and the Vaders game all come as one file with several types inside where everything works smoothly.
But if I split the source code into several files (one per type preferrably just like I’m used to in Java) how would I deal with the BlitzMax import/include stuff?
I read that by using “include” all included files are kind of physically inserted so that I end up with one big source file that is passed to the compiler and everything is compiled every time.
Is that just wasting time or are there some other “no go’s” inside?When using “import” files stay in a compiled form if they didn’t change and are not compiled again. But circular references are forbidden (TGame imports TPlayer and TPlayer imports TGame).
But I think with your approach used in the tutorial I would require such a circular reference, right?
How would you deal with that issue?
What’s your preferred approach?Sorry, I’m pretty new to BlitzMax and that question nags me a bit…
July 20, 2009 at 9:42 am #3400
imported_peterigzParticipantI would just use include if you want to separate your types into separate files, that’s exactly what it’s for really. You can use import if the code you’re importing will compile on its own, but if you have types that reference other types and objects/variables in separate files then you will have to use include instead.
The only other thing about include is that you have to make sure you include files in the right order so that every object/variable that an included file needs has already been declared.
I found this thread on blitz forums where Mark Sibly explain cyclic issues best:
Import’s can not be cyclic, so you are correct in saying that 2 types cannot mutually refer to each other via imports.
The solution to this is simple, if initially a little scary: 2 types which mutually refer to each other must appear in the same source file. You can do this either by physically placing the source code for the types into the same source file, or by using Include to produce a logically ‘large’ source file from several smaller source files. Indeed, this is the *real* reason Include is in there!
In my opinion – and I know this will be contentious – not allowing Import cycles is actually a very good thing. It gives you a very clear dependancy tree and allows for perfectly predictable startup/initialization behaviour, as any Imports are *guaranteed* to be fully initialized (ie: their ‘main’ code has run and returned) by the time you’re initializing.
I have also found that it almost forces you into writer cleaner code, making you think about your file/object dependancies a bit more carefully and occasionally prodding you into a better design – but that may be my imagination!
Link to thread here: http://www.blitzbasic.com/Community/posts.php?topic=44108
July 20, 2009 at 10:45 am #3401
thomashaaksParticipant@peterigz wrote:
I would just use include if you want to separate your types into separate files, that’s exactly what it’s for really.
Thanks Pete, I think I will choose that route.
The “circular import” issue sounds to me like a design issue – that Mr Sibly doesn’t want to change.
So the main Game type would include all the other files (in proper order), right? That should solve my multiple files question.
Thanks for your answer and the link!
Cheers,
ThomasJuly 23, 2009 at 10:32 am #3407
redsparkParticipant@thomashaaks wrote:
The “circular import” issue sounds to me like a design issue – that Mr Sibly doesn’t want to change.
It’s actually not possible to change it because imports are pre-compiled. Without both types present in the file that form a cyclical reference, the file wont compile. To change the import to allow it to import uncompiled code, gives you the same thing as an included file. So they are really designed for two different purposes.
If you split your types off into separate files and then include them all into your main file, you should be fine. You can also cheat a bit by making your game object Global. I know it is best to avoid Global variables. However, when something is unique and is going to be referred to throughout your code, a handful of Global variables wont hurt. It also saves popping and pushing them from the function calling stack at every object creation and saves the 4 bytes of pointer memory in every object that points to the Global object.
July 24, 2009 at 11:08 am #3408
thomashaaksParticipant@redspark wrote:
@thomashaaks wrote:
The “circular import” issue sounds to me like a design issue – that Mr Sibly doesn’t want to change.
It’s actually not possible to change it because imports are pre-compiled. Without both types present in the file that form a cyclical reference, the file wont compile. To change the import to allow it to import uncompiled code, gives you the same thing as an included file. So they are really designed for two different purposes.
Hi Redspark, first thanks a lot for the workaround suggestions – that will surely help me.
The suggestion of the Global game object isn’t cheating so much – using OO design patterns you call that a Singleton which is indeed nothing else but a global variable accessible from everywhere likeMyGlobalClass.GetSingleton();
😉
But still I’m convinced that technically there would be a way around the “circular import” problem – other languages like Java, C# or C++ handle those issues fine. It would just require a multi-pass compiler/linker IMHO. To solve this problem it would surely imply quite some work from BRL/Mark Sibly. But anyway, this is not to be solved by us.
Thanks again for your helpful answer – my question is solved 😀
Cheers,
Thomas -
AuthorPosts
You must be logged in to reply to this topic.