summaryrefslogtreecommitdiffstats
path: root/src/core/api
diff options
context:
space:
mode:
authorAndras Becsi <andras.becsi@theqtcompany.com>2015-05-11 14:32:01 +0200
committerLiang Qi <liang.qi@theqtcompany.com>2015-06-08 10:56:08 +0000
commit8c3178b64d992435cb90a426ff075fee6778e04a (patch)
treee53836e4824073851f94d4c6fcfac99526f0a100 /src/core/api
parentbfef77e3ca0d82253fb70ff178ff5a826c671d55 (diff)
Move QWebEngineCallback to core API and templatize CallbackDirectory
This undocumented helper template will also be utilized by the core API since Chromium's content API heavily relies on callbacks. To make the internal CallbackDirectory easily extendable with new types, templatize its callback registration and dispatching functions to be able to replace its type switches and the internal union. Change-Id: I3f636fef48973ac95253f1c1bd396550286e571e Reviewed-by: Pierre Rossi <pierre.rossi@theqtcompany.com>
Diffstat (limited to 'src/core/api')
-rw-r--r--src/core/api/core_api.pro2
-rw-r--r--src/core/api/qwebenginecallback.h92
-rw-r--r--src/core/api/qwebenginecallback_p.h213
3 files changed, 307 insertions, 0 deletions
diff --git a/src/core/api/core_api.pro b/src/core/api/core_api.pro
index 829b59925..e0a6c2de4 100644
--- a/src/core/api/core_api.pro
+++ b/src/core/api/core_api.pro
@@ -26,6 +26,8 @@ INCLUDEPATH += $$QTWEBENGINE_ROOT/src/core \
linux-g++*: QMAKE_CXXFLAGS += -Wno-unused-parameter
HEADERS = \
+ qwebenginecallback.h \
+ qwebenginecallback_p.h \
qtwebenginecoreglobal.h \
qtwebenginecoreglobal_p.h \
diff --git a/src/core/api/qwebenginecallback.h b/src/core/api/qwebenginecallback.h
new file mode 100644
index 000000000..a88fa838c
--- /dev/null
+++ b/src/core/api/qwebenginecallback.h
@@ -0,0 +1,92 @@
+/****************************************************************************
+**
+** Copyright (C) 2015 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the QtWebEngine module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see http://www.qt.io/terms-conditions. For further
+** information use the contact form at http://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPLv3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or later as published by the Free
+** Software Foundation and appearing in the file LICENSE.GPL included in
+** the packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 2.0 requirements will be
+** met: http://www.gnu.org/licenses/gpl-2.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QWEBENGINECALLBACK_H
+#define QWEBENGINECALLBACK_H
+
+#include "qtwebenginecoreglobal.h"
+
+#include <QtCore/qcompilerdetection.h> // Needed for Q_DECL_OVERRIDE
+#include <QExplicitlySharedDataPointer>
+#include <QString>
+#include <QVariant>
+
+namespace QtWebEngineCore {
+class CallbackDirectory;
+}
+
+QT_BEGIN_NAMESPACE
+
+namespace QtWebEnginePrivate {
+
+template <typename T>
+class QWebEngineCallbackPrivateBase : public QSharedData {
+public:
+ QWebEngineCallbackPrivateBase() {}
+ virtual ~QWebEngineCallbackPrivateBase() {}
+ virtual void operator()(T) = 0;
+};
+
+template <typename T, typename F>
+class QWebEngineCallbackPrivate : public QWebEngineCallbackPrivateBase<T> {
+public:
+ QWebEngineCallbackPrivate(F callable)
+ : m_callable(callable)
+ {}
+ virtual void operator()(T value) Q_DECL_OVERRIDE { m_callable(value); }
+private:
+ F m_callable;
+};
+
+} // namespace QtWebEnginePrivate
+
+template <typename T>
+class QWebEngineCallback {
+public:
+ template <typename F>
+ QWebEngineCallback(F f)
+ : d(new QtWebEnginePrivate::QWebEngineCallbackPrivate<T, F>(f))
+ { }
+ QWebEngineCallback() { }
+ operator bool() const { return d; }
+private:
+ friend class QtWebEngineCore::CallbackDirectory;
+ QExplicitlySharedDataPointer<QtWebEnginePrivate::QWebEngineCallbackPrivateBase<T> > d;
+};
+
+QT_END_NAMESPACE
+
+#endif // QWEBENGINECALLBACK_H
diff --git a/src/core/api/qwebenginecallback_p.h b/src/core/api/qwebenginecallback_p.h
new file mode 100644
index 000000000..9c798acbe
--- /dev/null
+++ b/src/core/api/qwebenginecallback_p.h
@@ -0,0 +1,213 @@
+/****************************************************************************
+**
+** Copyright (C) 2015 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the QtWebEngine module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see http://www.qt.io/terms-conditions. For further
+** information use the contact form at http://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPLv3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or later as published by the Free
+** Software Foundation and appearing in the file LICENSE.GPL included in
+** the packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 2.0 requirements will be
+** met: http://www.gnu.org/licenses/gpl-2.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QWEBENGINECALLBACK_P_H
+#define QWEBENGINECALLBACK_P_H
+
+#include "qtwebenginecoreglobal_p.h"
+#include "qwebenginecallback.h"
+
+#include <QHash>
+#include <QSharedData>
+#include <QString>
+#include <QVariant>
+#include <type_traits>
+
+#define FOR_EACH_TYPE(F) \
+ F(bool) \
+ F(int) \
+ F(const QString &) \
+ F(const QVariant &)
+
+namespace QtWebEngineCore {
+
+class CallbackDirectory {
+ template<typename T>
+ void invokeInternal(quint64 callbackId, T result);
+ template<typename T>
+ void invokeEmptyInternal(QtWebEnginePrivate::QWebEngineCallbackPrivateBase<T> *callback);
+
+public:
+ ~CallbackDirectory()
+ {
+ // "Cancel" pending callbacks by calling them with an invalid value.
+ // This guarantees that each callback is called exactly once.
+ for (CallbackSharedDataPointerBase * const sharedPtrBase: m_callbackMap) {
+ Q_ASSERT(sharedPtrBase);
+ sharedPtrBase->invokeEmpty();
+ delete sharedPtrBase;
+ }
+ }
+
+ template<typename T>
+ void registerCallback(quint64 callbackId, const QWebEngineCallback<T> &callback);
+
+ template<typename T>
+ void invokeEmpty(const QWebEngineCallback<T> &callback);
+
+#define DEFINE_INVOKE_FOR_TYPE(Type) \
+ void invoke(quint64 callbackId, Type result) { \
+ invokeInternal<Type>(callbackId, std::forward<Type>(result)); \
+ }
+ FOR_EACH_TYPE(DEFINE_INVOKE_FOR_TYPE)
+#undef DEFINE_INVOKE_FOR_TYPE
+
+private:
+ struct CallbackSharedDataPointerBase {
+ virtual ~CallbackSharedDataPointerBase() { }
+ virtual void invokeEmpty() = 0;
+ virtual void doRef() = 0;
+ virtual void doDeref() = 0;
+ virtual operator bool () const = 0;
+ };
+
+ template <typename T>
+ struct CallbackSharedDataPointer : public CallbackSharedDataPointerBase {
+ CallbackDirectory* parent;
+ QtWebEnginePrivate::QWebEngineCallbackPrivateBase<T> *callback;
+
+ ~CallbackSharedDataPointer() { doDeref(); }
+ CallbackSharedDataPointer() : parent(0), callback(0) { }
+ CallbackSharedDataPointer(const CallbackSharedDataPointer<T> &other)
+ : parent(other.parent), callback(other.callback) { doRef(); }
+ CallbackSharedDataPointer(CallbackDirectory *p, QtWebEnginePrivate::QWebEngineCallbackPrivateBase<T> *c)
+ : parent(p), callback(c) { Q_ASSERT(callback); doRef(); }
+
+ void invokeEmpty() override;
+ operator bool () const override { return callback; }
+
+ private:
+ void doRef() override;
+ void doDeref() override;
+ };
+
+ QHash<quint64, CallbackSharedDataPointerBase*> m_callbackMap;
+};
+
+template<typename T>
+inline
+void CallbackDirectory::registerCallback(quint64 callbackId, const QWebEngineCallback<T> &callback)
+{
+ if (!callback.d)
+ return;
+ m_callbackMap.insert(callbackId, new CallbackSharedDataPointer<T>(this, callback.d.data()));
+}
+
+template<typename T>
+inline
+void CallbackDirectory::invokeInternal(quint64 callbackId, T result)
+{
+ CallbackSharedDataPointerBase * const sharedPtrBase = m_callbackMap.take(callbackId);
+ if (!sharedPtrBase)
+ return;
+
+ auto ptr = static_cast<CallbackSharedDataPointer<T> *>(sharedPtrBase);
+ Q_ASSERT(ptr);
+ (*ptr->callback)(std::forward<T>(result));
+ delete ptr;
+}
+
+template<typename T>
+inline
+void CallbackDirectory::invokeEmptyInternal(QtWebEnginePrivate::QWebEngineCallbackPrivateBase<T> *callback)
+{
+ Q_ASSERT(callback);
+ using NoRefT = typename std::remove_reference<T>::type;
+ using NoConstNoRefT = typename std::remove_const<NoRefT>::type;
+ NoConstNoRefT t;
+ (*callback)(t);
+}
+
+template<>
+inline
+void CallbackDirectory::invokeEmptyInternal(QtWebEnginePrivate::QWebEngineCallbackPrivateBase<bool> *callback)
+{
+ Q_ASSERT(callback);
+ (*callback)(false);
+}
+
+template<>
+inline
+void CallbackDirectory::invokeEmptyInternal(QtWebEnginePrivate::QWebEngineCallbackPrivateBase<int> *callback)
+{
+ Q_ASSERT(callback);
+ (*callback)(0);
+}
+
+template<typename T>
+inline
+void CallbackDirectory::invokeEmpty(const QWebEngineCallback<T> &callback)
+{
+ if (!callback.d)
+ return;
+
+ invokeEmptyInternal(callback.d.data());
+}
+
+template <typename T>
+inline
+void CallbackDirectory::CallbackSharedDataPointer<T>::doRef()
+{
+ if (!callback)
+ return;
+
+ callback->ref.ref();
+}
+
+template <typename T>
+inline
+void CallbackDirectory::CallbackSharedDataPointer<T>::doDeref()
+{
+ if (!callback)
+ return;
+ if (!callback->ref.deref())
+ delete callback;
+}
+
+template <typename T>
+inline
+void CallbackDirectory::CallbackSharedDataPointer<T>::invokeEmpty()
+{
+ if (!callback)
+ return;
+
+ Q_ASSERT(parent);
+ parent->invokeEmptyInternal(callback);
+}
+
+} // namespace QtWebEngineCore
+
+#endif // QWEBENGINECALLBACK_P_H