Orocos Real-Time Toolkit
2.6.0
|
00001 /*************************************************************************** 00002 tag: The SourceWorks Tue Sep 7 00:55:18 CEST 2010 PartDataSource.hpp 00003 00004 PartDataSource.hpp - 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 #ifndef ORO_PARTDATASOURCE_HPP_ 00040 #define ORO_PARTDATASOURCE_HPP_ 00041 00042 #include "DataSource.hpp" 00043 #include "../types/carray.hpp" 00044 00045 namespace RTT 00046 { 00047 namespace internal 00048 { 00057 template<typename T> 00058 class PartDataSource 00059 : public AssignableDataSource<T> 00060 { 00061 // a reference to a value_t 00062 typename AssignableDataSource<T>::reference_t mref; 00063 // parent data source, for updating after set(). 00064 base::DataSourceBase::shared_ptr mparent; 00065 public: 00066 ~PartDataSource() {} 00067 00068 typedef boost::intrusive_ptr<PartDataSource<T> > shared_ptr; 00069 00076 PartDataSource( typename AssignableDataSource<T>::reference_t ref, 00077 base::DataSourceBase::shared_ptr parent ) 00078 : mref(ref), mparent(parent) 00079 { 00080 } 00081 00082 typename DataSource<T>::result_t get() const 00083 { 00084 return mref; 00085 } 00086 00087 typename DataSource<T>::result_t value() const 00088 { 00089 return mref; 00090 } 00091 00092 void set( typename AssignableDataSource<T>::param_t t ) 00093 { 00094 mref = t; 00095 updated(); 00096 } 00097 00098 typename AssignableDataSource<T>::reference_t set() 00099 { 00100 return mref; 00101 } 00102 00103 typename AssignableDataSource<T>::const_reference_t rvalue() const 00104 { 00105 return mref; 00106 } 00107 00108 void updated() { 00109 mparent->updated(); 00110 } 00111 00112 virtual PartDataSource<T>* clone() const { 00113 return new PartDataSource<T>(mref, mparent); 00114 } 00115 00116 virtual PartDataSource<T>* copy( std::map<const base::DataSourceBase*, base::DataSourceBase*>& replace ) const { 00117 // if somehow a copy exists, return the copy, otherwise return this (see Attribute copy) 00118 if ( replace[this] != 0 ) { 00119 assert ( dynamic_cast<PartDataSource<T>*>( replace[this] ) == static_cast<PartDataSource<T>*>( replace[this] ) ); 00120 return static_cast<PartDataSource<T>*>( replace[this] ); 00121 } 00122 // Both this and mparent are copied, but the part must also copy reference mref from the new parent ! 00123 assert( mparent->getRawPointer() != 0 && "Can't copy part of rvalue datasource."); 00124 if ( mparent->getRawPointer() == 0 ) 00125 throw std::runtime_error("PartDataSource.hpp: Can't copy part of rvalue datasource."); 00126 base::DataSourceBase::shared_ptr mparent_copy = mparent->copy(replace); 00127 // calculate the pointer offset in parent: 00128 int offset = reinterpret_cast<unsigned char*>( &mref ) - reinterpret_cast<unsigned char*>(mparent->getRawPointer()); 00129 // get the pointer to the new parent member: 00130 typename AssignableDataSource<T>::value_t* mref_copy = reinterpret_cast<typename AssignableDataSource<T>::value_t*>( reinterpret_cast<unsigned char*>(mparent_copy->getRawPointer()) + offset ); 00131 replace[this] = new PartDataSource<T>( *mref_copy, mparent_copy ); 00132 // returns copy 00133 return static_cast<PartDataSource<T>*>(replace[this]); 00134 00135 } 00136 }; 00137 00141 template<typename T> 00142 class PartDataSource< types::carray<T> > 00143 : public AssignableDataSource< types::carray<T> > 00144 { 00145 // keeps ref to real array. 00146 types::carray<T> mref; 00147 // parent data source, for updating after set(). 00148 base::DataSourceBase::shared_ptr mparent; 00149 public: 00150 ~PartDataSource() {} 00151 00152 typedef boost::intrusive_ptr<PartDataSource<T> > shared_ptr; 00153 00160 PartDataSource( types::carray<T> ref, 00161 base::DataSourceBase::shared_ptr parent ) 00162 : mref(ref), mparent(parent) 00163 { 00164 } 00165 00166 types::carray<T> get() const 00167 { 00168 return mref; 00169 } 00170 00171 types::carray<T> value() const 00172 { 00173 return mref; 00174 } 00175 00176 void set( typename AssignableDataSource< types::carray<T> >::param_t t ) 00177 { 00178 mref = t; 00179 updated(); 00180 } 00181 00182 types::carray<T>& set() 00183 { 00184 return mref; 00185 } 00186 00187 types::carray<T> const& rvalue() const 00188 { 00189 return mref; 00190 } 00191 00192 void updated() { 00193 mparent->updated(); 00194 } 00195 00196 virtual PartDataSource* clone() const { 00197 return new PartDataSource(mref, mparent); 00198 } 00199 00200 virtual PartDataSource* copy( std::map<const base::DataSourceBase*, base::DataSourceBase*>& replace ) const { 00201 // if somehow a copy exists, return the copy, otherwise return this (see Attribute copy) 00202 if ( replace[this] != 0 ) { 00203 assert ( dynamic_cast<PartDataSource*>( replace[this] ) == static_cast<PartDataSource*>( replace[this] ) ); 00204 return static_cast<PartDataSource*>( replace[this] ); 00205 } 00206 // Both this and mparent are copied, but the part must also copy reference mref from the new parent ! 00207 assert( mparent->getRawPointer() != 0 && "Can't copy part of rvalue datasource."); 00208 if ( mparent->getRawPointer() == 0 ) 00209 throw std::runtime_error("PartDataSource.hpp: Can't copy part of rvalue datasource."); 00210 base::DataSourceBase::shared_ptr mparent_copy = mparent->copy(replace); 00211 // calculate the pointer offset in parent: 00212 int offset = reinterpret_cast<unsigned char*>( mref.address() ) - reinterpret_cast<unsigned char*>(mparent->getRawPointer()); 00213 // get the pointer to the new parent member: 00214 types::carray<T> mref_copy; 00215 mref_copy.init(reinterpret_cast<T*>( reinterpret_cast<unsigned char*>(mparent_copy->getRawPointer()) + offset ), mref.count() ); 00216 replace[this] = new PartDataSource(mref_copy, mparent_copy); 00217 // return copy. 00218 return static_cast<PartDataSource*>(replace[this]); 00219 00220 } 00221 }; 00222 } 00223 } 00224 00225 00226 #endif /* ORO_PARTDATASOURCE_HPP_ */