How to set a namespace properly in this case?

Started by
14 comments, last by VanillaSnake21 7 years, 10 months ago

I changed the structure of my framework a little, but I would like to use namespaces instead of swapping files. How can I do that?

Current Structure:

WindowsMain.h

--Declares loop functions GameMain, GameUpdate etc

NameOfGame.cpp

---includes WindowsMain.h

--Defines the above functions

So I want to do something like this

WindowsMain.h

--- using namespace NameOfGame

NameOfGame.cpp

---- namespace NameOfGame { ... }

That way I can have multiple games in the same project and just switch the namespace when I want to work on one or the other, as right now I have to pretty much exclude any other game from the project otherwise I get a collision.

By the way when I do the above, I get an error "namespace undefined" even when I create a NameOfGame.h and define the namespace there and then include that file into WindowsMain.h

You didn't come into this world. You came out of it, like a wave from the ocean. You are not a stranger here. -Alan Watts

Advertisement

You can't write a "using" declaration for a namespace the compiler has not yet seen, and by the time the compiler is seeing the preprocessed WindowsMain.h you haven't declared the NameOfGame namespace. Do something to declare that namespace (even if it is empty) above WindowsMain.h:


// NameOfGame.cpp
namespace NameOfGame {};
#include "WindowsMain.h"

That said, this seems like a rather backwards approach as it requires what appears to be a general-purpose, library header (WindowsMain.h) to know something about the game-specific code that is consuming it (NameOfGame). It also requires a very specific and somewhat unorthodox code structure. There are definitely better ways at both the IDE level and the C++ level to handle this.

At the IDE level, you can pretty easily put multiple projects in a single solution (or multiple targets in a workspace, etc etc for whatever terminology your IDE of choice uses). Those multiple projects can share the same common source tree, except for their game-specific parts, or statically link to common functionality built into a library.

At the language level, you can write your main windows driver (main() or WinMain() function) to instantiate and use a Game object that implements a specific interface (e.g., IGame, where all your required entry points from WindowsMain.h are currently defined). Then, even if you don't want to go the route of creating multiple projects in the IDE, you can simply switch the game you run by changing main():


int main (...) {
   AsteroidsGame actualGame; // Change this to BreakoutGame or whatever to switch.
   IGame & game = actualGame; // illustrating interface only, not actually needed.

   return game.run();
}

You get the same result without the brittle nature of the technique you're trying to employ right now. I still don't think it's a great idea (you still have all that other code for other games sitting around and getting potentially rebuilt all the time), although you can alleviate some of the weirdness further with macros and preprocessor tricks. Really should just learn how to use multiple projects at that point though.

By the way when I do the above, I get an error "namespace undefined" even when I create a NameOfGame.h and define the namespace there and then include that file into WindowsMain.h

Why don't you give us a full example, with all of the code to reproduce the problem, instead of insisting something that sounds like it is impossible and making us guess what you did wrong?

@Josh Petrie So this structure in general is not ideal? My original goal was to try to avoid use of classes and encapsulation just as an experiment, so my code is very C-ish. I find that it's very flexible as the engine doesn't have to be in a single class or file but I just rather have a collection of functions that I can use at any point in the framework. That is why I chose not to use interfaces.

<You can't write a "using" declaration for a namespace the compiler has not yet seen, and by the time the compiler is seeing the preprocessed>

I actually do define an empty namespace of the same name in NameOfGame.h then include it into WindowsMain.h, then include WindowsMain.h into NameOfGame.h, in a circle.

My previous structure was a little different but I found this one in a book and thought it would be more straight forward. The previous structure was as follows:

NameOfGame.h

namespace NameOfGame

--Declares all loop functions GameInit, Main, Shutdown etc

NameOfGame.cpp

namespace NameOfGame

--Defines them

WindowsMain.h

--include NameOfGame.h

--using namespace NameOfGame;

That way the game declared and defined all it's functions that would later be called in WinMain. I'm thinking of just switching back to that approach.

PS. How can I share the code tree with multiple projects? (VS 2015)

You didn't come into this world. You came out of it, like a wave from the ocean. You are not a stranger here. -Alan Watts

So this structure in general is not ideal? My original goal was to try to avoid use of classes and encapsulation just as an experiment, so my code is very C-ish. I find that it's very flexible as the engine doesn't have to be in a single class or file but I just rather have a collection of functions that I can use at any point in the framework. That is why I chose not to use interfaces.

It's definitely not ideal. It is very clunky, brittle, and unorthodox.
Further, the ideas that code can be encapsulated, be "C-ish," and be in a single file... those are all completely orthogonal, separate ideas. Nothing about having one implies a requirement to have the other. That said, you can do the same thing in pure C:

struct GameFunctions {
   void (*UpdateFunction)(float);
   void (*RenderFunction)(float);
};


