Equalizer 1.0

eq/fabric/object.h

00001 
00002 /* Copyright (c) 2009-2011, Stefan Eilemann <eile@equalizergraphics.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 #ifndef EQFABRIC_OBJECT_H
00019 #define EQFABRIC_OBJECT_H
00020 
00021 #include <eq/fabric/api.h>
00022 #include <eq/fabric/error.h>        // enum
00023 #include <eq/fabric/serializable.h> // base class
00024 #include <co/objectVersion.h>       // member
00025 
00026 namespace eq
00027 {
00028 namespace fabric
00029 {
00036     class Object : public Serializable
00037     {
00038     public:
00042         EQFABRIC_API void setName( const std::string& name );
00043 
00045         EQFABRIC_API const std::string& getName() const;
00046 
00056         EQFABRIC_API void setUserData( co::Object* userData );
00057 
00059         co::Object* getUserData() { return _userData; }
00060 
00062         const co::Object* getUserData() const { return _userData; }
00064 
00076         EQFABRIC_API void setError( const int32_t error );
00077 
00079         co::base::Error getError() const { return _error; }
00081 
00093         uint32_t getTasks() const { return _tasks; }
00094 
00095         uint32_t getSerial() const { return _serial; } 
00096 
00097 
00099         EQFABRIC_API virtual bool isDirty() const;
00100 
00102         EQFABRIC_API virtual uint32_t commitNB( const uint32_t incarnation );
00103 
00105         EQFABRIC_API virtual void backup();
00106 
00108         EQFABRIC_API virtual void restore();
00109 
00115         enum DirtyBits
00116         {
00117             DIRTY_NAME       = Serializable::DIRTY_CUSTOM << 0, // 1
00118             DIRTY_USERDATA   = Serializable::DIRTY_CUSTOM << 1, // 2
00119             DIRTY_ERROR      = Serializable::DIRTY_CUSTOM << 2, // 4
00120             DIRTY_TASKS      = Serializable::DIRTY_CUSTOM << 3, // 8
00121             DIRTY_REMOVED    = Serializable::DIRTY_CUSTOM << 4, // 16
00122             DIRTY_SERIAL     = Serializable::DIRTY_CUSTOM << 5, // 32
00123             // Leave room for binary-compatible patches
00124             DIRTY_CUSTOM     = Serializable::DIRTY_CUSTOM << 6, // 64
00125             DIRTY_OBJECT_BITS = DIRTY_NAME | DIRTY_USERDATA | DIRTY_ERROR
00126         };
00127 
00128     protected:
00130         EQFABRIC_API Object();
00131         
00133         EQFABRIC_API virtual ~Object();
00134 
00139         virtual bool hasMasterUserData() { return false; }
00140 
00142         virtual uint32_t getUserDataLatency() const { return 0; }
00143 
00145         EQFABRIC_API void setTasks( const uint32_t tasks );
00146 
00147         EQFABRIC_API virtual void notifyDetach();
00148 
00149         EQFABRIC_API virtual void serialize( co::DataOStream& os,
00150                                           const uint64_t dirtyBits );
00151         EQFABRIC_API virtual void deserialize( co::DataIStream& is,
00152                                             const uint64_t dirtyBits );
00153 
00155         virtual uint64_t getRedistributableBits() const
00156             { return DIRTY_OBJECT_BITS; }
00157 
00163         EQFABRIC_API void postRemove( const Object* child );
00164 
00166         virtual void removeChild( const co::base::UUID& ) { EQUNIMPLEMENTED; }
00167 
00169         template< class C, class PKG, class S >
00170         void commitChild( C* child, S* sender, const uint32_t incarnation );
00171 
00173         template< class C > inline 
00174         void commitChild( C* child, const uint32_t incarnation )
00175             {
00176                 EQASSERT( child->isAttached( ));
00177                 child->commit( incarnation );
00178             }
00179 
00181         template< class C, class PKG, class S >
00182         void commitChildren( const std::vector< C* >& children, S* sender,
00183                              const uint32_t incarnation );
00184 
00186         template< class C, class PKG >
00187         void commitChildren( const std::vector< C* >& children,
00188                              const uint32_t incarnation )
00189             { commitChildren< C, PKG, Object >( children, this, incarnation ); }
00190 
00192         template< class C >
00193         void commitChildren( const std::vector< C* >& children,
00194                              const uint32_t incarnation );
00195 
00197         template< class C >
00198         void syncChildren( const std::vector< C* >& children );
00199 
00201         template< class P, class C >
00202         inline void releaseChildren( const std::vector< C* >& children );
00203 
00205         EQFABRIC_API bool _cmdSync( co::Command& command );
00206 
00207     private:
00208         struct BackupData
00209         {
00211             std::string name;
00212 
00214             co::ObjectVersion userData;
00215         }
00216             _data, _backup;
00217 
00219         co::Object* _userData;
00220 
00222         uint32_t _tasks;
00223 
00225         co::base::Error _error;
00226 
00228         uint32_t _serial;
00229 
00231         std::vector< co::base::UUID > _removedChildren;
00232 
00233         struct Private;
00234         Private* _private; // placeholder for binary-compatible changes
00235     };
00236 
00237     // Template Implementation
00238     template< class C, class PKG, class S > inline void
00239     Object::commitChild( C* child, S* sender, const uint32_t incarnation )
00240     {
00241         if( !child->isAttached( ))
00242         {
00243             EQASSERT( !isMaster( ));
00244             co::LocalNodePtr localNode = child->getConfig()->getLocalNode();
00245             PKG packet;
00246             packet.requestID = localNode->registerRequest();
00247 
00248             co::NodePtr node = child->getServer().get();
00249             sender->send( node, packet );
00250 
00251             uint128_t identifier;
00252             localNode->waitRequest( packet.requestID, identifier );
00253             EQCHECK( localNode->mapObject( child,identifier,co::VERSION_NONE ));
00254         }
00255         child->commit( incarnation );
00256     }
00257 
00258     template< class C, class PKG, class S > inline void
00259     Object::commitChildren( const std::vector< C* >& children, S* sender,
00260                             const uint32_t incarnation )
00261     {
00262         // TODO Opt: async register and commit
00263         for( typename std::vector< C* >::const_iterator i = children.begin();
00264              i != children.end(); ++i )
00265         {
00266             C* child = *i;
00267             commitChild< C, PKG, S >( child, sender, incarnation );
00268         }
00269     }
00270 
00271     template< class C >
00272     inline void Object::commitChildren( const std::vector< C* >& children,
00273                                         const uint32_t incarnation )
00274     {
00275         // TODO Opt: async commit
00276         for( typename std::vector< C* >::const_iterator i = children.begin();
00277              i != children.end(); ++i )
00278         {
00279             C* child = *i;
00280             EQASSERT( child->isAttached( ));
00281             child->commit( incarnation );
00282         }
00283     }
00284 
00285     template< class C >
00286     inline void Object::syncChildren( const std::vector< C* >& children )
00287     {
00288         for( typename std::vector< C* >::const_iterator i = children.begin();
00289              i != children.end(); ++i )
00290         {
00291             C* child = *i;
00292             EQASSERT( child->isMaster( )); // slaves are synced using version
00293             child->sync();
00294         }
00295     }
00296  
00297     template< class P, class C >
00298     inline void Object::releaseChildren( const std::vector< C* >& children )
00299     {
00300         while( !children.empty( ))
00301         {
00302             C* child = children.back();
00303             if( !child->isAttached( ))
00304             {
00305                 EQASSERT( isMaster( ));
00306                 return;
00307             }
00308 
00309             getLocalNode()->releaseObject( child );
00310             if( !isMaster( ))
00311             {
00312                 static_cast< P* >( this )->_removeChild( child );
00313                 static_cast< P* >( this )->release( child );
00314             }
00315         }
00316     }
00317 }
00318 }
00319 #endif // EQFABRIC_OBJECT_H
Generated on Sun May 8 2011 19:11:07 for Equalizer 1.0 by  doxygen 1.7.3