How to easily purge custom shared instances in cocos2d-x?

654 views Asked by At

I'm doing a small Cocos2d-x project, where I've been inspired by the "singleton" pattern implemented by CCDirector::sharedDirector() method and other shared instances in Cocos2d-x. For instance, in CCDirector.cpp we have

static CCDisplayLinkDirector *s_SharedDirector = NULL;

// ...

CCDirector* CCDirector::sharedDirector(void)
{
    if (!s_SharedDirector)
    {
        s_SharedDirector = new CCDisplayLinkDirector();
        s_SharedDirector->init();
    }

    return s_SharedDirector;
}

void CCDirector::purgeDirector()
{
    // cleanup scheduler
    getScheduler()->unscheduleAll();

    // ...

    // delete CCDirector
    release();
}

The purgeDirector() method purges all the other shared instances, like shared animation cache, shared sprite frame cache and so on - all cast in the same mold. I'd like to do a couple of these myself, like a shared game lobby.

I'd rather not modify CCDirector, since it is definitely subject to change.

Are there any natural place I could put my purge code? Are there possibilities for ringing a callback when cocos2d::CCDirector::sharedDirector()->end() is called or similar? Thanks!

2

There are 2 answers

0
conciliator On BEST ANSWER

After a serious "Douh!" moment, I realized that purging of custom singletons would most easily be placed in the AppDelegate::~AppDelegate() destructor, where AppDelegate is provided in the cocos2d-x Xcode template. So I did.

1
CodeSmile On

Okay, maybe you shouldn't get "inspired" by the Singleton pattern in the first place.

Yes, they're arguably easy to pick up and are tempting but they're also bad design in 99% of all cases (including most of cocos2d's Singletons). Especially since you said "a couple of these".

A Singleton is essentially a container for global variables. Global variables (like Singletons) are something best avoided unless they are completely decoupled from all other classes and serve a single purpose. The NSFileManager being a good example, or the SimpleAudioEngine singleton.

A better design uses a tree-like structure of dependent and contained objects, not unlike the hierarchy of nodes in a scene. In a singleton-less design it becomes trivial to "purge" objects. Once you purge the parent-most object handling a specific task (ie a scene) then all the descendant objects are automatically purged along with it - provided that there aren't any object lifetime (memory management) bugs in the code.

Each class should be responsible for creating and freeing the object it contains. By "contain" I mean instance pointers as member variables or sometimes array or dictionary member variables containing instance pointers.

This article explains C++ object life cycles well and to the point. But it's only a start.