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