Questions on the Dagon source code

Reading through the Dagon source code, I noticed a few things, and have a few questions as to why they’re done a certain way. Please note, this post is not meant to come across as a ‘what the fuck are you doing this for?’ kind of post, I am merely asking these questions for the purpose of improving my own abilities when it comes to programming projects, and possibly inciting discussion on how Dagon’s source code could possibly be improved.

  1. Why do you provide project files for XCode and Visual Studio, and make files?

Wouldn’t using a tool to generate these for you (such as CMake) be much better for the project as a whole? You wouldn’t need to maintain platform-specific project files any more, and should somebody want to build Dagon via a different build system or IDE (such as Eclipse on Windows), they would be able to just generate the files for that themselves, instead of you having to provide the files in the project.

  1. Instead of writing platform-specific code for windowing, OpenGL context creation, input handling, and threading, why not use other cross-platform libraries?

For example, creating display windows, OpenGL contexts, and input event handling could be done by libraries such as GLFW.
Cross-platform threading is part of the C++11 standard now, is it possible to use that instead of platform-specific threading code?
With this in mind, it’s possible to have one set of code handle everything, instead of implementing things specifically for a platform. This reduces the amount of code you have to write (and therefore maintain), and reduces the probability of subtle nuances happening between platforms.

  1. Storing pointers instead of ‘references’.

I’ve noticed that instead of using references in classes, classes have a pointer variable, which is then set to the address of a singleton’s instance.

e.g. for DGScript:

