From: Thomas Geymayer Date: Thu, 29 Nov 2012 23:06:17 +0000 (+0100) Subject: Add method canvas::Group::getElementById X-Git-Url: https://git.mxchange.org/?a=commitdiff_plain;h=8816d0a9ac5c33c7c911714978c91f732dc0bb42;p=simgear.git Add method canvas::Group::getElementById - canvas::Group: New method to get a (possibly nested) child by its id. - nasal::Ghost: Also support recursive parent hashes. --- diff --git a/simgear/canvas/CMakeLists.txt b/simgear/canvas/CMakeLists.txt index c0e7fecd..96a23eaa 100644 --- a/simgear/canvas/CMakeLists.txt +++ b/simgear/canvas/CMakeLists.txt @@ -16,7 +16,6 @@ set(HEADERS ) set(SOURCES - Canvas.cxx Canvas.cxx CanvasEvent.cxx CanvasEventListener.cxx diff --git a/simgear/canvas/elements/CanvasGroup.cxx b/simgear/canvas/elements/CanvasGroup.cxx index fdcc7ae2..07400268 100644 --- a/simgear/canvas/elements/CanvasGroup.cxx +++ b/simgear/canvas/elements/CanvasGroup.cxx @@ -66,11 +66,11 @@ namespace canvas //---------------------------------------------------------------------------- ElementPtr Group::createChild( const std::string& type, - const std::string& name ) + const std::string& id ) { SGPropertyNode* node = _node->addChild(type, 0, false); - if( !name.empty() ) - node->setStringValue("name", name); + if( !id.empty() ) + node->setStringValue("id", id); return getChild(node); } @@ -85,6 +85,32 @@ namespace canvas return child->second; } + //---------------------------------------------------------------------------- + ElementPtr Group::getElementById(const std::string& id) + { + std::vector groups; + + BOOST_FOREACH( ChildList::value_type child, _children ) + { + const ElementPtr& el = child.second; + if( el->getProps()->getStringValue("id") == id ) + return el; + + GroupPtr group = boost::dynamic_pointer_cast(el); + if( group ) + groups.push_back(group); + } + + BOOST_FOREACH( GroupPtr group, groups ) + { + ElementPtr el = group->getElementById(id); + if( el ) + return el; + } + + return ElementPtr(); + } + //---------------------------------------------------------------------------- void Group::update(double dt) { diff --git a/simgear/canvas/elements/CanvasGroup.hxx b/simgear/canvas/elements/CanvasGroup.hxx index 55b031e8..38cb0cc9 100644 --- a/simgear/canvas/elements/CanvasGroup.hxx +++ b/simgear/canvas/elements/CanvasGroup.hxx @@ -44,9 +44,16 @@ namespace canvas virtual ~Group(); ElementPtr createChild( const std::string& type, - const std::string& name = "" ); + const std::string& id = "" ); ElementPtr getChild(const SGPropertyNode* node); + /** + * Get first child with given id (breadth-first search) + * + * @param id Id (value if property node 'id') of element + */ + ElementPtr getElementById(const std::string& id); + virtual void update(double dt); virtual bool traverse(EventVisitor& visitor); diff --git a/simgear/nasal/cppbind/Ghost.hxx b/simgear/nasal/cppbind/Ghost.hxx index cfb6a960..bc32f9ed 100644 --- a/simgear/nasal/cppbind/Ghost.hxx +++ b/simgear/nasal/cppbind/Ghost.hxx @@ -628,7 +628,6 @@ namespace nasal return Ghost::getPtr( naGhost_ptr(me) ); // Now if it is derived from a ghost (hash with ghost in parent vector) - // TODO handle recursive parents else if( naIsHash(me) ) { naRef na_parents = naHash_cget(me, const_cast("parents")); @@ -644,8 +643,9 @@ namespace nasal parent != parents.end(); ++parent ) { - if( isBaseOf(naGhost_type(*parent)) ) - return Ghost::getPtr( naGhost_ptr(*parent) ); + pointer ptr = fromNasal(c, *parent); + if( ptr ) + return ptr; } } diff --git a/simgear/nasal/cppbind/cppbind_test.cxx b/simgear/nasal/cppbind/cppbind_test.cxx index 1ff01973..ef1b4674 100644 --- a/simgear/nasal/cppbind/cppbind_test.cxx +++ b/simgear/nasal/cppbind/cppbind_test.cxx @@ -153,6 +153,13 @@ int main(int argc, char* argv[]) obj.set("parents", parents); VERIFY( Ghost::fromNasal(c, obj.get_naRef()) == d3 ); + // Check recursive parents (aka parent-of-parent) + std::vector parents2; + parents2.push_back(obj.get_naRef()); + Hash derived_obj(c); + derived_obj.set("parents", parents2); + VERIFY( Ghost::fromNasal(c, derived_obj.get_naRef()) == d3 ); + naRef args[] = { to_nasal(c, std::string("test-arg")) };