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.
This commit is contained in:
Thomas Geymayer 2012-11-30 00:06:17 +01:00
parent 229837b14c
commit 8816d0a9ac
5 changed files with 47 additions and 8 deletions

View File

@ -16,7 +16,6 @@ set(HEADERS
) )
set(SOURCES set(SOURCES
Canvas.cxx
Canvas.cxx Canvas.cxx
CanvasEvent.cxx CanvasEvent.cxx
CanvasEventListener.cxx CanvasEventListener.cxx

View File

@ -66,11 +66,11 @@ namespace canvas
//---------------------------------------------------------------------------- //----------------------------------------------------------------------------
ElementPtr Group::createChild( const std::string& type, ElementPtr Group::createChild( const std::string& type,
const std::string& name ) const std::string& id )
{ {
SGPropertyNode* node = _node->addChild(type, 0, false); SGPropertyNode* node = _node->addChild(type, 0, false);
if( !name.empty() ) if( !id.empty() )
node->setStringValue("name", name); node->setStringValue("id", id);
return getChild(node); return getChild(node);
} }
@ -85,6 +85,32 @@ namespace canvas
return child->second; return child->second;
} }
//----------------------------------------------------------------------------
ElementPtr Group::getElementById(const std::string& id)
{
std::vector<GroupPtr> 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<Group>(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) void Group::update(double dt)
{ {

View File

@ -44,9 +44,16 @@ namespace canvas
virtual ~Group(); virtual ~Group();
ElementPtr createChild( const std::string& type, ElementPtr createChild( const std::string& type,
const std::string& name = "" ); const std::string& id = "" );
ElementPtr getChild(const SGPropertyNode* node); 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 void update(double dt);
virtual bool traverse(EventVisitor& visitor); virtual bool traverse(EventVisitor& visitor);

View File

@ -628,7 +628,6 @@ namespace nasal
return Ghost::getPtr( naGhost_ptr(me) ); return Ghost::getPtr( naGhost_ptr(me) );
// Now if it is derived from a ghost (hash with ghost in parent vector) // Now if it is derived from a ghost (hash with ghost in parent vector)
// TODO handle recursive parents
else if( naIsHash(me) ) else if( naIsHash(me) )
{ {
naRef na_parents = naHash_cget(me, const_cast<char*>("parents")); naRef na_parents = naHash_cget(me, const_cast<char*>("parents"));
@ -644,8 +643,9 @@ namespace nasal
parent != parents.end(); parent != parents.end();
++parent ) ++parent )
{ {
if( isBaseOf(naGhost_type(*parent)) ) pointer ptr = fromNasal(c, *parent);
return Ghost::getPtr( naGhost_ptr(*parent) ); if( ptr )
return ptr;
} }
} }

View File

@ -153,6 +153,13 @@ int main(int argc, char* argv[])
obj.set("parents", parents); obj.set("parents", parents);
VERIFY( Ghost<BasePtr>::fromNasal(c, obj.get_naRef()) == d3 ); VERIFY( Ghost<BasePtr>::fromNasal(c, obj.get_naRef()) == d3 );
// Check recursive parents (aka parent-of-parent)
std::vector<naRef> parents2;
parents2.push_back(obj.get_naRef());
Hash derived_obj(c);
derived_obj.set("parents", parents2);
VERIFY( Ghost<BasePtr>::fromNasal(c, derived_obj.get_naRef()) == d3 );
naRef args[] = { naRef args[] = {
to_nasal(c, std::string("test-arg")) to_nasal(c, std::string("test-arg"))
}; };