Remote Call Framework 3.2
Registry.hpp
Go to the documentation of this file.
1 
2 //******************************************************************************
3 // RCF - Remote Call Framework
4 //
5 // Copyright (c) 2005 - 2020, Delta V Software. All rights reserved.
6 // http://www.deltavsoft.com
7 //
8 // RCF is distributed under dual licenses - closed source or GPL.
9 // Consult your particular license for conditions of use.
10 //
11 // If you have not purchased a commercial license, you are using RCF
12 // under GPL terms.
13 //
14 // Version: 3.2
15 // Contact: support <at> deltavsoft.com
16 //
17 //******************************************************************************
18 
20 
21 #ifndef INCLUDE_SF_REGISTRY_HPP
22 #define INCLUDE_SF_REGISTRY_HPP
23 
24 #include <map>
25 #include <string>
26 #include <typeinfo>
27 
28 #include <memory>
29 
30 #include <RCF/Export.hpp>
31 #include <RCF/ThreadLibrary.hpp>
32 
33 #include <RCF/Tools.hpp>
34 
35 namespace SF {
36 
37  typedef RCF::ReadWriteMutex ReadWriteMutex;
38  typedef RCF::ReadLock ReadLock;
39  typedef RCF::WriteLock WriteLock;
40 
41  class I_SerializerPolymorphic;
42  class I_SerializerAny;
43 
44  class RCF_EXPORT Registry : Noncopyable
45  {
46  private:
47  Registry();
48 
49  typedef std::string Rtti;
50  typedef std::map<std::string, Rtti> TypenameToRtti;
51  typedef std::map<Rtti, std::string> RttiToTypename;
52 
53  typedef std::map<
54  std::pair<Rtti, Rtti>,
55  std::shared_ptr<I_SerializerPolymorphic> >
56  RttiToSerializerPolymorphic;
57 
58  typedef std::map<
59  Rtti,
60  std::shared_ptr<I_SerializerAny> >
61  RttiToSerializerAny;
62 
63  TypenameToRtti mTypenameToRtti;
64  RttiToTypename mRttiToTypename;
65  RttiToSerializerPolymorphic mRttiToSerializerPolymorphic;
66  RttiToSerializerAny mRttiToSerializerAny;
67  ReadWriteMutex mReadWriteMutex;
68 
69  public:
70 
71  friend void initRegistrySingleton();
72 
73  static Registry &getSingleton();
74 
75  static Registry *getSingletonPtr();
76 
77  template<typename Type>
78  void registerAny(Type *);
79 
80  template<typename Type>
81  void registerType(Type *, const std::string &typeName);
82 
83  template<typename Base, typename Derived>
84  void registerBaseAndDerived(Base *, Derived *);
85 
86  template<typename Base>
87  I_SerializerPolymorphic &getSerializerPolymorphic(
88  Base *,
89  const std::string &derivedTypeName);
90 
91  template<typename T>
92  std::string getTypeName()
93  {
94  return getTypeName( (T *) 0);
95  }
96 
97  template<typename Type>
98  void registerAny()
99  {
100  registerAny( (Type *) 0);
101  }
102 
103  template<typename Type>
104  void registerType(const std::string &typeName)
105  {
106  registerType( (Type *) 0);
107  }
108 
109  template<typename Base, typename Derived>
110  void registerBaseAndDerived()
111  {
112  registerBaseAndDerived( (Base *) 0, (Derived *) 0);
113  }
114 
115  template<typename Base>
116  I_SerializerPolymorphic &getSerializerPolymorphic(
117  const std::string &derivedTypeName)
118  {
119  return getSerializerPolymorphic( (Base *) 0, derivedTypeName);
120  }
121 
122  I_SerializerAny * getAnySerializer(const std::string &which);
123 
124  bool isTypeRegistered(const std::string &typeName);
125 
126  bool isTypeRegistered(const std::type_info &ti);
127 
128  template<typename T>
129  std::string getTypeName(T *)
130  {
131  return getTypeName(typeid(T));
132  }
133 
134  std::string getTypeName(const std::type_info &ti);
135 
136  void clear();
137 
138  };
139 
140  template<typename Type>
141  inline void registerAny(Type *)
142  {
143  Registry::getSingleton().registerAny( (Type *) 0);
144  }
145 
146  template<typename Type>
147  inline void registerType(Type *, const std::string &typeName)
148  {
149  Registry::getSingleton().registerType( (Type *) 0, typeName);
150  }
151 
152  template<typename Base, typename Derived>
153  inline void registerBaseAndDerived( Base *, Derived *)
154  {
155  Registry::getSingleton().registerBaseAndDerived(
156  (Base *) 0,
157  (Derived *) 0);
158  }
159 
160 } // namespace SF
161 
162 #include <SF/SerializePolymorphic.hpp>
163 //#include <SF/SerializeAny.hpp>
164 #include <SF/Serializer.hpp>
165 
166 namespace SF {
167 
171  template<typename T>
172  void registerType(const std::string &typeName)
173  {
174  Registry::getSingleton().registerType( (T *) 0, typeName);
175  }
176 
180  template<typename Base, typename Derived>
181  void registerBaseAndDerived()
182  {
183  Registry::getSingleton().registerBaseAndDerived(
184  (Base *) 0,
185  (Derived *) 0);
186  }
187 
188  template<typename T>
189  class SerializerAny;
190 
191  template<typename Type>
192  void Registry::registerAny(Type *)
193  {
194  WriteLock lock(mReadWriteMutex);
195  RCF_UNUSED_VARIABLE(lock);
196  Rtti typeRtti = typeid(Type).name();
197 
198  if ( mRttiToTypename.find(typeRtti) == mRttiToTypename.end() )
199  {
200  RCF::Exception e(RCF::RcfError_SfTypeRegistration, typeRtti);
201  RCF_THROW(e);
202  }
203 
204  mRttiToSerializerAny[typeRtti].reset(new SerializerAny<Type>());
205  }
206 
207  template<typename Type>
208  void Registry::registerType(Type *, const std::string &typeName)
209  {
210  WriteLock lock(mReadWriteMutex);
211  RCF_UNUSED_VARIABLE(lock);
212  Rtti typeRtti = typeid(Type).name();
213  mRttiToTypename[typeRtti] = typeName;
214  mTypenameToRtti[typeName] = typeRtti;
215 
216  // Instantiate Type's serialize function so we can register the
217  // base/derived info.
218  // NB: release build optimizers had better not eliminate this.
219  //if (0)
220  //{
221  // serialize( *((Archive *) NULL), *((Type *) NULL), 0);
222  //}
223  }
224 
225  template<typename Base, typename Derived>
226  void Registry::registerBaseAndDerived(Base *, Derived *)
227  {
228  WriteLock lock(mReadWriteMutex);
229  RCF_UNUSED_VARIABLE(lock);
230  Rtti baseRtti = typeid(Base).name();
231  Rtti derivedRtti = typeid(Derived).name();
232  std::pair<Rtti, Rtti> baseDerivedRtti(baseRtti, derivedRtti);
233 
234  mRttiToSerializerPolymorphic[baseDerivedRtti].reset(
235  new SerializerPolymorphic<Base,Derived>);
236  }
237 
238  template<typename Base>
239  I_SerializerPolymorphic &Registry::getSerializerPolymorphic(
240  Base *,
241  const std::string &derivedTypeName)
242  {
243  ReadLock lock(mReadWriteMutex);
244  RCF_UNUSED_VARIABLE(lock);
245  Rtti baseRtti = typeid(Base).name();
246  Rtti derivedRtti = mTypenameToRtti[derivedTypeName];
247  std::pair<Rtti, Rtti> baseDerivedRtti(baseRtti, derivedRtti);
248  if (
249  mRttiToSerializerPolymorphic.find(baseDerivedRtti)
250  == mRttiToSerializerPolymorphic.end())
251  {
252  RCF::Exception e( RCF::RcfError_SfBaseDerivedRegistration,
253  baseRtti,
254  derivedRtti);
255 
256  RCF_THROW(e);
257  }
258  return *mRttiToSerializerPolymorphic[ baseDerivedRtti ];
259  }
260 
261 } // namespace SF
262 
263 #endif // ! INCLUDE_SF_REGISTRY_HPP
Base class for all RCF exceptions.
Definition: Exception.hpp:64
Definition: ByteBuffer.hpp:189