DEVLOG 7 - Code Reorganization
I tried to reorganize the project so that the headers needed by users of the engine are visible, while the internal, and therefore unnecessary, ones are not.
What do I mean?
Let’s say we have a class called A. This class is used by the engine itself, but it can also be used by the developer, for example, to record commands or something similar.
So the developer will include class A in their header or source files so it can be used. But there’s a problem: Header A could include other headers that aren’t necessarily needed by the developer using the engine, thus polluting the headers.
How do I solve this problem?
Since I haven’t used C++ for years, I’ve been researching the problem online for months and found the following solutions:
-
Forward Declaration - This consists of declaring the required class in the header, in this case A, without using the
includedirective, which literally copies the headers included in the file containing the directive. This seems like a good method, but unfortunately the data can’t be variable by value, only by reference or pointer, since the compiler must know at compile time how much memory that specific object occupies.
-
Pimpl Idiom - This involves enclosing or encapsulating the information needed for the internal functioning of A in a class or struct that is hidden from the developer using the engine. This method could work and is almost standard, but personally, I don’t really like the idea of having to create another structure to achieve this goal. It’s more of a workaround, since the language has significant limitations in this regard.
-
C++20 Modules - Modules are a new way of programming in C++ because, among other things, they solve this problem. They also reduce compilation times and avoid separating the code into two separate files (.hpp and .cpp). I tried using them, and from a compiler perspective, they work great (I’m using Clang), but from a Clangd perspective, the situation is quite different:
While the compiler support is fairly mature, Clangd still has several issues; in fact, it reported errors everywhere. I even tried modifying the .clangd file by adding various flags, but the situation didn’t improve.
- There are other methods, such as Fast Pimpl, but they aren’t as flexible.
What I’m looking for is something flexible that generally works in all conditions and doesn’t introduce overhead, which Pimpl Idiom doesn’t.
The final solution was to use namespaces.
All the public headers that must be used by the developer using the engine are in the Eve/ namespace, while the internal headers that shouldn’t be used by the developer are in a namespace called Eve/Internal. If the developer uses these files, it’s their fault; they’re marked as internal to the engine and therefore shouldn’t be used.
I also changed build system and switched to CMake as it is more widespread in the C++ community and this can also give an advantage in the engine configuration section for other users
Comments 0
No comments yet. Be the first!
Sign in to join the conversation.