• Skip to content
  • Skip to link menu
KDE 4.2 API Reference
  • KDE API Reference
  • kdeedu
  • Sitemap
  • Contact Us
 

step/stepcore

object.h

Go to the documentation of this file.
00001 /* This file is part of StepCore library.
00002    Copyright (C) 2007 Vladimir Kuznetsov <ks.vladimir@gmail.com>
00003 
00004    StepCore library is free software; you can redistribute it and/or modify
00005    it under the terms of the GNU General Public License as published by
00006    the Free Software Foundation; either version 2 of the License, or
00007    (at your option) any later version.
00008 
00009    StepCore library 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 General Public License for more details.
00013 
00014    You should have received a copy of the GNU General Public License
00015    along with StepCore; if not, write to the Free Software
00016    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
00017 */
00018 
00023 #ifndef STEPCORE_OBJECT_H
00024 #define STEPCORE_OBJECT_H
00025 
00026 #include <QString>
00027 #include <QVariant>
00028 #include <QBitArray>
00029 
00030 #include "util.h"
00031 
00032 namespace StepCore {
00033 
00034 class MetaObject;
00035 class MetaProperty;
00036 
00037 #define STEPCORE_OBJECT(_className) \
00038     private: \
00039         typedef _className _thisType; \
00040         static const StepCore::MetaObject   _metaObject; \
00041         static const StepCore::MetaObject*  _superClasses[]; \
00042         static const StepCore::MetaProperty _classProperties[]; \
00043     public: \
00044         static  const StepCore::MetaObject* staticMetaObject() { return &_metaObject; } \
00045         virtual const StepCore::MetaObject* metaObject() const { return &_metaObject; } \
00046     private:
00047 
00051 class Object
00052 {
00053     STEPCORE_OBJECT(Object)
00054 
00055 public:
00056     explicit Object(const QString& name = QString()): _name(name) {}
00057     virtual ~Object() {}
00058 
00060     const QString& name() const { return _name; }
00062     void setName(const QString& name) { _name = name; }
00063 
00064 protected:
00065     QString _name;
00066 };
00067 
00071 class MetaProperty
00072 {
00073 public:
00074     enum {
00075         READABLE = 1, 
00076         WRITABLE = 2, 
00077         STORED = 4,   
00078         DYNAMIC = 32, 
00079         SIDEEFFECTS = 64 
00080 
00081 
00082     };
00083 
00084 public:
00085     MetaProperty():
00086         _name(""), _units(QString()), _description(""),
00087         _flags(0), _userTypeId(0), _readVariant(0), _writeVariant(0),
00088         _readString(0), _writeString(0) {}
00089 
00090     /*MetaProperty(const MetaProperty& p):
00091         _name(p._name), _units(p._units), _flags(p.flags), _userTypeId(p._userTypeId),
00092         _readVariant(p._readVariant), _writeVariant(p._writeVariant),
00093         _readString(p._readString), _writeString(p._writeString) {}*/
00094         
00095     MetaProperty(const QString& name, const QString& units,
00096                  const QString& description, int flags, int userType,
00097                  QVariant (*const readVariant)(const Object*),
00098                  bool (*const writeVariant)(Object* obj, const QVariant& v),
00099                  QString (*const readString)(const Object* obj),
00100                  bool (*const writeString)(Object* obj, const QString& v))
00101         : _name(name), _units(units), _description(description),
00102           _flags(flags), _userTypeId(userType),
00103           _readVariant(readVariant), _writeVariant(writeVariant),
00104           _readString(readString), _writeString(writeString) {}
00105 
00107     const QString& name() const { return _name; }
00109     const QString& units() const { return _units; }
00111     const QString& description() const { return _description; }
00113     int flags() const { return _flags; }
00114 
00116     int userTypeId() const { return _userTypeId; }
00118     QVariant readVariant(const Object* obj) const { return _readVariant(obj); }
00120     bool writeVariant(Object* obj, const QVariant& v) const { return _writeVariant(obj, v); }
00121 
00123     QString readString(const Object* obj) const { return _readString(obj); }
00125     bool writeString(Object* obj, const QString& s) const { return _writeString(obj, s); }
00126 
00128     bool isReadable() const { return _flags & READABLE; }
00130     bool isWritable() const { return _flags & WRITABLE; }
00132     bool isStored() const { return _flags & STORED; }
00134     bool isDynamic() const { return _flags & DYNAMIC; }
00137     bool hasSideEffects() const { return _flags & SIDEEFFECTS; }
00138 
00139 public:
00140     const QString _name;
00141     const QString _units;
00142     const QString _description;
00143     const int _flags;
00144     const int _userTypeId;
00145     QVariant (*const _readVariant)(const Object* obj);
00146     bool (*const _writeVariant)(Object* obj, const QVariant& v);
00147     QString (*const _readString)(const Object* obj);
00148     bool (*const _writeString)(Object* obj, const QString& v);
00149 };
00150 
00154 class MetaObject
00155 {
00156 public:
00157     enum {
00158         ABSTRACT = 1 
00159     };
00160 
00161 public:
00163     const QString& className() const { return _className; }
00165     const QString& description() const { return _description; }
00167     int classId() const { if(!_initialized) init(); return _classId; }
00168 
00170     bool isAbstract() const { return _flags & ABSTRACT; }
00172     Object* newObject() const { return _newObject(); }
00174     Object* cloneObject(const Object& obj) const { return _cloneObject(obj); }
00175 
00177     int superClassCount() const { return _superClassCount; }
00179     const MetaObject* superClass(int n) const { return _superClasses[n]; }
00181     bool inherits(const MetaObject* obj) const;
00183     template<class T> bool inherits() const { return inherits(T::staticMetaObject()); }
00185     template<class T> bool inherits(T*) const { return inherits(T::staticMetaObject()); }
00189     bool inherits(const char* name) const;
00190 
00192     int classPropertyCount() const { return _classPropertyCount; }
00194     const MetaProperty* classProperty(int n) const { return &_classProperties[n]; }
00195 
00197     int propertyCount() const { if(!_initialized) init(); return _allPropertyCount; }
00199     const MetaProperty* property(int n) const { if(!_initialized) init(); return _allProperties[n]; }
00201     const MetaProperty* property(const QString& name) const;
00202 
00203 public:
00204     void init() const;
00205     void copyProperties(const MetaProperty** dest) const;
00206 
00207     const QString     _className;
00208     const QString     _description;
00209     const int         _flags;
00210     Object* (*const _newObject)();
00211     Object* (*const _cloneObject)(const Object&);
00212 
00213     const MetaObject**  const _superClasses;
00214     const int                 _superClassCount;
00215     const MetaProperty* const _classProperties;
00216     const int                 _classPropertyCount;
00217 
00218     mutable bool                 _initialized;
00219     mutable const MetaProperty** _allProperties;
00220     mutable int                  _allPropertyCount;
00221 
00222     mutable int _classId;
00223     mutable QBitArray _allSuperClassIds;
00224 
00225     static int  s_classIdCount;
00226 };
00227 
00229 template<class _Dst, class _Src> // XXX: implement it better
00230 _Dst stepcore_cast(_Src src) {
00231     if(!src || !src->metaObject()->template inherits(_Dst())) return NULL;
00232     return static_cast<_Dst>(src);
00233 }
00234 
00235 /* Helper functions TODO: namespace of class ? */
00236 
00237 template<typename T> inline QString typeToString(const T& v) {
00238     return QVariant::fromValue(v).toString();
00239 }
00240 
00241 template<typename T> inline T stringToType(const QString& s, bool* ok) {
00242     QVariant v(s); *ok = v.convert((QVariant::Type) qMetaTypeId<T>());
00243     return v.value<T>();
00244 }
00245 
00246 template<typename T> inline QVariant typeToVariant(const T& v) {
00247     return QVariant::fromValue(v);
00248 }
00249 
00250 template<typename T> inline T variantToType(const QVariant& v, bool* ok) {
00251     if(v.userType() == qMetaTypeId<T>()) { *ok = true; return v.value<T>(); }
00252     QVariant vc(v); *ok = vc.convert((QVariant::Type)qMetaTypeId<T>());
00253     return vc.value<T>();
00254 }
00255 
00256 template<class C, typename T>
00257 struct MetaPropertyHelper {
00258 
00259     /* read */
00260     template<T (C::*_read)() const> static QVariant read(const Object* obj) {
00261         return typeToVariant<T>((dynamic_cast<const C*>(obj)->*_read)());
00262     }
00263     template<const T& (C::*_read)() const> static QVariant read(const Object* obj) {
00264         return typeToVariant<T>((dynamic_cast<const C*>(obj)->*_read)());
00265     }
00266 
00267     /* write */
00268     template<void (C::*_write)(T)> static bool write(Object* obj, const QVariant& v) {
00269         bool ok; T tv = variantToType<T>(v, &ok); if(!ok) return false;
00270         (dynamic_cast<C*>(obj)->*_write)(tv); return true;
00271     }
00272     template<void (C::*_write)(const T&)> static bool write(Object* obj, const QVariant& v) {
00273         bool ok; T tv = variantToType<T>(v, &ok); if(!ok) return false;
00274         (dynamic_cast<C*>(obj)->*_write)(tv); return true;
00275     }
00276     template<bool (C::*_write)(T)> static bool write(Object* obj, const QVariant& v) {
00277         bool ok; T tv = variantToType<T>(v, &ok); if(!ok) return false;
00278         return (dynamic_cast<C*>(obj)->*_write)(tv);
00279     }
00280     template<bool (C::*_write)(const T&)> static bool write(Object* obj, const QVariant& v) {
00281         bool ok; T tv = variantToType<T>(v, &ok); if(!ok) return false;
00282         return (dynamic_cast<C*>(obj)->*_write)(tv);
00283     }
00284 
00285     /* readString */
00286     template<T (C::*_read)() const> static QString readString(const Object* obj) {
00287         return typeToString<T>((dynamic_cast<const C*>(obj)->*_read)());
00288     }
00289     template<const T& (C::*_read)() const> static QString readString(const Object* obj) {
00290         return typeToString<T>((dynamic_cast<const C*>(obj)->*_read)());
00291     }
00292 
00293     /* writeString */
00294     template<void (C::*_write)(T)> static bool writeString(Object* obj, const QString& s) {
00295         bool ok; T tv = stringToType<T>(s, &ok); if(!ok) return false;
00296         (dynamic_cast<C*>(obj)->*_write)(tv); return true;
00297     }
00298     template<void (C::*_write)(const T&)> static bool writeString(Object* obj, const QString& s) {
00299         bool ok; T tv = stringToType<T>(s, &ok); if(!ok) return false;
00300         (dynamic_cast<C*>(obj)->*_write)(tv); return true;
00301     }
00302     template<bool (C::*_write)(T)> static bool writeString(Object* obj, const QString& s) {
00303         bool ok; T tv = stringToType<T>(s, &ok); if(!ok) return false;
00304         return (dynamic_cast<C*>(obj)->*_write)(tv);
00305     }
00306     template<bool (C::*_write)(const T&)> static bool writeString(Object* obj, const QString& s) {
00307         bool ok; T tv = stringToType<T>(s, &ok); if(!ok) return false;
00308         return (dynamic_cast<C*>(obj)->*_write)(tv);
00309     }
00310 
00311     static QVariant readNull(const Object* obj) { return QVariant(); }
00312     static QString readStringNull(const Object* obj) { return QString(); }
00313     static bool writeNull(Object* obj, const QVariant& v) { Q_UNUSED(obj) Q_UNUSED(v) return false; }
00314     static bool writeStringNull(Object* obj, const QString& s) { Q_UNUSED(obj) Q_UNUSED(s) return false; }
00315 };
00316 
00317 template<typename Class, int N>
00318 struct MetaObjectHelper {
00319     static Object* newObjectHelper() { return new Class(); }
00320     static Object* cloneObjectHelper(const Object& obj) {
00321         return new Class(static_cast<const Class&>(obj));
00322     }
00323 };
00324 
00325 template<class Class>
00326 struct MetaObjectHelper<Class, MetaObject::ABSTRACT> {
00327     static Object* newObjectHelper() { return NULL; }
00328     static Object* cloneObjectHelper(const Object& obj) { Q_UNUSED(obj) return NULL; }
00329 };
00330 
00331 #define STEPCORE_FROM_UTF8(str) QString::fromUtf8(str)
00332 
00333 #define STEPCORE_UNITS_NULL QString()
00334 #define STEPCORE_UNITS_1 QString("")
00335 
00336 #define _STEPCORE_PROPERTY_NULL StepCore::MetaProperty()
00337 
00338 #define STEPCORE_META_OBJECT(_className, _description, _flags, __superClasses, __properties) \
00339     const StepCore::MetaProperty _className::_classProperties[] = { _STEPCORE_PROPERTY_NULL, __properties }; \
00340     const StepCore::MetaObject*  _className::_superClasses[] = { 0, __superClasses }; \
00341     const StepCore::MetaObject   _className::_metaObject = { \
00342         QString(STEPCORE_STRINGIFY(_className)), QString(_description), _flags, \
00343         StepCore::MetaObjectHelper<_className, _flags & StepCore::MetaObject::ABSTRACT>::newObjectHelper, \
00344         StepCore::MetaObjectHelper<_className, _flags & StepCore::MetaObject::ABSTRACT>::cloneObjectHelper, \
00345         _superClasses+1, sizeof(_superClasses)/sizeof(*_superClasses)-1, \
00346         _classProperties+1, sizeof(_classProperties)/sizeof(*_classProperties)-1, false, 0, 0, 0, QBitArray() };
00347     
00348 #define STEPCORE_SUPER_CLASS(_className) _className::staticMetaObject(),
00349 
00350 #define STEPCORE_PROPERTY_RF(_type, _name, _units, _description, _flags, _read) \
00351     StepCore::MetaProperty( STEPCORE_STRINGIFY(_name), _units, _description, \
00352       StepCore::MetaProperty::READABLE | _flags, qMetaTypeId<_type>(), \
00353       StepCore::MetaPropertyHelper<_thisType, _type>::read<&_thisType::_read>, \
00354       StepCore::MetaPropertyHelper<_thisType, _type>::writeNull, \
00355       StepCore::MetaPropertyHelper<_thisType, _type>::readString<&_thisType::_read>, \
00356       StepCore::MetaPropertyHelper<_thisType, _type>::writeStringNull ),
00357 
00358 #define STEPCORE_PROPERTY_RWF(_type, _name, _units, _description, _flags, _read, _write) \
00359     StepCore::MetaProperty( STEPCORE_STRINGIFY(_name), _units, _description, \
00360       StepCore::MetaProperty::READABLE | StepCore::MetaProperty::WRITABLE | _flags, \
00361       qMetaTypeId<_type>(), \
00362       StepCore::MetaPropertyHelper<_thisType, _type>::read<&_thisType::_read>, \
00363       StepCore::MetaPropertyHelper<_thisType, _type>::write<&_thisType::_write>, \
00364       StepCore::MetaPropertyHelper<_thisType, _type>::readString<&_thisType::_read>, \
00365       StepCore::MetaPropertyHelper<_thisType, _type>::writeString<&_thisType::_write> ),
00366 
00367 #define STEPCORE_PROPERTY_R(_type, _name, _units, _description, _read) \
00368     STEPCORE_PROPERTY_RF(_type, _name, _units, _description, 0, _read)
00369 
00370 #define STEPCORE_PROPERTY_RW(_type, _name, _units, _description, _read, _write) \
00371     STEPCORE_PROPERTY_RWF(_type, _name, _units, _description, \
00372         StepCore::MetaProperty::STORED, _read, _write)
00373 
00374 #define STEPCORE_PROPERTY_R_D(_type, _name, _units, _description, _read) \
00375     STEPCORE_PROPERTY_RF(_type, _name, _units, _description, StepCore::MetaProperty::DYNAMIC, _read)
00376 
00377 #define STEPCORE_PROPERTY_RW_D(_type, _name, _units, _description, _read, _write) \
00378     STEPCORE_PROPERTY_RWF(_type, _name, _units, _description, \
00379         StepCore::MetaProperty::STORED | StepCore::MetaProperty::DYNAMIC, _read, _write)
00380 
00381 } // namespace StepCore
00382 
00383 #endif
00384 

step/stepcore

Skip menu "step/stepcore"
  • Main Page
  • Modules
  • Namespace List
  • Class Hierarchy
  • Alphabetical List
  • Class List
  • File List
  • Namespace Members
  • Class Members
  • Related Pages

kdeedu

Skip menu "kdeedu"
  • kalzium
  • kanagram
  • kig
  •   lib
  • klettres
  • kstars
  • libkdeedu
  •   keduvocdocument
  •   docs
  •   src
  • parley
  •   stepcore
Generated for kdeedu by doxygen 1.5.4
This website is maintained by Adriaan de Groot and Allen Winter.
KDE® and the K Desktop Environment® logo are registered trademarks of KDE e.V. | Legal