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. |