00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
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
00091
00092
00093
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>
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
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
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
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
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
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 }
00382
00383 #endif
00384