qscriptengine.h

Go to the documentation of this file.
00001 /****************************************************************************
00002 **
00003 ** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
00004 ** All rights reserved.
00005 ** Contact: Nokia Corporation (qt-info@nokia.com)
00006 **
00007 ** This file is part of the QtScript module of the Qt Toolkit.
00008 **
00009 ** $QT_BEGIN_LICENSE:LGPL-ONLY$
00010 ** GNU Lesser General Public License Usage
00011 ** This file may be used under the terms of the GNU Lesser
00012 ** General Public License version 2.1 as published by the Free Software
00013 ** Foundation and appearing in the file LICENSE.LGPL included in the
00014 ** packaging of this file.  Please review the following information to
00015 ** ensure the GNU Lesser General Public License version 2.1 requirements
00016 ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
00017 **
00018 ** If you have questions regarding the use of this file, please contact
00019 ** Nokia at qt-info@nokia.com.
00020 ** $QT_END_LICENSE$
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 &regexp);
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 * /* dummy */ = 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 * /* dummy */ = 0
00399 #endif
00400 )
00401 {
00402     const int id = qRegisterMetaType<T>(); // make sure it's registered
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 * /* dummy */ = 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