add SceneManager::getPersistedNodes

requested by alphalaneous
This commit is contained in:
matcool 2024-10-30 15:28:41 -03:00
parent a5ace74b75
commit 5009caa391
2 changed files with 31 additions and 21 deletions

View file

@ -3,28 +3,40 @@
#include "../DefaultInclude.hpp" #include "../DefaultInclude.hpp"
#include <cocos2d.h> #include <cocos2d.h>
#include <vector>
namespace cocos2d { #include <span>
class CCArray; #include <Geode/utils/cocos.hpp>
class CCNode;
}
namespace geode { namespace geode {
class GEODE_DLL SceneManager final { class GEODE_DLL SceneManager final {
protected: protected:
cocos2d::CCArray* m_persistedNodes; std::vector<Ref<cocos2d::CCNode>> m_persistedNodes;
cocos2d::CCScene* m_lastScene = nullptr; cocos2d::CCScene* m_lastScene = nullptr;
bool setup();
virtual ~SceneManager(); virtual ~SceneManager();
public: public:
static SceneManager* get(); static SceneManager* get();
/**
* Adds a node to the list of persisted nodes, which are kept across scene changes.
* @param node The node to keep across scenes.
*/
void keepAcrossScenes(cocos2d::CCNode* node); void keepAcrossScenes(cocos2d::CCNode* node);
/**
* Removes a node from the list of persisted nodes.
* @param node The node to forget.
*/
void forget(cocos2d::CCNode* node); void forget(cocos2d::CCNode* node);
/**
* Gets a span of the persisted nodes. To add new nodes to the list, use keepAcrossScenes.
*/
std::span<Ref<cocos2d::CCNode> const> getPersistedNodes();
// This method should only be called by geode itself
// TODO(v4): hide this
void willSwitchToScene(cocos2d::CCScene* scene); void willSwitchToScene(cocos2d::CCScene* scene);
}; };
} }

View file

@ -3,39 +3,37 @@
using namespace geode::prelude; using namespace geode::prelude;
bool SceneManager::setup() {
m_persistedNodes = CCArray::create();
m_persistedNodes->retain();
return true;
}
SceneManager* SceneManager::get() { SceneManager* SceneManager::get() {
static SceneManager* inst = nullptr; static SceneManager* inst = nullptr;
if (!inst) { if (!inst) {
inst = new SceneManager(); inst = new SceneManager();
inst->setup();
} }
return inst; return inst;
} }
SceneManager::~SceneManager() { SceneManager::~SceneManager() {}
m_persistedNodes->release();
}
void SceneManager::keepAcrossScenes(CCNode* node) { void SceneManager::keepAcrossScenes(CCNode* node) {
if (ranges::contains(m_persistedNodes, node)) {
return;
}
if (m_lastScene) { if (m_lastScene) {
node->removeFromParentAndCleanup(false); node->removeFromParentAndCleanup(false);
m_lastScene->addChild(node); m_lastScene->addChild(node);
} }
m_persistedNodes->addObject(node); m_persistedNodes.push_back(node);
} }
void SceneManager::forget(CCNode* node) { void SceneManager::forget(CCNode* node) {
m_persistedNodes->removeObject(node); std::erase(m_persistedNodes, node);
}
std::span<Ref<CCNode> const> SceneManager::getPersistedNodes() {
return m_persistedNodes;
} }
void SceneManager::willSwitchToScene(CCScene* scene) { void SceneManager::willSwitchToScene(CCScene* scene) {
for (auto node : CCArrayExt<CCNode*>(m_persistedNodes)) { for (auto& node : m_persistedNodes) {
// no cleanup in order to keep actions running // no cleanup in order to keep actions running
node->removeFromParentAndCleanup(false); node->removeFromParentAndCleanup(false);
scene->addChild(node); scene->addChild(node);