Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018 #pragma once
00019
00020 #ifndef __OpenKarto_MetaClass_h__
00021 #define __OpenKarto_MetaClass_h__
00022
00023 #include <OpenKarto/MetaType.h>
00024 #include <OpenKarto/MetaAttribute.h>
00025 #include <OpenKarto/MetaClassManager.h>
00026 #include <OpenKarto/Referenced.h>
00027 #include <OpenKarto/List.h>
00028
00029 namespace karto
00030 {
00031
00033
00034
00035
00036
00040
00041 struct MetaArgsPrivate;
00042
00046 class KARTO_EXPORT MetaArguments
00047 {
00048 public:
00052 MetaArguments();
00053
00058 MetaArguments(const Any& a0);
00059
00065 MetaArguments(const Any& a0, const Any& a1);
00066
00073 MetaArguments(const Any& a0, const Any& a1, const Any& a2);
00074
00082 MetaArguments(const Any& a0, const Any& a1, const Any& a2, const Any& a3);
00083
00092 MetaArguments(const Any& a0, const Any& a1, const Any& a2, const Any& a3, const Any& a4);
00093
00097 ~MetaArguments();
00098
00099 public:
00103 kt_size_t GetCount() const;
00104
00105 public:
00111 const Any& operator[](kt_size_t index) const;
00112
00113 public:
00118 static const MetaArguments& Empty()
00119 {
00120 static MetaArguments dummy;
00121
00122 return dummy;
00123 }
00124
00125 private:
00126 MetaArgsPrivate* m_pPrivate;
00127 };
00128
00132
00138 template <typename T>
00139 kt_bool CheckArgumentType(const Any& rAny)
00140 {
00141 return any_cast<T>(rAny) != NULL;
00142 }
00143
00147
00151 class MetaConstructor
00152 {
00153 public:
00157 virtual ~MetaConstructor()
00158 {
00159 }
00160
00161 public:
00168 virtual kt_bool CheckArguments(const MetaArguments& rArgs) const = 0;
00169
00176 virtual void* Create(const MetaArguments& rArgs) const = 0;
00177 };
00178
00182
00186 template <typename T>
00187 class MetaConstructorImpl0 : public MetaConstructor
00188 {
00189 public:
00190 virtual kt_bool CheckArguments(const MetaArguments& rArgs) const
00191 {
00192 return (rArgs.GetCount() == 0);
00193 }
00194
00195 virtual void* Create(const MetaArguments&) const
00196 {
00197 return new T();
00198 }
00199 };
00200
00204
00208 template <typename T, typename A0>
00209 class MetaConstructorImpl1 : public MetaConstructor
00210 {
00211 public:
00212 virtual kt_bool CheckArguments(const MetaArguments& rArgs) const
00213 {
00214 return (rArgs.GetCount() == 1) && CheckArgumentType<A0>(rArgs[0]);
00215 }
00216
00217 virtual void* Create(const MetaArguments& rArgs) const
00218 {
00219 return new T(any_cast<A0>(rArgs[0]));
00220 }
00221 };
00222
00226
00230 template <typename T, typename A0, typename A1>
00231 class MetaConstructorImpl2 : public MetaConstructor
00232 {
00233 public:
00234 virtual kt_bool CheckArguments(const MetaArguments& rArgs) const
00235 {
00236 return (rArgs.GetCount() == 2) && CheckArgumentType<A0>(rArgs[0]) && CheckArgumentType<A1>(rArgs[1]);
00237 }
00238
00239 virtual void* Create(const MetaArguments& rArgs) const
00240 {
00241 return new T(any_cast<A0>(rArgs[0]), any_cast<A1>(rArgs[1]));
00242 }
00243 };
00244
00245
00246
00250
00251 template <typename T> class MetaClassHelper;
00252
00256
00257 class MetaConstructor;
00258
00262 class KARTO_EXPORT MetaClass : public MetaAttribute, public Referenced
00263 {
00264 public:
00270 template <typename T>
00271 static MetaClassHelper<T> Register(const karto::String& rName)
00272 {
00273 MetaClass& newClass = MetaClassManager::GetInstance().RegisterNew(rName, KartoTypeId<T>::Get(false));
00274 return MetaClassHelper<T>(newClass);
00275 }
00276
00277 public:
00282 const karto::String& GetName() const;
00283
00288 kt_size_t GetBaseSize() const;
00289
00296 const MetaClass& GetBase(kt_size_t index) const;
00297
00303 template <typename T>
00304 T* Create(const MetaArguments& rArgs = MetaArguments::Empty()) const
00305 {
00306 void* pObject = NULL;
00307
00308 karto_const_forEach(List<const MetaConstructor*>, &m_Constructors)
00309 {
00310 const MetaConstructor* pConstructor = *iter;
00311
00312 if (pConstructor->CheckArguments(rArgs))
00313 {
00314 pObject = pConstructor->Create(rArgs);
00315 }
00316 }
00317
00318 if (pObject == NULL)
00319 {
00320 throw karto::Exception("Unable to create object '" + GetName() + "'. Please verify that .Constructor is defined for MetaClass");
00321 }
00322
00323 return static_cast<T*>(pObject);
00324 }
00325
00329 template <typename T>
00330 void Destroy(const T* pObject) const
00331 {
00332 delete pObject;
00333 }
00334
00335 public:
00341 kt_bool operator==(const MetaClass& rOther) const;
00342
00348 kt_bool operator!=(const MetaClass& rOther) const;
00349
00350 private:
00351 MetaClass(const karto::String& rName);
00352 ~MetaClass();
00353
00354 private:
00355 template <typename T> friend class MetaClassHelper;
00356 friend class MetaClassManager;
00357
00358 karto::String m_Name;
00359 List<const MetaClass*> m_BaseClasses;
00360
00361 List<const MetaConstructor*> m_Constructors;
00362 };
00363
00365
00366 }
00367
00368 #endif // __OpenKarto_MetaClass_h__