Equalizer  1.2.1
eq/fabric/object.h
00001 
00002 /* Copyright (c) 2009-2012, 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/types.h>
00024 #include <co/objectVersion.h>       // member
00025 #include <co/serializable.h>        // base class
00026 
00027 namespace eq
00028 {
00029 namespace fabric
00030 {
00037     class Object : public co::Serializable
00038     {
00039     public:
00043         EQFABRIC_API void setName( const std::string& name );
00044 
00046         EQFABRIC_API const std::string& getName() const;
00047 
00057         EQFABRIC_API void setUserData( co::Object* userData );
00058 
00060         co::Object* getUserData() { return _userData; }
00061 
00063         const co::Object* getUserData() const { return _userData; }
00065 
00077         EQFABRIC_API void setError( const int32_t error );
00078 
00080         co::base::Error getError() const { return _error; }
00082 
00094         uint32_t getTasks() const { return _tasks; }
00095 
00096         uint32_t getSerial() const { return _serial; } 
00097 
00098 
00100         EQFABRIC_API virtual bool isDirty() const;
00101 
00103         EQFABRIC_API virtual uint128_t commit( const uint32_t incarnation =
00104                                                CO_COMMIT_NEXT );
00105 
00107         EQFABRIC_API virtual void backup();
00108 
00110         EQFABRIC_API virtual void restore();
00111 
00117         enum DirtyBits
00118         {
00119             DIRTY_NAME       = Serializable::DIRTY_CUSTOM << 0, // 1
00120             DIRTY_USERDATA   = Serializable::DIRTY_CUSTOM << 1, // 2
00121             DIRTY_ERROR      = Serializable::DIRTY_CUSTOM << 2, // 4
00122             DIRTY_TASKS      = Serializable::DIRTY_CUSTOM << 3, // 8
00123             DIRTY_REMOVED    = Serializable::DIRTY_CUSTOM << 4, // 16
00124             DIRTY_SERIAL     = Serializable::DIRTY_CUSTOM << 5, // 32
00125             // Leave room for binary-compatible patches
00126             DIRTY_CUSTOM     = Serializable::DIRTY_CUSTOM << 6, // 64
00127             DIRTY_OBJECT_BITS = DIRTY_NAME | DIRTY_USERDATA | DIRTY_ERROR
00128         };
00129 
00130     protected:
00132         EQFABRIC_API Object();
00133         
00135         EQFABRIC_API virtual ~Object();
00136 
00141         virtual bool hasMasterUserData() { return false; }
00142 
00144         virtual uint32_t getUserDataLatency() const { return 0; }
00145 
00147         EQFABRIC_API void setTasks( const uint32_t tasks );
00148 
00149         EQFABRIC_API virtual void notifyDetach();
00150 
00151         EQFABRIC_API virtual void serialize( co::DataOStream& os,
00152                                              const uint64_t dirtyBits );
00153         EQFABRIC_API virtual void deserialize( co::DataIStream& is,
00154                                                const uint64_t dirtyBits );
00155 
00157         virtual uint64_t getRedistributableBits() const
00158             { return DIRTY_OBJECT_BITS; }
00159 
00165         EQFABRIC_API void postRemove( Object* child );
00166 
00168         virtual void removeChild( const co::base::UUID& ) { EQUNIMPLEMENTED; }
00169 
00171         template< class C, class PKG, class S >
00172         void commitChild( C* child, S* sender, const uint32_t incarnation );
00173 
00175         template< class C > inline 
00176         void commitChild( C* child, const uint32_t incarnation )
00177             {
00178                 EQASSERT( child->isAttached( ));
00179                 child->commit( incarnation );
00180             }
00181 
00183         template< class C, class PKG, class S >
00184         void commitChildren( const std::vector< C* >& children, S* sender,
00185                              const uint32_t incarnation );
00186 
00188         template< class C, class PKG >
00189         void commitChildren( const std::vector< C* >& children,
00190                              const uint32_t incarnation )
00191             { commitChildren< C, PKG, Object >( children, this, incarnation ); }
00192 
00194         template< class C >
00195         void commitChildren( const std::vector< C* >& children,
00196                              const uint32_t incarnation );
00197 
00199         template< class C >
00200         void syncChildren( const std::vector< C* >& children );
00201 
00203         template< class P, class C >
00204         inline void releaseChildren( const std::vector< C* >& children );
00205 
00207         EQFABRIC_API bool _cmdSync( co::Command& command );
00208 
00209     private:
00210         struct BackupData
00211         {
00213             std::string name;
00214 
00216             co::ObjectVersion userData;
00217         }
00218             _data, _backup;
00219 
00221         co::Object* _userData;
00222 
00224         uint32_t _tasks;
00225 
00227         co::base::Error _error;
00228 
00230         uint32_t _serial;
00231 
00233         std::vector< co::base::UUID > _removedChildren;
00234 
00235         struct Private;
00236         Private* _private; // placeholder for binary-compatible changes
00237     };
00238 
00239     // Template Implementation
00240     template< class C, class PKG, class S > inline void
00241     Object::commitChild( C* child, S* sender, const uint32_t incarnation )
00242     {
00243         if( !child->isAttached( ))
00244         {
00245             EQASSERT( !isMaster( ));
00246             co::LocalNodePtr localNode = child->getConfig()->getLocalNode();
00247             PKG packet( localNode->registerRequest( ));
00248 
00249             co::NodePtr node = child->getServer().get();
00250             sender->send( node, packet );
00251 
00252             uint128_t identifier;
00253             localNode->waitRequest( packet.requestID, identifier );
00254             EQCHECK( localNode->mapObject( child,identifier,co::VERSION_NONE ));
00255         }
00256         child->commit( incarnation );
00257     }
00258 
00259     template< class C, class PKG, class S > inline void
00260     Object::commitChildren( const std::vector< C* >& children, S* sender,
00261                             const uint32_t incarnation )
00262     {
00263         // TODO Opt: async register and commit
00264         for( typename std::vector< C* >::const_iterator i = children.begin();
00265              i != children.end(); ++i )
00266         {
00267             C* child = *i;
00268             commitChild< C, PKG, S >( child, sender, incarnation );
00269         }
00270     }
00271 
00272     template< class C >
00273     inline void Object::commitChildren( const std::vector< C* >& children,
00274                                         const uint32_t incarnation )
00275     {
00276         // TODO Opt: async commit
00277         for( typename std::vector< C* >::const_iterator i = children.begin();
00278              i != children.end(); ++i )
00279         {
00280             C* child = *i;
00281             EQASSERT( child->isAttached( ));
00282             child->commit( incarnation );
00283         }
00284     }
00285 
00286     template< class C >
00287     inline void Object::syncChildren( const std::vector< C* >& children )
00288     {
00289         for( typename std::vector< C* >::const_iterator i = children.begin();
00290              i != children.end(); ++i )
00291         {
00292             C* child = *i;
00293             EQASSERT( child->isMaster( )); // slaves are synced using version
00294             child->sync();
00295         }
00296     }
00297  
00298     template< class P, class C >
00299     inline void Object::releaseChildren( const std::vector< C* >& children )
00300     {
00301         for( size_t i = children.size(); i > 0; --i )
00302         {
00303             C* child = children[ i - 1 ];
00304 
00305             if( child->isAttached( ))
00306             {
00307                 getLocalNode()->releaseObject( child );
00308                 if( !isMaster( ))
00309                 {
00310                     static_cast< P* >( this )->_removeChild( child );
00311                     static_cast< P* >( this )->release( child );
00312                 }
00313             }
00314             else
00315             {
00316                 EQASSERT( isMaster( ));
00317             }
00318         }
00319     }
00320 }
00321 }
00322 #endif // EQFABRIC_OBJECT_H
Generated on Fri Jun 8 2012 15:44:31 for Equalizer 1.2.1 by  doxygen 1.8.0