Skip to content

Commit 07e9459

Browse files
committed
Searching With Path
1 parent 740a6a9 commit 07e9459

File tree

4 files changed

+125
-19
lines changed

4 files changed

+125
-19
lines changed

src/NodeFinder.hpp

Lines changed: 98 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -36,11 +36,14 @@ c++ has variants
3636
struct 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>
129199
class $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());

src/SelectButtonManager.cpp

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,13 +14,14 @@ SelectButtonManager* SelectButtonManager::get(){
1414
}
1515

1616
void SelectButtonManager::setButtons(){
17+
1718
ButtonActions actions;
1819
actions.selected = MenuCallback([this](CCMenuItem* sender){
1920
/*if("change-button-state"_spr == sender->getID()){
2021
sender->selected();
2122
return;
2223
}*/
23-
if(s_popUp && !sender->hasAncestor(s_popUp.data())){
24+
if(s_popUp && !sender->hasAncestor(s_popUp) && s_popUp->isRunning()){
2425
return;
2526
}
2627

@@ -42,7 +43,7 @@ void SelectButtonManager::setButtons(){
4243
});
4344

4445
actions.activate = MenuCallback([this](CCMenuItem* sender){
45-
if(s_popUp && !sender->hasAncestor(s_popUp)){
46+
if(s_popUp && !sender->hasAncestor(s_popUp) && s_popUp->isRunning()){
4647
return;
4748
}
4849
s_popUp = nullptr;
@@ -135,3 +136,4 @@ void SelectButtonManager::over(float df){
135136
SelectButtonManager::get()->m_currBtn->unselected();
136137
}
137138
}
139+

src/SelectButtonManager.hpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,4 +39,6 @@ class SelectButtonManager : public CCObject {
3939
// }
4040

4141
void over(float df);
42+
43+
4244
};

src/main.cpp

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,27 @@ class $modify(MyMenuLayer, MenuLayer) {
4646
finder->registerAddress("EditLevelLayer", "play-button", "AHHHH", [](CCNode* sender){
4747
HoldButtonManager::get()->registerWithNodeAndBase(
4848
sender,
49-
BASED_BUTTON_CREATE_FUNCTION(CrossButtonSprite, CrossBaseColor::Green, CrossBaseSize::Small)
49+
BASED_BUTTON_CREATE_FUNCTION(CircleButtonSprite, CircleBaseColor::Green, CircleBaseSize::Small)
50+
);
51+
});
52+
53+
std::list<NodeID> path = {
54+
{"GJListLayer", 0},
55+
{"list-view", 0},
56+
{"", 0},
57+
{"", 0},
58+
{"LevelCell", -1},
59+
{"main-layer", 0},
60+
{"main-menu", 0},
61+
{"view-button", 0}
62+
};
63+
64+
NodePath nodePath{path, "LevelBrowserLayer"};
65+
66+
finder->registerAddress("LevelBrowserLayer", nodePath, "2ndbutton", [](CCNode* sender){
67+
HoldButtonManager::get()->registerWithNodeAndBase(
68+
sender,
69+
BASED_BUTTON_CREATE_FUNCTION(CircleButtonSprite, CircleBaseColor::Green, CircleBaseSize::Small)
5070
);
5171
});
5272
}

0 commit comments

Comments
 (0)