11#pragma once
2+
23#include < Geode/Geode.hpp>
4+ #include " NodePath.hpp"
35
46using namespace geode ::prelude;
57
@@ -22,12 +24,21 @@ Then we call the callback with the found node (or nullptr if not found).
2224This means we need a way to represent the path to a node or just the node ID and search recursively.
2325
2426sum types would be nice
25- c++ has
26- copilot what the fuck why do you hate variants
27+ c++ has variants
2728
2829
2930*/
3031
32+ // using Address = std::variant<NodePath, std::string>;
33+
34+ // Map to map to map of tuples with address should probably have an ID given with it.
35+
36+ struct Address { // give better name;
37+ std::variant<NodePath, std::string> path;
38+ FunctionCallback callback;
39+ }; // don't love the fact that the id is not part of the struct
40+
41+
3142// does this need to be a singleton can it just be a static class?
3243class NodeFinder : public CCObject {
3344 /*
@@ -36,8 +47,10 @@ class NodeFinder : public CCObject{
3647 // static NodeFinder* instance;
3748public:
3849 // std::unordered_map<NodeAddress, std::unordered_set<FunctionCallback>> m_addresses;
39- std::unordered_map<std::string, std::unordered_map<std::string, std::unordered_map<std::string, FunctionCallback>>> m_addresses;
40-
50+ // std::unordered_map<std::string, std::unordered_map<std::string, std::unordered_map<std::string, FunctionCallback>>> m_addresses;
51+ std::unordered_map<std::string, std::unordered_map<std::string, Address>> m_addresses;
52+ // Map from top layer id to map of all (CallbackId, Address) pairs.
53+
4154 static NodeFinder* get (){
4255 static NodeFinder* instance = nullptr ;
4356 if (!instance){
@@ -49,44 +62,66 @@ class NodeFinder : public CCObject{
4962 /*
5063 Anything registered will be run once the node is created in the scene.
5164 */
52- void registerAddress (std::string const & layer, std::string const & nodeID, std::string const & callbackID, FunctionCallback callback){
53- m_addresses[layer][nodeID][callbackID] = callback;
65+ void registerAddress (std::string const & layer, std::string nodeID, std::string const & callbackID, FunctionCallback callback){
66+ m_addresses[layer][callbackID] = Address{nodeID, callback};
67+ }
68+
69+ void registerAddress (std::string const & layer, std::string const & callbackID, NodePath path, FunctionCallback callback){
70+ m_addresses[layer][callbackID] = Address{path, callback};
5471 }
5572
56- bool removeAddress (std::string const & layer, std::string const & nodeID, std::string const & callbackID){
73+ bool removeAddress (std::string const & layer, std::string const & callbackID){
5774 if (!m_addresses.contains (layer)){
5875 log::warn (" {} does not have any registered callbacks." , layer);
5976 return false ;
6077 }
61- if (!m_addresses[layer].contains (nodeID )) {
62- log::warn (" {} does not have any registered callbacks." ,nodeID );
78+ if (!m_addresses[layer].contains (callbackID )) {
79+ log::warn (" {} does not have any registered callbacks." , callbackID );
6380 return false ;
6481 }
65- if (!m_addresses[layer][nodeID].contains (callbackID)) {
66- log::warn (" {} has not been registered." , callbackID);
67- return false ;
68- }
69-
70- m_addresses[layer][nodeID].erase (callbackID);
71-
82+ m_addresses[layer].erase (callbackID);
7283 // if(m_addresses[layer][nodeID][callbackID].empty()) m_addresses[layer][nodeID].erase(callbackID);
73- if (m_addresses[layer][nodeID].empty ()) m_addresses[layer].erase (nodeID); // this may be bad
74- if (m_addresses[layer].empty ()) m_addresses.erase (layer);
84+ if (m_addresses[layer].empty ()) m_addresses.erase (layer); // not sure if this is needed
7585 return true ;
7686 }
7787
7888 bool run (CCNode* topLayer) {
7989 if (!m_addresses.contains (topLayer->getID ())) return false ;
8090 // if(!m_addresses[layer].contains(id)) return;
8191 // auto callbacks = m_addresses[layer][id];
82- for (auto callbacks:m_addresses[topLayer->getID ()]){
83- auto node = topLayer->getChildByIDRecursive (callbacks.first ); // do a thing that saves the path maybe??
84- for (auto callback: callbacks.second ) {
85- callback.second (node);
86- }
92+ for (auto map : m_addresses[topLayer->getID ()]) {
93+ call (map.second , topLayer);
8794 }
8895 return true ;
8996 }
97+
98+ void call (Address const & address, CCNode* topLayer){
99+ if (std::holds_alternative<std::string>(address.path )){ // contains only ID
100+ auto id = std::get<std::string>(address.path );
101+ auto node = topLayer->getChildByIDRecursive (id);
102+ address.callback (node);
103+ return ;
104+ }
105+
106+ auto path = std::get<NodePath>(address.path );
107+ CCNode* curr = topLayer;
108+ for (auto const & nodeID : path.path ){
109+ auto children = curr->getChildrenExt ();
110+ std::string id = nodeID.idName ;
111+ int index = nodeID.idIndex ;
112+
113+ auto filtered = utils::ranges::filter (children, [id](CCNode* sibling){
114+ return sibling->getID () == id;
115+ }); // children that match ID
116+
117+ if (filtered.size () <= index){
118+ log::warn (" Could not find node with ID {} at index {} among its siblings." , id, index);
119+ return ;
120+ }
121+ curr = filtered[index];
122+ }
123+ address.callback (curr);
124+ }
90125
91126};
92127
@@ -104,6 +139,7 @@ class $modify(MyCCLayer, CCLayer) {
104139 }
105140
106141 NodeFinder::get ()->run (this );
142+
107143 // log::debug("This is from the {} with {} children", this->getID(), this->getChildrenCount());
108144 // auto node = typeinfo_cast<CCTransitionFade
109145 /* auto btnManager = HoldButtonManager::get();
0 commit comments