diff options
author | Aaron Kennedy <aaron.kennedy@nokia.com> | 2011-06-09 12:34:59 +1000 |
---|---|---|
committer | Aaron Kennedy <aaron.kennedy@nokia.com> | 2011-06-09 12:34:59 +1000 |
commit | d9d952d3c0475b1e7f7b8df2b062f85f24387aca (patch) | |
tree | acaca0f2bfb6a1d20110f8a952e18c6f6e04f3f4 | |
parent | 0ad1d429820aae65d1b69813bf354455de3a1669 (diff) |
Allow extensions to register with the QV8Engine
This means we don't have to modify the QV8Engine class every time
a new JS API is added.
-rw-r--r-- | src/declarative/qml/v8/qv8engine.cpp | 33 | ||||
-rw-r--r-- | src/declarative/qml/v8/qv8engine_p.h | 43 |
2 files changed, 74 insertions, 2 deletions
diff --git a/src/declarative/qml/v8/qv8engine.cpp b/src/declarative/qml/v8/qv8engine.cpp index 530c9b0ef3..c7f05f0473 100644 --- a/src/declarative/qml/v8/qv8engine.cpp +++ b/src/declarative/qml/v8/qv8engine.cpp @@ -73,6 +73,10 @@ QV8Engine::QV8Engine() QV8Engine::~QV8Engine() { + for (int ii = 0; ii < m_extensionData.count(); ++ii) + delete m_extensionData[ii]; + m_extensionData.clear(); + qt_rem_qmlsqldatabase(this, m_sqlDatabaseData); m_sqlDatabaseData = 0; qt_rem_qmlxmlhttprequest(this, m_xmlHttpRequestData); @@ -149,6 +153,7 @@ QVariant QV8Engine::toVariant(v8::Handle<v8::Value> value, int typeHint) case QV8ObjectResource::DOMNodeType: case QV8ObjectResource::SQLDatabaseType: case QV8ObjectResource::ListModelType: + case QV8ObjectResource::Context2DType: return QVariant(); case QV8ObjectResource::QObjectType: return qVariantFromValue<QObject *>(m_qobjectWrapper.toQObject(r)); @@ -651,6 +656,34 @@ void QV8Engine::releaseHandle(void *handle) } #endif +struct QV8EngineRegistrationData +{ + QMutex mutex; + int extensionCount; +}; +Q_GLOBAL_STATIC(QV8EngineRegistrationData, registrationData); + +QMutex *QV8Engine::registrationMutex() +{ + return ®istrationData()->mutex; +} + +int QV8Engine::registerExtension() +{ + return registrationData()->extensionCount++; +} + +void QV8Engine::setExtensionData(int index, Deletable *data) +{ + if (m_extensionData.count() <= index) + m_extensionData.resize(index); + + if (m_extensionData.at(index)) + delete m_extensionData.at(index); + + m_extensionData[index] = data; +} + v8::Handle<v8::Value> QV8Engine::gc(const v8::Arguments &args) { gc(); diff --git a/src/declarative/qml/v8/qv8engine_p.h b/src/declarative/qml/v8/qv8engine_p.h index ee0b9115a3..1843460f76 100644 --- a/src/declarative/qml/v8/qv8engine_p.h +++ b/src/declarative/qml/v8/qv8engine_p.h @@ -56,6 +56,7 @@ #include <QtCore/qglobal.h> #include <QtCore/qvariant.h> #include <QtCore/qset.h> +#include <QtCore/qmutex.h> #include <private/qv8_p.h> #include <private/qdeclarativepropertycache_p.h> @@ -85,11 +86,33 @@ private: #define V8ENGINE() ((QV8Engine *)v8::External::Unwrap(args.Data())) #define V8FUNCTION(function, engine) v8::FunctionTemplate::New(function, v8::External::Wrap((QV8Engine*)engine))->GetFunction() -// XXX Are we mean to return a value here, or is an empty handle ok? #define V8THROW_ERROR(string) { \ v8::ThrowException(v8::Exception::Error(v8::String::New(string))); \ return v8::Handle<v8::Value>(); \ } +#define V8ENGINE_ACCESSOR() ((QV8Engine *)v8::External::Unwrap(info.Data())); +#define V8THROW_ERROR_SETTER(string) { \ + v8::ThrowException(v8::Exception::Error(v8::String::New(string))); \ + return; \ +} + +#define V8_DEFINE_EXTENSION(dataclass, datafunction) \ + inline dataclass *datafunction(QV8Engine *engine) \ + { \ + static int extensionId = -1; \ + if (extensionId == -1) { \ + QV8Engine::registrationMutex()->lock(); \ + if (extensionId == -1) \ + extensionId = QV8Engine::registerExtension(); \ + QV8Engine::registrationMutex()->unlock(); \ + } \ + dataclass *rv = (dataclass *)engine->extensionData(extensionId); \ + if (!rv) { \ + rv = new dataclass(engine); \ + engine->setExtensionData(extensionId, rv); \ + } \ + return rv; \ + } \ class QV8Engine; class QV8ObjectResource : public v8::Object::ExternalResource @@ -98,7 +121,7 @@ public: QV8ObjectResource(QV8Engine *engine) : engine(engine) { Q_ASSERT(engine); } enum ResourceType { ContextType, QObjectType, TypeType, ListType, VariantType, ValueTypeType, XMLHttpRequestType, DOMNodeType, SQLDatabaseType, - ListModelType }; + ListModelType, Context2DType }; virtual ResourceType resourceType() const = 0; QV8Engine *engine; @@ -253,6 +276,12 @@ public: static void releaseHandle(void *); #endif + static QMutex *registrationMutex(); + static int registerExtension(); + + inline Deletable *extensionData(int) const; + void setExtensionData(int, Deletable *); + private: QDeclarativeEngine *m_engine; v8::Persistent<v8::Context> m_context; @@ -269,6 +298,8 @@ private: void *m_xmlHttpRequestData; void *m_sqlDatabaseData; + + QVector<Deletable *> m_extensionData; Deletable *m_listModelData; QSet<QString> m_illegalNames; @@ -404,6 +435,14 @@ bool QV8Engine::startsWithUpper(v8::Handle<v8::String> string) ((c >= 'A' && c <= 'Z') || QChar::category(c) == QChar::Letter_Uppercase)); } +QV8Engine::Deletable *QV8Engine::extensionData(int index) const +{ + if (index < m_extensionData.count()) + return m_extensionData[index]; + else + return 0; +} + QT_END_NAMESPACE #endif // QDECLARATIVEV8ENGINE_P_H |