Main Page   Modules   Namespace List   Class Hierarchy   Alphabetical List   Compound List   File List   Namespace Members   Compound Members   File Members   Related Pages  

InterfaceRegistry.h

Go to the documentation of this file.
00001 /* SimData: Data Infrastructure for Simulations
00002  * Copyright (C) 2002 Mark Rose <tm2@stm.lbl.gov>
00003  * 
00004  * This file is part of SimData.
00005  * 
00006  * This program is free software; you can redistribute it and/or
00007  * modify it under the terms of the GNU General Public License
00008  * as published by the Free Software Foundation; either version 2
00009  * of the License, or (at your option) any later version.
00010  * 
00011  * This program is distributed in the hope that it will be useful,
00012  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00013  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00014  * GNU General Public License for more details.
00015  * 
00016  * You should have received a copy of the GNU General Public License
00017  * along with this program; if not, write to the Free Software
00018  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
00019  */
00020 
00021 
00028 #ifndef __SIMDATA_INTERFACEREGISTRY_H__
00029 #define __SIMDATA_INTERFACEREGISTRY_H__
00030 
00031 #include <string>
00032 #include <vector>
00033 #include <map>
00034 
00035 #include <SimData/Export.h>
00036 #include <SimData/HashUtility.h>
00037 #include <SimData/TypeAdapter.h>
00038 #include <SimData/ObjectInterface.h>
00039 #include <SimData/Namespace.h>
00040 #include <SimData/Exception.h>
00041 
00042 
00043 NAMESPACE_SIMDATA
00044 
00045 
00046 class Object;
00047 
00107 class SIMDATA_EXPORT InterfaceProxy {
00108 
00109 private:
00110 
00111         typedef std::map<std::string, ObjectInterfaceBase*> InterfaceMap;
00112         std::vector<std::string> _classNames;
00113         std::vector<hasht> _classHashes;
00114         std::vector<std::string> _variableNames;
00115         std::vector<std::string> _requiredNames;
00116         InterfaceMap _interfaces;
00117 
00122         InterfaceProxy();
00123 
00124 protected:
00125 
00141         void addInterface(ObjectInterfaceBase* objectinterface, 
00142                           std::string const &classname,
00143                           hasht const &classhash);
00144 
00153         ObjectInterfaceBase *findInterface(std::string const &varname, bool required) const;
00154 
00155 public:
00156 
00165         InterfaceProxy(const char *cname, hasht chash);
00166 #ifndef SWIG
00167         InterfaceProxy(const char *cname, hasht (*chash)());
00168 #endif // SWIG
00169 
00170         virtual ~InterfaceProxy() { }
00171 
00174         virtual Object *createObject() const;
00175 
00178         virtual hasht getClassHash() const;
00179         
00182         virtual const char *getClassName() const;
00183         
00184 #ifndef SWIG
00185 
00188         const TypeAdapter get(Object *o, std::string const &varname) const {
00189                 ObjectInterfaceBase *oi = findInterface(varname, true);
00190                 return oi->get(o, varname);
00191         }
00192 
00195         void set(Object *o, std::string const &varname, const TypeAdapter &v) {
00196                 ObjectInterfaceBase *oi = findInterface(varname, true);
00197                 oi->set(o, varname, v);
00198         }
00199 
00202         void push_back(Object *o, std::string const &varname, const TypeAdapter &v) {
00203                 ObjectInterfaceBase *oi = findInterface(varname, true);
00204                 oi->push_back(o, varname, v);
00205         }
00206 
00207         
00208 #endif // SWIG
00209         
00216         void set_enum(Object *o, std::string const &varname, std::string const &v) {
00217                 set(o, varname, TypeAdapter(v));
00218         }
00219 
00225         void clear(Object *o, std::string const &varname) {
00226                 ObjectInterfaceBase *oi = findInterface(varname, true);
00227                 oi->clear(o, varname);
00228         }
00229 
00232         bool variableExists(std::string const &varname) const {
00233                 return findInterface(varname, false) != 0;
00234         }
00235 
00239         bool variableRequired(std::string const &varname) const {
00240                 ObjectInterfaceBase *oi = findInterface(varname, true);
00241                 return oi->variableRequired(varname);
00242         }
00243 
00247         std::string variableType(std::string const &varname) const {
00248                 ObjectInterfaceBase *oi = findInterface(varname, true);
00249                 return oi->variableType(varname);
00250         }
00251 
00254         std::vector<std::string> getVariableNames() const {
00255                 // XXX this should return a const &, but swig currently doesn't
00256                 // convert such references to Python lists, so for now we copy 
00257                 // the full list.
00258                 return _variableNames;
00259         }
00260         
00263         std::vector<std::string> getRequiredNames() const {
00264                 // XXX this should return a const &, but swig currently doesn't
00265                 // convert such references to Python lists, so for now we copy 
00266                 // the full list.
00267                 return _requiredNames;
00268         }
00269 
00281         bool isSubclass(std::string const &cname) const;
00282 
00293         bool isSubclass(hasht const &chash) const;
00294 
00301         virtual bool isStatic() const { return false; }
00302 
00303 
00305 #ifdef SWIG
00306 public:
00307 %extend {
00308         virtual void set(Object *p, std::string const &varname, int v) {
00309                 self->set(p, varname, TypeAdapter(v));
00310         }
00311         virtual void set(Object *p, std::string const &varname, double v) {
00312                 self->set(p, varname, TypeAdapter(v));
00313         }
00314         virtual void set(Object *p, std::string const &varname, std::string const &v) {
00315                 self->set(p, varname, TypeAdapter(v));
00316         }
00317         virtual void set(Object *p, std::string const &varname, BaseType *v) {
00318                 self->set(p, varname, TypeAdapter(v));
00319         }
00320         virtual void push_back(Object *p, std::string const &varname, std::string const &v) {
00321                 self->push_back(p, varname, TypeAdapter(v));
00322         }
00323         virtual void push_back(Object *p, std::string const &varname, int v) {
00324                 self->push_back(p, varname, TypeAdapter(v));
00325         }
00326         virtual void push_back(Object *p, std::string const &varname, double v) {
00327                 self->push_back(p, varname, TypeAdapter(v));
00328         }
00329         virtual void push_back(Object *p, std::string const &varname, const BaseType &v) {
00330                 self->push_back(p, varname, TypeAdapter(v));
00331         }
00332 }
00333 #endif // SWIG
00334 
00335 };
00336 
00337 
00340 template <class C>
00341 class Singleton {
00342 public:
00345         static C& getInstance() {
00346                 static C __instance;
00347                 return __instance;
00348         }
00349 private:
00350         Singleton() {}
00351         ~Singleton() {}
00352 };
00353 
00362 class InterfaceRegistry {
00363         
00364 friend class InterfaceProxy;
00365 
00366 public:
00367         typedef std::vector<InterfaceProxy *> interface_list;
00368 
00373         InterfaceProxy *getInterface(const char *name);
00374         
00379         InterfaceProxy *getInterface(hasht key);
00380         
00385         bool hasInterface(const char *name);
00386         
00391         bool hasInterface(hasht key);
00392         
00395         std::vector<std::string> getInterfaceNames() const;
00396 
00399         std::vector<InterfaceProxy *> getInterfaces() const;
00400         
00403         static InterfaceRegistry &getInterfaceRegistry() {
00404                 return Singleton<InterfaceRegistry>::getInstance();
00405         }
00406 
00407 #if defined(_MSC_VER ) && (_MSC_VER <= 1200)
00408         virtual ~InterfaceRegistry();
00409 #endif
00410 
00411 private:
00412 
00413 #if !defined(_MSC_VER ) || (_MSC_VER > 1200)
00414         virtual ~InterfaceRegistry();
00415 #endif
00416 
00422         void addInterface(const char *name, hasht id, InterfaceProxy *proxy) throw(InterfaceError);
00423 
00424         friend class Singleton<InterfaceRegistry>;
00425         InterfaceRegistry();
00426         
00427         void __cleanup();
00428 
00429         typedef HASH_MAPS<const char*, InterfaceProxy*, HASH<const char*>, eqstr>::Type proxy_map;
00430         typedef HASHT_MAP<InterfaceProxy*>::Type proxy_id_map;
00431 
00432         proxy_map *__map;
00433         proxy_id_map *__id_map;
00434         interface_list *__list;
00435 
00436 };
00437 
00438 
00439 
00555 #if 0
00556         virtual bool isSubclass(std::string const &cname) const { \
00557                 return (cname == #classname) || \
00558                        nqbaseinterface::isSubclass(cname);\
00559         } \
00560         virtual bool isSubclass(SIMDATA(hasht) const &chash) const { \
00561                 return (chash == classname::_getClassHash()) || \
00562                        nqbaseinterface::isSubclass(chash);\
00563         } \
00564 
00565 #endif
00566 
00571 #define __SIMDATA_XML_INTERFACE_0(classname, baseinterface) \
00572 class classname##InterfaceProxy; \
00573 friend class classname##InterfaceProxy; \
00574 class classname##InterfaceProxy: public baseinterface \
00575 { \
00576         SIMDATA(ObjectInterface)<classname> *_interface; \
00577 public: 
00578 
00583 #define __SIMDATA_XML_INTERFACE_1(classname) \
00584         virtual SIMDATA(Object)* createObject() const { \
00585                 SIMDATA(Object) *o = new classname; \
00586                 assert(o); \
00587                 return o; \
00588         } \
00589         virtual bool isVirtual() const { return false; } \
00590         virtual bool isStatic() const { return classname::_isClassStatic(); }
00591                 
00596 #define __SIMDATA_XML_INTERFACE_V(classname) \
00597         virtual SIMDATA(Object)* createObject() const { assert(0); return 0; } \
00598         virtual bool isVirtual() const { return true; }
00599 
00600 
00605 #define __SIMDATA_XML_INTERFACE_2(classname, baseinterface, nqbaseinterface) \
00606         virtual SIMDATA(hasht) getClassHash() const { return classname::_getClassHash(); } \
00607         virtual const char * getClassName() const { return classname::_getClassName(); } \
00608         classname##InterfaceProxy(const char * cname = #classname, SIMDATA(hasht) (*chash)() = &classname::_getClassHash): \
00609                 baseinterface(cname, chash) \
00610         { \
00611                 std::string _classname = #classname; \
00612                 SIMDATA(hasht) _classhash = classname::_getClassHash(); \
00613                 _interface = new SIMDATA(ObjectInterface)<classname>; \
00614                 (*_interface)
00615 
00616 //-----------------------------------------
00617 
00618 
00619 #ifdef SWIG
00620 
00621         #define BEGIN_SIMDATA_XML_INTERFACE(classname)
00622         #define BEGIN_SIMDATA_XML_VIRTUAL_INTERFACE(classname)
00623         #define EXTEND_SIMDATA_XML_INTERFACE(classname, basename)
00624         #define EXTEND_SIMDATA_XML_VIRTUAL_INTERFACE(classname, basename)
00625 
00626 #else
00627 
00632         #define BEGIN_SIMDATA_XML_INTERFACE(classname) \
00633                 __SIMDATA_XML_INTERFACE_0(classname, SIMDATA(InterfaceProxy)) \
00634                 __SIMDATA_XML_INTERFACE_1(classname) \
00635                 __SIMDATA_XML_INTERFACE_2(classname, SIMDATA(InterfaceProxy), InterfaceProxy)
00636 
00641         #define BEGIN_SIMDATA_XML_VIRTUAL_INTERFACE(classname) \
00642                 __SIMDATA_XML_INTERFACE_0(classname, SIMDATA(InterfaceProxy)) \
00643                 __SIMDATA_XML_INTERFACE_V(classname) \
00644                 __SIMDATA_XML_INTERFACE_2(classname, SIMDATA(InterfaceProxy), InterfaceProxy)
00645 
00650         #define EXTEND_SIMDATA_XML_INTERFACE(classname, basename) \
00651                 __SIMDATA_XML_INTERFACE_0(classname, basename::basename##InterfaceProxy) \
00652                 __SIMDATA_XML_INTERFACE_1(classname) \
00653                 __SIMDATA_XML_INTERFACE_2(classname, basename::basename##InterfaceProxy, basename##InterfaceProxy) 
00654 
00659         #define EXTEND_SIMDATA_XML_VIRTUAL_INTERFACE(classname, basename) \
00660                 __SIMDATA_XML_INTERFACE_0(classname, basename::basename##InterfaceProxy) \
00661                 __SIMDATA_XML_INTERFACE_V(classname) \
00662                 __SIMDATA_XML_INTERFACE_2(classname, basename::basename##InterfaceProxy, basename##InterfaceProxy)
00663 
00664 #endif // SWIG
00665 
00666 
00667 //-----------------------------------------
00668 
00673 #ifdef SWIG
00674         #define SIMDATA_XML(id, var, req)
00675 #else
00676         #define SIMDATA_XML(id, var, req)       .def(id, &var, req) 
00677 #endif
00678                 
00679 //-----------------------------------------
00680 
00685 #ifdef SWIG
00686         #define SIMDATA_BIT(id, var, bit, req)
00687 #else
00688         #define SIMDATA_BIT(id, var, bit, req)  .def(id, &var, bit, req) 
00689 #endif
00690                 
00691 //-----------------------------------------
00692 
00697 #ifdef SWIG
00698         #define END_SIMDATA_XML_INTERFACE
00699 #else
00700         #define END_SIMDATA_XML_INTERFACE \
00701                         .pass(); \
00702                         addInterface(_interface, _classname, _classhash); \
00703                 } \
00704         };
00705 #endif
00706 
00711 #define SIMDATA_REGISTER_INTERFACE(classname) \
00712 namespace { \
00713         classname::classname##InterfaceProxy __##classname##_interface; \
00714 } /* anonymous namespace */
00715 
00720 #define SIMDATA_REGISTER_INNER_INTERFACE(prefix, classname) \
00721 namespace { \
00722         parent::classname::classname##InterfaceProxy __##prefix##_##classname##_interface; \
00723 } /* anonymous namespace */
00724 
00725 
00726 
00727 NAMESPACE_SIMDATA_END
00728 
00729 
00730 #endif // __SIMDATA_INTERFACEREGISTRY_H__
00731 
00732 

SimData version pre-0.4.0. For more information on SimData, visit the SimData Homepage.

Generated on Tue Oct 14 12:06:38 2003, using Doxygen 1.2.18.

[SF.net]