Development Day 6: String Pool

My first language was Java. So C++ does a few things where I said “why is C++ that way”, and there are other things where I saw “Java should’ve been this way”.

Java uses a String pool – for a touch more detail, see this StackOverflow question. The basic idea is that Strings are saved ahead of time in order to save memory.

ChronoWatch does things “by name”, meaning that it certainly would be nice if we used a String pool. But C++ doesn’t provide one.

The following code provides ChronoWatch with a String pool-like implementation. It’s a little slow because it’s a set, but it helps drastically lower the profiler’s memory usage.

#include <string>
#include <set>

using CW_Atom = const char*;

namespace ChronoTools
{
  static std::set<std::string> interned;

  inline CW_Atom atom_str(std::string const& value)
  {
    return ChronoTools::interned.insert(value).first->c_str();
  }
}

Time spent: 5 hours. (Other minor architecture changes were made to allow the string pool to work in the first place.)

Development Day 5: Time versus Timer

Imagine eight classes defined in the same *.cpp file.

… You can stop crying now.

ChronoWatch was thrown into GGEngine’s TimeUtils implementation, including functionality for telling a thread to sleep… and that’s about it.

Later, StopWatch was also added. This meant that the TimeUtils files (which had been renamed to ChronoSupport.cpp and ChronoSupport.hpp) ran at an approximate total of 840 lines of code. Oops. So much for lightweight.

So today, this happened:

DecoupleAgain

Yes, StopWatch no longer ships with ChronoWatch.

Additionally, ChronoWatch’s initial variables have been moved to their own file, so you can freely change them without looking at the actual implementation:ChronoVars

Time spent: 5.5 hours. (Other minor architecture changes were made in preparation for upcoming/additional functionality.)

~Nolan T Yoo

Development Day 2: What’s a Lambda?

As I prepare for the rewrite (however partial), it’s important to get ChronoWatch v1.0 into a readable state. This means:

  • Adding comments
  • Removing lambdas

“What’s a lambda?” you may ask. My answer – and this is why I’m removing lambdas – is “ask someone else”. I initially used them for writing in-place comparison functions. But that’s, to put it lightly, messy. Especially since the lambda I’m most interested in doesn’t actually change in terms of functionality. But because it’s used in-place, it has to be written twice. Here’s ChronoWatch’s sorting with lambdas:

CW_Lambdas

Notice that the left.second > right.second line doesn’t change between the two std::sort calls.

The solution is to write lambda as an actual function, template it, and now remove the lambdas:

CW_NoLambdas

Disclaimer: There are times and places for lambdas – if there weren’t, they never would’ve been passed into the standard. However, in my case they make the code messier, and I don’t have a complete understanding of them anyway.

Time spent: 5.5 hours. (Other efficiency tweaks were made.)

~Nolan T Yoo

Development Day 1: Decoupling from the Engine

ChronoWatch v1.0 suffers (well, suffered) from two primary problems:

  • It’s actually part of the game engine (GGEngine).
  • It ships with its own macros.

It was originally part of the game engine because, while modular, ChronoWatch wasn’t intended to be used in other game engines. The work that must be done here isn’t the prevent the game engine from depending on ChronoWatch but the other way around – prevent ChronoWatch from depending on the game engine. This specifically means:

  • Cease using GGEngine’s exceptions.
  • Cease using GGEngine’s libraries.
  • Cease providing GGEngine with that awkward macro, which shouldn’t be ChronoWatch specific. It is a design decision that – should the macro be desired – the game team should re-implement it.

GGEngine’s exceptions are no longer used as of today.

CW_Exception


Macros were originally used because it appeared to make sense that a macro should exist for quickly getting the “real” current time. This is no longer the case.

Bye-Bye Macro

Time spent: 2.5 hours. (Admittedly, some tweaks were made to GGEngine as well.)

~Nolan T Yoo