Category Archives: C++

Cocos2d-x a great framework…but idiomatic C++ it is not.

I am not a C++ expert.  But I do know the language reasonably well.  I have some experience with it.  I once upon a time as a young yeoman programmer wrote a scan line rendering system in C++.  I wrote some windows C++ code (MFC yeah!) during an internship at Intel that focused on image processing and sported a pretty nifty UI.  For my Ph.D., I wrote a templated custom MapReduce inspired framework for managing parallel software development on an IBM Blue Gene.  I’ve Valgrinded (or is that Valground?).  That is a reasonable amount of experience, but it is not years of recent professional experience, which I think is needed to consider yourself a C++ expert.

Recently (four months ago) I came back to the C++ world after many years of mostly Java, and was surprised to discover a brand new world called C++11.  This was a world of auto, comprehensionsvariadic templates, and lambda functions the C++ way.  Most importantly, we suddenly have move semantics, which, in addition to giving you a real way to implement a unique_ptr, allow you to finally implement a natural functional model where your functions actually return things rather than modify the pointers to the “output parameters.”

Add to this the flexibility of the C++ template*, and I’m suddenly an excited C++ programmer again.

I brought this new excitement for C++ to a new project I’ve been thinking of embarking on, which is to explore the world of game development frameworks, to the game framework Cocos2d-x. So I’m looking at the Cocos2d code-base, and the first thing I see is the following code:


CCScene* HelloWorld::scene()
{
  CCScene * scene = NULL;
  do
  {
    // scene is an autorelease object
    scene = CCScene::create();
    CC_BREAK_IF(! scene);
    // layer is an autorelease object
    HelloWorld *layer = HelloWorld::create();
    CC_BREAK_IF(! layer);
    // add layer as a child to scene
    scene->addChild(layer);
  } while (0);
  // return the scene
  return scene;
}

And I’m thinking… “An autorelease object, what the hell is that?” Oh the joys of do it yourself memory management. Part of the excitement of coming back to C++ was the standardization of memory management to smart pointers like shared_ptr, weak_ptr, and unique_ptr. It turns out that an autorelease object within the context of Cosos2d-x comes from its history as an Objective-C library, and if I knew the Objective-C memory management model, I might have had a better clue. After a little research, an autorelease object is just an object that gets added to a pool of things that will be released on the framework’s time. The memory management system in the framework has three concepts:

  • create – Create an object
  • release – Release an object
  • autorelease – Don’t free the object now, but put it in the list of things that will be freed when it is safe.

Now, I was immediately disappointed by this development and yet another custom memory model to learn… and one that is not exception and thread safe at that. So I immediately did two things. First, I went out on the internet to see if anyone else complained about this issue (yes, it turns out). In fact, someone had created an extension to the Cocos2d system to make it behave in a smart pointer like way. Another person had created some C++11 syntactic sugar using variadic templates to make Cocos2D object references look and behave like smart pointers. That code is some great stuff to grok.

And the Cocos2D team themselves have recognized the issue and there is a 7 page thread devoted to the topic of whether to port the whole memory system to the C++ standard for the next major (v3) release of cocos2d-x. This thread is an interesting read in an of itself, as it goes over the pitfalls of performance testing and comparing these two fundamentally different methods.

If we look at the preceding code, we also see a second strangeness. What is this?


CC_BREAK_IF(! scene);

It sure looks like something fancy is going on here, doesn’t it. What is this craziness of putting your code inside of a fake loop…do…while(0) and calling this fancy CC_BREAK_IF() macro? Finding the declaration in platform/CCPlatformMacros.h, we see the definition:


#define CC_BREAK_IF(cond)            if(cond) break

Is that really all it is? An if(cond) break? Then why have a macro at all?…it seems to be obfuscating the code for no benefit and providing a barrier to learning. A quick google search indicates a stack overflow question on the same. It sure seems like back programming practice to me.

These things set me off a bit, so I do a quick search for that other great 2d-game framework I will flock to instead…and it turns out that it probably doesn’t exist. Cocos2d-x allows you to write a game once, and then run it across many platforms, all in a fancy open-source package. And its actual feature set is quite rich, including particle systems, easy parallax effects, splines, easing, and 2-D skeletal animation.

The cocos2d-x team is working on version 3 with a more C++ flavor. This presents a choice…do I try for the bleeding edge, and help them test as they go, or do I learn off of the tried and true 2.x? I’ll probable check out the dev branch and see how stable it seems and decide from there.

In the meantime, imagine the previous example as:


std::shared_ptr<Scene> HelloWorld::scene()
{
  auto scene = Scene::create();
  if (scene == nullptr) return nullptr;
  auto layer = HelloWorld::create();
  if (layer == nullptr) return nullptr;
  // add layer as a child to scene
  scene->addChild(layer);
  return scene;
}

Or maybe:


std::shared_ptr<Scene> HelloWorld::scene()
{
  auto scene = Scene::create();
  if (scene == nullptr) throw . . .;
  auto layer = HelloWorld::create();
  if (layer == nullptr) throw . . .;
  // add layer as a child to scene
  scene->addChild(layer);
  return scene;
}

*And reintroduced to the joys of the GNU C++ compiler’s ridiculously cryptic template compilation errors, but that is a topic for another day.