//****************************************************************************** // RCF - Remote Call Framework // Copyright (c) 2005 - 2007. All rights reserved. // Consult your license for conditions of use. // Developed by Jarl Lindrud. // Contact: jlindrud@hotmail.com . //****************************************************************************** #ifndef INCLUDE_SF_REGISTRY_HPP #define INCLUDE_SF_REGISTRY_HPP #include #include #include #include #include #include #include #include #include #include namespace SF { typedef util::ReadWriteMutex ReadWriteMutex; typedef util::ReadLock ReadLock; typedef util::WriteLock WriteLock; static const Platform::Threads::read_write_scheduling_policy ReaderPriority = Platform::Threads::reader_priority; static const Platform::Threads::read_write_scheduling_policy WriterPriority = Platform::Threads::writer_priority; class Registry : boost::noncopyable { private: Registry(); //typedef const std::type_info * Rtti; // not safe, several pointers might correspond to single type typedef std::string Rtti; std::map typeRttis; std::map typeNames; std::map, boost::shared_ptr > serializerPolymorphicInstances; ReadWriteMutex readWriteMutex; public: friend void initRegistrySingleton(); static Registry &getSingleton(); static Registry *getSingletonPtr(); template void registerType(Type *, const std::string &typeName) { WriteLock lock(readWriteMutex); RCF_UNUSED_VARIABLE(lock); Rtti typeRtti = typeid(Type).name(); typeNames[typeRtti] = typeName; typeRttis[typeName] = typeRtti; // instantiate Type's serializer function so we can register the base/derived info // NB: release build optimizers had better not eliminate this. if (0) { serialize( *((Archive *) NULL), *((Type *) NULL), 0); } } template void registerBaseAndDerived(Base *, Derived *) { WriteLock lock(readWriteMutex); RCF_UNUSED_VARIABLE(lock); Rtti baseRtti = typeid(Base).name(); Rtti derivedRtti = typeid(Derived).name(); std::pair baseDerivedRtti(baseRtti, derivedRtti); serializerPolymorphicInstances[baseDerivedRtti].reset( new SerializerPolymorphic); } #if !defined(_MSC_VER) || _MSC_VER > 1200 template void registerType(const std::string &typeName) { registerType( (Type *) 0); } template void registerBaseAndDerived() { registerBaseAndDerived( (Base *) 0, (Derived *) 0); } #endif #if !defined(_MSC_VER) || _MSC_VER > 1200 template I_SerializerPolymorphic &getSerializerPolymorphic(const std::string &derivedTypeName) { return getSerializerPolymorphic( (Base *) 0, derivedTypeName); } #endif template I_SerializerPolymorphic &getSerializerPolymorphic(Base *, const std::string &derivedTypeName) { ReadLock lock(readWriteMutex); RCF_UNUSED_VARIABLE(lock); Rtti baseRtti = typeid(Base).name(); Rtti derivedRtti = typeRttis[derivedTypeName]; std::pair baseDerivedRtti(baseRtti, derivedRtti); if (serializerPolymorphicInstances.find(baseDerivedRtti) == serializerPolymorphicInstances.end()) { RCF_THROW(RCF::Exception(RCF::SfError_BaseDerivedRegistration))(derivedTypeName)(baseRtti)(derivedRtti); } return *serializerPolymorphicInstances[ std::make_pair(baseRtti, derivedRtti) ]; } bool isTypeRegistered(const std::string &typeName); bool isTypeRegistered(const std::type_info &ti); #if !defined(_MSC_VER) || _MSC_VER > 1200 template std::string getTypeName() { //return getTypeName(typeid(T)); return getTypeName( (T *) 0); } #endif template std::string getTypeName(T *) { return getTypeName(typeid(T)); } std::string getTypeName(const std::type_info &ti); void clear(); }; #if !defined(_MSC_VER) || _MSC_VER > 1200 template inline void registerType(const std::string &typeName) { Registry::getSingleton().registerType( (Type *) 0, typeName); } template inline void registerBaseAndDerived() { Registry::getSingleton().registerBaseAndDerived( (Base *) 0, (Derived *) 0); } #endif template inline void registerType( Type *, const std::string &typeName) { Registry::getSingleton().registerType( (Type *) 0, typeName); } template inline void registerBaseAndDerived( Base *, Derived *) { Registry::getSingleton().registerBaseAndDerived( (Base *) 0, (Derived *) 0); } } // namespace SF #endif // ! INCLUDE_SF_REGISTRY_HPP