Orocos Real-Time Toolkit
2.6.0
|
00001 /*************************************************************************** 00002 tag: The SourceWorks Tue Sep 7 00:55:18 CEST 2010 TypeInfo.cpp 00003 00004 TypeInfo.cpp - description 00005 ------------------- 00006 begin : Tue September 07 2010 00007 copyright : (C) 2010 The SourceWorks 00008 email : peter@thesourceworks.com 00009 00010 *************************************************************************** 00011 * This library is free software; you can redistribute it and/or * 00012 * modify it under the terms of the GNU General Public * 00013 * License as published by the Free Software Foundation; * 00014 * version 2 of the License. * 00015 * * 00016 * As a special exception, you may use this file as part of a free * 00017 * software library without restriction. Specifically, if other files * 00018 * instantiate templates or use macros or inline functions from this * 00019 * file, or you compile this file and link it with other files to * 00020 * produce an executable, this file does not by itself cause the * 00021 * resulting executable to be covered by the GNU General Public * 00022 * License. This exception does not however invalidate any other * 00023 * reasons why the executable file might be covered by the GNU General * 00024 * Public License. * 00025 * * 00026 * This library is distributed in the hope that it will be useful, * 00027 * but WITHOUT ANY WARRANTY; without even the implied warranty of * 00028 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * 00029 * Lesser General Public License for more details. * 00030 * * 00031 * You should have received a copy of the GNU General Public * 00032 * License along with this library; if not, write to the Free Software * 00033 * Foundation, Inc., 59 Temple Place, * 00034 * Suite 330, Boston, MA 02111-1307 USA * 00035 * * 00036 ***************************************************************************/ 00037 00038 00039 #include "TypeInfo.hpp" 00040 #include "TypeConstructor.hpp" 00041 #include "../internal/DataSourceTypeInfo.hpp" 00042 #include "TypeTransporter.hpp" 00043 00044 #include "rtt-config.h" 00045 00046 #include "../Logger.hpp" 00047 #include "../base/AttributeBase.hpp" 00048 00049 namespace RTT 00050 { 00051 using namespace std; 00052 using namespace detail; 00053 using namespace internal; 00054 00055 TypeInfo::~TypeInfo() 00056 { 00057 // cleanup transporters 00058 for (Transporters::iterator i = transporters.begin(); i != transporters.end(); ++i) 00059 delete *i; 00060 00061 // cleanup constructors 00062 for (Constructors::iterator i= constructors.begin(); i != constructors.end(); ++i) 00063 delete (*i); 00064 } 00065 00066 std::vector<std::string> TypeInfo::getTypeNames() const 00067 { 00068 return mtypenames; 00069 } 00070 00071 void TypeInfo::addAlias(const std::string& alias) { 00072 // only alias new names: 00073 if ( !alias.empty() && find(mtypenames.begin(), mtypenames.end(), alias) == mtypenames.end() ) 00074 mtypenames.push_back(alias); 00075 } 00076 00077 bool TypeInfo::isType(const std::string& name) { 00078 return (find(mtypenames.begin(), mtypenames.end(), name) != mtypenames.end() ); 00079 } 00080 00081 base::AttributeBase* TypeInfo::buildVariable(std::string name, int hint) const 00082 { 00083 return mdsf ? mdsf->buildVariable(name, hint) : 0; 00084 } 00085 00086 DataSourceBase::shared_ptr TypeInfo::construct(const std::vector<DataSourceBase::shared_ptr>& args) const 00087 { 00088 00089 DataSourceBase::shared_ptr ds; 00090 // build default constructible: 00091 if ( args.empty() ) { 00092 AttributeBase* ab = this->buildVariable("constructor"); 00093 ds = ab->getDataSource(); 00094 delete ab; 00095 return ds; 00096 } 00097 00098 // return same type if equal: 00099 if ( args.size() == 1 && args.front()->getTypeInfo() == this ) 00100 return args.front(); 00101 00102 Constructors::const_iterator i= constructors.begin(); 00103 while (i != constructors.end() ) { 00104 ds = (*i)->build( args ); 00105 if ( ds ) 00106 return ds; 00107 ++i; 00108 } 00109 // returns empty data source to indicate not constructible 00110 return ds; 00111 } 00112 00113 void TypeInfo::addConstructor(TypeConstructor* tb) { 00114 constructors.push_back(tb); 00115 } 00116 00117 DataSourceBase::shared_ptr TypeInfo::convert(DataSourceBase::shared_ptr arg) const 00118 { 00119 DataSourceBase::shared_ptr ds; 00120 Constructors::const_iterator i= constructors.begin(); 00121 if ( arg->getTypeInfo() == this ) 00122 return arg; 00123 //log(Info) << getTypeName() << ": trying to convert from " << arg->getTypeName()<<endlog(); 00124 while (i != constructors.end() ) { 00125 ds = (*i)->convert( arg ); 00126 if ( ds ) { 00127 return ds; 00128 } 00129 ++i; 00130 } 00131 // if no conversion happend, return arg again. 00132 return arg; 00133 } 00134 00135 bool TypeInfo::addProtocol(int protocol_id, TypeTransporter* tt) 00136 { 00137 if (transporters.size() < static_cast<size_t>(protocol_id + 1)) 00138 transporters.resize(protocol_id + 1); 00139 if ( transporters[protocol_id] ) { 00140 log(Debug) << "A protocol with id "<<protocol_id<<" was already added for type "<< getTypeName()<<endlog(); 00141 delete tt; 00142 return false; 00143 } 00144 transporters[protocol_id] = tt; 00145 return true; 00146 } 00147 00148 TypeTransporter* TypeInfo::getProtocol(int protocol_id) const 00149 { 00150 // if the protocol is unknown to this type, return the protocol of the 'unknown type' 00151 // type, which is a fallback such that we won't have to return zero, but can 00152 // gracefully fall-back. 00153 // In order to not endlessly recurse, we check if we aren't the UnknownType ! 00154 if ( protocol_id + 1 > int(transporters.size()) || transporters[protocol_id] == 0) { 00155 if ( DataSourceTypeInfo<UnknownType>::getTypeInfo() != this ) 00156 return DataSourceTypeInfo<UnknownType>::getTypeInfo()->getProtocol( protocol_id ); 00157 else { 00158 log(Warning) << "The protocol with id "<<protocol_id<<" did not register a fall-back handler for unknown types!"<<endlog(); 00159 log(Warning) << " triggered by: "<< getTypeName() << " which does not have a transport."<<endlog(); 00160 return 0; // That transport did not register a fall-back ! 00161 } 00162 } 00163 return transporters[protocol_id]; 00164 } 00165 00166 bool TypeInfo::hasProtocol(int protocol_id) const 00167 { 00168 // if the protocol is unknown to this type, return the protocol of the 'unknown type' 00169 // type, which is a fallback such that we won't have to return zero, but can 00170 // gracefully fall-back. 00171 // In order to not endlessly recurse, we check if we aren't the UnknownType ! 00172 if ( protocol_id + 1 > int(transporters.size()) || transporters[protocol_id] == 0) { 00173 return false; 00174 } 00175 return true; 00176 } 00177 00178 std::vector<int> TypeInfo::getTransportNames() const 00179 { 00180 std::vector<int> ret; 00181 for (size_t i=0; i<transporters.size(); ++i) 00182 { 00183 // dump only protocols with an actual transporter 00184 // NB the transporter does not have a name, so you have to manually 00185 // match the protocol number to an actual transport 00186 if (0 != transporters[i]) 00187 { 00188 ret.push_back(i); 00189 } 00190 } 00191 return ret; 00192 } 00193 00194 }