00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038 #ifndef QTSCRIPTEXTENSIONS_GLOBAL_H
00039 #define QTSCRIPTEXTENSIONS_GLOBAL_H
00040
00041 #include <QtCore/QSharedData>
00042
00043 #define DECLARE_SELF(Class, __fn__) \
00044 Class* self = qscriptvalue_cast<Class*>(ctx->thisObject()); \
00045 if (!self) { \
00046 return ctx->throwError(QScriptContext::TypeError, \
00047 QString::fromLatin1("%0.prototype.%1: this object is not a %0") \
00048 .arg(#Class).arg(#__fn__)); \
00049 }
00050
00051 #define DECLARE_SELF2(Class, __fn__, __ret__) \
00052 Class* self = qscriptvalue_cast<Class*>(thisObject()); \
00053 if (!self) { \
00054 context()->throwError(QScriptContext::TypeError, \
00055 QString::fromLatin1("%0.prototype.%1: this object is not a %0") \
00056 .arg(#Class).arg(#__fn__)); \
00057 return __ret__; \
00058 }
00059
00060
00061
00062 #define ADD_METHOD(__p__, __f__) \
00063 __p__.setProperty(#__f__, __p__.engine()->newFunction(__f__))
00064
00065 #define ADD_GET_METHOD(__p__, __get__) \
00066 ADD_METHOD(__p__, __get__)
00067
00068 #define ADD_GET_SET_METHODS(__p__, __get__, __set__) \
00069 do { \
00070 ADD_METHOD(__p__, __get__); \
00071 ADD_METHOD(__p__, __set__); \
00072 } while (0);
00073
00074 #define ADD_CTOR_FUNCTION(__c__, __f__) ADD_METHOD(__c__, __f__)
00075
00076 #define ADD_ENUM_VALUE(__c__, __ns__, __v__) \
00077 __c__.setProperty(#__v__, QScriptValue(__c__.engine(), __ns__::__v__))
00078
00079
00080 #define BEGIN_DECLARE_METHOD(Class, __mtd__) \
00081 static QScriptValue __mtd__(QScriptContext *ctx, QScriptEngine *eng) \
00082 { \
00083 DECLARE_SELF(Class, __mtd__);
00084
00085 #define END_DECLARE_METHOD \
00086 }
00087
00088
00089 #define DECLARE_GET_METHOD(Class, __get__) \
00090 BEGIN_DECLARE_METHOD(Class, __get__) { \
00091 return qScriptValueFromValue(eng, self->__get__()); \
00092 } END_DECLARE_METHOD
00093
00094 #define DECLARE_SET_METHOD(Class, T, __set__) \
00095 BEGIN_DECLARE_METHOD(Class, __set__) { \
00096 self->__set__(qscriptvalue_cast<T>(ctx->argument(0))); \
00097 return eng->undefinedValue(); \
00098 } END_DECLARE_METHOD
00099
00100 #define DECLARE_GET_SET_METHODS(Class, T, __get__, __set__) \
00101 DECLARE_GET_METHOD(Class, __get__) \
00102 DECLARE_SET_METHOD(Class, T, __set__)
00103
00104
00105
00106 #define DECLARE_SIMPLE_GET_METHOD(Class, __get__) \
00107 BEGIN_DECLARE_METHOD(Class, __get__) { \
00108 return QScriptValue(eng, self->__get__()); \
00109 } END_DECLARE_METHOD
00110
00111 #define DECLARE_SIMPLE_SET_METHOD(Class, ToType, __set__) \
00112 BEGIN_DECLARE_METHOD(Class, __set__) { \
00113 self->__set__(ctx->argument(0).ToType()); \
00114 return eng->undefinedValue(); \
00115 } END_DECLARE_METHOD
00116
00117 #define DECLARE_BOOLEAN_GET_METHOD(Class, __set__) \
00118 DECLARE_SIMPLE_GET_METHOD(Class, __set__)
00119 #define DECLARE_BOOLEAN_SET_METHOD(Class, __set__) \
00120 DECLARE_SIMPLE_SET_METHOD(Class, toBoolean, __set__)
00121
00122 #define DECLARE_INT_GET_METHOD(Class, __set__) \
00123 DECLARE_SIMPLE_GET_METHOD(Class, __set__)
00124 #define DECLARE_INT_SET_METHOD(Class, __set__) \
00125 DECLARE_SIMPLE_SET_METHOD(Class, toInt32, __set__)
00126
00127 #define DECLARE_NUMBER_GET_METHOD(Class, __set__) \
00128 DECLARE_SIMPLE_GET_METHOD(Class, __set__)
00129 #define DECLARE_NUMBER_SET_METHOD(Class, __set__) \
00130 DECLARE_SIMPLE_SET_METHOD(Class, toNumber, __set__)
00131
00132 #define DECLARE_STRING_GET_METHOD(Class, __set__) \
00133 DECLARE_SIMPLE_GET_METHOD(Class, __set__)
00134 #define DECLARE_STRING_SET_METHOD(Class, __set__) \
00135 DECLARE_SIMPLE_SET_METHOD(Class, toString, __set__)
00136
00137 #define DECLARE_QOBJECT_GET_METHOD(Class, __get__) \
00138 BEGIN_DECLARE_METHOD(Class, __get__) { \
00139 return eng->newQObject(self->__get__()); \
00140 } END_DECLARE_METHOD
00141 #define DECLARE_QOBJECT_SET_METHOD(Class, __set__) \
00142 DECLARE_SIMPLE_SET_METHOD(Class, toQObject, __set__)
00143
00144 #define DECLARE_BOOLEAN_GET_SET_METHODS(Class, __get__, __set__) \
00145 DECLARE_BOOLEAN_GET_METHOD(Class, __get__) \
00146 DECLARE_BOOLEAN_SET_METHOD(Class, __set__)
00147
00148 #define DECLARE_NUMBER_GET_SET_METHODS(Class, __get__, __set__) \
00149 DECLARE_NUMBER_GET_METHOD(Class, __get__) \
00150 DECLARE_NUMBER_SET_METHOD(Class, __set__)
00151
00152 #define DECLARE_INT_GET_SET_METHODS(Class, __get__, __set__) \
00153 DECLARE_INT_GET_METHOD(Class, __get__) \
00154 DECLARE_INT_SET_METHOD(Class, __set__)
00155
00156 #define DECLARE_STRING_GET_SET_METHODS(Class, __get__, __set__) \
00157 DECLARE_STRING_GET_METHOD(Class, __get__) \
00158 DECLARE_STRING_SET_METHOD(Class, __set__)
00159
00160 #define DECLARE_QOBJECT_GET_SET_METHODS(Class, __get__, __set__) \
00161 DECLARE_QOBJECT_GET_METHOD(Class, __get__) \
00162 DECLARE_QOBJECT_SET_METHOD(Class, __set__)
00163
00164
00165 #define DECLARE_VOID_METHOD(Class, __fun__) \
00166 BEGIN_DECLARE_METHOD(Class, __fun__) { \
00167 self->__fun__(); \
00168 return eng->undefinedValue(); \
00169 } END_DECLARE_METHOD
00170
00171 #define DECLARE_VOID_NUMBER_METHOD(Class, __fun__) \
00172 BEGIN_DECLARE_METHOD(Class, __fun__) { \
00173 self->__fun__(ctx->argument(0).toNumber()); \
00174 return eng->undefinedValue(); \
00175 } END_DECLARE_METHOD
00176
00177 #define DECLARE_VOID_NUMBER_NUMBER_METHOD(Class, __fun__) \
00178 BEGIN_DECLARE_METHOD(Class, __fun__) { \
00179 self->__fun__(ctx->argument(0).toNumber(), ctx->argument(1).toNumber()); \
00180 return eng->undefinedValue(); \
00181 } END_DECLARE_METHOD
00182
00183 #define DECLARE_VOID_1ARG_METHOD(Class, ArgType, __fun__) \
00184 BEGIN_DECLARE_METHOD(Class, __fun__) { \
00185 self->__fun__(qscriptvalue_cast<ArgType>(ctx->argument(0))); \
00186 return eng->undefinedValue(); \
00187 } END_DECLARE_METHOD
00188
00189 #define DECLARE_BOOLEAN_1ARG_METHOD(Class, ArgType, __fun__) \
00190 BEGIN_DECLARE_METHOD(Class, __fun__) { \
00191 return QScriptValue(eng, self->__fun__(qscriptvalue_cast<ArgType>(ctx->argument(0)))); \
00192 } END_DECLARE_METHOD
00193
00194
00195 #define DECLARE_POINTER_METATYPE(T) \
00196 Q_DECLARE_METATYPE(T*) \
00197 Q_DECLARE_METATYPE(QScript::Pointer<T>::wrapped_pointer_type)
00198
00199 namespace QScript
00200 {
00201
00202 enum {
00203 UserOwnership = 1
00204 };
00205
00206 template <typename T>
00207 class Pointer : public QSharedData
00208 {
00209 public:
00210 typedef T* pointer_type;
00211 typedef QExplicitlySharedDataPointer<Pointer<T> > wrapped_pointer_type;
00212
00213 ~Pointer()
00214 {
00215 if (!(m_flags & UserOwnership))
00216 delete m_value;
00217 }
00218
00219 operator T*()
00220 {
00221 return m_value;
00222 }
00223
00224 operator const T*() const
00225 {
00226 return m_value;
00227 }
00228
00229 static wrapped_pointer_type create(T *value, uint flags = 0)
00230 {
00231 return wrapped_pointer_type(new Pointer(value, flags));
00232 }
00233
00234 static QScriptValue toScriptValue(QScriptEngine *engine, T* const &source)
00235 {
00236 if (!source)
00237 return engine->nullValue();
00238 return engine->newVariant(qVariantFromValue(source));
00239 }
00240
00241 static void fromScriptValue(const QScriptValue &value, T* &target)
00242 {
00243 if (value.isVariant()) {
00244 QVariant var = value.toVariant();
00245 if (qVariantCanConvert<T*>(var)) {
00246 target = qvariant_cast<T*>(var);
00247 } else if (qVariantCanConvert<wrapped_pointer_type>(var)) {
00248 target = qvariant_cast<wrapped_pointer_type>(var)->operator T*();
00249 } else {
00250
00251 target = 0;
00252 int type = qMetaTypeId<T*>();
00253 int pointerType = qMetaTypeId<wrapped_pointer_type>();
00254 QScriptValue proto = value.prototype();
00255 while (proto.isObject() && proto.isVariant()) {
00256 int protoType = proto.toVariant().userType();
00257 if ((type == protoType) || (pointerType == protoType)) {
00258 QByteArray name = QMetaType::typeName(var.userType());
00259 if (name.startsWith("QScript::Pointer<")) {
00260 target = (*reinterpret_cast<wrapped_pointer_type*>(var.data()))->operator T*();
00261 break;
00262 } else {
00263 target = static_cast<T*>(var.data());
00264 break;
00265 }
00266 }
00267 proto = proto.prototype();
00268 }
00269 }
00270 } else if (value.isQObject()) {
00271 QObject *qobj = value.toQObject();
00272 QByteArray typeName = QMetaType::typeName(qMetaTypeId<T*>());
00273 target = reinterpret_cast<T*>(qobj->qt_metacast(typeName.left(typeName.size()-1)));
00274 } else {
00275 target = 0;
00276 }
00277 }
00278
00279 uint flags() const
00280 { return m_flags; }
00281 void setFlags(uint flags)
00282 { m_flags = flags; }
00283 void unsetFlags(uint flags)
00284 { m_flags &= ~flags; }
00285
00286 protected:
00287 Pointer(T* value, uint flags)
00288 : m_flags(flags), m_value(value)
00289 {}
00290
00291 private:
00292 uint m_flags;
00293 T* m_value;
00294 };
00295
00296 template <typename T>
00297 int registerPointerMetaType(
00298 QScriptEngine *eng,
00299 const QScriptValue &prototype = QScriptValue(),
00300 T * = 0
00301 )
00302 {
00303 QScriptValue (*mf)(QScriptEngine *, T* const &) = Pointer<T>::toScriptValue;
00304 void (*df)(const QScriptValue &, T* &) = Pointer<T>::fromScriptValue;
00305 const int id = qMetaTypeId<T*>();
00306 qScriptRegisterMetaType_helper(
00307 eng, id, reinterpret_cast<QScriptEngine::MarshalFunction>(mf),
00308 reinterpret_cast<QScriptEngine::DemarshalFunction>(df),
00309 prototype);
00310 eng->setDefaultPrototype(qMetaTypeId<typename Pointer<T>::wrapped_pointer_type>(), prototype);
00311 return id;
00312 }
00313
00314 inline void maybeReleaseOwnership(const QScriptValue &value)
00315 {
00316 if (value.isVariant()) {
00317 QVariant var = value.toVariant();
00318 QByteArray name = QMetaType::typeName(var.userType());
00319 if (name.startsWith("QScript::Pointer<"))
00320 (*reinterpret_cast<Pointer<void*>::wrapped_pointer_type *>(var.data()))->setFlags(UserOwnership);
00321 }
00322 }
00323
00324 inline void maybeTakeOwnership(const QScriptValue &value)
00325 {
00326 if (value.isVariant()) {
00327 QVariant var = value.toVariant();
00328 QByteArray name = QMetaType::typeName(var.userType());
00329 if (name.startsWith("QScript::Pointer<"))
00330 (*reinterpret_cast<Pointer<void*>::wrapped_pointer_type *>(var.data()))->unsetFlags(UserOwnership);
00331 }
00332 }
00333
00334 template <class T>
00335 inline QScriptValue wrapPointer(QScriptEngine *eng, T *ptr, uint flags = 0)
00336 {
00337 return eng->newVariant(qVariantFromValue(Pointer<T>::create(ptr, flags)));
00338 }
00339
00340 }
00341
00342 #ifdef QGRAPHICSITEM_H
00343
00344 namespace QScript {
00345
00346 template <class T>
00347 inline QScriptValue wrapGVPointer(QScriptEngine *eng, T *item)
00348 {
00349 uint flags = item->parentItem() ? UserOwnership : 0;
00350 return wrapPointer<T>(eng, item, flags);
00351 }
00352
00353 }
00354
00355 #endif // QGRAPHICSITEM_H
00356
00357 #endif // QTSCRIPTEXTENSIONS_GLOBAL_H