Spliting project to multiple files question

If you are a new Irrlicht Engine user, and have a newbie-question, this is the forum for you. You may also post general programming questions here.
Post Reply
lisacvuk
Posts: 21
Joined: Thu Apr 17, 2014 4:50 pm

Spliting project to multiple files question

Post by lisacvuk »

Hello,
I'm working on a FPS game with Irrlicht. I done all of the code in a single file. The problem is that file is getting bigger and now it has >1000 lines of code. I tried to split it to multiple files, no success. I have several questions about that:
1. Should I declare device, smgr and so on at the start of every file?
2. If I shouldn't, what should I do?
3. Is it advisable to split project to multi files?
4. If I use same node in two files, let's say "ammo_box" is in "ammo.cpp" and "functions.cpp", should I declare "ammo_box" in both files?
I'm sorry if this shouldn't be put in Advanced Help. Please move it if so.
Thanks in advance, lisacvuk
thanhle
Posts: 325
Joined: Wed Jun 12, 2013 8:09 am

Re: Spliting project to multiple files question

Post by thanhle »

You could do that.
Or you can use singleton method.
Create a class that contains those global objects and pass that class around.
Or Create a class that contains those global objects and create different method to return them.
CuteAlien
Admin
Posts: 9734
Joined: Mon Mar 06, 2006 2:25 pm
Location: Tübingen, Germany
Contact:

Re: Spliting project to multiple files question

Post by CuteAlien »

OK, topic moved. The problem with that question is that I'm not sure yet which concepts you already know and which are still new to you.

Are you familiar with how header files look like? Meaning do you know how to separate a class or functions into a declaration (which is in the header) and a definition (the cpp file)? That's the first thing you need to understand for splitting up your file. That way each source file only needs to include the headers of other files to work with them. Basically the header contains the names you want to use and the sizes of types (classes, structs) so the compiler can work with them. While the source files contain the implementations. You can take a look at the Demo code in Irrlicht for a rough example, but there are probably better c++ tutorials out there.

The next one is how familiar are you with classes at all - and your knowledge about object oriented programming. Basically (nearly) all your code should go into classes when programming c++. Start for example with an application class. When you have the feeling that class is getting too large and there is stuff that belongs together then move it into an own class. And then you can create an object of that class in your application class. And then those classes get too big split them up again, etc. So you get a tree-like structure with the application class as your root (it can be named any way you like, some prefer to call it application, some call it after the name of your application, or some call it just game or mainclass or whatever...). It's probably a good idea to look at some open-source games to get a feeling for the kind of classes a game typically has. You often get the idea already just by reading over the file-names of another project as most people name their files the same way as they name their classes.

About your specific questions about ammo_box: You always try to have one class which is responsible for some kind of objects. In the case of an ammo_box it might be the class which is responsible for creating a scene maybe (or a level). Then that class has an access functions (examples might be: int getNumAmmoBoxes(); irr::scene::ISceneNode* getAmmoBox(int index); irr::scene::ISceneNode* getAmmoBoxAtPosition(const irr::core::vector3df& pos), void destroyAmmoBox(int index)). Every other part of your code which needs access to your ammo_box work with the access functions of the class responsible for managing your ammo_boxes. To make that possible they just need a pointer to the class responsible for managing those. You have several ways to give them that pointer.

One is over the tree like structure starting from your application class. That often looks something like: myApplication.getLevelManager()->getLevel("levelName")->getNumAmmoBoxes();

Another way is you pass that pointer to the class which will need it. For example the class that needs the ammo is the one responsible for the player. So you have a player object somewhere which is of class Player (again your choice how you name it really) and you know it will need access to your level class a lot. Then you can give your Player class a function like setActiveLevel(Level* activeLevel) which is called each time you switch your active level. That is a little more complicated to handle as you have to ensure it's always updated correct, but has the advantage that your Player class will only need to know about the Level class (aka it only includes that header-file). And the less a class knows about other classes the easier your code will be to read.

There are more solution, which are usually some kind of mix of those above. Like you might have functions in some place which make it just a little simpler to get to other objects. For example your IrrlichtDevice might be hidden deep into some classes. And then you have so long calls always to get to the ISceneManager and you get annoyed by typing it all the time. So you add a getSceneManager function directly in your application class which hides all the longer calls.

I hope this helped a little...
IRC: #irrlicht on irc.libera.chat
Code snippet repository: https://github.com/mzeilfelder/irr-playground-micha
Free racer made with Irrlicht: http://www.irrgheist.com/hcraftsource.htm
Post Reply