MetaClass.h
Go to the documentation of this file.
00001 /*
00002  * Copyright (C) 2006-2011, SRI International (R)
00003  *
00004  * This program is free software: you can redistribute it and/or modify
00005  * it under the terms of the GNU Lesser General Public License as published by
00006  * the Free Software Foundation, either version 3 of the License, or
00007  * (at your option) any later version.
00008  *
00009  * This program is distributed in the hope that it will be useful,
00010  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00011  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00012  * GNU Lesser General Public License for more details.
00013  *
00014  * You should have received a copy of the GNU Lesser General Public License
00015  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
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   //@cond EXCLUDE
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   // @endcond
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__


nav2d_karto
Author(s): Sebastian Kasperski
autogenerated on Thu Aug 27 2015 14:07:25