#pragma once #include "../DefaultInclude.hpp" #include "../ui/EnterLayerEvent.hpp" namespace cocos2d { class CCNode; } namespace geode { template concept IDProvidable = std::is_base_of_v && requires { { T::CLASS_NAME } -> std::convertible_to; }; class GEODE_DLL NodeStringIDManager { public: template using Provider = void(GEODE_CALL*)(T*); protected: std::unordered_map> m_providers; public: static NodeStringIDManager* get(); template void registerProvider(void(GEODE_CALL* fun)(T*)) { m_providers.insert({ T::CLASS_NAME, reinterpret_cast>(fun) }); } template bool provide(T* layer) const { if (m_providers.count(T::CLASS_NAME)) { m_providers.at(T::CLASS_NAME)(layer); return true; } return false; } }; template void GEODE_CALL geodeInternalProvideIDsFor(For* cls) { if (cls->getID() != For::CLASS_NAME) { cls->setID(For::CLASS_NAME); cls->provide(); EnterLayerEvent(For::CLASS_NAME, cls).post(); } } } #define $register_ids(Layer_) \ struct GEODE_CONCAT(ProvideIDsFor, Layer_) : public Layer_ {\ void provide();\ };\ $execute {\ NodeStringIDManager::get()->registerProvider(\ &geodeInternalProvideIDsFor\ );\ };\ void GEODE_CONCAT(ProvideIDsFor, Layer_)::provide()