00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024 #ifndef QSCRIPTENGINE_H
00025 #define QSCRIPTENGINE_H
00026
00027 #include <QtCore/qmetatype.h>
00028
00029 #include <QtCore/qvariant.h>
00030 #include <QtCore/qsharedpointer.h>
00031
00032 #ifndef QT_NO_QOBJECT
00033 #include <QtCore/qobject.h>
00034 #else
00035 #include <QtCore/qobjectdefs.h>
00036 #endif
00037
00038 #include <QtScript/qscriptvalue.h>
00039 #include <QtScript/qscriptcontext.h>
00040 #include <QtScript/qscriptstring.h>
00041 #include <QtScript/qscriptprogram.h>
00042
00043 QT_BEGIN_HEADER
00044
00045 QT_BEGIN_NAMESPACE
00046
00047 QT_MODULE(Script)
00048
00049 class QDateTime;
00050 class QScriptClass;
00051 class QScriptEngineAgent;
00052 class QScriptEnginePrivate;
00053
00054 #ifndef QT_NO_QOBJECT
00055
00056 template <class T>
00057 inline QScriptValue qscriptQMetaObjectConstructor(QScriptContext *, QScriptEngine *, T *)
00058 {
00059 return QScriptValue();
00060 }
00061
00062 #endif // QT_NO_QOBJECT
00063
00064 #ifndef QT_NO_REGEXP
00065 class QRegExp;
00066 #endif
00067
00068 #ifndef QT_NO_MEMBER_TEMPLATES
00069 template <typename T>
00070 inline QScriptValue qScriptValueFromValue(QScriptEngine *, const T &);
00071
00072 template <typename T>
00073 inline T qScriptValueToValue(const QScriptValue &);
00074 #endif
00075
00076 class QScriptSyntaxCheckResultPrivate;
00077 class Q_SCRIPT_EXPORT QScriptSyntaxCheckResult
00078 {
00079 public:
00080 enum State {
00081 Error,
00082 Intermediate,
00083 Valid
00084 };
00085
00086 QScriptSyntaxCheckResult(const QScriptSyntaxCheckResult &other);
00087 ~QScriptSyntaxCheckResult();
00088
00089 State state() const;
00090 int errorLineNumber() const;
00091 int errorColumnNumber() const;
00092 QString errorMessage() const;
00093
00094 QScriptSyntaxCheckResult &operator=(const QScriptSyntaxCheckResult &other);
00095
00096 private:
00097 QScriptSyntaxCheckResult();
00098 QScriptSyntaxCheckResult(QScriptSyntaxCheckResultPrivate *d);
00099 QExplicitlySharedDataPointer<QScriptSyntaxCheckResultPrivate> d_ptr;
00100
00101 Q_DECLARE_PRIVATE(QScriptSyntaxCheckResult)
00102 friend class QScriptEngine;
00103 friend class QScriptEnginePrivate;
00104 };
00105
00106 class Q_SCRIPT_EXPORT QScriptEngine
00107 #ifndef QT_NO_QOBJECT
00108 : public QObject
00109 #endif
00110 {
00111 #ifndef QT_NO_QOBJECT
00112 Q_OBJECT
00113 #endif
00114 public:
00115 enum ValueOwnership {
00116 QtOwnership,
00117 ScriptOwnership,
00118 AutoOwnership
00119 };
00120
00121 enum QObjectWrapOption {
00122 ExcludeChildObjects = 0x0001,
00123 ExcludeSuperClassMethods = 0x0002,
00124 ExcludeSuperClassProperties = 0x0004,
00125 ExcludeSuperClassContents = 0x0006,
00126 SkipMethodsInEnumeration = 0x0008,
00127 ExcludeDeleteLater = 0x0010,
00128 ExcludeSlots = 0x0020,
00129
00130 AutoCreateDynamicProperties = 0x0100,
00131 PreferExistingWrapperObject = 0x0200
00132 };
00133 Q_DECLARE_FLAGS(QObjectWrapOptions, QObjectWrapOption)
00134
00135 QScriptEngine();
00136 #ifndef QT_NO_QOBJECT
00137 explicit QScriptEngine(QObject *parent);
00138 #endif
00139 virtual ~QScriptEngine();
00140
00141 QScriptValue globalObject() const;
00142 void setGlobalObject(const QScriptValue &object);
00143
00144 QScriptContext *currentContext() const;
00145 QScriptContext *pushContext();
00146 void popContext();
00147
00148 bool canEvaluate(const QString &program) const;
00149 static QScriptSyntaxCheckResult checkSyntax(const QString &program);
00150
00151 QScriptValue evaluate(const QString &program, const QString &fileName = QString(), int lineNumber = 1);
00152
00153 QScriptValue evaluate(const QScriptProgram &program);
00154
00155 bool isEvaluating() const;
00156 void abortEvaluation(const QScriptValue &result = QScriptValue());
00157
00158 bool hasUncaughtException() const;
00159 QScriptValue uncaughtException() const;
00160 int uncaughtExceptionLineNumber() const;
00161 QStringList uncaughtExceptionBacktrace() const;
00162 void clearExceptions();
00163
00164 QScriptValue nullValue();
00165 QScriptValue undefinedValue();
00166
00167 typedef QScriptValue (*FunctionSignature)(QScriptContext *, QScriptEngine *);
00168 typedef QScriptValue (*FunctionWithArgSignature)(QScriptContext *, QScriptEngine *, void *);
00169
00170 QScriptValue newFunction(FunctionSignature signature, int length = 0);
00171 QScriptValue newFunction(FunctionSignature signature, const QScriptValue &prototype, int length = 0);
00172
00173 QScriptValue newFunction(FunctionWithArgSignature signature, void *arg);
00174
00175 QScriptValue newVariant(const QVariant &value);
00176 QScriptValue newVariant(const QScriptValue &object, const QVariant &value);
00177
00178 #ifndef QT_NO_REGEXP
00179 QScriptValue newRegExp(const QRegExp ®exp);
00180 #endif
00181
00182 QScriptValue newObject();
00183 QScriptValue newObject(QScriptClass *scriptClass, const QScriptValue &data = QScriptValue());
00184 QScriptValue newArray(uint length = 0);
00185 QScriptValue newRegExp(const QString &pattern, const QString &flags);
00186 QScriptValue newDate(qsreal value);
00187 QScriptValue newDate(const QDateTime &value);
00188 QScriptValue newActivationObject();
00189
00190 #ifndef QT_NO_QOBJECT
00191 QScriptValue newQObject(QObject *object, ValueOwnership ownership = QtOwnership,
00192 const QObjectWrapOptions &options = 0);
00193 QScriptValue newQObject(const QScriptValue &scriptObject, QObject *qtObject,
00194 ValueOwnership ownership = QtOwnership,
00195 const QObjectWrapOptions &options = 0);
00196
00197 QScriptValue newQMetaObject(const QMetaObject *metaObject, const QScriptValue &ctor = QScriptValue());
00198
00199 # ifndef QT_NO_MEMBER_TEMPLATES
00200 template <class T> QScriptValue scriptValueFromQMetaObject();
00201 # endif // QT_NO_MEMBER_TEMPLATES
00202
00203 #endif // QT_NO_QOBJECT
00204
00205
00206
00207 QScriptValue defaultPrototype(int metaTypeId) const;
00208 void setDefaultPrototype(int metaTypeId, const QScriptValue &prototype);
00209
00210
00211 typedef QScriptValue (*MarshalFunction)(QScriptEngine *, const void *);
00212 typedef void (*DemarshalFunction)(const QScriptValue &, void *);
00213
00214
00215
00216 #ifndef QT_NO_MEMBER_TEMPLATES
00217 template <typename T>
00218 inline QScriptValue toScriptValue(const T &value)
00219 {
00220 return qScriptValueFromValue(this, value);
00221 }
00222 template <typename T>
00223 inline T fromScriptValue(const QScriptValue &value)
00224 {
00225 return qScriptValueToValue<T>(value);
00226 }
00227 #endif // QT_NO_MEMBER_TEMPLATES
00228
00229 void installTranslatorFunctions(const QScriptValue &object = QScriptValue());
00230
00231 QScriptValue importExtension(const QString &extension);
00232 QStringList availableExtensions() const;
00233 QStringList importedExtensions() const;
00234
00235 void collectGarbage();
00236 void reportAdditionalMemoryCost(int size);
00237
00238 void setProcessEventsInterval(int interval);
00239 int processEventsInterval() const;
00240
00241 void setAgent(QScriptEngineAgent *agent);
00242 QScriptEngineAgent *agent() const;
00243
00244 QScriptString toStringHandle(const QString &str);
00245 QScriptValue toObject(const QScriptValue &value);
00246
00247 QScriptValue objectById(qint64 id) const;
00248
00249 #ifndef QT_NO_QOBJECT
00250 Q_SIGNALS:
00251 void signalHandlerException(const QScriptValue &exception);
00252 #endif
00253
00254 private:
00255 QScriptValue create(int type, const void *ptr);
00256
00257 bool convert(const QScriptValue &value, int type, void *ptr);
00258 static bool convertV2(const QScriptValue &value, int type, void *ptr);
00259
00260 void registerCustomType(int type, MarshalFunction mf, DemarshalFunction df,
00261 const QScriptValue &prototype);
00262
00263 friend inline void qScriptRegisterMetaType_helper(QScriptEngine *,
00264 int, MarshalFunction, DemarshalFunction, const QScriptValue &);
00265
00266 friend inline QScriptValue qScriptValueFromValue_helper(QScriptEngine *, int, const void *);
00267
00268 friend inline bool qscriptvalue_cast_helper(const QScriptValue &, int, void *);
00269
00270 protected:
00271 #ifdef QT_NO_QOBJECT
00272 QScopedPointer<QScriptEnginePrivate> d_ptr;
00273
00274 QScriptEngine(QScriptEnginePrivate &dd);
00275 #else
00276 QScriptEngine(QScriptEnginePrivate &dd, QObject *parent = 0);
00277 #endif
00278
00279 private:
00280 Q_DECLARE_PRIVATE(QScriptEngine)
00281 Q_DISABLE_COPY(QScriptEngine)
00282 #ifndef QT_NO_QOBJECT
00283 Q_PRIVATE_SLOT(d_func(), void _q_objectDestroyed(QObject *))
00284 #endif
00285 };
00286
00287 #ifndef QT_NO_QOBJECT
00288 template <class T>
00289 inline QScriptValue qScriptValueFromQMetaObject(
00290 QScriptEngine *engine
00291 #ifndef qdoc
00292 , T * = 0
00293 #endif
00294 )
00295 {
00296 typedef QScriptValue(*ConstructPtr)(QScriptContext *, QScriptEngine *, T *);
00297 ConstructPtr cptr = qscriptQMetaObjectConstructor<T>;
00298 return engine->newQMetaObject(&T::staticMetaObject,
00299 engine->newFunction(reinterpret_cast<QScriptEngine::FunctionWithArgSignature>(cptr), 0));
00300 }
00301
00302 #define Q_SCRIPT_DECLARE_QMETAOBJECT(T, _Arg1) \
00303 template<> inline QScriptValue qscriptQMetaObjectConstructor<T>(QScriptContext *ctx, QScriptEngine *eng, T *) \
00304 { \
00305 _Arg1 arg1 = qscriptvalue_cast<_Arg1> (ctx->argument(0)); \
00306 T* t = new T(arg1); \
00307 if (ctx->isCalledAsConstructor()) \
00308 return eng->newQObject(ctx->thisObject(), t, QScriptEngine::AutoOwnership); \
00309 QScriptValue o = eng->newQObject(t, QScriptEngine::AutoOwnership); \
00310 o.setPrototype(ctx->callee().property(QString::fromLatin1("prototype"))); \
00311 return o; \
00312 }
00313
00314 # ifndef QT_NO_MEMBER_TEMPLATES
00315 template <class T> QScriptValue QScriptEngine::scriptValueFromQMetaObject()
00316 {
00317 return qScriptValueFromQMetaObject<T>(this);
00318 }
00319 # endif // QT_NO_MEMBER_TEMPLATES
00320
00321 #endif // QT_NO_QOBJECT
00322
00323 inline QScriptValue qScriptValueFromValue_helper(QScriptEngine *engine, int type, const void *ptr)
00324 {
00325 if (!engine)
00326 return QScriptValue();
00327
00328 return engine->create(type, ptr);
00329 }
00330
00331 template <typename T>
00332 inline QScriptValue qScriptValueFromValue(QScriptEngine *engine, const T &t)
00333 {
00334 return qScriptValueFromValue_helper(engine, qMetaTypeId<T>(), &t);
00335 }
00336
00337 template <>
00338 inline QScriptValue qScriptValueFromValue<QVariant>(QScriptEngine *engine, const QVariant &v)
00339 {
00340 QScriptValue result = qScriptValueFromValue_helper(engine, v.userType(), v.data());
00341 if (!result.isValid())
00342 result = engine->newVariant(v);
00343 return result;
00344 }
00345
00346 inline bool qscriptvalue_cast_helper(const QScriptValue &value, int type, void *ptr)
00347 {
00348 return QScriptEngine::convertV2(value, type, ptr);
00349 }
00350
00351 template<typename T>
00352 T qscriptvalue_cast(const QScriptValue &value
00353 #if !defined qdoc && defined Q_CC_MSVC && _MSC_VER < 1300
00354 , T * = 0
00355 #endif
00356 )
00357 {
00358 T t;
00359 const int id = qMetaTypeId<T>();
00360
00361 if (qscriptvalue_cast_helper(value, id, &t))
00362 return t;
00363 else if (value.isVariant())
00364 return qvariant_cast<T>(value.toVariant());
00365
00366 return T();
00367 }
00368
00369 #if !defined Q_CC_MSVC || _MSC_VER >= 1300
00370 template <>
00371 inline QVariant qscriptvalue_cast<QVariant>(const QScriptValue &value)
00372 {
00373 return value.toVariant();
00374 }
00375 #endif
00376
00377 template <typename T>
00378 inline T qScriptValueToValue(const QScriptValue &value)
00379 {
00380 return qscriptvalue_cast<T>(value);
00381 }
00382
00383 inline void qScriptRegisterMetaType_helper(QScriptEngine *eng, int type,
00384 QScriptEngine::MarshalFunction mf,
00385 QScriptEngine::DemarshalFunction df,
00386 const QScriptValue &prototype)
00387 {
00388 eng->registerCustomType(type, mf, df, prototype);
00389 }
00390
00391 template<typename T>
00392 int qScriptRegisterMetaType(
00393 QScriptEngine *eng,
00394 QScriptValue (*toScriptValue)(QScriptEngine *, const T &t),
00395 void (*fromScriptValue)(const QScriptValue &, T &t),
00396 const QScriptValue &prototype = QScriptValue()
00397 #ifndef qdoc
00398 , T * = 0
00399 #endif
00400 )
00401 {
00402 const int id = qRegisterMetaType<T>();
00403
00404 qScriptRegisterMetaType_helper(
00405 eng, id, reinterpret_cast<QScriptEngine::MarshalFunction>(toScriptValue),
00406 reinterpret_cast<QScriptEngine::DemarshalFunction>(fromScriptValue),
00407 prototype);
00408
00409 return id;
00410 }
00411
00412 template <class Container>
00413 QScriptValue qScriptValueFromSequence(QScriptEngine *eng, const Container &cont)
00414 {
00415 QScriptValue a = eng->newArray();
00416 typename Container::const_iterator begin = cont.begin();
00417 typename Container::const_iterator end = cont.end();
00418 typename Container::const_iterator it;
00419 quint32 i;
00420 for (it = begin, i = 0; it != end; ++it, ++i)
00421 a.setProperty(i, qScriptValueFromValue(eng, *it));
00422 return a;
00423 }
00424
00425 template <class Container>
00426 void qScriptValueToSequence(const QScriptValue &value, Container &cont)
00427 {
00428 quint32 len = value.property(QLatin1String("length")).toUInt32();
00429 for (quint32 i = 0; i < len; ++i) {
00430 QScriptValue item = value.property(i);
00431 #if defined Q_CC_MSVC && !defined Q_CC_MSVC_NET
00432 cont.push_back(qscriptvalue_cast<Container::value_type>(item));
00433 #else
00434 cont.push_back(qscriptvalue_cast<typename Container::value_type>(item));
00435 #endif
00436 }
00437 }
00438
00439 template<typename T>
00440 int qScriptRegisterSequenceMetaType(
00441 QScriptEngine *engine,
00442 const QScriptValue &prototype = QScriptValue()
00443 #ifndef qdoc
00444 , T * = 0
00445 #endif
00446 )
00447 {
00448 return qScriptRegisterMetaType<T>(engine, qScriptValueFromSequence,
00449 qScriptValueToSequence, prototype);
00450 }
00451
00452 #ifndef QT_NO_QOBJECT
00453 Q_SCRIPT_EXPORT bool qScriptConnect(QObject *sender, const char *signal,
00454 const QScriptValue &receiver,
00455 const QScriptValue &function);
00456 Q_SCRIPT_EXPORT bool qScriptDisconnect(QObject *sender, const char *signal,
00457 const QScriptValue &receiver,
00458 const QScriptValue &function);
00459 #endif // QT_NO_QOBJECT
00460
00461 Q_DECLARE_OPERATORS_FOR_FLAGS(QScriptEngine::QObjectWrapOptions)
00462
00463 QT_END_NAMESPACE
00464
00465 QT_END_HEADER
00466
00467 #endif // QSCRIPTENGINE_H