Moments of Inertia by Rachel Crawford

About     Archive     Categories     Tags     Feed     Projects     Magewinds     Warcry Card Creator    

Object Factory with std::function

The Factory Method pattern! I need it for a thing. I needed to use it but I needed an example, and my search led me to this informative and well-written blog post by Guillaume Chereau. You should read it!

In this post I am going to talk about a little trick that I found very useful when dealing with a lot of subclasses of a single base class. This is typically what we see in video game, where we have a base Object class that represents any kind of object in the game, and then one subclass for each type of object, like the player, enemies, etc.

Guillaume presents this nice way to set up factory functions for subclasses of Object: inherit from an ObjectFactory base class, override the ‘create object’ method, make the constructor register the instance with the global std::map of string type names and ObjectFactory pointers, instantiate a global instance of the ObjectFactory subclass. It’s a nice way of doing things, but it makes you write out so much similar-ish code that he ends up using a macro so he can just write a single line:

// Player.cpp
REGISTER_TYPE(Player)

Macros, in my experience, are a liability for generating mysterious compiler errors and difficult-to-debug code. I don’t like having to rely on them to reduce code duplication or improve readability, so I started thinking of different ways to do it. What I came up with is basically binding a callback function. In my implementation, I’m giving std::function a whirl. Here’s the general idea:

class ObjectFactory {
public:
  Factory(const std::string typeName,
          std::function<Object*(Entity*)> factoryFunc)
  {
    mFactoryFunc = factoryFunc;
    Object::RegisterType(typeName, this);
  }
  Object* CreateObject() {
    return mFactoryFunc();
  }
private:
  std::function<Object*()> mFactoryFunc;
};

class Object {
static std::map<std::string, ObjectFactory*> smFactories;
public:
bool RegisterType(const std::string typeName, ObjectFactory* factory)
{
  smFactories[typeName] = typeFactory;
  return true;
}
Object* CreateObject(const std::string typeName, Object* object) {
  return smFactories[type]->CreateObject(object);
}
};

We don’t need subclasses of ObjectFactory any more, so we don’t need to write as much code. We just instantiate an ObjectFactory, providing a name and a lambda.

// Player.cpp
static ObjectFactory PlayerFactory(
  "Player",
  []()->Object*
  {
    return new Player();
  }
);

It’s not quite as compact as REGISTER_TYPE(Player), but you gain a lot of flexibility this way without having to go to the bother of writing out a big ObjectFactory subclass when you want to do something a bit different. Or compromise morally by using macros. You can bind more than just lambdas to std::functions: you can bind ordinary functions, member functions, any callable target.

One could use an alternative to std::function, as there are tradeoffs to consider, but this works for me, for now. I’m not likely to be using my object factory thousands of times per frame, and I bet the map lookup time outweighs the overhead of the function object call. The Object Factory pattern is not meant to be used in performance-critical situations, but for situations where flexibility and decoupling are desired. At any rate, in this instance it’s a tradeoff between virtual method calls and a slightly different kind of pointer-following. It’s always gonna suck.

As a final note: I’m actually using a std::unordered_map instead of a regular std::map because apparently lookup by key is faster with an unordered_map. Iteration over the values is slower, but that’s not what I’m going to be doing more of.

Quorn Bolognese

I took a whole bunch of photos one time I was making dinner about four months ago, when I still lived in Dundee. All of them have been sitting in a folder on my hard drive since then, untouched and unused, just like any other dumb blog post idea I get halfway through executing and then forget or fail to finish. At long last, however, here it is: the photographically-illustrated recipe I braved the bemused comments of my old flatmate for. “Why are you taking photos of your food?” he asked, as I pointed my mediocre digital camera into a steamy saucepan. I opened my mouth to speak, but couldn’t answer his question. Why do I do these things? So that YOU, dear reader, can learn how to make some reasonably okay faux-Bolognese using Quorn instead of beef? Or because deep inside of me there is a darkness waiting to emerge, a great ink blot from the deepest recesses of my soul, and I believe it is only through filling the void with frivolous ‘creative’ activities that I can prevent it rising to the surface?

