Collage
0.6.1
|
00001 00002 /* Copyright (c) 2012, Daniel Nachbaur <danielnachbaur@gmail.com> 00003 * 00004 * This library is free software; you can redistribute it and/or modify it under 00005 * the terms of the GNU Lesser General Public License version 2.1 as published 00006 * by the Free Software Foundation. 00007 * 00008 * This library is distributed in the hope that it will be useful, but WITHOUT 00009 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS 00010 * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more 00011 * details. 00012 * 00013 * You should have received a copy of the GNU Lesser General Public License 00014 * along with this library; if not, write to the Free Software Foundation, Inc., 00015 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 00016 */ 00017 00018 #include <co/object.h> 00019 #include <co/objectVersion.h> 00020 00021 namespace co 00022 { 00026 template<> 00027 inline DataIStream& DataIStream::operator >> ( std::string& str ) 00028 { 00029 uint64_t nElems = 0; 00030 *this >> nElems; 00031 LBASSERTINFO( nElems <= getRemainingBufferSize(), 00032 nElems << " > " << getRemainingBufferSize( )); 00033 if( nElems == 0 ) 00034 str.clear(); 00035 else 00036 str.assign( static_cast< const char* >( getRemainingBuffer(nElems)), 00037 size_t( nElems )); 00038 return *this; 00039 } 00040 00042 template<> inline DataIStream& DataIStream::operator >> ( Object*& object ) 00043 { 00044 ObjectVersion data; 00045 *this >> data; 00046 LBASSERT( object->getID() == data.identifier ); 00047 object->sync( data.version ); 00048 return *this; 00049 } 00050 00052 template< class T > inline DataIStream& 00053 DataIStream::operator >> ( lunchbox::Buffer< T >& buffer ) 00054 { 00055 uint64_t nElems = 0; 00056 *this >> nElems; 00057 LBASSERTINFO( nElems < LB_BIT48, 00058 "Out-of-sync co::DataIStream: " << nElems << " elements?" ); 00059 buffer.resize( nElems ); 00060 return *this >> Array< T >( buffer.getData(), nElems ); 00061 } 00062 00063 00064 template< class T > inline DataIStream& 00065 DataIStream::operator >> ( std::vector< T >& value ) 00066 { 00067 uint64_t nElems = 0; 00068 *this >> nElems; 00069 value.resize( nElems ); 00070 for( uint64_t i = 0; i < nElems; ++i ) 00071 *this >> value[i]; 00072 return *this; 00073 } 00074 00075 template< class K, class V > inline DataIStream& 00076 DataIStream::operator >> ( std::map< K, V >& map ) 00077 { 00078 map.clear(); 00079 uint64_t nElems = 0; 00080 *this >> nElems; 00081 for( uint64_t i = 0; i < nElems; ++i ) 00082 { 00083 typename std::map< K, V >::key_type key; 00084 typename std::map< K, V >::mapped_type value; 00085 *this >> key >> value; 00086 map.insert( std::make_pair( key, value )); 00087 } 00088 return *this; 00089 } 00090 00091 template< class T > inline DataIStream& 00092 DataIStream::operator >> ( std::set< T >& value ) 00093 { 00094 value.clear(); 00095 uint64_t nElems = 0; 00096 *this >> nElems; 00097 for( uint64_t i = 0; i < nElems; ++i ) 00098 { 00099 T item; 00100 *this >> item; 00101 value.insert( item ); 00102 } 00103 return *this; 00104 } 00105 00106 template< class K, class V > inline DataIStream& 00107 DataIStream::operator >> ( stde::hash_map< K, V >& map ) 00108 { 00109 map.clear(); 00110 uint64_t nElems = 0; 00111 *this >> nElems; 00112 for( uint64_t i = 0; i < nElems; ++i ) 00113 { 00114 typename stde::hash_map< K, V >::key_type key; 00115 typename stde::hash_map< K, V >::mapped_type value; 00116 *this >> key >> value; 00117 map.insert( std::make_pair( key, value )); 00118 } 00119 return *this; 00120 } 00121 00122 template< class T > inline DataIStream& 00123 DataIStream::operator >> ( stde::hash_set< T >& value ) 00124 { 00125 value.clear(); 00126 uint64_t nElems = 0; 00127 *this >> nElems; 00128 for( uint64_t i = 0; i < nElems; ++i ) 00129 { 00130 T item; 00131 *this >> item; 00132 value.insert( item ); 00133 } 00134 return *this; 00135 } 00136 00137 namespace 00138 { 00139 class ObjectFinder 00140 { 00141 public: 00142 ObjectFinder( const UUID& id ) : _id( id ) {} 00143 bool operator()( co::Object* candidate ) 00144 { return candidate->getID() == _id; } 00145 00146 private: 00147 const UUID _id; 00148 }; 00149 } 00150 00151 template<> inline void DataIStream::_swap( Array< void > ) const { /*NOP*/ } 00152 00153 template< typename O, typename C > inline void 00154 DataIStream::deserializeChildren( O* object, const std::vector< C* >& old_, 00155 std::vector< C* >& result ) 00156 { 00157 ObjectVersions versions; 00158 *this >> versions; 00159 std::vector< C* > old = old_; 00160 00161 // rebuild vector from serialized list 00162 result.clear(); 00163 for( ObjectVersions::const_iterator i = versions.begin(); 00164 i != versions.end(); ++i ) 00165 { 00166 const ObjectVersion& version = *i; 00167 00168 if( version.identifier == UUID::ZERO ) 00169 { 00170 result.push_back( 0 ); 00171 continue; 00172 } 00173 00174 typename std::vector< C* >::iterator j = 00175 stde::find_if( old, ObjectFinder( version.identifier )); 00176 00177 if( j == old.end( )) // previously unknown child 00178 { 00179 C* child = 0; 00180 object->create( &child ); 00181 LocalNodePtr localNode = object->getLocalNode(); 00182 LBASSERT( child ); 00183 LBASSERT( !object->isMaster( )); 00184 00185 LBCHECK( localNode->mapObject( child, version )); 00186 result.push_back( child ); 00187 } 00188 else 00189 { 00190 C* child = *j; 00191 old.erase( j ); 00192 if( object->isMaster( )) 00193 child->sync( VERSION_HEAD ); 00194 else 00195 child->sync( version.version ); 00196 00197 result.push_back( child ); 00198 } 00199 } 00200 00201 while( !old.empty( )) // removed children 00202 { 00203 C* child = old.back(); 00204 old.pop_back(); 00205 if( !child ) 00206 continue; 00207 00208 if( child->isAttached() && !child->isMaster( )) 00209 { 00210 LocalNodePtr localNode = object->getLocalNode(); 00211 localNode->unmapObject( child ); 00212 } 00213 object->release( child ); 00214 } 00215 } 00219 template<> inline DataIStream& 00220 DataIStream::operator >> ( std::vector< uint8_t >& value ) 00221 { return _readFlatVector( value );} 00222 00224 template<> inline DataIStream& 00225 DataIStream::operator >> ( std::vector< uint16_t >& value ) 00226 { return _readFlatVector( value ); } 00227 00229 template<> inline DataIStream& 00230 DataIStream::operator >> ( std::vector< int16_t >& value ) 00231 { return _readFlatVector( value ); } 00232 00234 template<> inline DataIStream& 00235 DataIStream::operator >> ( std::vector< uint32_t >& value ) 00236 { return _readFlatVector( value ); } 00237 00239 template<> inline DataIStream& 00240 DataIStream::operator >> ( std::vector< int32_t >& value ) 00241 { return _readFlatVector( value ); } 00242 00244 template<> inline DataIStream& 00245 DataIStream::operator >> ( std::vector< uint64_t>& value ) 00246 { return _readFlatVector( value ); } 00247 00249 template<> inline DataIStream& 00250 DataIStream::operator >> ( std::vector< int64_t >& value ) 00251 { return _readFlatVector( value ); } 00252 00254 template<> inline DataIStream& 00255 DataIStream::operator >> ( std::vector< float >& value ) 00256 { return _readFlatVector( value ); } 00257 00259 template<> inline DataIStream& 00260 DataIStream::operator >> ( std::vector< double >& value ) 00261 { return _readFlatVector( value ); } 00262 00264 template<> inline DataIStream& 00265 DataIStream::operator >> ( std::vector< ObjectVersion >& value ) 00266 { return _readFlatVector( value ); } 00268 }