About a month ago, the crunch was over. I suddenly had lots of time. Sadly, I was - and, relatively, still am - kind of burnt. I don't have the energy to pour into anything related to programming. Not as I used to.
I've tried a couple of things to get myself back on track. Developing a 100% managed milk-shape 3D model loader and renderer in managed DirectX was my first shot. The project's gone relatively well, and I enjoyed most of it, but I ran out of energy near the end. That said, I started it while in crunch mode, so my work on it can be least described as lame. Over the course of a month, I was able to put, *cough*, 10-15 hours into the thing. It currently loads and displays text ms3d files just fine. The binary loader is also 90% done. I'll release the code under a BSD license or similar license when I'm done with it, though I wonder when that's going to happen.
The second thing I tried, and with which I'm currently busy, is rejoining the CodeBlocks project as a developer. I did some minor contributions when it was first born, then backed out due to lack of time. Now that I have my time back, I checked it to find out it's gained a lot of complexity. Still, it's a fun experience. Wrestling with C++ is - as counter-productive it is sometimes compared to higher-level languages - lots of fun. [grin]
The compiler used by the CodeBlocks developers is MinGW-gcc. The first thing I'm doing is creating a VS.NET solution + projects to be able to build it with VC++ instead. This isn't as straightforward as it seems.
1. The code uses some constructs that aren't supported by VC++.NET. For example, Variadic macros, a feature that was added in C99. Luckily, this isn't that though.
2. The project is built over a plugin-based architecture. CodeBlocks exposes itself to plugins through what is called an SDK. This SDK contains the major components of the system; the code editor, the project manager, etc. The main executable project is merely a driver for these SDK components.
The problem is that the SDK is built as a DLL, for 2 reasons:
A. Each plugin needs to link to the SDK and so does the executable. Making it shared eliminates redundancy and reduces the final package size.
While point A is clear, point B needs a bit more clarification. We'll get to that after we describe why building the SDK as a DLL is trouble.
The SDK is composed of a multitude of classes. Exporting classes from DLLs, under Visual C++, is a pain. First, you have to mark each with __declspec(dllexport), which is easy. Second, you have to mark EVERY type that's used inside the class (as a data member) with __declspec(dllexport) as well. MinGW-gcc doesn't impose the 2nd constraint, so the developers didn't do the second step while writing CodeBlocks. And with the size of the code base, going through each and every class, tracking the types used internally and marking them is rather unpractical. (Well, more boring than unpractical, but you get the point).
So, my first reaction (back when I joined the project initially) was to simply build the SDK as a static library, not caring about the resulting size overhead of it being linked into multiple plugin DLLs. And I was greeted with a warm crash. Why? This takes us back to point B: Singletonitis.
Singletons are thoroughly (ab)used in the code-base - basically globals under cover. The editor, project manager, application configuration manager, template manager, plugin manager, macros manager, message manager, tools manager and personality manager are all singletons. They're used throughout the SDK, exe and plugin sources. When the SDK was built statically into each plugin, each plugin - being a DLL - got its own instance of the singletons. Thus, each plugin would use un-initialized managers on load/operation, promptly crashing.
The quick solution was to keep the SDK as a static library (for Visual C++ builds), and move the managers to a DLL of their own. The "Managers" DLL simply contains instances of all the singletons, and exposes accessor functions. The already-existing accessor functionality in the SDK was modified to either return directly (for MinGW-gcc builds) or delegate to the DLL (for Visual C++ builds).
Alongside that, I proposed to refactor the whole project, seeing as it wasn't clean enough or well-structured anymore. After all, it's been the work of Yiannis alone till that point, and I doubt he had planned for such a large project when he first started [smile]. Specifically, singletons made the whole project very bulky and inflexible. A single change to one of the singleton managers had diverse effects on the system, and given the hidden dependencies existing due to the use of singletons, such effects were always hard to track and contain. Given that the project back then was far from stable, Yiannis decided to first release a stable version 1.0, and then do a branch where all the refactoring can take place. I left not long after that.
Now that I'm back, it took me a while to wrap my head around these issues and get CodeBlocks to build again, especially since they've removed the VC6 solution due to being obsolete.