@@ -36,11 +36,14 @@ c++ has variants
3636struct Address { // give better name;
3737 std::variant<NodePath, std::string> path;
3838 FunctionCallback callback;
39+
3940}; // don't love the fact that the id is not part of the struct
4041
4142
4243// does this need to be a singleton can it just be a static class?
43- class NodeFinder : public CCObject {
44+ class NodeFinder : public CCNode {
45+ std::unordered_map<std::string, std::list<std::tuple<Ref<CCNode>, Address, Ref<CCNode>>>> m_foundNodes;
46+ // Node to watch, Address, TopLayer
4447 /*
4548 Takes a layer id and topLayer and if topLayer is the layer it returns the node related with the id.
4649 */
@@ -56,6 +59,7 @@ class NodeFinder : public CCObject{
5659 if (!instance){
5760 instance = new NodeFinder;
5861 }
62+ CCScheduler::get ()->scheduleUpdateForTarget (instance, 0 , false );
5963 return instance;
6064 }
6165
@@ -66,7 +70,7 @@ class NodeFinder : public CCObject{
6670 m_addresses[layer][callbackID] = Address{nodeID, callback};
6771 }
6872
69- void registerAddress (std::string const & layer, std::string const & callbackID, NodePath path , FunctionCallback callback){
73+ void registerAddress (std::string const & layer, NodePath path, std::string const & callbackID, FunctionCallback callback){
7074 m_addresses[layer][callbackID] = Address{path, callback};
7175 }
7276
@@ -87,9 +91,11 @@ class NodeFinder : public CCObject{
8791
8892 bool run (CCNode* topLayer) {
8993 if (!m_addresses.contains (topLayer->getID ())) return false ;
94+ log::debug (" Running NodeFinder for layer {}" , topLayer->getID ());
9095 // if(!m_addresses[layer].contains(id)) return;
9196 // auto callbacks = m_addresses[layer][id];
9297 for (auto map : m_addresses[topLayer->getID ()]) {
98+ log::debug (" Calling callback {}" , map.first );
9399 call (map.second , topLayer);
94100 }
95101 return true ;
@@ -100,34 +106,110 @@ class NodeFinder : public CCObject{
100106 auto id = std::get<std::string>(address.path );
101107 auto node = topLayer->getChildByIDRecursive (id);
102108 address.callback (node);
109+
110+ m_foundNodes[topLayer->getID ()].emplace_back (node, address, topLayer);
103111 return ;
104112 }
105113
114+ // change this to recursive at some point
106115 auto path = std::get<NodePath>(address.path );
107116 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 ;
117+
118+ std::list<NodeID>::iterator it = path.path .begin ();
119+ std::list<NodeID>::iterator end = path.path .end ();
120+ auto modifiedNode = callRecursive (it, end, address, curr);
121+ m_foundNodes[topLayer->getID ()].emplace_back (modifiedNode, address, topLayer);
122+ // for(auto const& nodeID : path.path){
123+ // auto children = curr->getChildrenExt();
124+ // std::string id = nodeID.idName;
125+ // int index = nodeID.idIndex;
126+
127+ // auto filtered = utils::ranges::filter(children, [id](CCNode* sibling){
128+ // return sibling->getID() == id;
129+ // }); // children that match ID
130+
131+ // if(filtered.size() <= index){
132+ // log::warn("Could not find node with ID {} at index {} among its siblings.", id, index);
133+ // return;
134+ // }
135+ // curr = filtered[index];
136+ // }
137+ // address.callback(curr);
138+ }
139+
140+ // Returns one of the modified nodes
141+ CCNode* callRecursive (std::list<NodeID>::iterator it, std::list<NodeID>::iterator end, Address address , CCNode* curr){
142+
143+ if (it == end){
144+ address.callback (curr);
145+ return curr;
146+ }
147+ // log::debug("Looking for ID {} at index {}", it->idName, it->idIndex);
148+
149+ auto children = curr->getChildrenExt ();
150+ std::string id = it->idName ;
151+ int index = it->idIndex ;
152+ auto filtered = utils::ranges::filter (children, [id](CCNode* sibling){
153+ return sibling->getID () == id;
154+ }); // children that match ID
155+
156+ if (index < 0 ){
157+ CCNode* lastNode = nullptr ;
158+ for (auto node : filtered){
159+ lastNode = callRecursive (std::next (it), end, address, node);
120160 }
121- curr = filtered[index] ;
161+ return lastNode ;
122162 }
123- address.callback (curr);
163+ if (filtered.size () <= index){
164+ log::warn (" Could not find node with ID {} at index {} among its siblings." , id, index);
165+ return nullptr ;
166+ }
167+
168+ curr = filtered[index];
169+
170+ return callRecursive (std::next (it), end, address, curr);
124171 }
125172
173+ void update (float df){ // i have decided iterators are evil
174+ for (auto const & [topLayerID, nodes] : m_foundNodes){
175+ for (auto it = nodes.begin (); it != nodes.end (); ) {
176+ auto [node, address, top] = *it;
177+ if (node && node->isRunning ()){
178+ ++it;
179+ continue ;
180+ }
181+ it = m_foundNodes[topLayerID].erase (it);
182+ log::debug (" Node {} is no longer running, re-calling callback" , node->getID ());
183+ call (address, top);
184+ }
185+ }
186+ }
187+
188+ void remove (CCNode* topLayer){
189+ if (!m_foundNodes.contains (topLayer->getID ())) return ;
190+ for (auto const & tuple : m_foundNodes[topLayer->getID ()]){
191+ auto [node, address, top] = tuple;
192+ log::debug (" Removing node {} from ones checked" , node->getID ());
193+ }
194+ m_foundNodes.erase (topLayer->getID ());
195+ }
126196};
127197
128198#include < Geode/modify/CCLayer.hpp>
129199class $modify(MyCCLayer, CCLayer) {
130200
201+ void onExit () {// Make priority of everything very late
202+ CCLayer::onExit ();
203+ auto parent = typeinfo_cast<CCScene*>(getParent ());
204+ if (!parent){
205+ return ;
206+ }
207+ if (this ->getID () == " " ){
208+ return ;
209+ }
210+
211+ NodeFinder::get ()->remove (this );
212+ }
131213 void onEnter () {// Make priority of everything very late
132214 CCLayer::onEnter ();
133215 auto parent = typeinfo_cast<CCScene*>(getParent ());
0 commit comments