diff --git a/src/CommandRepository.hpp b/src/CommandRepository.hpp index cf32ebae2..e1b70b77d 100644 --- a/src/CommandRepository.hpp +++ b/src/CommandRepository.hpp @@ -144,6 +144,7 @@ namespace RTT return false; } simplecommands[com->getName()] = com->getCommandImpl()->clone(); + this->add(com->getName(), 0); log(Debug) << "Added Command: '"<< com->getName() <<"'." <second == 0 ) return -1; return i->second->arity(); } /** @@ -520,7 +520,7 @@ namespace RTT ResultT produce( const std::string& name, const PropertyBag& args ) const { typename map_t::const_iterator i = data.find( name ); - if ( i == data.end() ) ORO_THROW_OR_RETURN(name_not_found_exception(), ResultT()); + if ( i == data.end() || i->second == 0) ORO_THROW_OR_RETURN(name_not_found_exception(), ResultT()); std::vector dsVect; std::transform( args.begin(), args.end(), std::back_inserter( dsVect ), @@ -540,7 +540,7 @@ namespace RTT const std::vector& args ) const { typename map_t::const_iterator i = data.find( name ); - if ( i == data.end() ) ORO_THROW_OR_RETURN(name_not_found_exception(), ResultT()); + if ( i == data.end() || i->second == 0) ORO_THROW_OR_RETURN(name_not_found_exception(), ResultT()); return i->second->produce( args ); } @@ -554,7 +554,7 @@ namespace RTT PropertyBag getArgumentSpec( const std::string& name ) const { typename map_t::const_iterator i = data.find( name ); - if ( i == data.end() ) ORO_THROW_OR_RETURN(name_not_found_exception(), PropertyBag()); + if ( i == data.end() || i->second == 0) ORO_THROW_OR_RETURN(name_not_found_exception(), PropertyBag()); return i->second->getArgumentSpec(); } @@ -568,7 +568,7 @@ namespace RTT Descriptions getArgumentList( const std::string& name ) const { typename map_t::const_iterator i = data.find( name ); - if ( i == data.end() ) ORO_THROW_OR_RETURN(name_not_found_exception(), Descriptions()); + if ( i == data.end() || i->second == 0) ORO_THROW_OR_RETURN(name_not_found_exception(), Descriptions()); return i->second->getArgumentList(); } @@ -582,7 +582,7 @@ namespace RTT std::string getResultType( const std::string& name ) const { typename map_t::const_iterator i = data.find( name ); - if ( i == data.end() ) ORO_THROW_OR_RETURN(name_not_found_exception(), std::string()); + if ( i == data.end() || i->second == 0) ORO_THROW_OR_RETURN(name_not_found_exception(), std::string()); return i->second->resultType(); } @@ -596,7 +596,7 @@ namespace RTT std::string getDescription( const std::string& name ) const { typename map_t::const_iterator i = data.find( name ); - if ( i == data.end() ) ORO_THROW_OR_RETURN(name_not_found_exception(), std::string()); + if ( i == data.end() || i->second == 0) ORO_THROW_OR_RETURN(name_not_found_exception(), std::string()); return i->second->description(); } diff --git a/src/Property.hpp b/src/Property.hpp index 45be9b6c6..6a876e28f 100644 --- a/src/Property.hpp +++ b/src/Property.hpp @@ -121,7 +121,7 @@ namespace RTT */ Property( const Property& orig) : PropertyBase(orig.getName(), orig.getDescription()), - _value( orig._value->clone() ) + _value( orig._value ? orig._value->clone() : 0 ) {} /** @@ -131,7 +131,7 @@ namespace RTT * @see ready() to inspect if the creation succeeded. */ Property( PropertyBase* source) - : PropertyBase(source->getName(), source->getDescription()), + : PropertyBase(source ? source->getName() : "", source ? source->getDescription() : ""), _value( source ? AssignableDataSource::narrow(source->getDataSource().get() ) : 0 ) { } @@ -167,14 +167,20 @@ namespace RTT */ Property& operator=( PropertyBase* source ) { - this->setName( source->getName() ); - this->setDescription( source->getDescription() ); - typename AssignableDataSource::shared_ptr vptr - = AssignableDataSource::narrow(source->getDataSource().get() ); - if (vptr) - _value = vptr; - else - _value = detail::BuildType::Value() ; + if ( source ) { + this->setName( source->getName() ); + this->setDescription( source->getDescription() ); + typename AssignableDataSource::shared_ptr vptr + = AssignableDataSource::narrow(source->getDataSource().get() ); + if (vptr) + _value = vptr; + else + _value = detail::BuildType::Value() ; + } else { + this->setName( "" ); + this->setDescription( "" ); + _value = 0; + } return *this; } diff --git a/src/dlib/DLibCommand.hpp b/src/dlib/DLibCommand.hpp index 8f5d331ae..de3eeaa93 100644 --- a/src/dlib/DLibCommand.hpp +++ b/src/dlib/DLibCommand.hpp @@ -76,12 +76,13 @@ namespace RTT { protected: int id; + ProtocolT* protocol; public: /** * The defaults are reset by the constructor. */ DLibCommandImpl() - : id(0) + : id(0), protocol(0) { } @@ -91,36 +92,36 @@ namespace RTT * @return true if ready and succesfully sent. */ bool invoke() { - if (id) - return ProtocolT::sendCommand(id); + if (id && (this->protocol->getCommandStatus(id) & ( DispatchInterface::Ready | DispatchInterface::Done) ) ) + return protocol->sendCommand(id); return false; } template bool invoke( T1 a1 ) { - if (id) - return ProtocolT::sendCommand(id, a1); + if (id && (this->protocol->getCommandStatus(id) & ( DispatchInterface::Ready | DispatchInterface::Done) ) ) + return protocol->sendCommand(id, a1); return false; } template bool invoke( T1 a1, T2 a2 ) { - if (id) - return ProtocolT::sendCommand(id, a1, a2); + if (id && (this->protocol->getCommandStatus(id) & ( DispatchInterface::Ready | DispatchInterface::Done) ) ) + return protocol->sendCommand(id, a1, a2); return false; } template bool invoke( T1 a1, T2 a2, T3 a3 ) { - if (id) - return ProtocolT::sendCommand(id, a1, a2, a3); + if (id && (this->protocol->getCommandStatus(id) & ( DispatchInterface::Ready | DispatchInterface::Done) ) ) + return protocol->sendCommand(id, a1, a2, a3); return false; } template bool invoke( T1 a1, T2 a2, T3 a3, T4 a4 ) { - if (id) - return ProtocolT::sendCommand(id, a1, a2, a4); + if (id && (this->protocol->getCommandStatus(id) & ( DispatchInterface::Ready | DispatchInterface::Done) ) ) + return protocol->sendCommand(id, a1, a2, a3, a4); return false; } }; @@ -147,9 +148,10 @@ namespace RTT * @param component The name of the target component. * @param name The name of this command. */ - DLibCommand(std::string component, std::string name) + DLibCommand(std::string component, std::string name, ProtocolT* _protocol) { - this->id = ProtocolT::getCommandId(component,name); + this->protocol = _protocol; + this->id = this->protocol->getCommandId(component,name); if (this->id == 0) { log(Error) << "Could not find Component '"<id); + unsigned int st = this->protocol->getCommandStatus(this->id); return st == DispatchInterface::Ready || st == DispatchInterface::Done; } @@ -171,27 +173,27 @@ namespace RTT } virtual bool done() const { - return ProtocolT::getCommandStatus(this->id) == DispatchInterface::Done; + return this->protocol->getCommandStatus(this->id) == DispatchInterface::Done; } virtual void reset() { - return ProtocolT::resetCommand(this->id); + return this->protocol->resetCommand(this->id); } virtual bool sent() const { - return ProtocolT::getCommandStatus(this->id) >= DispatchInterface::Sent; + return this->protocol->getCommandStatus(this->id) >= DispatchInterface::Sent; } virtual bool accepted() const { - return ProtocolT::getCommandStatus(this->id) >= DispatchInterface::Accepted; + return this->protocol->getCommandStatus(this->id) >= DispatchInterface::Accepted; } virtual bool executed() const { - return ProtocolT::getCommandStatus(this->id) >= DispatchInterface::Executed; + return this->protocol->getCommandStatus(this->id) >= DispatchInterface::Executed; } virtual bool valid() const { - return getCommandStatus(this->id) >= DispatchInterface::Valid; + return this->protocol->getCommandStatus(this->id) >= DispatchInterface::Valid; } virtual ConditionInterface* createCondition() const diff --git a/tests/property_test.cpp b/tests/property_test.cpp index 0e67ef25d..f3a56afff 100644 --- a/tests/property_test.cpp +++ b/tests/property_test.cpp @@ -220,6 +220,23 @@ void PropertyTest::testInit() Property pui("PUI","", 0 ); Property pi("PI","", 0 ); Property pb("PB","", false ); + + // Test null assignment + PropertyBase* pbase = 0; + Property p2 = pbase; + CPPUNIT_ASSERT( !p2.ready() ); + Property p3; + CPPUNIT_ASSERT( !p3.ready() ); + + p3 = pbase; + CPPUNIT_ASSERT( !p3.ready() ); + + p2 = p3; + CPPUNIT_ASSERT( !p2.ready() ); + + p2 = pi; + CPPUNIT_ASSERT( p2.ready() ); + CPPUNIT_ASSERT(true); } diff --git a/tools/scripts/header_gen.sh b/tools/scripts/header_gen.sh index 67f8a03ec..04522ab4d 100755 --- a/tools/scripts/header_gen.sh +++ b/tools/scripts/header_gen.sh @@ -20,11 +20,30 @@ echo " copyright : (C) "`date +%Y` $1 >> $3.tmp.header echo " email : "$2 >> $3.tmp.header echo " " >> $3.tmp.header echo " ***************************************************************************" >> $3.tmp.header +echo " * This library is free software; you can redistribute it and/or *" >> $3.tmp.header +echo " * modify it under the terms of the GNU General Public *" >> $3.tmp.header +echo " * License as published by the Free Software Foundation; *" >> $3.tmp.header +echo " * version 2 of the License. *" >> $3.tmp.header echo " * *" >> $3.tmp.header -echo " * This program is free software; you can redistribute it and/or modify *" >> $3.tmp.header -echo " * it under the terms of the GNU General Public License as published by *" >> $3.tmp.header -echo " * the Free Software Foundation; either version 2 of the License, or *" >> $3.tmp.header -echo " * (at your option) any later version. *" >> $3.tmp.header +echo " * As a special exception, you may use this file as part of a free *" >> $3.tmp.header +echo " * software library without restriction. Specifically, if other files *" >> $3.tmp.header +echo " * instantiate templates or use macros or inline functions from this *" >> $3.tmp.header +echo " * file, or you compile this file and link it with other files to *" >> $3.tmp.header +echo " * produce an executable, this file does not by itself cause the *" >> $3.tmp.header +echo " * resulting executable to be covered by the GNU General Public *" >> $3.tmp.header +echo " * License. This exception does not however invalidate any other *" >> $3.tmp.header +echo " * reasons why the executable file might be covered by the GNU General *" >> $3.tmp.header +echo " * Public License. *" >> $3.tmp.header +echo " * *" >> $3.tmp.header +echo " * This library is distributed in the hope that it will be useful, *" >> $3.tmp.header +echo " * but WITHOUT ANY WARRANTY; without even the implied warranty of *" >> $3.tmp.header +echo " * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU *" >> $3.tmp.header +echo " * Lesser General Public License for more details. *" >> $3.tmp.header +echo " * *" >> $3.tmp.header +echo " * You should have received a copy of the GNU General Public *" >> $3.tmp.header +echo " * License along with this library; if not, write to the Free Software *" >> $3.tmp.header +echo " * Foundation, Inc., 59 Temple Place, *" >> $3.tmp.header +echo " * Suite 330, Boston, MA 02111-1307 USA *" >> $3.tmp.header echo " * *" >> $3.tmp.header echo " ***************************************************************************/" >> $3.tmp.header echo " " >> $3.tmp.header