To be honest, it’s more of a list of suggestions than a recipe, because I tend to just chuck whatever I happen to have into most things I cook and, usually, it turns out okay. Hopefully the main takeaway from this will be that yeah, you can just make regular old straightforward and wholesome meals using Quorn, that it’s easy to cook with, and usually cheaper than meat.

Read more...

Now Reading

I just finished reading Michael Pye’s The Edge of the World: How the North Sea Made Us Who We Are. This took a bit longer than expected because I lost the book when I was ten pages from the end and couldn’t find it for weeks until it eventually turned up in my mum’s office room1. Weird how things can just vanish and reappear. Anyway, I enjoyed it! It’s a sweeping overview of the growth of trade and interconnectedness in northern Europe and the shifts in culture that came along with it. It goes from the fall of the Roman Empire up to the dawn of the modern era, taking in all kinds of interesting bits like the rise of the Frisian trade network, which spread commerce across the North Sea, and the plague laws, which contributed to the creation of the modern nation-state. There’s too much contained within to talk about here, and usually it’s an engrossing read, but I don’t think I can recommend reading it cover-to-cover the way I did. There’s a little too much fluff, or occasional sidetracks into details which are interesting but slow down the pace a bit. So maybe this book is better suited for dipping in and out of, skimming through sections until something catches your eye.

I’m now reading a book I found on the charity exchange bookshelf at my GP practice. It was a lucky find, and I only noticed it because I was in a queue for the front desk and its colourful binding made it stand out. It’s probably the most esoteric thing I’ve read all year.

Read more...

London Trip (16th-19th June)

Introduction

In June me and Natalie took a trip down to London. I started writing this blog post about it on the way back to Dundee, but completely forgot to finish it because of how much work I had to do. So here it is, a month and a bit late…

Read more...

Handling JSON with json.hpp

json.hpp is a single-header C++ library for handling JSON. It provides easy, clean ways to read from and write to JSON files. It’s written in C++ 11, which has pros (great functionality, trivial to integrate) and cons (won’t work with older compilers or those that don’t fully support C++ 11), but, like, it’s 2016, man. It’s about time to make use of modern C++, rather than just stare wistfully at it from afar.

Reading in JSON from a file is easy. Let’s say you’ve got a file called ‘data.json’ which looks like this:

{
  "info": {
    "name": "Rachel",
    "age": 22,
    "likesBacon": true
  }
}

To read it into a C++ application, you use a std::ifstream to feed the data to an instance of nlohmann::json:

using json = nlohmann::json;
json j;
std::ifstream ifs("data.json");
if (!ifs.is_open()) {
  return false;
}
ifs >> j;
ifs.close();

Next, you operate on j using a variety of syntax options to extract the data you want. json::find is a safe way to search the JSON for a particular attribute (field). Standard square-brackets syntax can be used to extract the value of an attribute, which can itself be another group of attributes. To make accessing the sub-attributes of an attribute easier you can just create another json object, like so:

Person person;

// verify that "info" attribute exists in j
if (j.find("info") != j.end()) {
  json info = j["info"];

  // verify that "name" attribute exists in info
  if (info.find("name") != info.end()) {
    person.name = info["name"]; // person.name == "Rachel"
  }

}

And that’s how simple it is to extract data from a .json file and use it in an application.

Outputting to a file is easy, too. You just fill up a json object and then stream it out to an std::ofstream or something of the sort.

I really like this little library, although I’ve only scratched the surface of what you can do with it here. I wanted to make others aware of it for the next time they need to handle JSON in C++. There’s no standard library support for JSON in C++ like there is in other languages like Python and there’s not really a go-to non-standard option out there, so recommendations are useful. I’m using it to create an import system for Aseprite, which can export .json files to accompany sprite-sheets. More on that later.