GLFW code design

nobody wrote on Monday, August 29, 2005:

Hello all, I’m trying to make a game along with some friends and I’m trying to use GLFW for video and keyboard input. To do this I’m building two different C++ classes, one handles graphics and the other handles input. My problem is that I’m trying to completely logically separate the classes, as well as how the classes actually get input and display graphics.
Unfortunately, this means both classes will need to run GLFWInit() in their constructors and GLFWTerminate() in their destructors. But, whichever one calls GLFWTerminate() will automatically ruin the other class that is using GLFW commands to do its work! Is there any way I can design my code to avoid this problem? I’m hoping to still keep the classes from having to interact with each other, or even from interacting with some sort of global variable if possible.

I would truly appreciate it if any of you could help me!

John

sqweek wrote on Monday, August 29, 2005:

How do you feel about a singleton? Too close to a global variable?
If you’re not sure what it is, a singleton is a class which never has more than one instance. So, every time you call its constructor, you get the same instance.
You can see where I’m going with this - give both the graphics and input classes a ‘glfwFoo’ member, where ‘glfwFoo’ is a Singleton class[1] that keeps track of how many times it has been instantiated, and only calls glfwTerminate() after it has been destructed that many times[2].
But I’ve just covered theory here - of course in C++ (in fact every OO language I know) you don’t choose what is returned from a constructor. One way around that is to make the constructor private and have static member functions like construct() and destruct().
Anyway, I’m sure I’ve glossed over some details but I hope that gives you enough to think about :slight_smile:

If you’re dead set against anything that kind of global though, another option is to make a glfwInterface class that calls glfwInit() on construction and glfwTerminate() on destruction, and then overload the graphics/input classes constructors to be able to accept a glfwInterface instance. That way you could create one glfwInterface object and share it between the two classes… though uh… now that I think of it that would be pretty much the same as just calling glfwInit() prior to instantiating the graphics/input classes and then glfwTerminate() after you’re done with them.

Aaaannyways, hope that gives you a lead. G’luck!

[1] Actually it would probably have to be a pointer to said class
[2] I’ll note that this behaviour sounds very similar to STL’s auto_ptr, but I’ve not actually used it…

kohaistyle wrote on Monday, August 29, 2005:

Additionnally, i don’t see why your keyboard Class has anything to do with initializing/closing GLFW ?

That should be the Video/Init class task …
( you can’t use GLFW keyboard, if GLFW hasn’t been started, but you can use it if no GL window has been started )

nobody wrote on Tuesday, August 30, 2005:

Well, really my idea was like this. I wanted to end up with a video class and an input class where I could exchange the internal workings of either one without having to worry about the other. That way, if I decided to use a different graphics API for the video class I wouldn’t have to do anything at all to the input class. This may seem pretty nitpicky, but I really really like to be able to completely separate what feel like unrelated things.

I appreciate the ideas. I think I’ll take your advice of simply moving the glfwInit and glfwTerminate calls outside of the classes themselves. It makes the incapsulation incomplete, but it is something I can live with. It will only be a small change to delete those calls should I decide to use a different API packages for my classes.

In response to kohaistyle, I was trying to encapsulate the keyboard input class so that I could potentially use it in any project that I ever wanted. Unfortunately, this would make initializing and closing GLFW necessary.

Thank you for the responses! I’m not sure there is a way to perfectly solve this problem perfectly (from an encapsulation perspective anyway). I appreciate the help.

John

peterpp wrote on Tuesday, August 30, 2005:

My solution is:
class KernelServer - interface that provides threading and mutexes,
class GlfwKernelServer - descendant, that implements some methods using GLFW api. Calls glfwInit/Terminate in constructor/destructor.

class GfxServer - interface for video.
class GlfwGfxServer - use GLFW api.

And finally InputServer and GlfwInputServer.

Any kind of kernel server have to be created as first. (Not only the one that use GLFW).

nobody wrote on Thursday, September 01, 2005:

I hadn’t thought of doing that. Interesting design. Thanks for the idea!

John