Correct way to do create a scene?

I have a memory problem that I have tracked down to be the main scene layer being chucked out of memory. If I comment out the “layer->retain()” below I get issues when I navigate away from this scene with “replace” and then want come back with from another scene with “replace” later on.

So should I retain here ? and if so how do I release it? If I drill into the code I can see that addChild adds layer to a standard STL vector which should retain it anyway unless something somewhere is clearing that vector.

Thanks.

Scene* GameScene::createScene() {

    Scene* GameScene::createScene() {
    // 'scene' is an autorelease object
    auto scene = Scene::createWithPhysics();

    // 'layer' is an autorelease object
    auto layer = GameScene::create();
    // Note: this needs a retain for some reason
    layer->retain();

    layer->setPhysicsWorld(scene->getPhysicsWorld());
    scene->addChild(layer);

    return scene;
}
Scene* GameScene::createScene() {
    auto scene = Scene::createWithPhysics();
    auto layer = GameScene::create();
    layer->setPhysicsWorld(scene->getPhysicsWorld());
    scene->addChild(layer);
    return scene;
}

You don’t need to retain, layer in an autorelease object.

Except it’s not retaining the layer on re-entry layer, hence my question?

Does your scene extend cocos2d::Layer like this?:

class GameScene : public cocos2d::Layer {
public:
static cocos2d::Scene* createScene();
CREATE_FUNC(GameScene);
}

Yes, though I inherit from BaseScene so it looks like this:

  class GameScene : public BaseScene
  {
    private:
        typedef BaseScene inherited;
    public:
        static Scene* createScene();
        ...
        CREATE_FUNC(GameScene)
   };

   class BaseScene : public Layer
   {
    private:
	typedef Layer inherited;
    public:
	static Scene* createScene();
        ...
	CREATE_FUNC(BaseScene)
};

All my scenes follow the same pattern, though I only see memory problems with the GameScene.

Must be something I don’t understand?

Ok so you want to make a base scene and then extend it? Let me show you how I did it.
In my case GameScene is a BaseScene, so don’t get confused :slight_smile:

GameScene.h

class GameScene : public cocos2d::Layer
{
public:    
    ~GameScene();
};

nothing explicitly needed in GameScene.cpp.

SafariScene.h:

class SafariScene : public GameScene
{
public:
    static cocos2d::Scene* createScene();
    
    CREATE_FUNC(SafariScene);

    void initScene();
    
    ~SafariScene();
};

SafariScene.cpp:

Scene* SafariScene::createScene() {
    auto scene = Scene::create();
    auto layer = SafariScene::create();
    layer->initScene();
    scene->addChild(layer);
    return scene;
}

void SafariScene::initScene(){
    //this is a custom init called after main init so I can already can have some basic stuff created by GameScene
}

Then I simply create this scene like this:
scene = SafariScene::createScene();

Hope this helps.

Why you guys creating scene from layer, I think, more right way is to just inherit from cocos2d::Scene, and override create macros.

class SafariScene : public cocos2d::Scene
{
public:
    CREATE_FUNC(SafariScene);
};

But in my project i have use another tip. Check out: I make function, which creating cocos objects with variadic arguments, which passes to constructor

/*
	Create autorelease cocos object

	@note T must be derived from cocos2d::Ref
	@param args [optional] arguments that forwards to T constructor
	@return autorelease object
*/
template<typename T, typename... Args>
inline T* make_autorelease( Args&&... args )noexcept {
	static_assert( std::is_base_of<cocos2d::Ref, T>::value,
					"T must be derived from cocos2d::Ref" );

	auto pRet = new( std::nothrow ) T{ std::forward<Args>( args )... };
	if ( pRet && pRet->init( ) ) {
		pRet->autorelease( );
		return pRet;
	} else {
		delete pRet;
		pRet = nullptr;
		return nullptr;
	}
}

And create by this:

make_autorelease<LevelScene>( )

or

    field_.addNode( *make_autorelease<Bomb>( *&field_,
					     2u,
					     currSquare )

i think, it’s more clear C++ way. Because, we don’t use macros at all!!!

Oh yes! I should inherit from Scene not layer! How did I miss that :slight_smile: that’s probably the issue. Also not sure I understand variadic code being the new girl but I will give it a try! Thanks.

You don’t even need Layer now-a-days. It really doesn’t serve a lot of purpose.

Why ? I thought layer was light weight and a scene holds usually layers with other elements as children. I use them quite a bit to avoid having one big scene class.

Replace Layer with Node when you extend