int main () {
   GameFunctions functions;
   functions.UpdateFunction = &AsteroidsGame_Update;
   functions.RenderFunction = &AsteroidsGame_Render;


   while(!done) {
     functions.UpdateFunction(elapsedTime);
     functions.RenderFunction(elapsedTime);
   }
}
or similar.
I still don't really understand your desire to avoid actually putting separate projects in separate projects.

My previous structure was a little different but I found this one in a book and thought it would be more straight forward. The previous structure was as follows:

Namespaces are basically a red herring here. You can do exactly what you are trying to do without using them, and it will be simpler.

PS. How can I share the code tree with multiple projects? (VS 2015)

If you don't have it on GitHub or similar, you could .zip it and upload it.

@JPetrie, thank you for all the suggestions. I'm using function pointers for a few things in the framework already, but I was worried that it might be a little too slow to call a Render or update function through a pointer. Especially since all my rendering is done in software. I'm probably still going to keep it like that since there's no penalty like with other methods.

edit: <I still don't really understand your desire to avoid actually putting separate projects in separate projects. >

Just because it's faster. You said I can just use subversion or something and sync the base code into a new project?

You didn't come into this world. You came out of it, like a wave from the ocean. You are not a stranger here. -Alan Watts

I was worried that it might be a little too slow to call a Render or update function through a pointer. Especially since all my rendering is done in software. I'm probably still going to keep it like that since there's no penalty like with other methods.

If that ever becomes the bottleneck in your code, you're in pretty excellent shape. It will not be an issue.

Just because it's faster. You said I can just use subversion or something and sync the base code into a new project?

What you're doing is unlikely to be faster. It will be, at best, on par. It's likely to actually be slower in practice, if for no other reason than you are compiling the code for all your games all the time, especially when you change common header files.
I'm not suggesting you use Subversion (I mean, you should use version control in general but that's a whole different subject). Rather I'm suggesting you use your IDEs built-in functionality to create different projects and create dependencies between those. Instead of creating one project in which you re-invent your own method of doing what the IDE can already do better.
For example, if you're using Visual Studio, you have a solution file (whatever.sln). A solution file can contain multiple projects (.vcxproj files in the case of C++); you have at least one by default. You're trying to put everything in one .vcxproj and do some unusual preprocessor/lexical/language "tricks" to switch out which game you're building, running and debugging.
But you can also create more .vcxprojs. You can create one .vcxproj per game. On the disk, you organize your code like this:

MySolution.sln
CommonCode/
  - source code for your common utilities, "engine" functionality, et cetera -- anything that would be shared -- goes here
Asteroids/
  - Asteroids.vcxproj
  - source code specific to the Asteroids game goes here.
Breakout/
  - Breakout.vcxproj
  - source code specific to the Breakout game goes here.

Each .vcxproj can reference the common code and include it all. But within VS, you can set any individual project to be the "startup" project, which means that's the one it will build and run when you hit F5 (or whatever).

For bonus points you'll want to actually create a project that builds your common code into a static library and have the rest of game projects link against that, because manually referencing the common source code in every project becomes cumbersome fast.

This gives you a way to have multiple games, sharing code, in one solution and switch between them trivially without having to actually modify any of your code... and it's the way the rest of the world accomplishes this task. Even if you don't use VS almost every IDE worth using has a similar set of functionality.

That would indeed be a much better way. There were so many projects that I had to just manually copy code from one to another. So I can just reference a common code project from any other one? How would I do that? I'm using VS 2015. And is it really faster then what I'm doing now?

A static lib I could build of course, but my core code does change once in a while. That would be something I do once I have everything really stable.

You didn't come into this world. You came out of it, like a wave from the ocean. You are not a stranger here. -Alan Watts

A static lib I could build of course, but my core code does change once in a while. That would be something I do once I have everything really stable.

That's fine; just create a .vxcproj that builds the static library and include that project in your solution as well. You may find this guide on MSDN useful for getting set up.

A static lib I could build of course, but my core code does change once in a while. That would be something I do once I have everything really stable.

That's fine; just create a .vxcproj that builds the static library and include that project in your solution as well. You may find this guide on MSDN useful for getting set up.

I don't want to create a library yet since my code is still changing, but I do plan on doing that once it settles. I just wanted to know how to reference the base code. It's ok I'm looking it up right now though. Thank you for pointing me in the right direction.

edit: Sorry, I could not find any guides on how to do that. I found a thread on stackoverflow, people just say use "Add Existing Item"? Is that the only way? That would be really long a tedious, I have about 5 core files. It really wouldn't make sense for me to change from my current situation. I thought you meant there was a way to pick a .vcxproj file as a whole for reference.

You didn't come into this world. You came out of it, like a wave from the ocean. You are not a stranger here. -Alan Watts

This topic is closed to new replies.

Advertisement