145 lines
4.0 KiB
Plaintext
145 lines
4.0 KiB
Plaintext
// Copyright (C) 2010, Guy Barrand. All rights reserved.
|
|
// See the file tools.license for terms.
|
|
|
|
//
|
|
// Helper functions to search node(s) in a scene graph.
|
|
//
|
|
|
|
#ifndef tools_sg_search
|
|
#define tools_sg_search
|
|
|
|
#include "search_action"
|
|
#include "node"
|
|
|
|
namespace tools {
|
|
namespace sg {
|
|
|
|
template <class NODE>
|
|
inline NODE* find_first_node_of_class(std::ostream& a_out,node& a_from) {
|
|
search_action action(a_out);
|
|
action.reset();
|
|
action.set_what(search_action::search_node_of_class);
|
|
action.set_stop_at_first(true);
|
|
action.set_class(NODE::s_class());
|
|
a_from.search(action);
|
|
const std::vector<void*>& _objs = action.objs();
|
|
if(_objs.empty()) return 0;
|
|
return (NODE*)_objs[0];
|
|
}
|
|
|
|
inline node* find_first_node_with_class(std::ostream& a_out,node& a_from,const std::string& a_class) {
|
|
search_action action(a_out);
|
|
action.reset();
|
|
action.set_what(search_action::search_node_of_class);
|
|
action.set_stop_at_first(true);
|
|
action.set_class(a_class);
|
|
a_from.search(action);
|
|
const std::vector<void*>& _objs = action.objs();
|
|
if(_objs.empty()) return 0;
|
|
return (node*)_objs[0];
|
|
}
|
|
|
|
}}
|
|
|
|
#include "path"
|
|
|
|
namespace tools {
|
|
namespace sg {
|
|
|
|
inline const path_t& find_path(search_action& a_action,node& a_from,node& a_node,bool a_verbose) {
|
|
a_action.reset();
|
|
a_action.set_what(search_action::search_path_to_node);
|
|
a_action.set_node(&a_node);
|
|
a_from.search(a_action);
|
|
if(!a_action.done()) {
|
|
if(a_verbose) {
|
|
a_action.out() << "tools::sg::find_path :"
|
|
<< " not found node of class " << a_node.s_cls()
|
|
<< " from head node of class " << a_from.s_cls()
|
|
<< std::endl;
|
|
}
|
|
a_action.clear_path();
|
|
return a_action.path();
|
|
}
|
|
if(a_verbose) {
|
|
a_action.out() << "tools::sg::find_path :"
|
|
<< " found node of class " << a_node.s_cls()
|
|
<< " from head node of class " << a_from.s_cls()
|
|
<< std::endl;
|
|
}
|
|
const path_t& path = a_action.path();
|
|
if(path.empty()) {
|
|
if(a_verbose) {
|
|
a_action.out() << "tools::sg::find_path :"
|
|
<< " node has no path !"
|
|
<< std::endl;
|
|
}
|
|
return path;
|
|
}
|
|
if(&a_node!=path[path.size()-1]) {
|
|
a_action.out() << "tools::sg::find_path :"
|
|
<< " node / path tail mismatch !"
|
|
<< " node " << a_node.s_cls()
|
|
<< " tail " << path[path.size()-1]->s_cls()
|
|
<< std::endl;
|
|
a_action.clear_path();
|
|
return a_action.path();
|
|
}
|
|
return path;
|
|
}
|
|
|
|
inline const search_action::paths_t& find_paths(search_action& a_action,node& a_from,const std::string& a_class){
|
|
a_action.reset();
|
|
a_action.set_what(search_action::search_path_to_node_of_class);
|
|
a_action.set_class(a_class);
|
|
a_from.search(a_action);
|
|
return a_action.paths();
|
|
}
|
|
|
|
template <class NODE>
|
|
inline const search_action::paths_t& find_paths(search_action& a_action,node& a_from){
|
|
a_action.reset();
|
|
a_action.set_what(search_action::search_path_to_node_of_class);
|
|
a_action.set_class(NODE::s_class());
|
|
a_from.search(a_action);
|
|
return a_action.paths();
|
|
}
|
|
|
|
template <class NODE>
|
|
inline NODE* find_ancestor(std::ostream& a_out,node& a_from,node& a_node,bool a_verbose) {
|
|
search_action action(a_out);
|
|
return rfind<NODE>(find_path(action,a_from,a_node,a_verbose));
|
|
}
|
|
|
|
template <class CONTAINER>
|
|
inline CONTAINER* find_container(std::ostream& a_out,node& a_from,node& a_node,bool a_verbose) {
|
|
search_action action(a_out);
|
|
return container<CONTAINER>(find_path(action,a_from,a_node,a_verbose));
|
|
}
|
|
|
|
template <class NODE>
|
|
inline NODE* search_node(std::ostream& a_out,node& a_from) {
|
|
search_action sa(a_out);
|
|
const paths_t& paths = find_paths<NODE>(sa,a_from);
|
|
tools_vforcit(path_t,paths,it) {
|
|
NODE* _node = tail<NODE>(*it);
|
|
if(_node) return _node;
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
template <class SELECTABLE>
|
|
inline SELECTABLE* search_selectable(std::ostream& a_out,node& a_from) {
|
|
search_action sa(a_out);
|
|
const paths_t& paths = find_paths<SELECTABLE>(sa,a_from);
|
|
tools_vforcit(path_t,paths,it) {
|
|
SELECTABLE* _node = tail<SELECTABLE>(*it);
|
|
if(_node && _node->border_visible.value()) return _node;
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
}}
|
|
|
|
#endif
|