Proposal for v3.0: remove all the create method out of their class

the static create method makes the node class very difficult to inherit. most of the create method do the same thing. if i want to create a subclass of node, i must override all the create method just to return a right pointer. what’s worse. it sounds like the constructor will be changed to protected. i must write the code again and again, because the type is different.so i suggest to use a template class to manage the create methods. for example:

template 
class CC_CREATOR
{
public:
  static B* create(){
    B *ret = new B();
    if (ret && ret->init())
    {
      ret->autorelease();
      return ret;
    }
    CC_SAFE_DELETE(ret);
      return NULL;
  }
};

than i can move the create method out of ccsprite:

template
class CC_CREATOR
: public CC_CREATOR
{
public:
  static B* createWithTexture(CCTexture2D *pTexture)
  {
    B *pobSprite = new B();
    if (pobSprite && pobSprite->initWithTexture(pTexture))
    {
      pobSprite->autorelease();
      return pobSprite;
    }
    CC_SAFE_DELETE(pobSprite);
    return NULL;
  }

  static B* createWithTexture(CCTexture2D *pTexture, const CCRect& rect)
  {
    B *pobSprite = new B();
    if (pobSprite && pobSprite->initWithTexture(pTexture, rect))
    {
      pobSprite->autorelease();
      return pobSprite;
    }
    CC_SAFE_DELETE(pobSprite);
    return NULL;
  }

  static B* createWithFileName(const char *pszFileName)
  {
    B *pobSprite = new B();
    if (pobSprite && pobSprite->initWithFile(pszFileName))
    {
      pobSprite->autorelease();
      return pobSprite;
    }
    CC_SAFE_DELETE(pobSprite);
    return NULL;
  }

  static B* createWithFileName(const char *pszFileName, const CCRect& rect)
  {
    B *pobSprite = new B();
    if (pobSprite && pobSprite->initWithFile(pszFileName, rect))
    {
      pobSprite->autorelease();
      return pobSprite;
    }
    CC_SAFE_DELETE(pobSprite);
    return NULL;
  }

  static B* createWithSpriteFrame(CCSpriteFrame *pSpriteFrame)
  {
    B *pobSprite = new B();
    if (pSpriteFrame && pobSprite && pobSprite->initWithSpriteFrame(pSpriteFrame))
    {
      pobSprite->autorelease();
      return pobSprite;
    }
    CC_SAFE_DELETE(pobSprite);
    return NULL;
  }

  static B* createWithSpriteFrameName(const char *pszSpriteFrameName)
  {
    CCSpriteFrame *pFrame = CCSpriteFrameCache::sharedSpriteFrameCache()->spriteFrameByName(pszSpriteFrameName);

#if COCOS2D_DEBUG > 0
    char msg[256] = {0};
    sprintf(msg, "Invalid spriteFrameName: %s", pszSpriteFrameName);
    CCAssert(pFrame != NULL, msg);
#endif

    return createWithSpriteFrame(pFrame);
  }  
};

the create method with a file name should not be called create, change to createwithfilename is much better. the create() method is the same with ccnode. if you want to change the logic of create method, override it’s relevant init method. or you can use a new createwithxxx to hande this. now i can easily inherit a node class:

class MySprite : public CCSprite
{

};

template
class CC_CREATOR
: public CC_CREATOR
{
public:
  static B* createWithMy(const char *pszFileName)
  {

  }

};

the subclass of mysprite can also get the right createwithmy method if you defined it’s cc_creator.the new create method can used like this:

  CCSprite* test = CC_CREATOR::create();
  MySprite* test2 = CC_CREATOR::createWithFileName("Icon-57.png");

Yep, constructors are put into protected, so can not use it like this.

you can declare cc_create to be a friend class. there is no reason to forbid creating a node in my own way. that will make the engine too hard to optimise.you can just add a line to avoid this.

  template  friend class CC_CREATOR;

Minggo Zhang wrote:

Yep, constructors are put into protected, so can not use it like this.

That sounds awful to me.

It sounds bad. Why not create subclasses and overload functions if needed?

But back to the topic “remove all the create method out of their class”, I have another thought about fascade pattern (http://en.wikipedia.org/wiki/Facade_pattern) which may be worth to implement

@Tsiannian Simon
Friend property can not be inherited.

@Minggo Zhang
how about this:

#define CREATE_FUNC(__TYPE__) \
  template  friend class CC_CREATOR;