summaryrefslogtreecommitdiffstats
path: root/src/runtime/Qt3DSEventCallbacks.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/runtime/Qt3DSEventCallbacks.cpp')
-rw-r--r--src/runtime/Qt3DSEventCallbacks.cpp258
1 files changed, 258 insertions, 0 deletions
diff --git a/src/runtime/Qt3DSEventCallbacks.cpp b/src/runtime/Qt3DSEventCallbacks.cpp
new file mode 100644
index 0000000..25d720e
--- /dev/null
+++ b/src/runtime/Qt3DSEventCallbacks.cpp
@@ -0,0 +1,258 @@
+/****************************************************************************
+**
+** Copyright (C) 1993-2009 NVIDIA Corporation.
+** Copyright (C) 2017 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of Qt 3D Studio.
+**
+** $QT_BEGIN_LICENSE:GPL$
+** 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 https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 or (at your option) any later version
+** approved by the KDE Free Qt Foundation. The licenses are as published by
+** the Free Software Foundation and appearing in the file LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "RuntimePrefix.h"
+
+//==============================================================================
+// Includes
+//==============================================================================
+#include "Qt3DSEventCallbacks.h"
+
+//==============================================================================
+// Namespace
+//==============================================================================
+namespace Q3DStudio {
+
+//==============================================================================
+/**
+ * Constructor
+ */
+CEventCallbacks::CEventCallbacks()
+ : m_EventCallbacksList(0, 0, "EventCallbacksList")
+ , m_CallbackList(0, 0, "CallbackList")
+{
+}
+
+//==============================================================================
+/**
+ * Destructor
+ */
+CEventCallbacks::~CEventCallbacks()
+{
+ UnregisterAllCallbacks();
+}
+
+//==============================================================================
+/**
+ * Registers a callback to be triggered when a specific event is fired on an
+ * element.
+ * @param inElement element to monitor
+ * @param inEventHash event hash to monitor
+ * @param inCallback static callback function
+ * @param inContextData arbitary data pointer
+ */
+void CEventCallbacks::RegisterCallback(TElement *inElement, const TEventCommandHash inEventHash,
+ const TEventCallback inCallback, void *inContextData)
+{
+ TEventCallbacksList *theEventCallbackList = NULL;
+
+ // Look for the list of callbacks for this element
+ FOR_ARRAY(SElementCallbackEntry *, theEntry, m_EventCallbacksList)
+ {
+ if (inElement == (*theEntry)->m_Element) {
+ theEventCallbackList = &(*theEntry)->m_EventEntries;
+ break;
+ }
+ }
+
+ // Create a new list of callbacks if it does not already exist
+ if (!theEventCallbackList) {
+ SElementCallbackEntry *theElementCallbackEntry =
+ Q3DStudio_new(SElementCallbackEntry) SElementCallbackEntry();
+ theElementCallbackEntry->m_Element = inElement;
+ m_EventCallbacksList.Push(theElementCallbackEntry);
+ theEventCallbackList = &m_EventCallbacksList.Top()->m_EventEntries;
+ }
+
+ TCallbackList *theElementCallbackList = NULL;
+
+ // Look for the list of callbacks for this event
+ FOR_ARRAY(SEventCallbackEntry *, theEntry, (*theEventCallbackList))
+ {
+ if (inEventHash == (*theEntry)->m_EventHash) {
+ theElementCallbackList = &(*theEntry)->m_Callbacks;
+ break;
+ }
+ }
+
+ // Create a new list of callbacks if it does not already exist
+ if (!theElementCallbackList) {
+ SEventCallbackEntry *theEventCallbackEntry =
+ Q3DStudio_new(SEventCallbackEntry) SEventCallbackEntry();
+ theEventCallbackEntry->m_EventHash = inEventHash;
+ theEventCallbackList->Push(theEventCallbackEntry);
+ theElementCallbackList = &theEventCallbackList->Top()->m_Callbacks;
+ }
+
+ // Insert callback
+ SCallbackEntry theCallbackEntry = { inCallback, inContextData };
+ theElementCallbackList->Push(theCallbackEntry);
+}
+
+//==============================================================================
+/**
+ * Unregisters an event callback.
+ * @param inElement element to monitor
+ * @param inEventHash event hash to monitor
+ * @param inCallback static callback function
+ * @param inContextData arbitary data pointer
+ * @param outLast indicates if element no longer has callbacks registered
+ * @return BOOL true if callback is unregistered successfully
+ */
+BOOL CEventCallbacks::UnregisterCallback(TElement *inElement, const TEventCommandHash inEventHash,
+ const TEventCallback inCallback, void *inContextData,
+ BOOL &outLast)
+{
+ outLast = false;
+
+ TEventCallbacksList *theEventCallbackList = NULL;
+
+ INT32 theEventListIndex = 0;
+ SElementCallbackEntry *theFoundEntry = NULL;
+ FOR_ARRAY(SElementCallbackEntry *, theEntry, m_EventCallbacksList)
+ {
+ if (inElement == (*theEntry)->m_Element) {
+ theFoundEntry = *theEntry;
+ theEventCallbackList = &(*theEntry)->m_EventEntries;
+ break;
+ }
+ ++theEventListIndex;
+ }
+
+ if (!theEventCallbackList)
+ return false;
+
+ TCallbackList *theElementCallbackList = NULL;
+
+ INT32 theElementListIndex = 0;
+ SEventCallbackEntry *theEventCallbackEntry = NULL;
+ FOR_ARRAY(SEventCallbackEntry *, theEntry, (*theEventCallbackList))
+ {
+ if (inEventHash == (*theEntry)->m_EventHash) {
+ theEventCallbackEntry = *theEntry;
+ theElementCallbackList = &(*theEntry)->m_Callbacks;
+ break;
+ }
+ ++theElementListIndex;
+ }
+
+ if (!theElementCallbackList)
+ return false;
+
+ INT32 theCallbackIndex = 0;
+ FOR_ARRAY(SCallbackEntry, theEntry, (*theElementCallbackList))
+ {
+ if (inCallback == theEntry->m_Function && inContextData == theEntry->m_ContextData) {
+ theElementCallbackList->Remove(theCallbackIndex);
+
+ if (theElementCallbackList->GetCount() == 0) {
+ Q3DStudio_delete(theEventCallbackEntry, SEventCallbackEntry);
+ theEventCallbackList->Remove(theElementListIndex);
+ }
+
+ if (theEventCallbackList->GetCount() == 0) {
+ Q3DStudio_delete(theFoundEntry, SElementCallbackEntry);
+ m_EventCallbacksList.Remove(theEventListIndex);
+ outLast = true;
+ }
+
+ return true;
+ }
+ ++theCallbackIndex;
+ }
+
+ return false;
+}
+
+//==============================================================================
+/**
+ * Unregisters all callbacks.
+ */
+void CEventCallbacks::UnregisterAllCallbacks()
+{
+ FOR_ARRAY(SElementCallbackEntry *, theEntry, m_EventCallbacksList)
+ Q3DStudio_delete(*theEntry, SElementCallbackEntry);
+ m_EventCallbacksList.Clear();
+}
+
+//==============================================================================
+/**
+ * Fires event callbacks
+ * @param ioEvent the event that was fired
+ */
+void CEventCallbacks::FireCallbacks(SEventCommand &ioEvent)
+{
+ TEventCallbacksList *theEventCallbackList = NULL;
+
+ // Look for the list of callbacks for this element
+ FOR_ARRAY(SElementCallbackEntry *, theEntry, m_EventCallbacksList)
+ {
+ if (ioEvent.m_Target == (*theEntry)->m_Element) {
+ theEventCallbackList = &(*theEntry)->m_EventEntries;
+ break;
+ }
+ }
+
+ if (!theEventCallbackList)
+ return;
+
+ // Look for the list of callbacks for this event
+ FOR_ARRAY(SEventCallbackEntry *, theEntry, (*theEventCallbackList))
+ {
+ if (ioEvent.m_Type == (*theEntry)->m_EventHash) {
+ PerformCallbacks((*theEntry)->m_Callbacks, ioEvent);
+ break;
+ }
+ }
+}
+
+//==============================================================================
+/**
+ * Executing a list of callbacks
+ * @param inCallbackList the list of callbacks to invoke
+ * @param ioEvent the event to pass to the callbacks
+ */
+void CEventCallbacks::PerformCallbacks(TCallbackList &inCallbackList, SEventCommand &ioEvent)
+{
+ // As the callbacks can potentially do a register/unregister that would alter the call list,
+ // it is safer to get a clean copy of the call list to iterate through.
+
+ // Clumsy way to do a m_CallbackList = inCallbackList
+ m_CallbackList.Clear(false);
+ m_CallbackList.Reserve(inCallbackList.GetCount());
+ FOR_ARRAY(SCallbackEntry, theEntry, inCallbackList)
+ m_CallbackList.Push(*theEntry);
+
+ // Invoking the callbacks
+ FOR_ARRAY(SCallbackEntry, theEntry, m_CallbackList)
+ theEntry->m_Function(theEntry->m_ContextData, ioEvent);
+}
+
+} // namespace Q3DStudio