...
class DGScript {
    DGConfig* config;
    DGLog* log;
    DGSystem* system;
...
DGScript::DGScript() {
    log = &DGLog::getInstance();
    config = &DGConfig::getInstance();
    system = &DGSystem::getInstance();
...

Would it be better to instead use references? e.g.:

...
class DGScript {
    DGConfig& config;
    DGLog& log;
    DGSystem& system;
...
DGScript::DGScript() :
    log(DGLog::getInstance()),
    config(DGConfig::getInstance()),
    system(DGSystem::getInstance())
{
...

Internally, they’re still pointers, but I think it better conveys the message that the reference will be given during construction, instead of just being an address to an object, and that the class does not own or create the object, but merely uses an existing one.

  1. Not using initializer lists in class constructors

It seems as though class constructors in Dagon do not use initializer lists, and instead sets values during the body of the class constructor.
Is there a reason for setting these values during the body of the constructor?
Is this also related to point #3 in some form?

  1. Not using namespaces

Instead of using the built-in namespace support, Dagon prepends classes with ‘DG’.
Would it instead be better to use a DG namespace? At that point, the DG prepend becomes optional, and stops things filling up the default namespace.

Again this post is not meant as a personal attack on the Dagon project, I would just like to hear educated reasons for why things have been done as they are in Dagon, from professional game devs.

Hi Phazon. Welcome to the forums!

I can’t answer your questions. Agustin is usually really quick to answer, but right now he’s in the final hours of his Kickstarter campaign. It might be tomorrow before he’s recovered enough to answer. :stuck_out_tongue:

Hey there! Thanks for the interest on the engine!

Like Imari said, I’m just leaving behind an incredibly hectic period, and only now have a clear (enough) head to address this post.

First, let me say this: I appreciate ANY kind of input, so always feel free to speak up your mind. One of the reasons I’m open sourcing Dagon is precisely to improve its code and make it better.

To understand why some things are they way they are, some background: until now the engine has been 99% coded by myself alone. I’m no way a guru programmer but I’m very organized and like to produce clean code. I’m not a big fan of C++. In fact, Dagon was originally coded in pure C, and then I migrated to C++ for the sake of maintainability (C was becoming too much of a mess). That is why I’m not using all the features of C++, which can become just as messy. I wanted to strike a balance between C/C++.

Now, for the specific inquiries:

  1. OS X is the main platform of development I’m using and I like the way I can organize the project with Xcode. I attempted to use CMake at one point but I’m not familiar enough with it. I’d definitely appreciate such a contribution as I want to achieve flawless compiling across all systems.

  2. Since we need very few interaction with the OS (launching an OpenGL window and getting input is enough to get us started), I decided against using such libraries. SFML is unstable on Mac and SDL can be annoying for my taste. But I’ll look into GLFW and I was unaware of the C++11 standard. This is a very good suggestion!

  3. You’re right, it’s more elegant even.

  4. No reason in particular, it was a singleton model I decided to use. You’re also right, it would make more sense to initialize such values on the header.

  5. This one in particular came from my experience while programming Objective-C, the way Apple names classes with ‘NS’ at the beginning. I like that and, since I’m not such a big fan of namespaces, I found it to be a nice solution.

So, in short, it’s been a question of style. But, again, I’m open to every suggestion and I wouldn’t mind to refactor the code if developers find a better solution. I’m just wary of C++ and have seen projects becoming a disaster to maintain because its features were overused. I’d like to keep Dagon “clean” and elegant, in the way C has always been. And I confess drawing inspiration from Objective-C quite a bit. If it wasn’t for portability issues, that would have been my language of choice.

Anyway, awesome analysis. I’m certainly hoping for more stuff like this in the future :nod:

Thanks for the reply!

  1. Fair point - if you’ve got some time, I’d recommend looking into CMake (if nobody contributes working CMake configuration files, that is). The initial hurdle will probably help the maintainability of the project in the long run.

  2. When SFML actually goes stable (which will hopefully be soon!), using the sfml-window (which depends on sfml-system) sub-libraries could be a good alternative to rolling your own stuff. SFML has a very clean and simple API, in my opinion.
    If you’re willing to intermingle C-style code with C++, though, glfw will also be a good option. You’ll still need to use GLEW, though, as neither provide OpenGL function prototypes and initialisation.

C++11’s threading API should hopefully be properly provided by most compilers by now, but alternatives exist if you have to stick with C++03. TinyThread++ (http://tinythreadpp.bitsnbites.eu/) comes to mind.

3/4. Personally, I’d avoid defining class functions/constructors in headers, as it’s normally in good-taste to keep the declarations and definitions separate, in-case you need to do anything that would end up in circular dependencies.

Also, as for singletons, I’d recommend maybe considering using the service locator model (http://gameprogrammingpatterns.com/service-locator.html), as you then have control over when the ‘singleton’ objects are created and destroyed - global class instances can sometimes lead to hard-to-track bugs because of the ambiguous construction and destruction order.

  1. May I ask why you’re not a huge fan on namespaces? Are there some problems introduced when using them, or is this harking back to your usage of C/Objective-C and their lack of namespaces?

C++ shouldn’t really get too difficult to maintain if you use good standards and design patterns which help with maintainability, and try and stay out of C++ template territory outside of the STL (due to them being a nightmare to debug). Generally, when using a language, it’s good to use the ‘isms’ of that language. You wouldn’t use nothing but C in objective-C for example, you’d try and embrace what Objective-C provides as much as you can if you can help it.
C++ code can still be clean and elegant - but that can be said of any language, really.

May I also ask why you dislike C++, yet like Objective-C?

Again, thanks for the reply :slight_smile:. I always like to hear the opinions of other programmers!

And thanks again for the thoughtful comments! :slight_smile:

Let’s see…

  1. Yes, CMake would be my first choice. Feels robust enough and less annoying than Makefile.

  2. Also, SMFL would be my choice instead of SDL. I like the way it’s organized and designed. But for the sake of simplicity, GLFW looks like an interesting alternative. I’m already using GLEW in the engine.

3/4. Will look into this, thanks!

  1. In my experience, when you start using namespaces you eventually lose track of which namespace you should be using. Also, it has a negative impact on readability unless you’re 100% sure of what you’re looking. That is, when you see the short DG prefix, you always know it’s a Dagon function. But, again, this is a pet peeve of mine. I’m used to that approach in C and it doesn’t feel worthwhile enough to bring this feature from C++.

As for Objective-C vs C++, I think Obj-C brings just the right features to make C object oriented. It retains the elegancy and simplicity of the language. On the other hand, C++ is awfully over engineered: templates, operator overload, namespaces, etc. It feels like too much and and overall “dirtier” language than Obj-C.

hey please excuse me if i’m being blind!

question 1: is there a specific reason why dagon uses libglew 1.6 instead of the latest v
(don’t answer if its because i takes a long time to overhaul code; i program i understand)

question 3: why have support for two os specific IDEs when you could just support one crossplatform IDE

Check out this new post for an exhaustive update: http://forum.senscape.net/index.php/topic,1857.0.html

In short, that’s the GLEW version I compiled but there’s no particular reason. I’m now compiling against 1.9 with no problems. In any case, I don’t think I’ll be providing binaries in the project any longer.

Also, I’m switching to Premake for building Dagon :slight_smile: