summaryrefslogtreecommitdiffstats
path: root/src/Authoring/QT3DSDM/Systems/Cores
diff options
context:
space:
mode:
authorMäättä Antti <antti.maatta@qt.io>2017-10-19 11:10:15 +0300
committerAntti Määttä <antti.maatta@qt.io>2017-10-24 13:23:48 +0000
commit51e7b6187f3816336e4c9a4a0ab87f788ff1c092 (patch)
tree1affc607519b945b6fb434a9a29dc84a9ab073ec /src/Authoring/QT3DSDM/Systems/Cores
parentaa75bf1a20a101a5a5080cc99075a345f2a61caf (diff)
Rename UICDM and UICIMP to QT3DS
Task-number: QT3DS-18 Change-Id: I3800cd72b449b033b0b42cf2dd9e9eccc4eb7f8f Reviewed-by: Tomi Korpipää <tomi.korpipaa@qt.io> Reviewed-by: Miikka Heikkinen <miikka.heikkinen@qt.io>
Diffstat (limited to 'src/Authoring/QT3DSDM/Systems/Cores')
-rw-r--r--src/Authoring/QT3DSDM/Systems/Cores/ActionCoreProducer.cpp289
-rw-r--r--src/Authoring/QT3DSDM/Systems/Cores/ActionCoreProducer.h125
-rw-r--r--src/Authoring/QT3DSDM/Systems/Cores/AnimationCoreProducer.cpp488
-rw-r--r--src/Authoring/QT3DSDM/Systems/Cores/AnimationCoreProducer.h148
-rw-r--r--src/Authoring/QT3DSDM/Systems/Cores/DataCoreProducer.cpp457
-rw-r--r--src/Authoring/QT3DSDM/Systems/Cores/DataCoreProducer.h175
-rw-r--r--src/Authoring/QT3DSDM/Systems/Cores/SimpleActionCore.cpp240
-rw-r--r--src/Authoring/QT3DSDM/Systems/Cores/SimpleActionCore.h165
-rw-r--r--src/Authoring/QT3DSDM/Systems/Cores/SimpleAnimationCore.cpp618
-rw-r--r--src/Authoring/QT3DSDM/Systems/Cores/SimpleAnimationCore.h218
-rw-r--r--src/Authoring/QT3DSDM/Systems/Cores/SimpleDataCore.cpp574
-rw-r--r--src/Authoring/QT3DSDM/Systems/Cores/SimpleDataCore.h373
-rw-r--r--src/Authoring/QT3DSDM/Systems/Cores/SimpleSlideCore.cpp408
-rw-r--r--src/Authoring/QT3DSDM/Systems/Cores/SimpleSlideCore.h395
-rw-r--r--src/Authoring/QT3DSDM/Systems/Cores/SimpleSlideGraphCore.cpp169
-rw-r--r--src/Authoring/QT3DSDM/Systems/Cores/SimpleSlideGraphCore.h134
-rw-r--r--src/Authoring/QT3DSDM/Systems/Cores/SlideCoreProducer.cpp555
-rw-r--r--src/Authoring/QT3DSDM/Systems/Cores/SlideCoreProducer.h187
-rw-r--r--src/Authoring/QT3DSDM/Systems/Cores/SlideGraphCoreProducer.cpp245
-rw-r--r--src/Authoring/QT3DSDM/Systems/Cores/SlideGraphCoreProducer.h98
20 files changed, 6061 insertions, 0 deletions
diff --git a/src/Authoring/QT3DSDM/Systems/Cores/ActionCoreProducer.cpp b/src/Authoring/QT3DSDM/Systems/Cores/ActionCoreProducer.cpp
new file mode 100644
index 00000000..89bcd183
--- /dev/null
+++ b/src/Authoring/QT3DSDM/Systems/Cores/ActionCoreProducer.cpp
@@ -0,0 +1,289 @@
+/****************************************************************************
+**
+** 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-EXCEPT$
+** 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 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** 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 "Qt3DSDMPrefix.h"
+#include "ActionCoreProducer.h"
+#include "HandleSystemTransactions.h"
+#include "VectorTransactions.h"
+#include "SignalsImpl.h"
+
+using namespace std;
+
+namespace qt3dsdm {
+
+CUICDMActionHandle CActionCoreProducer::CreateAction(Qt3DSDMInstanceHandle inInstance,
+ CUICDMSlideHandle inSlide,
+ Qt3DSDMInstanceHandle inOwner,
+ SLong4 inTriggerTargetObjects)
+{
+ CUICDMActionHandle retval =
+ m_Data->CreateAction(inInstance, inSlide, inOwner, inTriggerTargetObjects);
+ CREATE_HANDLE_CREATE_TRANSACTION(m_Consumer, retval, m_Data->m_Objects);
+ return retval;
+}
+
+void CActionCoreProducer::DeleteAction(CUICDMActionHandle inAction,
+ Qt3DSDMInstanceHandle &outInstance)
+{
+ // Ensure action exists
+ SAction *theAction = CSimpleActionCore::GetActionNF(inAction, m_Data->m_Objects);
+ CREATE_HANDLE_DELETE_TRANSACTION(m_Consumer, inAction, m_Data->m_Objects);
+ do_all(theAction->m_ActionInfo.m_HandlerArgs,
+ std::bind(DoCreateHandleDeleteTransaction, __FILE__, __LINE__, m_Consumer,
+ std::placeholders::_1, std::ref(m_Data->m_Objects)));
+ m_Data->DeleteAction(inAction, outInstance);
+}
+
+const SActionInfo &CActionCoreProducer::GetActionInfo(CUICDMActionHandle inAction) const
+{
+ return m_Data->GetActionInfo(inAction);
+}
+
+void CActionCoreProducer::GetActions(CUICDMSlideHandle inSlide, Qt3DSDMInstanceHandle inOwner,
+ TActionHandleList &outActions) const
+{
+ return m_Data->GetActions(inSlide, inOwner, outActions);
+}
+
+void CActionCoreProducer::GetActions(CUICDMSlideHandle inSlide, TActionHandleList &outActions) const
+{
+ return m_Data->GetActions(inSlide, outActions);
+}
+
+void CActionCoreProducer::GetActions(Qt3DSDMInstanceHandle inOwner,
+ TActionHandleList &outActions) const
+{
+ return m_Data->GetActions(inOwner, outActions);
+}
+
+void CActionCoreProducer::GetActions(TActionHandleList &outActions) const
+{
+ return m_Data->GetActions(outActions);
+}
+
+Qt3DSDMInstanceHandle CActionCoreProducer::GetActionInstance(CUICDMActionHandle inAction) const
+{
+ return m_Data->GetActionInstance(inAction);
+}
+
+CUICDMActionHandle
+CActionCoreProducer::GetActionByInstance(Qt3DSDMInstanceHandle inActionInstance) const
+{
+ return m_Data->GetActionByInstance(inActionInstance);
+}
+
+void CActionCoreProducer::SetTriggerObject(CUICDMActionHandle inAction,
+ const SObjectRefType &inTriggerObject)
+{
+ SAction *theAction = CSimpleActionCore::GetActionNF(inAction, m_Data->m_Objects);
+ if (m_Consumer) {
+ m_Consumer->OnTransaction(TTransactionPtr(CREATE_GENERIC_TRANSACTION(
+ std::bind(&CSimpleActionCore::SetTriggerObject, m_Data, inAction, inTriggerObject),
+ std::bind(&CSimpleActionCore::SetTriggerObject, m_Data, inAction,
+ theAction->m_ActionInfo.m_TriggerObject))));
+ }
+ m_Data->SetTriggerObject(inAction, inTriggerObject);
+ GetSignalSender()->SendTriggerObjectSet(inAction, theAction->m_ActionInfo.m_TriggerObject);
+}
+
+void CActionCoreProducer::SetTargetObject(CUICDMActionHandle inAction,
+ const SObjectRefType &inTargetObject)
+{
+ SAction *theAction = CSimpleActionCore::GetActionNF(inAction, m_Data->m_Objects);
+ if (m_Consumer) {
+ m_Consumer->OnTransaction(TTransactionPtr(CREATE_GENERIC_TRANSACTION(
+ std::bind(&CSimpleActionCore::SetTargetObject, m_Data, inAction, inTargetObject),
+ std::bind(&CSimpleActionCore::SetTargetObject, m_Data, inAction,
+ theAction->m_ActionInfo.m_TargetObject))));
+ }
+ m_Data->SetTargetObject(inAction, inTargetObject);
+ GetSignalSender()->SendTargetObjectSet(inAction, theAction->m_ActionInfo.m_TargetObject);
+}
+
+void CActionCoreProducer::SetEvent(CUICDMActionHandle inAction, const wstring &inEventHandle)
+{
+ SAction *theAction = CSimpleActionCore::GetActionNF(inAction, m_Data->m_Objects);
+ if (m_Consumer) {
+ m_Consumer->OnTransaction(TTransactionPtr(CREATE_GENERIC_TRANSACTION(
+ std::bind(&CSimpleActionCore::SetEvent, m_Data, inAction, inEventHandle),
+ std::bind(&CSimpleActionCore::SetEvent, m_Data, inAction,
+ theAction->m_ActionInfo.m_Event))));
+ }
+ m_Data->SetEvent(inAction, inEventHandle);
+ GetSignalSender()->SendEventSet(inAction, inEventHandle);
+}
+
+void CActionCoreProducer::SetHandler(CUICDMActionHandle inAction, const wstring &inHandlerHandle)
+{
+ SAction *theAction = CSimpleActionCore::GetActionNF(inAction, m_Data->m_Objects);
+ if (m_Consumer) {
+ m_Consumer->OnTransaction(TTransactionPtr(CREATE_GENERIC_TRANSACTION(
+ std::bind(&CSimpleActionCore::SetHandler, m_Data, inAction, inHandlerHandle),
+ std::bind(&CSimpleActionCore::SetHandler, m_Data, inAction,
+ theAction->m_ActionInfo.m_Handler))));
+ }
+ m_Data->SetHandler(inAction, inHandlerHandle);
+ GetSignalSender()->SendHandlerSet(inAction, inHandlerHandle);
+}
+
+CUICDMHandlerArgHandle CActionCoreProducer::AddHandlerArgument(CUICDMActionHandle inAction,
+ const TCharStr &inName,
+ HandlerArgumentType::Value inArgType,
+ DataModelDataType::Value inValueType)
+{
+ CUICDMHandlerArgHandle retval =
+ m_Data->AddHandlerArgument(inAction, inName, inArgType, inValueType);
+ SAction *theAction = CSimpleActionCore::GetActionNF(inAction, m_Data->m_Objects);
+ CreateVecInsertTransaction<CUICDMHandlerArgHandle>(__FILE__, __LINE__, m_Consumer, retval,
+ theAction->m_ActionInfo.m_HandlerArgs);
+ CREATE_HANDLE_CREATE_TRANSACTION(m_Consumer, retval, m_Data->m_Objects);
+ GetSignalSender()->SendHandlerArgumentAdded(inAction, retval, inName, inArgType, inValueType);
+ return retval;
+}
+
+void CActionCoreProducer::RemoveHandlerArgument(CUICDMHandlerArgHandle inHandlerArgument)
+{
+ SHandlerArgument *theHandlerArgument =
+ CSimpleActionCore::GetHandlerArgumentNF(inHandlerArgument, m_Data->m_Objects);
+ SAction *theAction = CSimpleActionCore::GetActionNF(
+ theHandlerArgument->m_HandlerArgInfo.m_Action, m_Data->m_Objects);
+ if (exists(theAction->m_ActionInfo.m_HandlerArgs,
+ std::bind(equal_to<CUICDMHandlerArgHandle>(), inHandlerArgument,
+ std::placeholders::_1))) {
+ CreateVecEraseTransaction<CUICDMHandlerArgHandle>(__FILE__, __LINE__, m_Consumer,
+ inHandlerArgument,
+ theAction->m_ActionInfo.m_HandlerArgs);
+ CREATE_HANDLE_DELETE_TRANSACTION(m_Consumer, inHandlerArgument, m_Data->m_Objects);
+ }
+ m_Data->RemoveHandlerArgument(inHandlerArgument);
+ GetSignalSender()->SendHandlerArgumentRemoved(theAction->m_Handle, theHandlerArgument->m_Handle,
+ theHandlerArgument->m_HandlerArgInfo.m_Name,
+ theHandlerArgument->m_HandlerArgInfo.m_ArgType,
+ theHandlerArgument->m_HandlerArgInfo.m_ValueType);
+}
+
+const SHandlerArgumentInfo &
+CActionCoreProducer::GetHandlerArgumentInfo(CUICDMHandlerArgHandle inHandlerArgument) const
+{
+ return m_Data->GetHandlerArgumentInfo(inHandlerArgument);
+}
+
+void CActionCoreProducer::GetHandlerArguments(CUICDMActionHandle inAction,
+ THandlerArgHandleList &outHandlerArguments) const
+{
+ return m_Data->GetHandlerArguments(inAction, outHandlerArguments);
+}
+
+void CActionCoreProducer::GetHandlerArgumentValue(CUICDMHandlerArgHandle inHandlerArgument,
+ SValue &outValue) const
+{
+ return m_Data->GetHandlerArgumentValue(inHandlerArgument, outValue);
+}
+
+void CActionCoreProducer::SetHandlerArgumentValue(CUICDMHandlerArgHandle inHandlerArgument,
+ const SValue &inValue)
+{
+ SHandlerArgument *theHandlerArgument =
+ CSimpleActionCore::GetHandlerArgumentNF(inHandlerArgument, m_Data->m_Objects);
+ if (m_Consumer) {
+ m_Consumer->OnTransaction(TTransactionPtr(CREATE_GENERIC_TRANSACTION(
+ std::bind(&CSimpleActionCore::SetHandlerArgumentValue, m_Data, inHandlerArgument,
+ inValue),
+ std::bind(&CSimpleActionCore::SetHandlerArgumentValue, m_Data, inHandlerArgument,
+ theHandlerArgument->m_HandlerArgInfo.m_Value))));
+ }
+ m_Data->SetHandlerArgumentValue(inHandlerArgument, inValue);
+ GetSignalSender()->SendHandlerArgumentValueSet(inHandlerArgument, inValue);
+}
+
+// CHandleBase
+bool CActionCoreProducer::HandleValid(int inHandle) const
+{
+ return m_Data->HandleValid(inHandle);
+}
+
+// ITransactionProducer implementation
+void CActionCoreProducer::SetConsumer(TTransactionConsumerPtr inConsumer)
+{
+ m_Consumer = inConsumer;
+}
+
+TSignalConnectionPtr CActionCoreProducer::ConnectTriggerObjectSet(
+ const std::function<void(CUICDMActionHandle, SObjectRefType &)> &inCallback)
+{
+ return GetSignalProvider()->ConnectTriggerObjectSet(inCallback);
+}
+TSignalConnectionPtr CActionCoreProducer::ConnectTargetObjectSet(
+ const std::function<void(CUICDMActionHandle, SObjectRefType &)> &inCallback)
+{
+ return GetSignalProvider()->ConnectTargetObjectSet(inCallback);
+}
+TSignalConnectionPtr CActionCoreProducer::ConnectEventSet(
+ const std::function<void(CUICDMActionHandle, const wstring &)> &inCallback)
+{
+ return GetSignalProvider()->ConnectEventSet(inCallback);
+}
+TSignalConnectionPtr CActionCoreProducer::ConnectHandlerSet(
+ const std::function<void(CUICDMActionHandle, const wstring &)> &inCallback)
+{
+ return GetSignalProvider()->ConnectHandlerSet(inCallback);
+}
+
+TSignalConnectionPtr CActionCoreProducer::ConnectHandlerArgumentAdded(
+ const std::function<void(CUICDMActionHandle, CUICDMHandlerArgHandle, const TCharStr &,
+ HandlerArgumentType::Value, DataModelDataType::Value)> &inCallback)
+{
+ return GetSignalProvider()->ConnectHandlerArgumentAdded(inCallback);
+}
+TSignalConnectionPtr CActionCoreProducer::ConnectHandlerArgumentRemoved(
+ const std::function<void(CUICDMActionHandle, CUICDMHandlerArgHandle, const TCharStr &,
+ HandlerArgumentType::Value, DataModelDataType::Value)> &inCallback)
+{
+ return GetSignalProvider()->ConnectHandlerArgumentRemoved(inCallback);
+}
+TSignalConnectionPtr CActionCoreProducer::ConnectHandlerArgumentValueSet(
+ const std::function<void(CUICDMHandlerArgHandle, const SValue &)> &inCallback)
+{
+ return GetSignalProvider()->ConnectHandlerArgumentValueSet(inCallback);
+}
+
+void CActionCoreProducer::InitSignaller()
+{
+ m_Signaller = CreateActionCoreSignaller();
+}
+
+IActionCoreSignalProvider *CActionCoreProducer::GetSignalProvider()
+{
+ return dynamic_cast<IActionCoreSignalProvider *>(m_Signaller.get());
+}
+
+IActionCoreSignalSender *CActionCoreProducer::GetSignalSender()
+{
+ return dynamic_cast<IActionCoreSignalSender *>(m_Signaller.get());
+}
+}
diff --git a/src/Authoring/QT3DSDM/Systems/Cores/ActionCoreProducer.h b/src/Authoring/QT3DSDM/Systems/Cores/ActionCoreProducer.h
new file mode 100644
index 00000000..5aec831b
--- /dev/null
+++ b/src/Authoring/QT3DSDM/Systems/Cores/ActionCoreProducer.h
@@ -0,0 +1,125 @@
+/****************************************************************************
+**
+** 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-EXCEPT$
+** 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 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** 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$
+**
+****************************************************************************/
+#pragma once
+#ifndef ACTIONCOREPRODUCERH
+#define ACTIONCOREPRODUCERH
+
+#include "SimpleActionCore.h"
+#include "Qt3DSDMTransactions.h"
+#include "Qt3DSDMSignals.h"
+#include "Qt3DSDMStringTable.h"
+
+namespace qt3dsdm {
+class CActionCoreProducer : public IActionCore,
+ public ITransactionProducer,
+ public IActionCoreSignalProvider
+{
+ Q_DISABLE_COPY(CActionCoreProducer)
+
+ TSimpleActionCorePtr m_Data;
+ TTransactionConsumerPtr m_Consumer;
+ TSignalItemPtr m_Signaller;
+
+public:
+ CActionCoreProducer(TStringTablePtr inStringTable)
+ : m_Data(new CSimpleActionCore(inStringTable))
+ {
+ InitSignaller();
+ }
+
+ TSimpleActionCorePtr GetTransactionlessActionCore() const { return m_Data; }
+
+ // IActionCore implementation
+ IStringTable &GetStringTable() const override { return m_Data->GetStringTable(); }
+ TStringTablePtr GetStringTablePtr() const override { return m_Data->GetStringTablePtr(); }
+ // Action
+ CUICDMActionHandle CreateAction(Qt3DSDMInstanceHandle inInstance, CUICDMSlideHandle inSlide,
+ Qt3DSDMInstanceHandle inOwner, SLong4 inTriggerTargetObjects) override;
+ void DeleteAction(CUICDMActionHandle inAction, Qt3DSDMInstanceHandle &outInstance) override;
+ const SActionInfo &GetActionInfo(CUICDMActionHandle inAction) const override;
+ void GetActions(CUICDMSlideHandle inSlide, Qt3DSDMInstanceHandle inOwner,
+ TActionHandleList &outActions) const override;
+ void GetActions(CUICDMSlideHandle inSlide, TActionHandleList &outActions) const override;
+ void GetActions(Qt3DSDMInstanceHandle inOwner, TActionHandleList &outActions) const override;
+ void GetActions(TActionHandleList &outActions) const override;
+ Qt3DSDMInstanceHandle GetActionInstance(CUICDMActionHandle inAction) const override;
+ CUICDMActionHandle GetActionByInstance(Qt3DSDMInstanceHandle inActionInstance) const override;
+
+ // Action Properties
+ void SetTriggerObject(CUICDMActionHandle inAction, const SObjectRefType &inTriggerObject) override;
+ void SetTargetObject(CUICDMActionHandle inAction, const SObjectRefType &inTargetObject) override;
+ void SetEvent(CUICDMActionHandle inAction, const wstring &inEventHandle) override;
+ void SetHandler(CUICDMActionHandle inAction, const wstring &inHandlerHandle) override;
+
+ // Action Argument
+ CUICDMHandlerArgHandle AddHandlerArgument(CUICDMActionHandle inAction, const TCharStr &inName,
+ HandlerArgumentType::Value inArgType,
+ DataModelDataType::Value inValueType) override;
+ void RemoveHandlerArgument(CUICDMHandlerArgHandle inHandlerArgument) override;
+ const SHandlerArgumentInfo &
+ GetHandlerArgumentInfo(CUICDMHandlerArgHandle inHandlerArgument) const override;
+ void GetHandlerArguments(CUICDMActionHandle inAction,
+ THandlerArgHandleList &outHandlerArguments) const override;
+
+ // Action Argument Properties
+ void GetHandlerArgumentValue(CUICDMHandlerArgHandle inHandlerArgument, SValue &outValue) const override;
+ void SetHandlerArgumentValue(CUICDMHandlerArgHandle inHandlerArgument, const SValue &inValue) override;
+
+ // CHandleBase
+ bool HandleValid(int inHandle) const override;
+
+ // ITransactionProducer implementation
+ void SetConsumer(TTransactionConsumerPtr inConsumer) override;
+
+ TSignalConnectionPtr ConnectTriggerObjectSet(
+ const std::function<void(CUICDMActionHandle, SObjectRefType &)> &inCallback) override;
+ TSignalConnectionPtr ConnectTargetObjectSet(
+ const std::function<void(CUICDMActionHandle, SObjectRefType &)> &inCallback) override;
+ virtual TSignalConnectionPtr
+ ConnectEventSet(const std::function<void(CUICDMActionHandle, const wstring &)> &inCallback) override;
+ virtual TSignalConnectionPtr
+ ConnectHandlerSet(const std::function<void(CUICDMActionHandle, const wstring &)> &inCallback) override;
+
+ TSignalConnectionPtr ConnectHandlerArgumentAdded(
+ const std::function<void(CUICDMActionHandle, CUICDMHandlerArgHandle, const TCharStr &,
+ HandlerArgumentType::Value, DataModelDataType::Value)> &inCallback) override;
+ TSignalConnectionPtr ConnectHandlerArgumentRemoved(
+ const std::function<void(CUICDMActionHandle, CUICDMHandlerArgHandle, const TCharStr &,
+ HandlerArgumentType::Value, DataModelDataType::Value)> &inCallback) override;
+ TSignalConnectionPtr ConnectHandlerArgumentValueSet(
+ const std::function<void(CUICDMHandlerArgHandle, const SValue &)> &inCallback) override;
+
+private:
+ void InitSignaller();
+ IActionCoreSignalProvider *GetSignalProvider();
+ IActionCoreSignalSender *GetSignalSender();
+};
+}
+
+#endif
diff --git a/src/Authoring/QT3DSDM/Systems/Cores/AnimationCoreProducer.cpp b/src/Authoring/QT3DSDM/Systems/Cores/AnimationCoreProducer.cpp
new file mode 100644
index 00000000..10c934b6
--- /dev/null
+++ b/src/Authoring/QT3DSDM/Systems/Cores/AnimationCoreProducer.cpp
@@ -0,0 +1,488 @@
+/****************************************************************************
+**
+** 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-EXCEPT$
+** 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 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** 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 "Qt3DSDMPrefix.h"
+#include "AnimationCoreProducer.h"
+#include "HandleSystemTransactions.h"
+#include "VectorTransactions.h"
+#include "SignalsImpl.h"
+#ifdef _WIN32
+#pragma warning(disable : 4512) // assignment operator not generated
+#endif
+
+using namespace std;
+
+namespace qt3dsdm {
+
+struct SArtistEditedUndoRedoScope
+{
+ TSimpleAnimationCorePtr m_AnimationCore;
+ CUICDMAnimationHandle m_Animation;
+ TTransactionConsumerPtr m_Consumer;
+ bool m_ArtistEdited;
+ SArtistEditedUndoRedoScope(TSimpleAnimationCorePtr inAnimCore, CUICDMAnimationHandle inAnim,
+ TTransactionConsumerPtr inConsumer)
+ : m_AnimationCore(inAnimCore)
+ , m_Animation(inAnim)
+ , m_Consumer(inConsumer)
+ , m_ArtistEdited(inAnimCore->IsArtistEdited(inAnim))
+ {
+ }
+ ~SArtistEditedUndoRedoScope()
+ {
+ bool edited = m_AnimationCore->IsArtistEdited(m_Animation);
+ if (m_Consumer && edited != m_ArtistEdited) {
+ m_Consumer->OnTransaction(TTransactionPtr(CREATE_GENERIC_TRANSACTION(
+ std::bind(&CSimpleAnimationCore::SetIsArtistEdited, m_AnimationCore, m_Animation,
+ edited),
+ std::bind(&CSimpleAnimationCore::SetIsArtistEdited, m_AnimationCore, m_Animation,
+ m_ArtistEdited))));
+ }
+ }
+};
+
+struct SLookupCacheDoUndoOp : public ITransaction
+{
+ std::shared_ptr<SAnimationTrack> m_Animation;
+ TSimpleAnimationCorePtr m_AnimationCore;
+ bool m_AddOnDo;
+ SLookupCacheDoUndoOp(const char *inFile, int inLine, CUICDMAnimationHandle inAnimHandle,
+ TSimpleAnimationCorePtr inCore, bool addOnDo)
+ : ITransaction(inFile, inLine)
+ , m_AnimationCore(inCore)
+ , m_AddOnDo(addOnDo)
+ {
+ THandleObjectMap::const_iterator theIter(inCore->m_Objects.find(inAnimHandle));
+ if (theIter != inCore->m_Objects.end())
+ m_Animation = static_pointer_cast<SAnimationTrack>(theIter->second);
+ }
+ void Remove()
+ {
+ if (m_Animation)
+ m_AnimationCore->RemoveAnimationFromLookupCache(m_Animation);
+ }
+ void Add()
+ {
+ if (m_Animation)
+ m_AnimationCore->AddAnimationToLookupCache(m_Animation);
+ }
+ void Do() override
+ {
+ if (m_AddOnDo)
+ Add();
+ else
+ Remove();
+ }
+ void Undo() override
+ {
+ if (m_AddOnDo)
+ Remove();
+ else
+ Add();
+ }
+};
+
+CUICDMAnimationHandle
+CAnimationCoreProducer::CreateAnimation(CUICDMSlideHandle inSlide, Qt3DSDMInstanceHandle inInstance,
+ Qt3DSDMPropertyHandle inProperty, size_t inIndex,
+ EAnimationType inAnimationType, bool inFirstKeyframeDynamic)
+{
+ CUICDMAnimationHandle retval = m_Data->CreateAnimation(inSlide, inInstance, inProperty, inIndex,
+ inAnimationType, inFirstKeyframeDynamic);
+
+ CREATE_HANDLE_CREATE_TRANSACTION(m_Consumer, retval, m_Data->m_Objects);
+ if (m_Consumer)
+ m_Consumer->OnTransaction(
+ std::make_shared<SLookupCacheDoUndoOp>(__FILE__, __LINE__, retval, m_Data, true));
+ GetSignalSender()->SendAnimationCreated(retval, inSlide, inInstance, inProperty, inIndex,
+ inAnimationType);
+ return retval;
+}
+
+void CAnimationCoreProducer::DeleteAnimation(CUICDMAnimationHandle inAnimation)
+{
+ // Ensure animation exists
+ SAnimationTrack *theAnimation =
+ CSimpleAnimationCore::GetAnimationNF(inAnimation, m_Data->m_Objects);
+ GetSignalSender()->SendBeforeAnimationDeleted(inAnimation);
+ if (m_Consumer)
+ m_Consumer->OnTransaction(std::make_shared<SLookupCacheDoUndoOp>(
+ __FILE__, __LINE__, inAnimation, m_Data, false));
+ CREATE_HANDLE_DELETE_TRANSACTION(m_Consumer, inAnimation, m_Data->m_Objects);
+ do_all(theAnimation->m_Keyframes,
+ std::bind(DoCreateHandleDeleteTransaction, __FILE__, __LINE__, m_Consumer,
+ std::placeholders::_1, std::ref(m_Data->m_Objects)));
+ SAnimationInfo theInfo = m_Data->GetAnimationInfo(inAnimation);
+ m_Data->DeleteAnimation(inAnimation);
+ GetSignalSender()->SendAnimationDeleted(inAnimation, theInfo.m_Slide, theInfo.m_Instance,
+ theInfo.m_Property, theInfo.m_Index,
+ theInfo.m_AnimationType);
+}
+
+CUICDMAnimationHandle CAnimationCoreProducer::GetAnimation(CUICDMSlideHandle inSlide,
+ Qt3DSDMInstanceHandle inInstance,
+ Qt3DSDMPropertyHandle inProperty,
+ size_t inIndex) const
+{
+ return m_Data->GetAnimation(inSlide, inInstance, inProperty, inIndex);
+}
+
+SAnimationInfo CAnimationCoreProducer::GetAnimationInfo(CUICDMAnimationHandle inAnimation) const
+{
+ return m_Data->GetAnimationInfo(inAnimation);
+}
+
+void CAnimationCoreProducer::GetAnimations(TAnimationHandleList &outAnimations) const
+{
+ return m_Data->GetAnimations(outAnimations);
+}
+
+void CAnimationCoreProducer::GetAnimations(TAnimationInfoList &outAnimations,
+ CUICDMSlideHandle inMaster,
+ CUICDMSlideHandle inSlide) const
+{
+ return m_Data->GetAnimations(outAnimations, inMaster, inSlide);
+}
+
+void CAnimationCoreProducer::SetFirstKeyframeDynamic(CUICDMAnimationHandle inAnimation,
+ bool inValue)
+{
+ SAnimationInfo theInfo(m_Data->GetAnimationInfo(inAnimation));
+ SArtistEditedUndoRedoScope __editedScope(m_Data, inAnimation, m_Consumer);
+ if (m_Consumer) {
+ m_Consumer->OnTransaction(TTransactionPtr(CREATE_GENERIC_TRANSACTION(
+ std::bind(&CSimpleAnimationCore::SetFirstKeyframeDynamic, m_Data, inAnimation,
+ inValue),
+ std::bind(&CSimpleAnimationCore::SetFirstKeyframeDynamic, m_Data, inAnimation,
+ theInfo.m_DynamicFirstKeyframe))));
+ }
+ m_Data->SetFirstKeyframeDynamic(inAnimation, inValue);
+ GetSignalSender()->SendFirstKeyframeDynamicSet(inAnimation, inValue);
+}
+
+inline void DirtyKeyframes(CUICDMAnimationHandle inAnimation, THandleObjectMap &inObjects)
+{
+ SAnimationTrack *theAnimation = CSimpleAnimationCore::GetAnimationNF(inAnimation, inObjects);
+ theAnimation->m_KeyframesDirty = true;
+}
+
+inline void CreateDirtyKeyframesTransaction(TTransactionConsumerPtr inConsumer,
+ CUICDMAnimationHandle inAnimation,
+ THandleObjectMap &inObjects)
+{
+ if (inConsumer) {
+ inConsumer->OnTransaction(TTransactionPtr(CREATE_GENERIC_TRANSACTION(
+ std::bind(DirtyKeyframes, inAnimation, std::ref(inObjects)),
+ std::bind(DirtyKeyframes, inAnimation, std::ref(inObjects)))));
+ }
+}
+
+CUICDMKeyframeHandle CAnimationCoreProducer::InsertKeyframe(CUICDMAnimationHandle inAnimation,
+ const TKeyframe &inKeyframe)
+{
+ SArtistEditedUndoRedoScope __editedScope(m_Data, inAnimation, m_Consumer);
+ CUICDMKeyframeHandle retval = m_Data->InsertKeyframe(inAnimation, inKeyframe);
+ SAnimationTrack *theAnimation =
+ CSimpleAnimationCore::GetAnimationNF(inAnimation, m_Data->m_Objects);
+ CreateVecInsertTransaction<CUICDMKeyframeHandle>(__FILE__, __LINE__, m_Consumer, retval,
+ theAnimation->m_Keyframes);
+ CREATE_HANDLE_CREATE_TRANSACTION(m_Consumer, retval, m_Data->m_Objects);
+ CreateDirtyKeyframesTransaction(m_Consumer, inAnimation, m_Data->m_Objects);
+ GetSignalSender()->SendKeyframeInserted(inAnimation, retval, inKeyframe);
+ return retval;
+}
+
+void CAnimationCoreProducer::EraseKeyframe(CUICDMKeyframeHandle inKeyframe)
+{
+ SKeyframe *theKeyframe = CSimpleAnimationCore::GetKeyframeNF(inKeyframe, m_Data->m_Objects);
+ SArtistEditedUndoRedoScope __editedScope(m_Data, theKeyframe->m_Animation, m_Consumer);
+ GetSignalSender()->SendBeforeKeyframeErased(inKeyframe);
+ SAnimationTrack *theAnimation =
+ CSimpleAnimationCore::GetAnimationNF(theKeyframe->m_Animation, m_Data->m_Objects);
+ if (exists(theAnimation->m_Keyframes, std::bind(equal_to<int>(), inKeyframe,
+ std::placeholders::_1))) {
+ CreateVecEraseTransaction<CUICDMKeyframeHandle>(__FILE__, __LINE__, m_Consumer, inKeyframe,
+ theAnimation->m_Keyframes);
+ CREATE_HANDLE_DELETE_TRANSACTION(m_Consumer, inKeyframe, m_Data->m_Objects);
+ CreateDirtyKeyframesTransaction(m_Consumer, theKeyframe->m_Animation, m_Data->m_Objects);
+ }
+ int theKeyframeHandle = theKeyframe->m_Handle;
+ TKeyframe theData = theKeyframe->m_Keyframe;
+ m_Data->EraseKeyframe(inKeyframe);
+ GetSignalSender()->SendKeyframeErased(theAnimation->m_Handle, theKeyframeHandle, theData);
+}
+
+template <typename TDataType>
+struct VectorSwapTransaction : public ITransaction
+{
+ vector<TDataType> m_Data;
+ vector<TDataType> &m_Target;
+ VectorSwapTransaction(const char *inFile, int inLine, vector<TDataType> &inTarget)
+ : ITransaction(inFile, inLine)
+ , m_Data(inTarget)
+ , m_Target(inTarget)
+ {
+ }
+ void Do() override { std::swap(m_Data, m_Target); }
+ void Undo() override { Do(); }
+};
+
+void CAnimationCoreProducer::DeleteAllKeyframes(CUICDMAnimationHandle inAnimation)
+{
+ // Ensure animation exists
+ SAnimationTrack *theAnimation =
+ CSimpleAnimationCore::GetAnimationNF(inAnimation, m_Data->m_Objects);
+ SArtistEditedUndoRedoScope __editedScope(m_Data, inAnimation, m_Consumer);
+ GetSignalSender()->SendBeforeAllKeyframesErased(inAnimation);
+ do_all(theAnimation->m_Keyframes,
+ std::bind(DoCreateHandleDeleteTransaction, __FILE__, __LINE__, m_Consumer,
+ std::placeholders::_1, std::ref(m_Data->m_Objects)));
+ if (m_Consumer)
+ m_Consumer->OnTransaction(std::make_shared<VectorSwapTransaction<CUICDMKeyframeHandle>>(
+ __FILE__, __LINE__, std::ref(theAnimation->m_Keyframes)));
+ theAnimation->m_Keyframes.clear();
+}
+
+CUICDMAnimationHandle
+CAnimationCoreProducer::GetAnimationForKeyframe(CUICDMKeyframeHandle inKeyframe) const
+{
+ return m_Data->GetAnimationForKeyframe(inKeyframe);
+}
+
+struct KeyframeDataTransaction : public ITransaction, public IMergeableTransaction<TKeyframe>
+{
+ TSimpleAnimationCorePtr m_AnimationCore;
+ CUICDMKeyframeHandle m_Keyframe;
+ TKeyframe m_OldData;
+ TKeyframe m_NewData;
+
+ KeyframeDataTransaction(const char *inFile, int inLine, TSimpleAnimationCorePtr animCore,
+ CUICDMKeyframeHandle keyframe, TKeyframe oldData, TKeyframe newData)
+ : ITransaction(inFile, inLine)
+ , m_AnimationCore(animCore)
+ , m_Keyframe(keyframe)
+ , m_OldData(oldData)
+ , m_NewData(newData)
+ {
+ }
+
+ void Do() override { m_AnimationCore->DoSetKeyframeData(m_Keyframe, m_NewData); }
+ void Undo() override { m_AnimationCore->DoSetKeyframeData(m_Keyframe, m_OldData); }
+
+ void Update(const TKeyframe &inKeyframe) override { m_NewData = inKeyframe; }
+};
+
+void CAnimationCoreProducer::SetKeyframeData(CUICDMKeyframeHandle inKeyframe,
+ const TKeyframe &inData)
+{
+ SKeyframe *theKeyframe = CSimpleAnimationCore::GetKeyframeNF(inKeyframe, m_Data->m_Objects);
+ SArtistEditedUndoRedoScope __editedScope(m_Data, theKeyframe->m_Animation, m_Consumer);
+ TKeyframe theNewData(inData);
+ TKeyframe theOldData = theKeyframe->m_Keyframe;
+ m_Data->SetKeyframeData(inKeyframe, inData);
+ TKeyframeDataMergeMap::iterator iter(m_KeyframeMergeMap.find(inKeyframe));
+ if (iter != m_KeyframeMergeMap.end())
+ iter->second->Update(theNewData);
+ else {
+ if (m_Consumer) {
+ std::shared_ptr<KeyframeDataTransaction> theKeyframeTransaction(
+ std::make_shared<KeyframeDataTransaction>(__FILE__, __LINE__, m_Data, inKeyframe,
+ theOldData, theNewData));
+ m_Consumer->OnTransaction(static_pointer_cast<ITransaction>(theKeyframeTransaction));
+ m_KeyframeMergeMap.insert(make_pair(
+ inKeyframe,
+ static_pointer_cast<IMergeableTransaction<TKeyframe>>(theKeyframeTransaction)));
+ }
+ GetSignalSender()->SendKeyframeUpdated(inKeyframe, inData);
+ }
+}
+
+TKeyframe CAnimationCoreProducer::GetKeyframeData(CUICDMKeyframeHandle inKeyframe) const
+{
+ return m_Data->GetKeyframeData(inKeyframe);
+}
+
+void CAnimationCoreProducer::GetKeyframes(CUICDMAnimationHandle inAnimation,
+ TKeyframeHandleList &outKeyframes) const
+{
+ return m_Data->GetKeyframes(inAnimation, outKeyframes);
+}
+
+size_t CAnimationCoreProducer::GetKeyframeCount(CUICDMAnimationHandle inAnimation) const
+{
+ return m_Data->GetKeyframeCount(inAnimation);
+}
+
+void CAnimationCoreProducer::OffsetAnimations(CUICDMSlideHandle inSlide,
+ Qt3DSDMInstanceHandle inInstance,
+ long inMillisecondOffset)
+{
+ float theOffsetSeconds = static_cast<float>(inMillisecondOffset) / 1000.f;
+ for (THandleObjectMap::const_iterator iter = m_Data->m_Objects.begin(),
+ end = m_Data->m_Objects.end();
+ iter != end; ++iter) {
+ SAnimationTrack *theTrack = static_cast<SAnimationTrack *>(iter->second.get());
+ if (theTrack->m_Slide == inSlide && theTrack->m_Instance == inInstance) {
+ for (size_t keyframeIdx = 0, keyframeEnd = theTrack->m_Keyframes.size();
+ keyframeIdx < keyframeEnd; ++keyframeIdx) {
+ CUICDMKeyframeHandle theKeyframeHandle(theTrack->m_Keyframes[keyframeIdx]);
+ TKeyframe theCurrentKeyframe = m_Data->GetKeyframeData(theKeyframeHandle);
+
+ float seconds = qt3dsdm::GetKeyframeSeconds(theCurrentKeyframe);
+
+ theCurrentKeyframe =
+ qt3dsdm::SetKeyframeSeconds(theCurrentKeyframe, seconds + theOffsetSeconds);
+
+ SetKeyframeData(theKeyframeHandle, theCurrentKeyframe);
+ }
+ }
+ }
+}
+
+void CAnimationCoreProducer::SetIsArtistEdited(CUICDMAnimationHandle inAnimation, bool inEdited)
+{
+ SArtistEditedUndoRedoScope __editedScope(m_Data, inAnimation, m_Consumer);
+ m_Data->SetIsArtistEdited(inAnimation, inEdited);
+}
+
+bool CAnimationCoreProducer::IsArtistEdited(CUICDMAnimationHandle inAnimation) const
+{
+ return m_Data->IsArtistEdited(inAnimation);
+}
+// Animation Evaluation.
+float CAnimationCoreProducer::EvaluateAnimation(CUICDMAnimationHandle inAnimation,
+ float inSeconds) const
+{
+ return m_Data->EvaluateAnimation(inAnimation, inSeconds);
+}
+
+bool CAnimationCoreProducer::KeyframeValid(CUICDMKeyframeHandle inKeyframe) const
+{
+ return m_Data->KeyframeValid(inKeyframe);
+}
+
+bool CAnimationCoreProducer::AnimationValid(CUICDMAnimationHandle inAnimation) const
+{
+ return m_Data->AnimationValid(inAnimation);
+}
+
+void CAnimationCoreProducer::CopyAnimations(CUICDMSlideHandle inSourceSlide,
+ Qt3DSDMInstanceHandle inSourceInstance,
+ CUICDMSlideHandle inDestSlide,
+ Qt3DSDMInstanceHandle inDestInstance)
+{
+ std::vector<SAnimationTrack *> theAnimations;
+ for (THandleObjectMap::const_iterator iter = m_Data->m_Objects.begin(),
+ end = m_Data->m_Objects.end();
+ iter != end; ++iter) {
+ SAnimationTrack *theTrack = static_cast<SAnimationTrack *>(iter->second.get());
+ if (theTrack->m_Instance == inSourceInstance && theTrack->m_Slide == inSourceSlide)
+ theAnimations.push_back(theTrack);
+ }
+ for (size_t idx = 0, end = theAnimations.size(); idx < end; ++idx) {
+ const SAnimationTrack &newTrack(*theAnimations[idx]);
+ CUICDMAnimationHandle theNewAnimation(
+ CreateAnimation(inDestSlide, inDestInstance, newTrack.m_Property, newTrack.m_Index,
+ newTrack.m_AnimationType, newTrack.m_FirstKeyframeDynamic));
+ for (size_t keyIdx = 0, keyEnd = newTrack.m_Keyframes.size(); keyIdx < keyEnd; ++keyIdx)
+ InsertKeyframe(theNewAnimation, GetKeyframeData(newTrack.m_Keyframes[keyIdx]));
+ }
+}
+
+// ITransactionProducer implementation
+void CAnimationCoreProducer::SetConsumer(TTransactionConsumerPtr inConsumer)
+{
+ m_Consumer = inConsumer;
+ m_KeyframeMergeMap.clear();
+}
+
+TSignalConnectionPtr CAnimationCoreProducer::ConnectAnimationCreated(
+ const std::function<void(CUICDMAnimationHandle, CUICDMSlideHandle, Qt3DSDMInstanceHandle,
+ Qt3DSDMPropertyHandle, size_t, EAnimationType)> &inCallback)
+{
+ return GetSignalProvider()->ConnectAnimationCreated(inCallback);
+}
+TSignalConnectionPtr CAnimationCoreProducer::ConnectBeforeAnimationDeleted(
+ const std::function<void(CUICDMAnimationHandle)> &inCallback)
+{
+ return GetSignalProvider()->ConnectBeforeAnimationDeleted(inCallback);
+}
+TSignalConnectionPtr CAnimationCoreProducer::ConnectAnimationDeleted(
+ const std::function<void(CUICDMAnimationHandle, CUICDMSlideHandle, Qt3DSDMInstanceHandle,
+ Qt3DSDMPropertyHandle, size_t, EAnimationType)> &inCallback)
+{
+ return GetSignalProvider()->ConnectAnimationDeleted(inCallback);
+}
+TSignalConnectionPtr CAnimationCoreProducer::ConnectKeyframeInserted(
+ const std::function<void(CUICDMAnimationHandle, CUICDMKeyframeHandle, const TKeyframe &)>
+ &inCallback)
+{
+ return GetSignalProvider()->ConnectKeyframeInserted(inCallback);
+}
+TSignalConnectionPtr CAnimationCoreProducer::ConnectBeforeKeyframeErased(
+ const std::function<void(CUICDMKeyframeHandle)> &inCallback)
+{
+ return GetSignalProvider()->ConnectBeforeKeyframeErased(inCallback);
+}
+TSignalConnectionPtr CAnimationCoreProducer::ConnectKeyframeErased(
+ const std::function<void(CUICDMAnimationHandle, CUICDMKeyframeHandle, const TKeyframe &)>
+ &inCallback)
+{
+ return GetSignalProvider()->ConnectKeyframeErased(inCallback);
+}
+TSignalConnectionPtr CAnimationCoreProducer::ConnectBeforeAllKeyframesErased(
+ const std::function<void(CUICDMAnimationHandle)> &inCallback)
+{
+ return GetSignalProvider()->ConnectBeforeAllKeyframesErased(inCallback);
+}
+TSignalConnectionPtr CAnimationCoreProducer::ConnectKeyframeUpdated(
+ const std::function<void(CUICDMKeyframeHandle, const TKeyframe &)> &inCallback)
+{
+ return GetSignalProvider()->ConnectKeyframeUpdated(inCallback);
+}
+TSignalConnectionPtr CAnimationCoreProducer::ConnectFirstKeyframeDynamicSet(
+ const std::function<void(CUICDMAnimationHandle, bool)> &inCallback)
+{
+ return GetSignalProvider()->ConnectFirstKeyframeDynamicSet(inCallback);
+}
+
+void CAnimationCoreProducer::InitSignaller()
+{
+ m_Signaller = CreateAnimationCoreSignaller();
+}
+
+IAnimationCoreSignalProvider *CAnimationCoreProducer::GetSignalProvider()
+{
+ return dynamic_cast<IAnimationCoreSignalProvider *>(m_Signaller.get());
+}
+
+IAnimationCoreSignalSender *CAnimationCoreProducer::GetSignalSender()
+{
+ return dynamic_cast<IAnimationCoreSignalSender *>(m_Signaller.get());
+}
+}
diff --git a/src/Authoring/QT3DSDM/Systems/Cores/AnimationCoreProducer.h b/src/Authoring/QT3DSDM/Systems/Cores/AnimationCoreProducer.h
new file mode 100644
index 00000000..b8e4d23a
--- /dev/null
+++ b/src/Authoring/QT3DSDM/Systems/Cores/AnimationCoreProducer.h
@@ -0,0 +1,148 @@
+/****************************************************************************
+**
+** 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-EXCEPT$
+** 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 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** 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$
+**
+****************************************************************************/
+#pragma once
+#ifndef ANIMATIONCOREPRODUCERH
+#define ANIMATIONCOREPRODUCERH
+#include "SimpleAnimationCore.h"
+#include "Qt3DSDMTransactions.h"
+#include "Qt3DSDMSignals.h"
+
+namespace qt3dsdm {
+class CAnimationCoreProducer : public IAnimationCore,
+ public ITransactionProducer,
+ public IAnimationCoreSignalProvider
+{
+ Q_DISABLE_COPY(CAnimationCoreProducer)
+
+ typedef std::shared_ptr<IMergeableTransaction<TKeyframe>> TKeyframeDataMergeMapEntry;
+ typedef std::unordered_map<int, TKeyframeDataMergeMapEntry> TKeyframeDataMergeMap;
+
+ TSimpleAnimationCorePtr m_Data;
+ TTransactionConsumerPtr m_Consumer;
+ TSignalItemPtr m_Signaller;
+ TKeyframeDataMergeMap m_KeyframeMergeMap;
+
+public:
+ CAnimationCoreProducer()
+ : m_Data(new CSimpleAnimationCore())
+ {
+ InitSignaller();
+ }
+ CAnimationCoreProducer(TStringTablePtr strTable)
+ : m_Data(new CSimpleAnimationCore(strTable))
+ {
+ InitSignaller();
+ }
+
+ TSimpleAnimationCorePtr GetTransactionlessAnimationCore() const { return m_Data; }
+
+ // IAnimationManger implementation
+
+ CUICDMAnimationHandle CreateAnimation(CUICDMSlideHandle inSlide,
+ Qt3DSDMInstanceHandle inInstance,
+ Qt3DSDMPropertyHandle inProperty, size_t inIndex,
+ EAnimationType inAnimationType,
+ bool inFirstKeyframeDynamic) override;
+ void DeleteAnimation(CUICDMAnimationHandle inAnimation) override;
+ CUICDMAnimationHandle GetAnimation(CUICDMSlideHandle inSlide, Qt3DSDMInstanceHandle inInstance,
+ Qt3DSDMPropertyHandle inProperty, size_t inIndex) const override;
+ SAnimationInfo GetAnimationInfo(CUICDMAnimationHandle inAnimation) const override;
+ void GetAnimations(TAnimationHandleList &outAnimations) const override;
+ void GetAnimations(TAnimationInfoList &outAnimations, CUICDMSlideHandle inMaster,
+ CUICDMSlideHandle inSlide) const override;
+ void GetSpecificInstanceAnimations(CUICDMSlideHandle inSlide, Qt3DSDMInstanceHandle inInstance,
+ TAnimationHandleList &outAnimations) override
+ {
+ m_Data->GetSpecificInstanceAnimations(inSlide, inInstance, outAnimations);
+ }
+
+ void SetFirstKeyframeDynamic(CUICDMAnimationHandle inAnimation, bool inValue) override;
+
+ CUICDMKeyframeHandle InsertKeyframe(CUICDMAnimationHandle inAnimation,
+ const TKeyframe &inKeyframe) override;
+ void EraseKeyframe(CUICDMKeyframeHandle) override;
+ void DeleteAllKeyframes(CUICDMAnimationHandle inAnimation) override;
+ CUICDMAnimationHandle GetAnimationForKeyframe(CUICDMKeyframeHandle inKeyframe) const override;
+ TKeyframe GetKeyframeData(CUICDMKeyframeHandle inKeyframe) const override;
+ void SetKeyframeData(CUICDMKeyframeHandle inKeyframe, const TKeyframe &inData) override;
+ void GetKeyframes(CUICDMAnimationHandle inAnimation, TKeyframeHandleList &outKeyframes) const override;
+ size_t GetKeyframeCount(CUICDMAnimationHandle inAnimation) const override;
+ bool IsFirstKeyframe(CUICDMKeyframeHandle inKeyframe) const override
+ {
+ return m_Data->IsFirstKeyframe(inKeyframe);
+ }
+ void OffsetAnimations(CUICDMSlideHandle inSlide, Qt3DSDMInstanceHandle inInstance,
+ long inMillisecondOffset) override;
+
+ void SetIsArtistEdited(CUICDMAnimationHandle inAnimation, bool inEdited = true) override;
+ bool IsArtistEdited(CUICDMAnimationHandle inAnimation) const override;
+
+ // Animation Evaluation.
+ float EvaluateAnimation(CUICDMAnimationHandle inAnimation, float inSeconds) const override;
+
+ bool KeyframeValid(CUICDMKeyframeHandle inKeyframe) const override;
+ bool AnimationValid(CUICDMAnimationHandle inAnimation) const override;
+
+ void CopyAnimations(CUICDMSlideHandle inSourceSlide, Qt3DSDMInstanceHandle inSourceInstance,
+ CUICDMSlideHandle inDestSlide, Qt3DSDMInstanceHandle inDestInstance) override;
+
+ // ITransactionProducer implementation
+ void SetConsumer(TTransactionConsumerPtr inConsumer) override;
+
+ TSignalConnectionPtr ConnectAnimationCreated(
+ const std::function<void(CUICDMAnimationHandle, CUICDMSlideHandle, Qt3DSDMInstanceHandle,
+ Qt3DSDMPropertyHandle, size_t, EAnimationType)> &inCallback) override;
+ virtual TSignalConnectionPtr
+ ConnectBeforeAnimationDeleted(const std::function<void(CUICDMAnimationHandle)> &inCallback) override;
+ TSignalConnectionPtr ConnectAnimationDeleted(
+ const std::function<void(CUICDMAnimationHandle, CUICDMSlideHandle, Qt3DSDMInstanceHandle,
+ Qt3DSDMPropertyHandle, size_t, EAnimationType)> &inCallback) override;
+ TSignalConnectionPtr ConnectKeyframeInserted(
+ const std::function<void(CUICDMAnimationHandle, CUICDMKeyframeHandle, const TKeyframe &)>
+ &inCallback) override;
+ virtual TSignalConnectionPtr
+ ConnectBeforeKeyframeErased(const std::function<void(CUICDMKeyframeHandle)> &inCallback) override;
+ TSignalConnectionPtr ConnectKeyframeErased(
+ const std::function<void(CUICDMAnimationHandle, CUICDMKeyframeHandle, const TKeyframe &)>
+ &inCallback) override;
+ virtual TSignalConnectionPtr
+ ConnectBeforeAllKeyframesErased(const std::function<void(CUICDMAnimationHandle)> &inCallback) override;
+ TSignalConnectionPtr ConnectKeyframeUpdated(
+ const std::function<void(CUICDMKeyframeHandle, const TKeyframe &)> &inCallback) override;
+ TSignalConnectionPtr ConnectFirstKeyframeDynamicSet(
+ const std::function<void(CUICDMAnimationHandle, bool)> &inCallback) override;
+
+private:
+ void InitSignaller();
+ IAnimationCoreSignalProvider *GetSignalProvider();
+ IAnimationCoreSignalSender *GetSignalSender();
+};
+}
+
+#endif
diff --git a/src/Authoring/QT3DSDM/Systems/Cores/DataCoreProducer.cpp b/src/Authoring/QT3DSDM/Systems/Cores/DataCoreProducer.cpp
new file mode 100644
index 00000000..51194105
--- /dev/null
+++ b/src/Authoring/QT3DSDM/Systems/Cores/DataCoreProducer.cpp
@@ -0,0 +1,457 @@
+/****************************************************************************
+**
+** 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-EXCEPT$
+** 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 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** 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 "Qt3DSDMPrefix.h"
+#include "DataCoreProducer.h"
+#include "HandleSystemTransactions.h"
+#include "VectorTransactions.h"
+#include "SignalsImpl.h"
+#ifdef _WIN32
+#pragma warning(disable : 4503) // decorated name length exceeded
+#endif
+namespace qt3dsdm {
+
+Qt3DSDMInstanceHandle CDataCoreProducer::CreateInstance(Qt3DSDMInstanceHandle inTargetId)
+{
+ Qt3DSDMInstanceHandle retval = m_Data->CreateInstance(inTargetId);
+ CREATE_HANDLE_CREATE_TRANSACTION(m_Consumer, retval, m_Data->m_Objects);
+ GetDataCoreSender()->SignalInstanceCreated(retval);
+ return retval;
+}
+
+inline tuple<Qt3DSDMPropertyHandle, SUICDMPropertyDefinition>
+TransformProperty(Qt3DSDMPropertyHandle inProperty, CSimpleDataCore &inData)
+{
+ return make_tuple(inProperty, inData.GetProperty(inProperty));
+}
+
+inline void SignalPropertyRemoved(Qt3DSDMInstanceHandle inInstance,
+ tuple<Qt3DSDMPropertyHandle, SUICDMPropertyDefinition> inData,
+ IDataCoreSignalSender *inSender)
+{
+ inSender->SignalPropertyRemoved(inInstance, get<0>(inData), get<1>(inData).m_Name.wide_str(),
+ get<1>(inData).m_Type);
+}
+
+void CDataCoreProducer::DeleteInstance(Qt3DSDMInstanceHandle inInstance)
+{
+ TIntList theProperties;
+ TIntList theInstances;
+
+ GetDataCoreSender()->SignalBeforeInstanceDeleted(inInstance);
+ // Ensure the instance exists
+ m_Data->GetInstanceNF(inInstance, m_Data->m_Objects);
+ do_all(m_Data->m_Objects,
+ std::bind(CSimpleDataCore::FindRelatedItemsForDelete, inInstance.GetHandleValue(),
+ std::ref(theProperties), std::ref(theInstances), std::placeholders::_1));
+
+ if (m_Consumer) {
+ CREATE_HANDLE_DELETE_TRANSACTION(m_Consumer, inInstance, m_Data->m_Objects);
+ do_all(theProperties, std::bind(HandleDeleteTransaction, __FILE__, __LINE__,
+ std::placeholders::_1,
+ std::ref(m_Data->m_Objects), m_Consumer));
+ }
+
+ vector<tuple<Qt3DSDMPropertyHandle, SUICDMPropertyDefinition>> theDefinitionList;
+ theDefinitionList.resize(theProperties.size());
+
+ function<tuple<Qt3DSDMPropertyHandle, SUICDMPropertyDefinition>(Qt3DSDMPropertyHandle)>
+ thePropertyTransform(bind(TransformProperty, std::placeholders::_1, ref(*m_Data)));
+ transform(theProperties.begin(), theProperties.end(), theDefinitionList.begin(),
+ thePropertyTransform);
+
+ GetDataCoreSender()->SignalInstanceDeleted(inInstance);
+
+ m_Data->DeleteInstance(inInstance);
+ // Signal that these theProperties are no longer with us.
+ do_all(theDefinitionList, bind(SignalPropertyRemoved, inInstance,
+ std::placeholders::_1, GetDataCoreSender()));
+}
+
+bool CDataCoreProducer::IsInstanceOrDerivedFrom(Qt3DSDMInstanceHandle inInstance,
+ Qt3DSDMInstanceHandle inParent) const
+{
+ return m_Data->IsInstanceOrDerivedFrom(inInstance, inParent);
+}
+
+void CDataCoreProducer::GetInstances(TInstanceHandleList &outInstances) const
+{
+ m_Data->GetInstances(outInstances);
+}
+void CDataCoreProducer::GetInstancesDerivedFrom(TInstanceHandleList &outInstances,
+ Qt3DSDMInstanceHandle inParentHandle) const
+{
+ m_Data->GetInstancesDerivedFrom(outInstances, inParentHandle);
+}
+
+struct ClearInstanceParentCacheTransaction : public ITransaction
+{
+ const CDataModelInstance &m_Instance;
+ ClearInstanceParentCacheTransaction(const char *inFile, int inLine,
+ const CDataModelInstance &inst)
+ : ITransaction(inFile, inLine)
+ , m_Instance(inst)
+ {
+ }
+ void Do() override { m_Instance.ClearParentCache(); }
+ void Undo() override { m_Instance.ClearParentCache(); }
+};
+
+void CDataCoreProducer::DeriveInstance(Qt3DSDMInstanceHandle inInstance,
+ Qt3DSDMInstanceHandle inParent)
+{
+ m_Data->DeriveInstance(inInstance, inParent);
+ TDataModelInstancePtr theInstance =
+ CSimpleDataCore::GetInstanceNF(inInstance, m_Data->m_Objects);
+ if (m_Consumer) {
+ CreateHashMapInsertTransaction(
+ __FILE__, __LINE__, m_Consumer,
+ make_pair(inParent.GetHandleValue(),
+ CSimpleDataCore::GetInstanceNF(inParent, m_Data->m_Objects)),
+ theInstance->m_Parents);
+ m_Consumer->OnTransaction(std::static_pointer_cast<ITransaction>(
+ std::make_shared<ClearInstanceParentCacheTransaction>(__FILE__, __LINE__,
+ *theInstance)));
+ }
+ GetDataCoreSender()->SignalInstanceDerived(inInstance, inParent);
+}
+
+void CDataCoreProducer::GetInstanceParents(Qt3DSDMInstanceHandle inHandle,
+ TInstanceHandleList &outParents) const
+{
+ m_Data->GetInstanceParents(inHandle, outParents);
+}
+
+Qt3DSDMPropertyHandle CDataCoreProducer::AddProperty(Qt3DSDMInstanceHandle inInstance,
+ TCharPtr inName, DataModelDataType::Value inPropType)
+{
+ Qt3DSDMPropertyHandle retval = m_Data->AddProperty(inInstance, inName, inPropType);
+ TDataModelInstancePtr theInstance =
+ CSimpleDataCore::GetInstanceNF(inInstance, m_Data->m_Objects);
+ CreateVecInsertTransaction<int>(__FILE__, __LINE__, m_Consumer, retval,
+ theInstance->m_Properties);
+ CREATE_HANDLE_CREATE_TRANSACTION(m_Consumer, retval, m_Data->m_Objects);
+ GetDataCoreSender()->SignalPropertyAdded(inInstance, retval, inName, inPropType);
+ return retval;
+}
+
+void CDataCoreProducer::GetInstanceProperties(Qt3DSDMInstanceHandle inInstance,
+ TPropertyHandleList &outProperties) const
+{
+ m_Data->GetInstanceProperties(inInstance, outProperties);
+}
+
+const SUICDMPropertyDefinition &
+CDataCoreProducer::GetProperty(Qt3DSDMPropertyHandle inProperty) const
+{
+ return m_Data->GetProperty(inProperty);
+}
+
+void CDataCoreProducer::RemoveProperty(Qt3DSDMPropertyHandle inProperty)
+{
+ SUICDMPropertyDefinition theDef = GetProperty(inProperty);
+ TDataModelInstancePtr theInstance =
+ CSimpleDataCore::GetInstanceNF(theDef.m_Instance, m_Data->m_Objects);
+ if (find_if<TIntList::iterator>(theInstance->m_Properties,
+ std::bind(equal_to<int>(), inProperty, std::placeholders::_1))
+ != theInstance->m_Properties.end()) {
+ CreateVecEraseTransaction<int>(__FILE__, __LINE__, m_Consumer, inProperty,
+ theInstance->m_Properties);
+ CREATE_HANDLE_DELETE_TRANSACTION(m_Consumer, inProperty, m_Data->m_Objects);
+ GetDataCoreSender()->SignalPropertyRemoved(theDef.m_Instance, inProperty,
+ theDef.m_Name.wide_str(), theDef.m_Type);
+ m_Data->RemoveProperty(inProperty);
+ } else {
+ throw PropertyNotFound(L"");
+ }
+}
+
+inline void AddCopyInstancePropertyTransaction(int inProperty, const TIntList &inOriginalList,
+ CDataModelInstance &inInstance,
+ TTransactionConsumerPtr &inConsumer)
+{
+ // if this property was never in the original list
+ if (find_if<TIntList::const_iterator>(inOriginalList,
+ std::bind(equal_to<int>(), inProperty,
+ std::placeholders::_1))
+ == inOriginalList.end())
+ CreateVecInsertTransaction<int>(__FILE__, __LINE__, inConsumer,
+ Qt3DSDMPropertyHandle(inProperty), inInstance.m_Properties);
+}
+
+inline void AddCopyInstanceValuePropertyTransaction(const TPropertyPair &inProperty,
+ const TPropertyPairHash &inOriginalList,
+ CDataModelInstance &inInstance,
+ TTransactionConsumerPtr &inConsumer)
+{
+ // if this property was never in the original list
+ if (inOriginalList.end() == inOriginalList.find(inProperty.first))
+ CreateHashMapInsertTransaction(__FILE__, __LINE__, inConsumer, inProperty,
+ inInstance.m_PropertyValues);
+}
+
+struct InstancePropertyValuesTransaction : public ITransaction
+{
+ CDataModelInstance &m_Instance;
+ TIntList m_OldProperties;
+ TPropertyPairList m_OldValues;
+ TIntList m_NewProperties;
+ TPropertyPairList m_NewValues;
+
+ InstancePropertyValuesTransaction(const char *inFile, int inLine,
+ CDataModelInstance &inInstance)
+ : ITransaction(inFile, inLine)
+ , m_Instance(inInstance)
+ , m_OldProperties(inInstance.m_Properties)
+ {
+ inInstance.ToPropertyPairList(m_OldValues);
+ }
+
+ void SetNew()
+ {
+ m_NewProperties = m_Instance.m_Properties;
+ m_Instance.ToPropertyPairList(m_NewValues);
+ }
+
+ void Do() override
+ {
+ m_Instance.m_Properties = m_NewProperties;
+ m_Instance.FromPropertyPairList(m_NewValues);
+ }
+
+ void Undo() override
+ {
+ m_Instance.m_Properties = m_OldProperties;
+ m_Instance.FromPropertyPairList(m_OldValues);
+ }
+};
+
+void CDataCoreProducer::CopyInstanceProperties(Qt3DSDMInstanceHandle inSrcInstance,
+ Qt3DSDMInstanceHandle inDestInstance)
+{
+ TDataModelInstancePtr theInstance =
+ CSimpleDataCore::GetInstanceNF(inDestInstance, m_Data->m_Objects);
+ if (m_Consumer) {
+ // Create the transaction object setting its 'old values' property to the current instance
+ // property values.
+ std::shared_ptr<InstancePropertyValuesTransaction> theTransaction(
+ std::make_shared<InstancePropertyValuesTransaction>(__FILE__, __LINE__,
+ ref(*theInstance)));
+
+ // Change the current instance property values
+ m_Data->CopyInstanceProperties(inSrcInstance, inDestInstance);
+
+ // Ask the transaction to copy the new values into it's new values datastructure.
+ theTransaction->SetNew();
+
+ m_Consumer->OnTransaction(std::static_pointer_cast<ITransaction>(theTransaction));
+ } else {
+ m_Data->CopyInstanceProperties(inSrcInstance, inDestInstance);
+ }
+}
+
+Qt3DSDMPropertyHandle
+CDataCoreProducer::GetAggregateInstancePropertyByName(Qt3DSDMInstanceHandle inInstance,
+ const TCharStr &inStr) const
+{
+ return m_Data->GetAggregateInstancePropertyByName(inInstance, inStr);
+}
+
+void CDataCoreProducer::GetAggregateInstanceProperties(Qt3DSDMInstanceHandle inInstance,
+ TPropertyHandleList &outProperties) const
+{
+ m_Data->GetAggregateInstanceProperties(inInstance, outProperties);
+}
+
+void CDataCoreProducer::GetSpecificInstancePropertyValues(Qt3DSDMInstanceHandle inHandle,
+ TPropertyHandleValuePairList &outValues)
+{
+ m_Data->GetSpecificInstancePropertyValues(inHandle, outValues);
+}
+
+bool CDataCoreProducer::HasAggregateInstanceProperty(Qt3DSDMInstanceHandle inInstance,
+ Qt3DSDMPropertyHandle inProperty) const
+{
+ return m_Data->HasAggregateInstanceProperty(inInstance, inProperty);
+}
+
+void CDataCoreProducer::CheckValue(Qt3DSDMInstanceHandle inInstance, Qt3DSDMPropertyHandle inProperty,
+ const SValue &inValue) const
+{
+ return m_Data->CheckValue(inInstance, inProperty, inValue);
+}
+
+bool CDataCoreProducer::GetInstancePropertyValue(Qt3DSDMInstanceHandle inHandle,
+ Qt3DSDMPropertyHandle inProperty,
+ SValue &outValue) const
+{
+ return m_Data->GetInstancePropertyValue(inHandle, inProperty, outValue);
+}
+
+inline void EraseProperty(TPropertyPairHash &inProperties, int inProperty)
+{
+ inProperties.erase(
+ find_if(inProperties.begin(), inProperties.end(),
+ std::bind(CSimpleDataCore::InstancePropertyMatches, inProperty,
+ std::placeholders::_1)));
+}
+
+void CDataCoreProducer::SetInstancePropertyValue(Qt3DSDMInstanceHandle inHandle,
+ Qt3DSDMPropertyHandle inProperty,
+ const SValue &inValue)
+{
+ // Two possible courses of actions. The property exists, in which case
+ // we need to get its old value.
+ // If it doesn't exist, then we need to erase for undo.
+ TPropertyValuePair theOldValue(PropertyValueFlags(PropertyValueFlags::SetViaAutoPropagate),
+ SInternValue(0.0f, GetStringTable()));
+ TDataModelInstancePtr theInstance = CSimpleDataCore::GetInstanceNF(inHandle, m_Data->m_Objects);
+ TPropertyPairHash::iterator theItem =
+ theInstance->m_PropertyValues.find(inProperty.GetHandleValue());
+ bool foundProp = theItem != theInstance->m_PropertyValues.end();
+ if (foundProp)
+ theOldValue = theItem->second;
+ m_Data->SetInstancePropertyValue(inHandle, inProperty, inValue);
+ TPropertyValuePair theNewValue =
+ theInstance->m_PropertyValues.find(inProperty.GetHandleValue())->second;
+ if (m_Consumer) {
+ // Check if we already have the entry
+ TSlideInstancePropertyPair theKey(inHandle, inProperty);
+ TPropertyMergeMap::iterator iter = m_PropertyMergeMap.find(theKey);
+ // Then we merge the values in to the original event where they
+ // first happened.
+ if (iter != m_PropertyMergeMap.end()) {
+ iter->second->Update(theNewValue);
+ return; // don't send the signal if we just updated value
+ } else // Else we add a new merge entry.
+ {
+ TPropertyMergeMapEntry theEntry;
+ if (!foundProp)
+ theEntry = CreateHashMapInsertTransaction(
+ __FILE__, __LINE__, m_Consumer,
+ make_pair(inProperty.GetHandleValue(), theNewValue),
+ theInstance->m_PropertyValues);
+ else
+ theEntry = CreateHashMapSwapTransaction(__FILE__, __LINE__, m_Consumer,
+ inProperty.GetHandleValue(), theOldValue,
+ theNewValue, theInstance->m_PropertyValues);
+ m_PropertyMergeMap.insert(std::make_pair(theKey, theEntry));
+ }
+ }
+ GetPropertyCoreSender()->SignalInstancePropertyValue(inHandle, inProperty, inValue);
+}
+
+bool CDataCoreProducer::HandleValid(int inHandle) const
+{
+ return m_Data->HandleValid(inHandle);
+}
+
+void CDataCoreProducer::SetConsumer(TTransactionConsumerPtr inConsumer)
+{
+ m_Consumer = inConsumer;
+ m_PropertyMergeMap.clear();
+}
+
+TSignalConnectionPtr CDataCoreProducer::ConnectInstancePropertyValue(
+ const std::function<void(Qt3DSDMInstanceHandle, Qt3DSDMPropertyHandle, const SValue &)>
+ &inCallback)
+{
+ return GetPropertyCoreProvider()->ConnectInstancePropertyValue(inCallback);
+}
+
+TSignalConnectionPtr CDataCoreProducer::ConnectInstanceCreated(
+ const std::function<void(Qt3DSDMInstanceHandle)> &inCallback)
+{
+ return GetDataCoreProvider()->ConnectInstanceCreated(inCallback);
+}
+
+TSignalConnectionPtr CDataCoreProducer::ConnectInstanceDeleted(
+ const std::function<void(Qt3DSDMInstanceHandle)> &inCallback)
+{
+ return GetDataCoreProvider()->ConnectInstanceDeleted(inCallback);
+}
+
+TSignalConnectionPtr CDataCoreProducer::ConnectBeforeInstanceDeleted(
+ const std::function<void(Qt3DSDMInstanceHandle)> &inCallback)
+{
+ return GetDataCoreProvider()->ConnectBeforeInstanceDeleted(inCallback);
+}
+
+TSignalConnectionPtr CDataCoreProducer::ConnectInstanceDerived(
+ const std::function<void(Qt3DSDMInstanceHandle, Qt3DSDMInstanceHandle)> &inCallback)
+{
+ return GetDataCoreProvider()->ConnectInstanceDerived(inCallback);
+}
+
+TSignalConnectionPtr CDataCoreProducer::ConnectInstanceParentRemoved(
+ const std::function<void(Qt3DSDMInstanceHandle, Qt3DSDMInstanceHandle)> &inCallback)
+{
+ return GetDataCoreProvider()->ConnectInstanceParentRemoved(inCallback);
+}
+
+TSignalConnectionPtr CDataCoreProducer::ConnectPropertyAdded(
+ const std::function<void(Qt3DSDMInstanceHandle, Qt3DSDMPropertyHandle, TCharPtr,
+ DataModelDataType::Value)> &inCallback)
+{
+ return GetDataCoreProvider()->ConnectPropertyAdded(inCallback);
+}
+
+TSignalConnectionPtr CDataCoreProducer::ConnectPropertyRemoved(
+ const std::function<void(Qt3DSDMInstanceHandle, Qt3DSDMPropertyHandle, TCharPtr,
+ DataModelDataType::Value)> &inCallback)
+{
+ return GetDataCoreProvider()->ConnectPropertyRemoved(inCallback);
+}
+
+void CDataCoreProducer::InitSignallers()
+{
+ m_InstancePropertyCoreSignaller = CreatePropertyCoreSignaller();
+ m_DataCoreSignaller = CreateDataCoreSignaller();
+}
+
+IInstancePropertyCoreSignalProvider *CDataCoreProducer::GetPropertyCoreProvider()
+{
+ return dynamic_cast<IInstancePropertyCoreSignalProvider *>(
+ m_InstancePropertyCoreSignaller.get());
+}
+
+IInstancePropertyCoreSignalSender *CDataCoreProducer::GetPropertyCoreSender()
+{
+ return dynamic_cast<IInstancePropertyCoreSignalSender *>(m_InstancePropertyCoreSignaller.get());
+}
+
+IDataCoreSignalProvider *CDataCoreProducer::GetDataCoreProvider()
+{
+ return dynamic_cast<IDataCoreSignalProvider *>(m_DataCoreSignaller.get());
+}
+
+IDataCoreSignalSender *CDataCoreProducer::GetDataCoreSender()
+{
+ return dynamic_cast<IDataCoreSignalSender *>(m_DataCoreSignaller.get());
+}
+}
diff --git a/src/Authoring/QT3DSDM/Systems/Cores/DataCoreProducer.h b/src/Authoring/QT3DSDM/Systems/Cores/DataCoreProducer.h
new file mode 100644
index 00000000..0b4e697a
--- /dev/null
+++ b/src/Authoring/QT3DSDM/Systems/Cores/DataCoreProducer.h
@@ -0,0 +1,175 @@
+/****************************************************************************
+**
+** 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-EXCEPT$
+** 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 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** 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$
+**
+****************************************************************************/
+#pragma once
+#ifndef DATACOREPRODUCERH
+#define DATACOREPRODUCERH
+
+#include "Qt3DSDMTransactions.h"
+#include "SimpleDataCore.h"
+#include "Qt3DSDMSignals.h"
+#include "SimpleSlideCore.h"
+
+namespace qt3dsdm {
+
+class CDataCoreProducer : public IDataCore,
+ public ITransactionProducer,
+ public IInstancePropertyCoreSignalProvider,
+ public IDataCoreSignalProvider
+{
+ typedef std::shared_ptr<IMergeableTransaction<TPropertyValuePair>> TPropertyMergeMapEntry;
+ typedef std::unordered_map<TSlideInstancePropertyPair, TPropertyMergeMapEntry>
+ TPropertyMergeMap;
+
+ TTransactionConsumerPtr m_Consumer;
+ TSimpleDataCorePtr m_Data;
+ TSignalItemPtr m_InstancePropertyCoreSignaller;
+ TSignalItemPtr m_DataCoreSignaller;
+
+ TPropertyMergeMap m_PropertyMergeMap;
+
+public:
+ CDataCoreProducer(TStringTablePtr inStringTable)
+ : m_Data(new CSimpleDataCore(inStringTable))
+ {
+ InitSignallers();
+ }
+ virtual ~CDataCoreProducer() {}
+
+ IStringTable &GetStringTable() const override { return m_Data->GetStringTable(); }
+ std::shared_ptr<IStringTable> GetStringTablePtr() const override
+ {
+ return m_Data->GetStringTablePtr();
+ }
+
+ // IHandleBase
+ bool HandleValid(int inHandle) const override;
+
+ // IInstancePropertyCore
+ //===============================================================
+ Qt3DSDMPropertyHandle GetAggregateInstancePropertyByName(Qt3DSDMInstanceHandle inInstance,
+ const TCharStr &inStr) const override;
+ void GetAggregateInstanceProperties(Qt3DSDMInstanceHandle inInstance,
+ TPropertyHandleList &outProperties) const override;
+ void GetSpecificInstancePropertyValues(Qt3DSDMInstanceHandle inHandle,
+ TPropertyHandleValuePairList &outValues) override;
+ bool HasAggregateInstanceProperty(Qt3DSDMInstanceHandle inInstance,
+ Qt3DSDMPropertyHandle inProperty) const override;
+
+ void CheckValue(Qt3DSDMInstanceHandle inInstance, Qt3DSDMPropertyHandle inProperty,
+ const SValue &inValue) const override;
+ bool GetInstancePropertyValue(Qt3DSDMInstanceHandle inHandle,
+ Qt3DSDMPropertyHandle inProperty, SValue &outValue) const override;
+ void SetInstancePropertyValue(Qt3DSDMInstanceHandle inHandle,
+ Qt3DSDMPropertyHandle inProperty, const SValue &inValue) override;
+ //===============================================================
+
+ // IDataCore
+ //===============================================================
+ Qt3DSDMInstanceHandle CreateInstance(Qt3DSDMInstanceHandle hdl = Qt3DSDMInstanceHandle()) override;
+ void GetInstances(TInstanceHandleList &outInstances) const override;
+ void GetInstancesDerivedFrom(TInstanceHandleList &outInstances,
+ Qt3DSDMInstanceHandle inParent) const override;
+ void DeleteInstance(Qt3DSDMInstanceHandle inHandle) override;
+
+ void DeriveInstance(Qt3DSDMInstanceHandle inInstance, Qt3DSDMInstanceHandle inParent) override;
+ void GetInstanceParents(Qt3DSDMInstanceHandle inHandle,
+ TInstanceHandleList &outParents) const override;
+ bool IsInstanceOrDerivedFrom(Qt3DSDMInstanceHandle inInstance,
+ Qt3DSDMInstanceHandle inParent) const override;
+
+ Qt3DSDMPropertyHandle AddProperty(Qt3DSDMInstanceHandle inInstance, TCharPtr inName,
+ DataModelDataType::Value inPropType) override;
+ void GetInstanceProperties(Qt3DSDMInstanceHandle inInstance,
+ TPropertyHandleList &outProperties) const override;
+ const SUICDMPropertyDefinition &GetProperty(Qt3DSDMPropertyHandle inProperty) const override;
+ void RemoveProperty(Qt3DSDMPropertyHandle inProperty) override;
+ void CopyInstanceProperties(Qt3DSDMInstanceHandle inSrcInstance,
+ Qt3DSDMInstanceHandle inDestInstance) override;
+
+ void RemoveCachedValues(Qt3DSDMInstanceHandle inInstance) override
+ {
+ m_Data->RemoveCachedValues(inInstance);
+ }
+ bool IsInstance(int inHandle) const override { return m_Data->IsInstance(inHandle); }
+ bool IsProperty(int inHandle) const override { return m_Data->IsProperty(inHandle); }
+ //===============================================================
+
+ //===============================================================
+ // Set the current consumer
+ //===============================================================
+ void SetConsumer(TTransactionConsumerPtr inConsumer) override;
+
+ //===============================================================
+ // Return a serializable data model for load/save
+ //===============================================================
+ virtual TSimpleDataCorePtr GetTransactionlessDataCore() { return m_Data; }
+ virtual TSimpleDataCorePtr GetTransactionlessDataCore() const { return m_Data; }
+
+ //===============================================================
+ // Signal provider implementation
+ //===============================================================
+ TSignalConnectionPtr ConnectInstancePropertyValue(
+ const std::function<void(Qt3DSDMInstanceHandle, Qt3DSDMPropertyHandle, const SValue &)>
+ &inCallback) override;
+ virtual TSignalConnectionPtr
+ ConnectInstanceCreated(const std::function<void(Qt3DSDMInstanceHandle)> &inCallback) override;
+ virtual TSignalConnectionPtr
+ ConnectInstanceDeleted(const std::function<void(Qt3DSDMInstanceHandle)> &inCallback) override;
+ virtual TSignalConnectionPtr
+ ConnectBeforeInstanceDeleted(const std::function<void(Qt3DSDMInstanceHandle)> &inCallback) override;
+ TSignalConnectionPtr ConnectInstanceDerived(
+ const std::function<void(Qt3DSDMInstanceHandle, Qt3DSDMInstanceHandle)> &inCallback) override;
+ TSignalConnectionPtr ConnectInstanceParentRemoved(
+ const std::function<void(Qt3DSDMInstanceHandle, Qt3DSDMInstanceHandle)> &inCallback) override;
+ virtual TSignalConnectionPtr
+ ConnectPropertyAdded(const std::function<void(Qt3DSDMInstanceHandle, Qt3DSDMPropertyHandle,
+ TCharPtr, DataModelDataType::Value)> &inCallback) override;
+ virtual TSignalConnectionPtr
+ ConnectPropertyRemoved(const std::function<void(Qt3DSDMInstanceHandle, Qt3DSDMPropertyHandle,
+ TCharPtr, DataModelDataType::Value)> &inCallback) override;
+
+private:
+ CDataCoreProducer(const CDataCoreProducer&) = delete;
+ CDataCoreProducer& operator=(const CDataCoreProducer&) = delete;
+
+ template <typename TTransactionType>
+ inline void RunWithConsumer(TTransactionType inTransaction)
+ {
+ qt3dsdm::RunWithConsumer(m_Consumer, inTransaction);
+ }
+
+ void InitSignallers();
+ IInstancePropertyCoreSignalProvider *GetPropertyCoreProvider();
+ IInstancePropertyCoreSignalSender *GetPropertyCoreSender();
+ IDataCoreSignalProvider *GetDataCoreProvider();
+ IDataCoreSignalSender *GetDataCoreSender();
+};
+}
+
+#endif
diff --git a/src/Authoring/QT3DSDM/Systems/Cores/SimpleActionCore.cpp b/src/Authoring/QT3DSDM/Systems/Cores/SimpleActionCore.cpp
new file mode 100644
index 00000000..4f4e0a46
--- /dev/null
+++ b/src/Authoring/QT3DSDM/Systems/Cores/SimpleActionCore.cpp
@@ -0,0 +1,240 @@
+/****************************************************************************
+**
+** 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-EXCEPT$
+** 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 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** 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 "Qt3DSDMPrefix.h"
+#include "SimpleActionCore.h"
+
+namespace qt3dsdm {
+
+CUICDMActionHandle CSimpleActionCore::CreateAction(Qt3DSDMInstanceHandle inInstance,
+ CUICDMSlideHandle inSlide,
+ Qt3DSDMInstanceHandle inOwner,
+ SLong4 inTriggerTargetObjects)
+{
+ int nextId = GetNextId();
+ CUICDMActionHandle retval = CreateActionWithHandle(nextId, inInstance, inSlide, inOwner);
+ SetTriggerObject(retval, inTriggerTargetObjects);
+ SetTargetObject(retval, inTriggerTargetObjects);
+ return retval;
+}
+
+void CSimpleActionCore::DeleteAction(CUICDMActionHandle inAction, Qt3DSDMInstanceHandle &outInstance)
+{
+ SAction *theAction = GetActionNF(inAction, m_Objects);
+ outInstance = theAction->m_ActionInfo.m_Instance;
+ do_all(theAction->m_ActionInfo.m_HandlerArgs,
+ std::bind(EraseHandle, std::placeholders::_1, std::ref(m_Objects)));
+ EraseHandle(inAction, m_Objects);
+}
+
+const SActionInfo &CSimpleActionCore::GetActionInfo(CUICDMActionHandle inAction) const
+{
+ const SAction *theAction = GetActionNF(inAction, m_Objects);
+ return theAction->m_ActionInfo;
+}
+
+inline void AddIfActionMatches(const THandleObjectPair &inPair, CUICDMSlideHandle inSlide,
+ Qt3DSDMInstanceHandle inOwner, TActionHandleList &outActions)
+{
+ if (inPair.second->GetType() == CHandleObject::EHandleObjectTypeAction) {
+ const SAction *theAction = static_cast<SAction *>(inPair.second.get());
+ if ((!inSlide.Valid() || inSlide == theAction->m_ActionInfo.m_Slide)
+ && (!inOwner.Valid() || inOwner == theAction->m_ActionInfo.m_Owner))
+ outActions.push_back(inPair.first);
+ }
+}
+
+// Return all actions that belong to a certain instance in a certain slide
+void CSimpleActionCore::GetActions(CUICDMSlideHandle inSlide, Qt3DSDMInstanceHandle inOwner,
+ TActionHandleList &outActions) const
+{
+ outActions.clear();
+ do_all(m_Objects,
+ std::bind(AddIfActionMatches,
+ std::placeholders::_1, inSlide, inOwner, std::ref(outActions)));
+}
+
+// Return all actions that exist in a certain slide
+void CSimpleActionCore::GetActions(CUICDMSlideHandle inSlide, TActionHandleList &outActions) const
+{
+ GetActions(inSlide, 0, outActions);
+}
+
+// Return all actions that belong to a certain instance
+void CSimpleActionCore::GetActions(Qt3DSDMInstanceHandle inOwner,
+ TActionHandleList &outActions) const
+{
+ GetActions(0, inOwner, outActions);
+}
+
+// Return all actions
+void CSimpleActionCore::GetActions(TActionHandleList &outActions) const
+{
+ outActions.clear();
+ outActions.reserve(m_Objects.size());
+ do_all(m_Objects,
+ std::bind(MaybeAddObject<SAction, CUICDMActionHandle>,
+ std::placeholders::_1, std::ref(outActions)));
+}
+
+// Return the instance that was allocated for this action.
+Qt3DSDMInstanceHandle CSimpleActionCore::GetActionInstance(CUICDMActionHandle inAction) const
+{
+ return GetActionNF(inAction, m_Objects)->m_ActionInfo.m_Instance;
+}
+
+inline bool ActionInstanceMatches(const THandleObjectPair &inPair, Qt3DSDMInstanceHandle inInstance)
+{
+ if (inPair.second->GetType() == CHandleObject::EHandleObjectTypeAction) {
+ const SAction *theAction = static_cast<SAction *>(inPair.second.get());
+ if (inInstance == theAction->m_ActionInfo.m_Instance)
+ return true;
+ }
+ return false;
+}
+
+// Reverse lookup into the action system so you can match actions to instances.
+CUICDMActionHandle
+CSimpleActionCore::GetActionByInstance(Qt3DSDMInstanceHandle inActionInstance) const
+{
+ THandleObjectMap::const_iterator theAction =
+ find_if(m_Objects.begin(), m_Objects.end(),
+ std::bind(ActionInstanceMatches, std::placeholders::_1, inActionInstance));
+ if (theAction != m_Objects.end())
+ return theAction->first;
+ throw ActionNotFound(L"");
+}
+
+// Action Properties
+void CSimpleActionCore::SetTriggerObject(CUICDMActionHandle inAction,
+ const SObjectRefType &inTriggerObject)
+{
+ SAction *theAction = GetActionNF(inAction, m_Objects);
+ theAction->m_ActionInfo.m_TriggerObject = inTriggerObject;
+}
+
+void CSimpleActionCore::SetTargetObject(CUICDMActionHandle inAction,
+ const SObjectRefType &inTargetObject)
+{
+ SAction *theAction = GetActionNF(inAction, m_Objects);
+ theAction->m_ActionInfo.m_TargetObject = inTargetObject;
+}
+
+void CSimpleActionCore::SetEvent(CUICDMActionHandle inAction, const wstring &inEventHandle)
+{
+ SAction *theAction = GetActionNF(inAction, m_Objects);
+ theAction->m_ActionInfo.m_Event = inEventHandle;
+}
+
+void CSimpleActionCore::SetHandler(CUICDMActionHandle inAction, const wstring &inHandlerHandle)
+{
+ SAction *theAction = GetActionNF(inAction, m_Objects);
+ theAction->m_ActionInfo.m_Handler = inHandlerHandle;
+}
+
+// Action Argument
+CUICDMHandlerArgHandle CSimpleActionCore::AddHandlerArgument(CUICDMActionHandle inAction,
+ const TCharStr &inName,
+ HandlerArgumentType::Value inArgType,
+ DataModelDataType::Value inValueType)
+{
+ int nextId = GetNextId();
+ return AddHandlerArgumentWithHandle(nextId, inAction, inName, inArgType, inValueType);
+}
+
+void CSimpleActionCore::RemoveHandlerArgument(CUICDMHandlerArgHandle inHandlerArgument)
+{
+ SHandlerArgument *theHandlerArgument = GetHandlerArgumentNF(inHandlerArgument, m_Objects);
+ SAction *theAction = GetActionNF(theHandlerArgument->m_HandlerArgInfo.m_Action, m_Objects);
+ EraseHandle(inHandlerArgument, m_Objects);
+ erase_if(theAction->m_ActionInfo.m_HandlerArgs,
+ std::bind(equal_to<int>(), std::placeholders::_1, inHandlerArgument.GetHandleValue()));
+}
+
+const SHandlerArgumentInfo &
+CSimpleActionCore::GetHandlerArgumentInfo(CUICDMHandlerArgHandle inHandlerArgument) const
+{
+ if (HandleValid(inHandlerArgument)) {
+ const SHandlerArgument *theHandlerArgument =
+ GetHandlerArgumentNF(inHandlerArgument, m_Objects);
+ return theHandlerArgument->m_HandlerArgInfo;
+ } else {
+ static SHandlerArgumentInfo dummy;
+ return dummy;
+ }
+}
+
+void CSimpleActionCore::GetHandlerArguments(CUICDMActionHandle inAction,
+ THandlerArgHandleList &outHandlerArguments) const
+{
+ const SAction *theAction = GetActionNF(inAction, m_Objects);
+ outHandlerArguments = theAction->m_ActionInfo.m_HandlerArgs;
+}
+
+// Action Argument Properties
+void CSimpleActionCore::GetHandlerArgumentValue(CUICDMHandlerArgHandle inHandlerArgument,
+ SValue &outValue) const
+{
+ const SHandlerArgument *theHandlerArgument = GetHandlerArgumentNF(inHandlerArgument, m_Objects);
+ outValue = theHandlerArgument->m_HandlerArgInfo.m_Value;
+}
+
+void CSimpleActionCore::SetHandlerArgumentValue(CUICDMHandlerArgHandle inHandlerArgument,
+ const SValue &inValue)
+{
+ SHandlerArgument *theHandlerArgument = GetHandlerArgumentNF(inHandlerArgument, m_Objects);
+ theHandlerArgument->m_HandlerArgInfo.m_Value = inValue;
+}
+
+// Helper functions
+CUICDMActionHandle CSimpleActionCore::CreateActionWithHandle(int inHandle,
+ Qt3DSDMInstanceHandle inInstance,
+ CUICDMSlideHandle inSlide,
+ Qt3DSDMInstanceHandle inOwner)
+{
+ if (HandleValid(inHandle))
+ throw HandleExists(L"");
+ m_Objects.insert(make_pair(
+ inHandle, (THandleObjectPtr) new SAction(inHandle, inInstance, inSlide, inOwner)));
+ return inHandle;
+}
+
+CUICDMHandlerArgHandle
+CSimpleActionCore::AddHandlerArgumentWithHandle(int inHandle, CUICDMActionHandle inAction,
+ const TCharStr &inName, HandlerArgumentType::Value inArgType,
+ DataModelDataType::Value inValueType)
+{
+ if (HandleValid(inHandle))
+ throw HandleExists(L"");
+ m_Objects.insert(make_pair(inHandle, (THandleObjectPtr) new SHandlerArgument(
+ inHandle, inAction, inName, inArgType, inValueType)));
+ SAction *theAction = GetActionNF(inAction, m_Objects);
+ theAction->m_ActionInfo.m_HandlerArgs.push_back(inHandle);
+ return inHandle;
+}
+}
diff --git a/src/Authoring/QT3DSDM/Systems/Cores/SimpleActionCore.h b/src/Authoring/QT3DSDM/Systems/Cores/SimpleActionCore.h
new file mode 100644
index 00000000..0700d5c9
--- /dev/null
+++ b/src/Authoring/QT3DSDM/Systems/Cores/SimpleActionCore.h
@@ -0,0 +1,165 @@
+/****************************************************************************
+**
+** 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-EXCEPT$
+** 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 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** 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$
+**
+****************************************************************************/
+#pragma once
+#ifndef ACTIONCOREH
+#define ACTIONCOREH
+
+#include "Qt3DSDMActionCore.h"
+#include "HandleSystemBase.h"
+#include "Qt3DSDMErrors.h"
+
+namespace qt3dsdm {
+struct SAction : public CHandleObject
+{
+ SActionInfo m_ActionInfo;
+
+ SAction() {}
+
+ SAction(int inHandle, Qt3DSDMInstanceHandle inInstance, CUICDMSlideHandle inSlide,
+ Qt3DSDMInstanceHandle inOwner)
+ : CHandleObject(inHandle)
+ , m_ActionInfo(inInstance, inSlide, inOwner)
+ {
+ }
+
+ static const EHandleObjectType s_Type = CHandleObject::EHandleObjectTypeAction;
+ EHandleObjectType GetType() override { return s_Type; }
+};
+
+struct SHandlerArgument : public CHandleObject
+{
+ SHandlerArgumentInfo m_HandlerArgInfo;
+
+ SHandlerArgument() {}
+
+ SHandlerArgument(int inHandle, CUICDMActionHandle inAction, const TCharStr &inName,
+ HandlerArgumentType::Value inArgType, DataModelDataType::Value inValueType)
+ : CHandleObject(inHandle)
+ , m_HandlerArgInfo(inAction, inName, inArgType, inValueType)
+ {
+ }
+
+ static const EHandleObjectType s_Type = CHandleObject::EHandleObjectTypeActionHandlerArgument;
+ EHandleObjectType GetType() override { return s_Type; }
+};
+
+class CSimpleActionCore : public CHandleBase, public IActionCore
+{
+ mutable TStringTablePtr m_StringTable;
+
+public: // Use
+ CSimpleActionCore(TStringTablePtr strTable)
+ : m_StringTable(strTable)
+ {
+ }
+
+ IStringTable &GetStringTable() const override { return *m_StringTable.get(); }
+ TStringTablePtr GetStringTablePtr() const override { return m_StringTable; }
+ // Action
+ CUICDMActionHandle CreateAction(Qt3DSDMInstanceHandle inInstance, CUICDMSlideHandle inSlide,
+ Qt3DSDMInstanceHandle inOwner, SLong4 inTriggerTargetObjects) override;
+ void DeleteAction(CUICDMActionHandle inAction, Qt3DSDMInstanceHandle &outInstance) override;
+ const SActionInfo &GetActionInfo(CUICDMActionHandle inAction) const override;
+ void GetActions(CUICDMSlideHandle inSlide, Qt3DSDMInstanceHandle inOwner,
+ TActionHandleList &outActions) const override;
+ void GetActions(CUICDMSlideHandle inSlide, TActionHandleList &outActions) const override;
+ void GetActions(Qt3DSDMInstanceHandle inOwner, TActionHandleList &outActions) const override;
+ void GetActions(TActionHandleList &outActions) const override;
+
+ // Return the instance that was allocated for this action.
+ Qt3DSDMInstanceHandle GetActionInstance(CUICDMActionHandle inAction) const override;
+ // Reverse lookup into the action system so you can match actions to instances.
+ CUICDMActionHandle GetActionByInstance(Qt3DSDMInstanceHandle inActionInstance) const override;
+
+ // Action Properties
+ void SetTriggerObject(CUICDMActionHandle inAction, const SObjectRefType &inTriggerObject) override;
+ void SetTargetObject(CUICDMActionHandle inAction, const SObjectRefType &inTargetObject) override;
+ void SetEvent(CUICDMActionHandle inAction, const wstring &inEvent) override;
+ void SetHandler(CUICDMActionHandle inAction, const wstring &inHandler) override;
+
+ // Action Argument
+ CUICDMHandlerArgHandle AddHandlerArgument(CUICDMActionHandle inAction, const TCharStr &inName,
+ HandlerArgumentType::Value inArgType,
+ DataModelDataType::Value inValueType) override;
+ void RemoveHandlerArgument(CUICDMHandlerArgHandle inHandlerArgument) override;
+ const SHandlerArgumentInfo &
+ GetHandlerArgumentInfo(CUICDMHandlerArgHandle inHandlerArgument) const override;
+ void GetHandlerArguments(CUICDMActionHandle inAction,
+ THandlerArgHandleList &outHandlerArguments) const override;
+
+ // Action Argument Properties
+ void GetHandlerArgumentValue(CUICDMHandlerArgHandle inHandlerArgument, SValue &outValue) const override;
+ void SetHandlerArgumentValue(CUICDMHandlerArgHandle inHandlerArgument, const SValue &inValue) override;
+
+ // CHandleBase
+ bool HandleValid(int inHandle) const override { return CHandleBase::HandleValid(inHandle); }
+
+ // Helper functions
+ CUICDMActionHandle CreateActionWithHandle(int inHandle, Qt3DSDMInstanceHandle inInstance,
+ CUICDMSlideHandle inSlide,
+ Qt3DSDMInstanceHandle inOwner);
+ CUICDMHandlerArgHandle AddHandlerArgumentWithHandle(int inHandle, CUICDMActionHandle inAction,
+ const TCharStr &inName,
+ HandlerArgumentType::Value inArgType,
+ DataModelDataType::Value inValueType);
+
+ static SAction *GetActionNF(int inHandle, THandleObjectMap &inObjects)
+ {
+ return const_cast<SAction *>(
+ GetActionNF(inHandle, static_cast<const THandleObjectMap &>(inObjects)));
+ }
+
+ static const SAction *GetActionNF(int inHandle, const THandleObjectMap &inObjects)
+ {
+ const SAction *theAction = GetHandleObject<SAction>(inHandle, inObjects);
+ if (theAction)
+ return theAction;
+ throw ActionNotFound(L"");
+ }
+
+ static SHandlerArgument *GetHandlerArgumentNF(int inHandle, THandleObjectMap &inObjects)
+ {
+ return const_cast<SHandlerArgument *>(
+ GetHandlerArgumentNF(inHandle, static_cast<const THandleObjectMap &>(inObjects)));
+ }
+
+ static const SHandlerArgument *GetHandlerArgumentNF(int inHandle,
+ const THandleObjectMap &inObjects)
+ {
+ const SHandlerArgument *theItem = GetHandleObject<SHandlerArgument>(inHandle, inObjects);
+ if (theItem)
+ return theItem;
+ throw HandlerArgumentNotFound(L"");
+ }
+};
+
+typedef std::shared_ptr<CSimpleActionCore> TSimpleActionCorePtr;
+}
+
+#endif
diff --git a/src/Authoring/QT3DSDM/Systems/Cores/SimpleAnimationCore.cpp b/src/Authoring/QT3DSDM/Systems/Cores/SimpleAnimationCore.cpp
new file mode 100644
index 00000000..dd761cbc
--- /dev/null
+++ b/src/Authoring/QT3DSDM/Systems/Cores/SimpleAnimationCore.cpp
@@ -0,0 +1,618 @@
+/****************************************************************************
+**
+** 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-EXCEPT$
+** 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 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** 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 "Qt3DSDMPrefix.h"
+#include "SimpleAnimationCore.h"
+
+typedef long INT32;
+typedef float FLOAT;
+#define DATALOGGER_CUBICROOT 0
+
+struct SPerfLogEvent
+{
+ SPerfLogEvent(int) {}
+};
+
+typedef SPerfLogEvent TPerfLogMathEvent1;
+
+#include "Qt3DSCubicRoots.h"
+#include "Qt3DSCubicRootsImpl.h"
+#include "Qt3DSBezierEval.h"
+#include <boost/unordered_map.hpp>
+#include <boost/iterator/transform_iterator.hpp>
+using namespace std;
+using namespace boost;
+
+namespace qt3dsdm {
+
+CUICDMAnimationHandle
+CSimpleAnimationCore::CreateAnimation(CUICDMSlideHandle inSlide, Qt3DSDMInstanceHandle inInstance,
+ Qt3DSDMPropertyHandle inProperty, size_t inIndex,
+ EAnimationType inAnimationType, bool inFirstKeyframeDynamic)
+{
+ if (GetAnimation(inSlide, inInstance, inProperty, inIndex).Valid())
+ throw AnimationExists(L"");
+
+ int nextId = GetNextId();
+ CUICDMAnimationHandle retval = CreateAnimationWithHandle(
+ nextId, inSlide, inInstance, inProperty, inIndex, inAnimationType, inFirstKeyframeDynamic);
+ AddAnimationToLookupCache(retval);
+ return retval;
+}
+
+void CSimpleAnimationCore::DeleteAnimation(CUICDMAnimationHandle inAnimation)
+{
+ RemoveAnimationFromLookupCache(inAnimation);
+ SAnimationTrack *theItem = GetAnimationNF(inAnimation, m_Objects);
+ do_all(theItem->m_Keyframes, std::bind(EraseHandle,
+ std::placeholders::_1, std::ref(m_Objects)));
+ EraseHandle(inAnimation, m_Objects);
+}
+
+void CSimpleAnimationCore::EnsureAnimationCache() const
+{
+ if (m_AnimationMatchesCache.size() == 0) {
+ for (THandleObjectMap::const_iterator theIter = m_Objects.begin(), theEnd = m_Objects.end();
+ theIter != theEnd; ++theIter) {
+ if (theIter->second->GetType() == CHandleObject::EHandleObjectTypeSAnimationTrack)
+ AddAnimationToLookupCache(static_pointer_cast<SAnimationTrack>(theIter->second));
+ }
+ }
+}
+
+CUICDMAnimationHandle CSimpleAnimationCore::GetAnimation(CUICDMSlideHandle inSlide,
+ Qt3DSDMInstanceHandle inInstance,
+ Qt3DSDMPropertyHandle inProperty,
+ size_t inIndex) const
+{
+ EnsureAnimationCache();
+
+ pair<TStateInstanceAnimationMap::const_iterator, TStateInstanceAnimationMap::const_iterator>
+ theRange(m_AnimationMatchesCache.equal_range(
+ make_pair(inSlide.GetHandleValue(), inInstance.GetHandleValue())));
+ for (TStateInstanceAnimationMap::const_iterator theIter = theRange.first;
+ theIter != theRange.second; ++theIter) {
+ std::shared_ptr<SAnimationTrack> theItem = theIter->second;
+ if (inSlide.GetHandleValue() == theItem->m_Slide
+ && inInstance.GetHandleValue() == theItem->m_Instance
+ && inProperty.GetHandleValue() == theItem->m_Property && inIndex == theItem->m_Index)
+ return theItem->m_Handle;
+ }
+ return 0;
+}
+
+SAnimationInfo CSimpleAnimationCore::GetAnimationInfo(CUICDMAnimationHandle inAnimation) const
+{
+ if (m_Objects.find(inAnimation) != m_Objects.end()) {
+ const SAnimationTrack *theItem = GetAnimationNF(inAnimation, m_Objects);
+ return CreateAnimationInfo(theItem->m_Slide, theItem->m_Instance, theItem->m_Property,
+ theItem->m_Index, theItem->m_AnimationType,
+ theItem->m_FirstKeyframeDynamic, theItem->m_ArtistEdited);
+ }
+ return SAnimationInfo();
+}
+
+inline void AddIfAnimation(const THandleObjectPair &inPair, TAnimationHandleList &outAnimations)
+{
+ if (inPair.second->GetType() == CHandleObject::EHandleObjectTypeSAnimationTrack)
+ outAnimations.push_back(inPair.first);
+}
+
+void CSimpleAnimationCore::GetAnimations(TAnimationHandleList &outAnimations) const
+{
+ outAnimations.clear();
+ do_all(m_Objects, std::bind(AddIfAnimation, std::placeholders::_1, std::ref(outAnimations)));
+}
+
+void CSimpleAnimationCore::GetAnimations(TAnimationInfoList &outAnimations,
+ CUICDMSlideHandle inMaster,
+ CUICDMSlideHandle inSlide) const
+{
+ outAnimations.clear();
+ for (THandleObjectMap::const_iterator iter = m_Objects.begin(), end = m_Objects.end();
+ iter != end; ++iter) {
+ if (iter->second->GetType() == CHandleObject::EHandleObjectTypeSAnimationTrack) {
+ const SAnimationTrack *theItem =
+ static_cast<const SAnimationTrack *>(iter->second.get());
+ // If either master or slide is valid, then item slide must match.
+ // If item slide matches neither, then we ignore unless neither are valid.
+ bool keep = (theItem->m_Slide == inMaster || theItem->m_Slide == inSlide)
+ || (inMaster.Valid() == false && inSlide.Valid() == false);
+ if (keep) {
+ outAnimations.push_back(
+ CreateAnimationInfo(theItem->m_Slide, theItem->m_Instance, theItem->m_Property,
+ theItem->m_Index, theItem->m_AnimationType,
+ theItem->m_FirstKeyframeDynamic, theItem->m_ArtistEdited));
+ }
+ }
+ }
+}
+
+inline void AddSpecificAnimationsIf(const THandleObjectPair &inPair, CUICDMSlideHandle inSlide,
+ Qt3DSDMInstanceHandle inInstance,
+ TAnimationHandleList &outAnimations)
+{
+ if (inPair.second->GetType() == CHandleObject::EHandleObjectTypeSAnimationTrack) {
+ const SAnimationTrack *theTrack = static_cast<const SAnimationTrack *>(inPair.second.get());
+ if (theTrack->m_Slide == inSlide && theTrack->m_Instance == inInstance)
+ outAnimations.push_back(inPair.first);
+ }
+}
+
+void CSimpleAnimationCore::GetSpecificInstanceAnimations(CUICDMSlideHandle inSlide,
+ Qt3DSDMInstanceHandle inInstance,
+ TAnimationHandleList &outAnimations)
+{
+ EnsureAnimationCache();
+ pair<TStateInstanceAnimationMap::const_iterator, TStateInstanceAnimationMap::const_iterator>
+ theRange(m_AnimationMatchesCache.equal_range(
+ make_pair(inSlide.GetHandleValue(), inInstance.GetHandleValue())));
+ for (TStateInstanceAnimationMap::const_iterator iter = theRange.first; iter != theRange.second;
+ ++iter)
+ outAnimations.push_back(iter->second->m_Handle);
+}
+
+void CSimpleAnimationCore::SetFirstKeyframeDynamic(CUICDMAnimationHandle inAnimation, bool inValue)
+{
+ SAnimationTrack *theItem = GetAnimationNF(inAnimation, m_Objects);
+ theItem->m_FirstKeyframeDynamic = inValue;
+ SetIsArtistEdited(inAnimation);
+}
+
+inline void CheckKeyframeType(EAnimationType inExpected, const TKeyframe &inKeyframe)
+{
+ if (inExpected != GetKeyframeType(inKeyframe))
+ throw AnimationKeyframeTypeError(L"");
+}
+
+// keyframe manipulation
+CUICDMKeyframeHandle CSimpleAnimationCore::InsertKeyframe(CUICDMAnimationHandle inAnimation,
+ const TKeyframe &inKeyframe)
+{
+ SAnimationTrack *theItem = GetAnimationNF(inAnimation, m_Objects);
+ CheckKeyframeType(theItem->m_AnimationType, inKeyframe);
+ int nextId = GetNextId();
+ m_Objects.insert(
+ make_pair(nextId, (THandleObjectPtr) new SKeyframe(nextId, inAnimation, inKeyframe)));
+ theItem->m_Keyframes.push_back(nextId);
+ theItem->m_KeyframesDirty = true;
+ SetIsArtistEdited(inAnimation);
+ return nextId;
+}
+
+void CSimpleAnimationCore::EraseKeyframe(CUICDMKeyframeHandle inKeyframe)
+{
+ SKeyframe *theKeyframe = GetKeyframeNF(inKeyframe, m_Objects);
+ int theAnimHandle(theKeyframe->m_Animation);
+ SAnimationTrack *theItem = GetAnimationNF(theAnimHandle, m_Objects);
+ EraseHandle(inKeyframe, m_Objects);
+ erase_if(theItem->m_Keyframes, std::bind(equal_to<int>(),
+ std::placeholders::_1, inKeyframe.GetHandleValue()));
+ SetIsArtistEdited(theAnimHandle);
+}
+
+void CSimpleAnimationCore::DeleteAllKeyframes(CUICDMAnimationHandle inAnimation)
+{
+ SAnimationTrack *theItem = GetAnimationNF(inAnimation, m_Objects);
+ do_all(theItem->m_Keyframes, std::bind(EraseHandle,
+ std::placeholders::_1, std::ref(m_Objects)));
+ theItem->m_Keyframes.clear();
+ SetIsArtistEdited(inAnimation);
+}
+
+CUICDMAnimationHandle
+CSimpleAnimationCore::GetAnimationForKeyframe(CUICDMKeyframeHandle inKeyframe) const
+{
+ const SKeyframe *theKeyframe = GetKeyframeNF(inKeyframe, m_Objects);
+ return theKeyframe->m_Animation;
+}
+
+TKeyframe CSimpleAnimationCore::GetKeyframeData(CUICDMKeyframeHandle inKeyframe) const
+{
+ const SKeyframe *theKeyframe = GetKeyframeNF(inKeyframe, m_Objects);
+ return theKeyframe->m_Keyframe;
+}
+
+void CSimpleAnimationCore::SetKeyframeData(CUICDMKeyframeHandle inKeyframe, const TKeyframe &inData)
+{
+ DoSetKeyframeData(inKeyframe, inData);
+ SKeyframe *theKeyframe = GetKeyframeNF(inKeyframe, m_Objects);
+ SetIsArtistEdited(theKeyframe->m_Animation);
+}
+
+void CSimpleAnimationCore::DoSetKeyframeData(CUICDMKeyframeHandle inKeyframe,
+ const TKeyframe &inData)
+{
+ SKeyframe *theKeyframe = GetKeyframeNF(inKeyframe, m_Objects);
+ CheckKeyframeType(GetKeyframeType(theKeyframe->m_Keyframe), inData);
+ theKeyframe->m_Keyframe = inData;
+ SAnimationTrack *theItem = GetAnimationNF(theKeyframe->m_Animation, m_Objects);
+ theItem->m_KeyframesDirty = true;
+}
+
+bool KeyframeLessThan(int inLeftSide, int inRightSide, const THandleObjectMap &inObjects)
+{
+ const SKeyframe *theLeft = CSimpleAnimationCore::GetKeyframeNF(inLeftSide, inObjects);
+ const SKeyframe *theRight = CSimpleAnimationCore::GetKeyframeNF(inRightSide, inObjects);
+ return KeyframeTime(theLeft->m_Keyframe) < KeyframeTime(theRight->m_Keyframe);
+}
+
+void SortKeyframes(TKeyframeHandleList &inKeyframes, const THandleObjectMap &inObjects)
+{
+ return stable_sort(inKeyframes.begin(), inKeyframes.end(),
+ std::bind(KeyframeLessThan, std::placeholders::_1,
+ std::placeholders::_2, std::ref(inObjects)));
+}
+
+void CheckKeyframesSorted(const SAnimationTrack *theItem, const THandleObjectMap &inObjects)
+{
+ if (theItem->m_KeyframesDirty) {
+ SAnimationTrack *theNonConst = const_cast<SAnimationTrack *>(theItem);
+ SortKeyframes(theNonConst->m_Keyframes, inObjects);
+ theNonConst->m_KeyframesDirty = false;
+ }
+}
+
+void CSimpleAnimationCore::GetKeyframes(CUICDMAnimationHandle inAnimation,
+ TKeyframeHandleList &outKeyframes) const
+{
+ const SAnimationTrack *theItem = GetAnimationNF(inAnimation, m_Objects);
+ CheckKeyframesSorted(theItem, m_Objects);
+ outKeyframes = theItem->m_Keyframes;
+}
+
+size_t CSimpleAnimationCore::GetKeyframeCount(CUICDMAnimationHandle inAnimation) const
+{
+ const SAnimationTrack *theItem = GetAnimationNF(inAnimation, m_Objects);
+ return theItem->m_Keyframes.size();
+}
+
+bool CSimpleAnimationCore::IsFirstKeyframe(CUICDMKeyframeHandle inKeyframe) const
+{
+ CUICDMAnimationHandle theAnimation = GetAnimationForKeyframe(inKeyframe);
+ if (theAnimation.Valid()) {
+ const SAnimationTrack *theItem = GetAnimationNF(theAnimation, m_Objects);
+ return theItem->m_Keyframes.size() && theItem->m_Keyframes[0] == inKeyframe;
+ }
+ return false;
+}
+
+void CSimpleAnimationCore::OffsetAnimations(CUICDMSlideHandle /*inSlide*/,
+ Qt3DSDMInstanceHandle /*inInstance*/, long /*inOffset*/)
+{
+ throw std::runtime_error("unimplemented");
+}
+
+void CSimpleAnimationCore::SetIsArtistEdited(CUICDMAnimationHandle inAnimation, bool inEdited)
+{
+ if (m_Objects.find(inAnimation) == m_Objects.end()) {
+ Q_ASSERT(false);
+ return;
+ }
+ SAnimationTrack *theItem = GetAnimationNF(inAnimation, m_Objects);
+ if (theItem->m_ArtistEdited != inEdited)
+ theItem->m_ArtistEdited = inEdited;
+}
+
+bool CSimpleAnimationCore::IsArtistEdited(CUICDMAnimationHandle inAnimation) const
+{
+ if (m_Objects.find(inAnimation) == m_Objects.end()) {
+ return false;
+ }
+ const SAnimationTrack *theItem = GetAnimationNF(inAnimation, m_Objects);
+ return theItem->m_ArtistEdited;
+}
+
+inline bool KeyframeTimeLessThan(int inKeyframe, float inSeconds, const THandleObjectMap &inObjects)
+{
+ const SKeyframe *theKeyframe = CSimpleAnimationCore::GetKeyframeNF(inKeyframe, inObjects);
+ return KeyframeTime(theKeyframe->m_Keyframe) < inSeconds;
+}
+
+inline bool KeyframeValueTimeLessThan(const TKeyframe &inLeft, const TKeyframe &inRight)
+{
+ return KeyframeTime(inLeft) < KeyframeTime(inRight);
+}
+
+TKeyframe IntToKeyframe(int inKeyframe, const THandleObjectMap &inObjects)
+{
+ const SKeyframe *theKeyframe = CSimpleAnimationCore::GetKeyframeNF(inKeyframe, inObjects);
+ return theKeyframe->m_Keyframe;
+}
+
+inline float KeyframeValue(int inKeyframe, const THandleObjectMap &inObjects)
+{
+ const SKeyframe *theKeyframe = CSimpleAnimationCore::GetKeyframeNF(inKeyframe, inObjects);
+ return KeyframeValueValue(theKeyframe->m_Keyframe);
+}
+
+inline float EvaluateLinear(float inS1, float inS2, float inV1, float inV2, float inSeconds)
+{
+ float amount = (inSeconds - inS1) / (inS2 - inS1);
+ return inV1 + amount * (inV2 - inV1);
+}
+
+inline float EvaluateLinearKeyframe(SLinearKeyframe &inK1, SLinearKeyframe &inK2, float inSeconds)
+{
+ return EvaluateLinear(inK1.m_KeyframeSeconds, inK2.m_KeyframeSeconds, inK1.m_KeyframeValue,
+ inK2.m_KeyframeValue, inSeconds);
+}
+
+inline float DoBezierEvaluation(float inSeconds, const SBezierKeyframe &inK1,
+ const SBezierKeyframe &inK2)
+{
+ return Q3DStudio::EvaluateBezierKeyframe(
+ inSeconds, inK1.m_KeyframeSeconds, inK1.m_KeyframeValue, inK1.m_OutTangentTime,
+ inK1.m_OutTangentValue, inK2.m_InTangentTime, inK2.m_InTangentValue, inK2.m_KeyframeSeconds,
+ inK2.m_KeyframeValue);
+}
+
+// Animation Evaluation.
+float CSimpleAnimationCore::EvaluateAnimation(CUICDMAnimationHandle inAnimation,
+ float inSeconds) const
+{
+ const SAnimationTrack *theItem = GetAnimationNF(inAnimation, m_Objects);
+ if (theItem->m_Keyframes.empty())
+ return 0.0f;
+ CheckKeyframesSorted(theItem, m_Objects);
+ // Default to linear for now.
+ SLinearKeyframe theKeyframe = { 0 };
+ theKeyframe.m_KeyframeSeconds = inSeconds;
+ TKeyframe theSearchKey(theKeyframe);
+ function<TKeyframe(int)> theIntToKeyframe(
+ std::bind(IntToKeyframe, std::placeholders::_1, std::ref(m_Objects)));
+ typedef transform_iterator<function<TKeyframe(int)>, TKeyframeHandleList::const_iterator>
+ TTransformIterator;
+ TTransformIterator theBound =
+ lower_bound(make_transform_iterator(theItem->m_Keyframes.begin(), theIntToKeyframe),
+ make_transform_iterator(theItem->m_Keyframes.end(), theIntToKeyframe),
+ theSearchKey, KeyframeValueTimeLessThan);
+ if (theBound.base() == theItem->m_Keyframes.end())
+ return KeyframeValue(theItem->m_Keyframes.back(), m_Objects);
+ if (theBound.base() == theItem->m_Keyframes.begin())
+ return KeyframeValue(*theItem->m_Keyframes.begin(), m_Objects);
+ TTransformIterator theStartIter = theBound;
+ --theStartIter;
+
+ // Both iterators must be valid at this point...
+ TKeyframe theStart = *theStartIter;
+ TKeyframe theFinish = *theBound;
+ switch (theItem->m_AnimationType) {
+ default:
+ throw AnimationEvaluationError(L"");
+ case EAnimationTypeLinear: {
+ SLinearKeyframe k1 = get<SLinearKeyframe>(theStart);
+ SLinearKeyframe k2 = get<SLinearKeyframe>(theFinish);
+ return EvaluateLinearKeyframe(k1, k2, inSeconds);
+ }
+ case EAnimationTypeBezier: {
+ SBezierKeyframe k1 = get<SBezierKeyframe>(theStart);
+ SBezierKeyframe k2 = get<SBezierKeyframe>(theFinish);
+ return DoBezierEvaluation(inSeconds, k1, k2);
+ }
+ case EAnimationTypeEaseInOut: {
+ SEaseInEaseOutKeyframe k1 = get<SEaseInEaseOutKeyframe>(theStart);
+ SEaseInEaseOutKeyframe k2 = get<SEaseInEaseOutKeyframe>(theFinish);
+ return DoBezierEvaluation(
+ inSeconds, CreateBezierKeyframeFromEaseInEaseOutKeyframe(NULL, k1, &k2.m_KeyframeValue),
+ CreateBezierKeyframeFromEaseInEaseOutKeyframe(&k1.m_KeyframeValue, k2, NULL));
+ }
+ }
+}
+
+bool CSimpleAnimationCore::KeyframeValid(CUICDMKeyframeHandle inKeyframe) const
+{
+ return HandleObjectValid<SKeyframe>(inKeyframe, m_Objects);
+}
+
+bool CSimpleAnimationCore::AnimationValid(CUICDMAnimationHandle inAnimation) const
+{
+ return HandleObjectValid<SAnimationTrack>(inAnimation, m_Objects);
+}
+
+CUICDMAnimationHandle CSimpleAnimationCore::CreateAnimationWithHandle(
+ int inHandle, CUICDMSlideHandle inSlide, Qt3DSDMInstanceHandle inInstance,
+ Qt3DSDMPropertyHandle inProperty, size_t inIndex, EAnimationType inAnimationType,
+ bool inFirstKeyframeDynamic)
+{
+ if (HandleValid(inHandle))
+ throw HandleExists(L"");
+ m_Objects.insert(make_pair(inHandle, (THandleObjectPtr) new SAnimationTrack(
+ inHandle, inSlide, inInstance, inProperty, inIndex,
+ inAnimationType, inFirstKeyframeDynamic, true)));
+ return inHandle;
+}
+
+void CSimpleAnimationCore::AddAnimationToLookupCache(CUICDMAnimationHandle inAnimation) const
+{
+ THandleObjectMap::const_iterator theAnim = m_Objects.find(inAnimation);
+ if (theAnim != m_Objects.end())
+ AddAnimationToLookupCache(static_pointer_cast<SAnimationTrack>(theAnim->second));
+}
+void CSimpleAnimationCore::RemoveAnimationFromLookupCache(CUICDMAnimationHandle inAnimation) const
+{
+ THandleObjectMap::const_iterator theAnim = m_Objects.find(inAnimation);
+ if (theAnim != m_Objects.end())
+ RemoveAnimationFromLookupCache(static_pointer_cast<SAnimationTrack>(theAnim->second));
+}
+
+// Ensure there is only one of these in the multimap.
+void CSimpleAnimationCore::AddAnimationToLookupCache(
+ std::shared_ptr<SAnimationTrack> inAnimation) const
+{
+ CUICDMSlideHandle theSlide = inAnimation->m_Slide;
+ Qt3DSDMInstanceHandle theInstance = inAnimation->m_Instance;
+ pair<TStateInstanceAnimationMap::iterator, TStateInstanceAnimationMap::iterator> theRange =
+ m_AnimationMatchesCache.equal_range(
+ make_pair(theSlide.GetHandleValue(), theInstance.GetHandleValue()));
+ for (TStateInstanceAnimationMap::iterator theIter = theRange.first; theIter != theRange.second;
+ ++theIter) {
+ if (theIter->second == inAnimation)
+ return;
+ }
+ m_AnimationMatchesCache.insert(
+ make_pair(make_pair(theSlide.GetHandleValue(), theInstance.GetHandleValue()), inAnimation));
+}
+
+// Remove this from the multimap
+void CSimpleAnimationCore::RemoveAnimationFromLookupCache(
+ std::shared_ptr<SAnimationTrack> inAnimation) const
+{
+ TStateInstanceAnimationMap &theMap(m_AnimationMatchesCache);
+ CUICDMSlideHandle theSlide = inAnimation->m_Slide;
+ Qt3DSDMInstanceHandle theInstance = inAnimation->m_Instance;
+ pair<TStateInstanceAnimationMap::iterator, TStateInstanceAnimationMap::iterator> theRange =
+ theMap.equal_range(make_pair(theSlide.GetHandleValue(), theInstance.GetHandleValue()));
+ for (TStateInstanceAnimationMap::iterator theIter = theRange.first; theIter != theRange.second;
+ ++theIter) {
+ if (theIter->second == inAnimation) {
+ theMap.erase(theIter);
+ break;
+ }
+ }
+}
+
+//================================================================================
+// UICDMAnimation.h function implementations
+//================================================================================
+
+void CopyKeyframe(CUICDMAnimationHandle inAnimation, CUICDMKeyframeHandle inKeyframe,
+ const IAnimationCore &inSourceAnimationCore, IAnimationCore &inDestAnimationCore)
+{
+ TKeyframe theData = inSourceAnimationCore.GetKeyframeData(inKeyframe);
+ inDestAnimationCore.InsertKeyframe(inAnimation, theData);
+}
+
+void CopyKeyframes(const IAnimationCore &inSourceAnimationCore, IAnimationCore &inDestAnimationCore,
+ CUICDMAnimationHandle inDestAnimation, const TKeyframeHandleList &inKeyframes)
+{
+ do_all(inKeyframes,
+ std::bind(CopyKeyframe, inDestAnimation, std::placeholders::_1,
+ std::cref(inSourceAnimationCore), std::ref(inDestAnimationCore)));
+}
+
+CUICDMAnimationHandle CopyAnimation(TAnimationCorePtr inAnimationCore,
+ CUICDMAnimationHandle inAnimation, CUICDMSlideHandle inNewSlide,
+ Qt3DSDMInstanceHandle inNewInstance,
+ Qt3DSDMPropertyHandle inNewProperty, size_t inNewIndex)
+{
+ TKeyframeHandleList theKeyframes;
+ inAnimationCore->GetKeyframes(inAnimation, theKeyframes);
+ SAnimationInfo theInfo(inAnimationCore->GetAnimationInfo(inAnimation));
+ CUICDMAnimationHandle theAnimation =
+ inAnimationCore->CreateAnimation(inNewSlide, inNewInstance, inNewProperty, inNewIndex,
+ theInfo.m_AnimationType, theInfo.m_DynamicFirstKeyframe);
+ CopyKeyframes(*inAnimationCore, *inAnimationCore, theAnimation, theKeyframes);
+ return theAnimation;
+}
+
+SBezierKeyframe GetBezierKeyframeData(CUICDMKeyframeHandle inKeyframe,
+ const IAnimationCore &inAnimationCore)
+{
+ return get<SBezierKeyframe>(inAnimationCore.GetKeyframeData(inKeyframe));
+}
+
+SEaseInEaseOutKeyframe GetEaseInEaseOutKeyframeData(CUICDMKeyframeHandle inKeyframe,
+ const IAnimationCore &inAnimationCore)
+{
+ return get<SEaseInEaseOutKeyframe>(inAnimationCore.GetKeyframeData(inKeyframe));
+}
+
+TKeyframeHandleList::iterator SafeIncrementIterator(TKeyframeHandleList::iterator inIter,
+ const TKeyframeHandleList::iterator &inEnd)
+{
+ return inIter == inEnd ? inEnd : inIter + 1;
+}
+
+void GetKeyframesAsBezier(CUICDMAnimationHandle inAnimation, const IAnimationCore &inAnimationCore,
+ TBezierKeyframeList &outKeyframes)
+{
+ SAnimationInfo theInfo(inAnimationCore.GetAnimationInfo(inAnimation));
+ TKeyframeHandleList theKeyframes;
+ inAnimationCore.GetKeyframes(inAnimation, theKeyframes);
+ outKeyframes.resize(theKeyframes.size());
+ switch (theInfo.m_AnimationType) {
+ default:
+ throw invalid_argument("AnimationType");
+ case EAnimationTypeBezier:
+ transform(theKeyframes.begin(), theKeyframes.end(), outKeyframes.begin(),
+ std::bind(GetBezierKeyframeData, std::placeholders::_1,
+ std::cref(inAnimationCore)));
+ break;
+ case EAnimationTypeEaseInOut: {
+
+ TKeyframeHandleList::iterator theEndKeyframe = theKeyframes.end();
+
+ typedef std::function<SEaseInEaseOutKeyframe(CUICDMKeyframeHandle)> TConvertFunc;
+ TConvertFunc theDataConverter(
+ std::bind(GetEaseInEaseOutKeyframeData, std::placeholders::_1,
+ std::cref(inAnimationCore)));
+ typedef boost::transform_iterator<TConvertFunc, TKeyframeHandleList::iterator>
+ TTransformIterator;
+ TTransformIterator thePreviousKeyframe(
+ make_transform_iterator(theKeyframes.begin(), theDataConverter));
+ TTransformIterator theCurrentKeyframe(make_transform_iterator(
+ SafeIncrementIterator(thePreviousKeyframe.base(), theEndKeyframe), theDataConverter));
+ TTransformIterator theNextKeyframe(make_transform_iterator(
+ SafeIncrementIterator(theCurrentKeyframe.base(), theEndKeyframe), theDataConverter));
+
+ TBezierKeyframeList::iterator theResult(outKeyframes.begin());
+
+ if (thePreviousKeyframe.base() != theEndKeyframe) {
+ float *theNextValuePtr = NULL;
+ float theNextValue;
+ if (theCurrentKeyframe.base() != theEndKeyframe) {
+ theNextValue = theCurrentKeyframe->m_KeyframeValue;
+ theNextValuePtr = &theNextValue;
+ }
+ *theResult = CreateBezierKeyframeFromEaseInEaseOutKeyframe(NULL, *thePreviousKeyframe,
+ theNextValuePtr);
+ theResult = theResult + 1;
+ }
+ for (; theCurrentKeyframe.base() != theEndKeyframe;
+ ++thePreviousKeyframe,
+ theCurrentKeyframe = make_transform_iterator(
+ SafeIncrementIterator(theCurrentKeyframe.base(), theEndKeyframe),
+ theDataConverter),
+ theNextKeyframe = make_transform_iterator(
+ SafeIncrementIterator(theNextKeyframe.base(), theEndKeyframe), theDataConverter),
+ ++theResult) {
+ float theLastValue(thePreviousKeyframe->m_KeyframeValue);
+ float *theNextValuePtr = NULL;
+ float theNextValue;
+ if (theNextKeyframe.base() != theEndKeyframe) {
+ theNextValue = theNextKeyframe->m_KeyframeValue;
+ theNextValuePtr = &theNextValue;
+ }
+ *theResult = CreateBezierKeyframeFromEaseInEaseOutKeyframe(
+ &theLastValue, *theCurrentKeyframe, theNextValuePtr);
+ }
+ } break;
+ }
+}
+}
diff --git a/src/Authoring/QT3DSDM/Systems/Cores/SimpleAnimationCore.h b/src/Authoring/QT3DSDM/Systems/Cores/SimpleAnimationCore.h
new file mode 100644
index 00000000..62d7e6c8
--- /dev/null
+++ b/src/Authoring/QT3DSDM/Systems/Cores/SimpleAnimationCore.h
@@ -0,0 +1,218 @@
+/****************************************************************************
+**
+** 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-EXCEPT$
+** 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 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** 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$
+**
+****************************************************************************/
+#pragma once
+#ifndef ANIMATIONCOREH
+#define ANIMATIONCOREH
+#include "Qt3DSDMAnimation.h"
+#include "HandleSystemBase.h"
+#include <boost/unordered_map.hpp>
+
+namespace qt3dsdm {
+struct SAnimationTrack : public CHandleObject
+{
+ int m_Slide;
+ int m_Instance;
+ int m_Property;
+ EAnimationType m_AnimationType;
+ size_t m_Index;
+ TKeyframeHandleList m_Keyframes;
+ bool m_KeyframesDirty;
+ bool m_FirstKeyframeDynamic;
+ bool m_ArtistEdited;
+
+ SAnimationTrack()
+ : m_Slide(0)
+ , m_Instance(0)
+ , m_Property(0)
+ , m_AnimationType(EAnimationTypeLinear)
+ , m_Index(0)
+ , m_KeyframesDirty(false)
+ , m_FirstKeyframeDynamic(false)
+ , m_ArtistEdited(true)
+ {
+ }
+
+ SAnimationTrack(int inHandle, CUICDMSlideHandle inSlide, Qt3DSDMInstanceHandle inInstance,
+ Qt3DSDMPropertyHandle inProperty, size_t inIndex, EAnimationType inAnimationType,
+ bool inFirstKeyframeDynamic, bool inArtistEdited)
+ : CHandleObject(inHandle)
+ , m_Slide(inSlide)
+ , m_Instance(inInstance)
+ , m_Property(inProperty)
+ , m_AnimationType(inAnimationType)
+ , m_Index(inIndex)
+ , m_KeyframesDirty(false)
+ , m_FirstKeyframeDynamic(inFirstKeyframeDynamic)
+ , m_ArtistEdited(inArtistEdited)
+ {
+ }
+
+ static const EHandleObjectType s_Type = CHandleObject::EHandleObjectTypeSAnimationTrack;
+ EHandleObjectType GetType() override { return s_Type; }
+};
+
+struct SKeyframe : public CHandleObject
+{
+ TKeyframe m_Keyframe;
+ int m_Animation;
+
+ SKeyframe(int inHandle, int inAnimation, const TKeyframe &inKeyframe)
+ : CHandleObject(inHandle)
+ , m_Keyframe(inKeyframe)
+ , m_Animation(inAnimation)
+ {
+ }
+
+ static const EHandleObjectType s_Type = CHandleObject::EHandleObjectTypeSKeyframe;
+ EHandleObjectType GetType() override { return s_Type; }
+};
+
+class CAnimationCoreProducer;
+
+class CSimpleAnimationCore : public CHandleBase, public IAnimationCore
+{
+ TStringTablePtr m_StringTable;
+ typedef boost::unordered_multimap<std::pair<int, int>, std::shared_ptr<SAnimationTrack>>
+ TStateInstanceAnimationMap;
+ // state,instance pair map to animation handle to speed up querying if a particular
+ // property is animated.
+ mutable TStateInstanceAnimationMap m_AnimationMatchesCache;
+
+public: // Use
+ friend class CAnimationCoreProducer;
+ // We don't use the string table ptr we are constructed with
+ // but the testing system needs an unified interface to creating
+ // objects
+ CSimpleAnimationCore() {}
+ CSimpleAnimationCore(TStringTablePtr strTable)
+ : m_StringTable(strTable)
+ {
+ }
+ TStringTablePtr GetStringTablePtr() const { return m_StringTable; }
+
+ CUICDMAnimationHandle CreateAnimation(CUICDMSlideHandle inSlide,
+ Qt3DSDMInstanceHandle inInstance,
+ Qt3DSDMPropertyHandle inProperty, size_t inIndex,
+ EAnimationType inAnimationType,
+ bool inFirstKeyframeDynamic) override;
+ void DeleteAnimation(CUICDMAnimationHandle inAnimation) override;
+ CUICDMAnimationHandle GetAnimation(CUICDMSlideHandle inSlide, Qt3DSDMInstanceHandle inInstance,
+ Qt3DSDMPropertyHandle inProperty, size_t inIndex) const override;
+ SAnimationInfo GetAnimationInfo(CUICDMAnimationHandle inAnimation) const override;
+ void GetAnimations(TAnimationHandleList &outAnimations) const override;
+ void GetAnimations(TAnimationInfoList &outAnimations, CUICDMSlideHandle inMaster,
+ CUICDMSlideHandle inSlide) const override;
+ void GetSpecificInstanceAnimations(CUICDMSlideHandle inSlide, Qt3DSDMInstanceHandle inInstance,
+ TAnimationHandleList &outAnimations) override;
+
+ void SetFirstKeyframeDynamic(CUICDMAnimationHandle inAnimation, bool inValue) override;
+
+ // keyframe manipulation
+ CUICDMKeyframeHandle InsertKeyframe(CUICDMAnimationHandle inAnimation,
+ const TKeyframe &inKeyframe) override;
+ void EraseKeyframe(CUICDMKeyframeHandle inKeyframe) override;
+ void DeleteAllKeyframes(CUICDMAnimationHandle inAnimation) override;
+ CUICDMAnimationHandle GetAnimationForKeyframe(CUICDMKeyframeHandle inKeyframe) const override;
+ TKeyframe GetKeyframeData(CUICDMKeyframeHandle inKeyframe) const override;
+ void SetKeyframeData(CUICDMKeyframeHandle inKeyframe, const TKeyframe &inData) override;
+ // Set the keyframe data, but don't set the artist edited flag. Used for undo/redo operations
+ // where the artist edited flag has handeled by a different transaction
+ void DoSetKeyframeData(CUICDMKeyframeHandle inKeyframe, const TKeyframe &inData);
+ void GetKeyframes(CUICDMAnimationHandle inAnimation, TKeyframeHandleList &outKeyframes) const override;
+ size_t GetKeyframeCount(CUICDMAnimationHandle inAnimation) const override;
+ bool IsFirstKeyframe(CUICDMKeyframeHandle inKeyframe) const override;
+ // Only implemented in the producer for now.
+ void OffsetAnimations(CUICDMSlideHandle inSlide, Qt3DSDMInstanceHandle inInstance,
+ long inOffset) override;
+
+ void SetIsArtistEdited(CUICDMAnimationHandle inAnimation, bool inEdited = true) override;
+ bool IsArtistEdited(CUICDMAnimationHandle inAnimation) const override;
+
+ // Animation Evaluation.
+ float EvaluateAnimation(CUICDMAnimationHandle inAnimation, float inSeconds) const override;
+
+ bool KeyframeValid(CUICDMKeyframeHandle inKeyframe) const override;
+ bool AnimationValid(CUICDMAnimationHandle inAnimation) const override;
+
+ // Only implemented at the producer level, not at the simple core level.
+ void CopyAnimations(CUICDMSlideHandle /*inSourceSlide*/,
+ Qt3DSDMInstanceHandle /*inSourceInstance*/,
+ CUICDMSlideHandle /*inDestSlide*/, Qt3DSDMInstanceHandle /*inDestInstance*/) override
+ {
+ throw AnimationNotFound(L"");
+ }
+
+ // Lookup cache management so we can find particular animations quickly.
+ void ClearAnimationMatchesLookupCache() const { m_AnimationMatchesCache.clear(); }
+ void AddAnimationToLookupCache(CUICDMAnimationHandle inAnimation) const;
+ void RemoveAnimationFromLookupCache(CUICDMAnimationHandle inAnimation) const;
+ void AddAnimationToLookupCache(std::shared_ptr<SAnimationTrack> inAnimation) const;
+ void RemoveAnimationFromLookupCache(std::shared_ptr<SAnimationTrack> inAnimation) const;
+
+ void EnsureAnimationCache() const;
+
+ CUICDMAnimationHandle CreateAnimationWithHandle(int inHandle, CUICDMSlideHandle inSlide,
+ Qt3DSDMInstanceHandle inInstance,
+ Qt3DSDMPropertyHandle inProperty, size_t inIndex,
+ EAnimationType inAnimationType,
+ bool inFirstKeyframeDynamic);
+
+ static SAnimationTrack *GetAnimationNF(int inHandle, THandleObjectMap &inObjects)
+ {
+ return const_cast<SAnimationTrack *>(
+ GetAnimationNF(inHandle, static_cast<const THandleObjectMap &>(inObjects)));
+ }
+
+ static const SAnimationTrack *GetAnimationNF(int inHandle, const THandleObjectMap &inObjects)
+ {
+ const SAnimationTrack *theAnimation = GetHandleObject<SAnimationTrack>(inHandle, inObjects);
+ if (theAnimation)
+ return theAnimation;
+ throw AnimationNotFound(L"");
+ }
+
+ static SKeyframe *GetKeyframeNF(int inHandle, THandleObjectMap &inObjects)
+ {
+ return const_cast<SKeyframe *>(
+ GetKeyframeNF(inHandle, static_cast<const THandleObjectMap &>(inObjects)));
+ }
+
+ static const SKeyframe *GetKeyframeNF(int inHandle, const THandleObjectMap &inObjects)
+ {
+ const SKeyframe *theItem = GetHandleObject<SKeyframe>(inHandle, inObjects);
+ if (theItem)
+ return theItem;
+ throw AnimationKeyframeNotFound(L"");
+ }
+};
+
+typedef std::shared_ptr<CSimpleAnimationCore> TSimpleAnimationCorePtr;
+}
+
+#endif
diff --git a/src/Authoring/QT3DSDM/Systems/Cores/SimpleDataCore.cpp b/src/Authoring/QT3DSDM/Systems/Cores/SimpleDataCore.cpp
new file mode 100644
index 00000000..b401d83c
--- /dev/null
+++ b/src/Authoring/QT3DSDM/Systems/Cores/SimpleDataCore.cpp
@@ -0,0 +1,574 @@
+/****************************************************************************
+**
+** 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-EXCEPT$
+** 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 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** 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 "Qt3DSDMPrefix.h"
+#include "SimpleDataCore.h"
+
+namespace qt3dsdm {
+TUICDMDebugLogFunction g_UICDMDebugLogger = NULL;
+// Instances
+Qt3DSDMInstanceHandle CSimpleDataCore::CreateInstance(Qt3DSDMInstanceHandle hdl)
+{
+ int nextId = hdl;
+ if (hdl.Valid() == false)
+ nextId = GetNextId();
+
+ return CreateInstanceWithHandle(nextId);
+}
+
+inline void RemoveParentFromClass(int inParent, int inChild, THandleObjectMap &inMap)
+{
+ TDataModelInstancePtr theInstance = CSimpleDataCore::GetInstanceNF(inChild, inMap);
+ theInstance->m_Parents.erase(theInstance->m_Parents.find(inParent));
+ // Cascade the delete operation
+}
+
+void CSimpleDataCore::DeleteInstance(Qt3DSDMInstanceHandle inHandle)
+{
+ // Ensure it exists in the first place.
+ CSimpleDataCore::GetInstanceNF(inHandle, m_Objects); // Check for instance existance
+ CSimpleDataCore::EraseHandle(inHandle, m_Objects);
+ TIntList properties;
+ TIntList instances;
+ do_all(m_Objects, std::bind(FindRelatedItemsForDelete, inHandle.GetHandleValue(),
+ std::ref(properties), std::ref(instances), std::placeholders::_1));
+ do_all(instances, std::bind(RemoveParentFromClass, inHandle.GetHandleValue(),
+ std::placeholders::_1, std::ref(m_Objects)));
+ do_all(properties, std::bind(EraseHandle, std::placeholders::_1, std::ref(m_Objects)));
+}
+
+void CSimpleDataCore::GetInstances(TInstanceHandleList &outInstances) const
+{
+ // reserve the vector to m_Objects.size() to prevent vector reallocation
+ // m_Objects.size() is the upper bound of the no of instances
+ // the exact no of instances = m_Objects.size() - the no of properties as added by
+ // CClientDataModelBridge::InitializeDataCore (as of now, we have 31 properties)
+ outInstances.reserve(m_Objects.size());
+ do_all(m_Objects, std::bind(MaybeAddObject<CDataModelInstance, Qt3DSDMInstanceHandle>,
+ std::placeholders::_1, std::ref(outInstances)));
+}
+
+// Get instances that are derived from a specific parent
+void CSimpleDataCore::GetInstancesDerivedFrom(TInstanceHandleList &outInstances,
+ Qt3DSDMInstanceHandle inParentHandle) const
+{
+ do_all(m_Objects, std::bind(&CSimpleDataCore::AddInstanceIfDerivedFrom, this,
+ std::placeholders::_1,
+ std::ref(outInstances), inParentHandle));
+}
+
+// add instance that is derived from a specific parent
+void CSimpleDataCore::AddInstanceIfDerivedFrom(const std::pair<int, THandleObjectPtr> &inItem,
+ TInstanceHandleList &outInstances,
+ Qt3DSDMInstanceHandle inParentHandle) const
+{
+ if (inItem.second->GetType() == CHandleObject::EHandleObjectTypeCDataModelInstance) {
+ TDataModelInstancePtr theInstance = static_pointer_cast<CDataModelInstance>(inItem.second);
+ if (IsInstanceOrDerivedFromHelper(theInstance, inParentHandle))
+ outInstances.push_back(inItem.first);
+ }
+}
+
+// Derivation
+void CSimpleDataCore::DeriveInstance(Qt3DSDMInstanceHandle inInstance, Qt3DSDMInstanceHandle inParent)
+{
+ if (g_UICDMDebugLogger)
+ g_UICDMDebugLogger("CSimpleDataCore::DeriveInstance Enter");
+ TDataModelInstancePtr theInstance = CSimpleDataCore::GetInstanceNF(inInstance, m_Objects);
+ if (theInstance->m_Parents.find(inParent) == theInstance->m_Parents.end()) {
+ std::shared_ptr<CDataModelInstance> theParent(GetInstanceNF(inParent, m_Objects));
+ theInstance->m_Parents.insert(make_pair(inParent, theParent));
+ }
+ if (g_UICDMDebugLogger)
+ g_UICDMDebugLogger("CSimpleDataCore::DeriveInstance Leave");
+}
+
+void CSimpleDataCore::GetInstanceParents(Qt3DSDMInstanceHandle inHandle,
+ TInstanceHandleList &outParents) const
+{
+ const TDataModelInstancePtr theInstance = GetInstanceNF(inHandle, m_Objects);
+ for (CDataModelInstance::TInstancePairList::const_iterator theParent =
+ theInstance->m_Parents.begin();
+ theParent != theInstance->m_Parents.end(); ++theParent)
+ outParents.push_back(theParent->first);
+}
+
+inline bool ComparePropertyNames(const TCharStr &inName, int inPropHandle,
+ const THandleObjectMap &inObjects)
+{
+ if (CSimpleDataCore::GetPropertyDefinitionNF(inPropHandle, inObjects)->m_Definition.m_Name
+ == inName)
+ return true;
+ return false;
+}
+
+inline const wchar_t *SafeStrPtr(const wchar_t *inData)
+{
+ return inData == NULL ? L"" : inData;
+}
+
+// Properties
+Qt3DSDMPropertyHandle CSimpleDataCore::AddProperty(Qt3DSDMInstanceHandle inInstance, TCharPtr inName,
+ DataModelDataType::Value inPropType)
+{
+ UICDM_LOG_FUNCTION("CSimpleDataCore::AddProperty");
+ UICDM_DEBUG_LOG(m_StringTable->GetNarrowStr(inName));
+ TDataModelInstancePtr theInstance = GetInstanceNF(inInstance, m_Objects);
+ TCharStr theName(inName);
+ if (find_if<TIntList::iterator>(
+ theInstance->m_Properties,
+ std::bind(ComparePropertyNames, std::ref(theName),
+ std::placeholders::_1, std::ref(m_Objects)))
+ != theInstance->m_Properties.end()) {
+ UICDM_DEBUG_LOG("Property Exists!!");
+ throw PropertyExists(L"");
+ }
+
+ int nextId = GetNextId();
+ return AddPropertyWithHandle(nextId, inInstance, inName, inPropType);
+}
+
+void CSimpleDataCore::GetInstanceProperties(Qt3DSDMInstanceHandle inInstance,
+ TPropertyHandleList &outProperties) const
+{
+ transformv_all(GetInstanceNF(inInstance, m_Objects)->m_Properties, outProperties);
+}
+
+const SUICDMPropertyDefinition &CSimpleDataCore::GetProperty(Qt3DSDMPropertyHandle inProperty) const
+{
+ const CDataModelPropertyDefinitionObject *theProp =
+ GetPropertyDefinitionNF(inProperty, m_Objects);
+ return theProp->m_Definition;
+}
+
+void CSimpleDataCore::RemoveProperty(Qt3DSDMPropertyHandle inProperty)
+{
+ CDataModelPropertyDefinitionObject *theProp =
+ CSimpleDataCore::GetPropertyDefinitionNF(inProperty, m_Objects);
+ TDataModelInstancePtr theInstance =
+ CSimpleDataCore::GetInstanceNF(theProp->m_Definition.m_Instance, m_Objects);
+ erase_if(theInstance->m_Properties,
+ std::bind(equal_to<int>(), inProperty.GetHandleValue(), std::placeholders::_1));
+ CSimpleDataCore::EraseHandle(inProperty, m_Objects);
+}
+
+inline bool PropertyMatches(int inProperty, Qt3DSDMPropertyHandle inTarget)
+{
+ return inProperty == inTarget.GetHandleValue();
+}
+
+inline bool GetInstanceValue(Qt3DSDMInstanceHandle inInstanceHandle,
+ Qt3DSDMPropertyHandle inPropertyHandle, CSimpleDataCore &inDataCore,
+ SValue &outValue)
+{
+ const TDataModelInstancePtr theInstance =
+ CSimpleDataCore::GetInstanceNF(inInstanceHandle, inDataCore.m_Objects);
+
+ TPropertyPairHash::const_iterator theInstanceProp =
+ theInstance->m_PropertyValues.find(inPropertyHandle.GetHandleValue());
+ if (theInstanceProp != theInstance->m_PropertyValues.end()) {
+ outValue = theInstanceProp->second.second.GetValue();
+ return true;
+ }
+ return false;
+}
+
+inline void CopyInstanceProperty(Qt3DSDMPropertyHandle inSrcPropertyHandle,
+ Qt3DSDMInstanceHandle inSrcInstanceHandle,
+ Qt3DSDMInstanceHandle inInstanceHandle, CSimpleDataCore &inDataCore)
+{
+ // create the property definition that matches the source
+ const SUICDMPropertyDefinition &theProperty = inDataCore.GetProperty(inSrcPropertyHandle);
+ Qt3DSDMPropertyHandle theNewProperty =
+ inDataCore.AddProperty(inInstanceHandle, theProperty.m_Name.wide_str(), theProperty.m_Type);
+ // copy the value if one exists on the src.
+ SValue theValue;
+ if (GetInstanceValue(inSrcInstanceHandle, inSrcPropertyHandle, inDataCore, theValue))
+ inDataCore.SetInstancePropertyValue(inInstanceHandle, theNewProperty, theValue);
+}
+
+// logic : if destination property is one gained through derivation in inSrcInstanceHandle, copy the
+// value over.
+inline void CopyAggregatedPropertyValues(Qt3DSDMPropertyHandle inDestPropertyHandle,
+ Qt3DSDMInstanceHandle inSrcInstanceHandle,
+ Qt3DSDMInstanceHandle inInstanceHandle,
+ const TPropertyHandleList &inSrcNonAggregateList,
+ CSimpleDataCore &inDataCore)
+{
+ if (find_if(inSrcNonAggregateList.begin(), inSrcNonAggregateList.end(),
+ bind(PropertyMatches, inDestPropertyHandle, std::placeholders::_1))
+ == inSrcNonAggregateList.end()
+ && inDataCore.HasAggregateInstanceProperty(inSrcInstanceHandle, inDestPropertyHandle)) {
+ SValue theValue;
+ if (GetInstanceValue(inSrcInstanceHandle, inDestPropertyHandle, inDataCore, theValue))
+ inDataCore.SetInstancePropertyValue(inInstanceHandle, inDestPropertyHandle, theValue);
+ }
+}
+
+void CSimpleDataCore::CopyInstanceProperties(Qt3DSDMInstanceHandle inSrcInstance,
+ Qt3DSDMInstanceHandle inDestInstance)
+{
+ TPropertyHandleList theList;
+ GetInstanceProperties(inSrcInstance, theList);
+ do_all(theList, bind(CopyInstanceProperty, std::placeholders::_1,
+ inSrcInstance, inDestInstance, ref(*this)));
+
+ TPropertyHandleList theDestList;
+ GetAggregateInstanceProperties(inDestInstance, theDestList);
+ do_all(theDestList, std::bind(CopyAggregatedPropertyValues, std::placeholders::_1,
+ inSrcInstance, inDestInstance,
+ theList, std::ref(*this)));
+}
+
+void CSimpleDataCore::RemoveCachedValues(Qt3DSDMInstanceHandle inInstance)
+{
+ const TDataModelInstancePtr theInstance = CSimpleDataCore::GetInstanceNF(inInstance, m_Objects);
+ theInstance->RemoveCachedValues();
+}
+
+void GetAggregateProperties(const TDataModelInstancePtr inInstance, TIntList &inVisited,
+ TPropertyHandleList &outProperties)
+{
+ if (find(inVisited.begin(), inVisited.end(), inInstance->m_Handle) == inVisited.end()) {
+ inVisited.push_back(inInstance->m_Handle);
+ size_t theSize = outProperties.size();
+ outProperties.resize(theSize + inInstance->m_Properties.size());
+ transform(inInstance->m_Properties.begin(), inInstance->m_Properties.end(),
+ outProperties.begin() + theSize, identity<int>);
+ for (CDataModelInstance::TInstancePairList::const_iterator theParent =
+ inInstance->m_Parents.begin();
+ theParent != inInstance->m_Parents.end(); ++theParent)
+ GetAggregateProperties(theParent->second, inVisited, outProperties);
+ }
+}
+
+template <typename TPredicate>
+inline std::tuple<bool, Qt3DSDMInstanceHandle, Qt3DSDMPropertyHandle>
+RecurseFindProperty(const TDataModelInstancePtr inInstance, TPredicate inPredicate)
+{
+ TIntList::const_iterator theFind = eastl::find_if(inInstance->m_Properties.begin(),
+ inInstance->m_Properties.end(), inPredicate);
+ if (theFind != inInstance->m_Properties.end())
+ return make_tuple(true, inInstance->m_Handle, *theFind);
+
+ for (CDataModelInstance::TInstancePairList::const_iterator theParent =
+ inInstance->m_Parents.begin();
+ theParent != inInstance->m_Parents.end(); ++theParent) {
+ std::tuple<bool, Qt3DSDMInstanceHandle, Qt3DSDMPropertyHandle> theValue =
+ RecurseFindProperty(theParent->second, inPredicate);
+ if (get<0>(theValue))
+ return theValue;
+ }
+ return make_tuple(false, 0, 0);
+}
+
+inline bool PropertyNameMatches(int inProperty, const THandleObjectMap &inObjects,
+ const TCharStr &inStr)
+{
+ const CDataModelPropertyDefinitionObject *theProp =
+ CSimpleDataCore::GetPropertyDefinitionNF(inProperty, inObjects);
+ return (theProp->m_Definition.m_Name == inStr);
+}
+
+Qt3DSDMPropertyHandle
+CSimpleDataCore::GetAggregateInstancePropertyByName(Qt3DSDMInstanceHandle inInstance,
+ const TCharStr &inStr) const
+{
+ const TDataModelInstancePtr theInstance = GetInstanceNF(inInstance, m_Objects);
+ return get<2>(
+ RecurseFindProperty(theInstance, std::bind(PropertyNameMatches,
+ std::placeholders::_1, std::ref(m_Objects),
+ std::ref(inStr))));
+}
+
+// A simplified RecurseFindProperty function
+bool RecurseFindPropertyMatches(const TDataModelInstancePtr inInstance,
+ Qt3DSDMPropertyHandle inProperty)
+{
+ TIntList::const_iterator theFind =
+ find(inInstance->m_Properties.begin(), inInstance->m_Properties.end(),
+ inProperty.GetHandleValue());
+ if (theFind != inInstance->m_Properties.end())
+ return true;
+
+ for (CDataModelInstance::TInstancePairList::const_iterator theParent =
+ inInstance->m_Parents.begin();
+ theParent != inInstance->m_Parents.end(); ++theParent) {
+ if (RecurseFindPropertyMatches(theParent->second, inProperty))
+ return true;
+ }
+ return false;
+}
+
+bool CSimpleDataCore::HasAggregateInstanceProperty(Qt3DSDMInstanceHandle inInstance,
+ Qt3DSDMPropertyHandle inProperty) const
+{
+ const TDataModelInstancePtr theInstance = GetInstanceNF(inInstance, m_Objects);
+ if (theInstance->m_PropertyValues.find(inProperty.GetHandleValue())
+ != theInstance->m_PropertyValues.end())
+ return true;
+
+ return RecurseFindPropertyMatches(theInstance, inProperty);
+}
+
+void CSimpleDataCore::GetAggregateInstanceProperties(Qt3DSDMInstanceHandle inInstance,
+ TPropertyHandleList &outProperties) const
+{
+ TIntList inVisited;
+ const TDataModelInstancePtr theInstance = GetInstanceNF(inInstance, m_Objects);
+ GetAggregateProperties(theInstance, inVisited, outProperties);
+}
+
+void CSimpleDataCore::CheckValue(Qt3DSDMInstanceHandle inInstance, Qt3DSDMPropertyHandle inProperty,
+ const SValue &inValue) const
+{
+ CheckPropertyExistence(GetInstanceNF(inInstance, m_Objects), inProperty, m_Objects);
+ const CDataModelPropertyDefinitionObject *theDefinition =
+ CSimpleDataCore::GetPropertyDefinitionNF(inProperty, m_Objects);
+ CheckValueType(theDefinition->m_Definition.m_Type, inValue);
+}
+
+bool CSimpleDataCore::GetInstancePropertyValueHelper(const TDataModelInstancePtr inInstance,
+ Qt3DSDMPropertyHandle inProperty,
+ SValue &outValue) const
+{
+ TPropertyPairHash::const_iterator theInstanceProp =
+ inInstance->m_PropertyValues.find(inProperty);
+ if (theInstanceProp != inInstance->m_PropertyValues.end()) {
+ outValue = theInstanceProp->second.second.GetValue();
+ return true;
+ } else {
+ // Is the property valid?
+ const CDataModelPropertyDefinitionObject *theProp =
+ GetPropertyDefinitionNF(inProperty, m_Objects);
+ int thePropInstance = theProp->m_Definition.m_Instance;
+ if (thePropInstance != inInstance->m_Handle) {
+ for (CDataModelInstance::TInstancePairList::const_iterator theParent =
+ inInstance->m_Parents.begin();
+ theParent != inInstance->m_Parents.end(); ++theParent) {
+ if (IsInstanceOrDerivedFromHelper(theParent->second, thePropInstance)
+ && GetInstancePropertyValueHelper(theParent->second, inProperty, outValue)) {
+ // Quietly propagate to this instance so next time we won't go through this
+ // large property lookup chain.
+ inInstance->m_PropertyValues.insert(std::make_pair(
+ inProperty,
+ TPropertyValuePair(
+ PropertyValueFlags(PropertyValueFlags::SetViaAutoPropagate),
+ SInternValue::ISwearThisHasAlreadyBeenInternalized(outValue))));
+ return true;
+ }
+ }
+ }
+ }
+ return false;
+}
+
+bool CSimpleDataCore::GetInstancePropertyValue(Qt3DSDMInstanceHandle inHandle,
+ Qt3DSDMPropertyHandle inProperty,
+ SValue &outValue) const
+{
+ if (IsInstance(inHandle) == false || IsProperty(inProperty) == false) {
+ Q_ASSERT(0);
+ return false;
+ }
+ const TDataModelInstancePtr theInstance = GetInstanceNF(inHandle, m_Objects);
+ return GetInstancePropertyValueHelper(theInstance, inProperty, outValue);
+}
+
+void CSimpleDataCore::SetInstancePropertyValue(Qt3DSDMInstanceHandle inHandle,
+ Qt3DSDMPropertyHandle inProperty,
+ const SValue &inValue)
+{
+ if (IsInstance(inHandle) == false || IsProperty(inProperty) == false) {
+ Q_ASSERT(0);
+ return;
+ }
+ CheckValue(inHandle, inProperty, inValue);
+ UncheckedSetSpecificInstancePropertyValue(inHandle, inProperty, inValue, PropertyValueFlags());
+}
+
+void CSimpleDataCore::GetSpecificInstancePropertyValues(Qt3DSDMInstanceHandle inHandle,
+ TPropertyHandleValuePairList &outValues)
+{
+ if (IsInstance(inHandle) == false)
+ return;
+
+ TDataModelInstancePtr theInstance = GetInstanceNF(inHandle, m_Objects);
+ for (TPropertyPairHash::const_iterator theIter = theInstance->m_PropertyValues.begin(),
+ theEnd = theInstance->m_PropertyValues.end();
+ theIter != theEnd; ++theIter) {
+ const pair<int, TPropertyValuePair> &thePair(*theIter);
+ if (thePair.second.first.IsSetViaAutoPropagation() == false) {
+ Qt3DSDMPropertyHandle thePropertyHandle(thePair.first);
+ SValue theValue(thePair.second.second.GetValue());
+ outValues.push_back(make_pair(thePair.first, theValue));
+ }
+ }
+}
+
+bool CSimpleDataCore::IsInstance(int inHandle) const
+{
+ return HandleObjectValid<CDataModelInstance>(inHandle, m_Objects);
+}
+bool CSimpleDataCore::IsProperty(int inHandle) const
+{
+ return HandleObjectValid<CDataModelPropertyDefinitionObject>(inHandle, m_Objects);
+}
+
+Qt3DSDMInstanceHandle CSimpleDataCore::CreateInstanceWithHandle(int inHandle)
+{
+ if (g_UICDMDebugLogger)
+ g_UICDMDebugLogger("CSimpleDataCore::CreateInstance Enter");
+ if (HandleValid(inHandle)) {
+ if (g_UICDMDebugLogger) {
+ g_UICDMDebugLogger("CSimpleDataCore::CreateInstance Handle Exists!!");
+ char buf[32];
+ sprintf(buf, "%d", inHandle);
+ g_UICDMDebugLogger(buf);
+ }
+ throw HandleExists(L"");
+ }
+
+ THandleObjectPtr theHandleObjectPtr(new CDataModelInstance(inHandle));
+ const pair<int, THandleObjectPtr> thePair(std::make_pair(inHandle, theHandleObjectPtr));
+ m_Objects.insert(thePair);
+
+ if (g_UICDMDebugLogger)
+ g_UICDMDebugLogger("CSimpleDataCore::CreateInstance Leave");
+
+ return inHandle;
+}
+
+Qt3DSDMPropertyHandle CSimpleDataCore::AddPropertyWithHandle(int inHandle,
+ Qt3DSDMInstanceHandle inInstance,
+ TCharPtr inName,
+ DataModelDataType::Value inPropType)
+{
+ UICDM_DEBUG_LOG("CSimpleDataCore::AddPropertyWithHandle Enter");
+ UICDM_DEBUG_LOG(m_StringTable->GetNarrowStr(inName));
+ if (HandleValid(inHandle)) {
+ if (g_UICDMDebugLogger) {
+ g_UICDMDebugLogger("CSimpleDataCore::AddPropertyWithHandle Handle Exists!!");
+ char buf[32];
+ sprintf(buf, "%d", inHandle);
+ g_UICDMDebugLogger(buf);
+ }
+
+ throw HandleExists(L"");
+ }
+
+ TDataModelInstancePtr theInstance = GetInstanceNF(inInstance, m_Objects);
+
+ SUICDMPropertyDefinition theDefinition(inInstance, SafeStrPtr(inName), inPropType);
+ THandleObjectPtr theHandleObjectPtr(
+ new CDataModelPropertyDefinitionObject(inHandle, theDefinition));
+ const pair<int, THandleObjectPtr> thePair(std::make_pair(inHandle, theHandleObjectPtr));
+ m_Objects.insert(thePair);
+ theInstance->m_Properties.push_back(inHandle);
+ UICDM_DEBUG_LOG("CSimpleDataCore::AddPropertyWithHandle Leave");
+ return inHandle;
+}
+
+bool CSimpleDataCore::GetSpecificInstancePropertyValue(Qt3DSDMInstanceHandle inInstance,
+ Qt3DSDMPropertyHandle inProperty,
+ SValue &outValue) const
+{
+ const TDataModelInstancePtr theInstance = GetInstanceNF(inInstance, m_Objects);
+ TPropertyPairHash::const_iterator theInstanceProp =
+ theInstance->m_PropertyValues.find(inProperty);
+ if (theInstanceProp != theInstance->m_PropertyValues.end()) {
+ outValue = theInstanceProp->second.second.GetValue();
+ return true;
+ }
+ return false;
+}
+
+void CSimpleDataCore::GetSpecificInstancePropertyValues(Qt3DSDMInstanceHandle inInstance,
+ TPropertyPairHash &outValues) const
+{
+ const TDataModelInstancePtr theInstance = GetInstanceNF(inInstance, m_Objects);
+ outValues = theInstance->m_PropertyValues;
+}
+
+void CSimpleDataCore::UncheckedSetSpecificInstancePropertyValue(Qt3DSDMInstanceHandle inInstance,
+ Qt3DSDMPropertyHandle inProperty,
+ const SValue &inValue,
+ PropertyValueFlags inIsUserSet)
+{
+ TDataModelInstancePtr theInstance = GetInstanceNF(inInstance, m_Objects);
+ TPropertyValuePair theValuePair(inIsUserSet, SInternValue(inValue, GetStringTable()));
+
+ std::pair<TPropertyPairHash::iterator, bool> theInsert = theInstance->m_PropertyValues.insert(
+ std::make_pair(inProperty.GetHandleValue(), theValuePair));
+ if (theInsert.second == false)
+ theInsert.first->second = theValuePair;
+}
+
+bool CSimpleDataCore::CheckParentPropertyExistenceWithFail(const TDataModelInstancePtr inInstance,
+ int inProperty,
+ const THandleObjectMap &inObjects)
+{
+ if (find(inInstance->m_Properties.begin(), inInstance->m_Properties.end(), inProperty)
+ != inInstance->m_Properties.end())
+ return true;
+ for (CDataModelInstance::TInstancePairList::const_iterator theParent =
+ inInstance->m_Parents.begin();
+ theParent != inInstance->m_Parents.end(); ++theParent) {
+ if (CheckParentPropertyExistenceWithFail(theParent->second, inProperty, inObjects))
+ return true;
+ }
+ return false;
+}
+
+// safety check to see if property exists
+void CSimpleDataCore::CheckPropertyExistence(const TDataModelInstancePtr inInstance, int inProperty,
+ const THandleObjectMap &inObjects)
+{
+ if (!CheckParentPropertyExistenceWithFail(inInstance, inProperty, inObjects))
+ throw PropertyNotFound(L"");
+}
+
+bool CSimpleDataCore::IsInstanceOrDerivedFromHelper(const TDataModelInstancePtr inInstance,
+ Qt3DSDMInstanceHandle inParent) const
+{
+ if (inInstance->m_Handle == inParent) // Am I this object?
+ return true;
+ return inInstance->IsDerivedFrom(inParent);
+}
+
+bool CSimpleDataCore::IsInstanceOrDerivedFrom(Qt3DSDMInstanceHandle inInstance,
+ Qt3DSDMInstanceHandle inParent) const
+{
+ if (IsInstance(inInstance) == false || IsInstance(inParent) == false)
+ return false;
+ if (inInstance == inParent) // Am I this object?
+ return true;
+ const TDataModelInstancePtr theInstance = GetInstanceNF(inInstance, m_Objects);
+ return IsInstanceOrDerivedFromHelper(theInstance, inParent);
+}
+}
diff --git a/src/Authoring/QT3DSDM/Systems/Cores/SimpleDataCore.h b/src/Authoring/QT3DSDM/Systems/Cores/SimpleDataCore.h
new file mode 100644
index 00000000..2f216d1a
--- /dev/null
+++ b/src/Authoring/QT3DSDM/Systems/Cores/SimpleDataCore.h
@@ -0,0 +1,373 @@
+/****************************************************************************
+**
+** 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-EXCEPT$
+** 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 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** 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$
+**
+****************************************************************************/
+#pragma once
+#ifndef DATACOREH
+#define DATACOREH
+
+#include "Qt3DSDMDataTypes.h"
+#include "Qt3DSDMSignals.h"
+#include "HandleSystemBase.h"
+#include "Qt3DSDMPropertyDefinition.h"
+#include "Qt3DSDMDataCore.h"
+#include "Qt3DSDMStringTable.h"
+#include <unordered_set>
+#include "Qt3DSDMValue.h"
+
+namespace qt3dsdm {
+
+struct PropertyValueFlags
+{
+ enum Enum {
+ // Property values that are set via event propagation should
+ // not be serialized to a file. The auto-propagation step
+ // is meant to make looking up property values quicker because
+ // the the derivation chain doesn't need to be followed to get
+ // the latest default value.
+ SetViaAutoPropagate = 1,
+ };
+
+ int m_Flags;
+
+ PropertyValueFlags()
+ : m_Flags(0)
+ {
+ }
+ explicit PropertyValueFlags(int inFlags)
+ : m_Flags(inFlags)
+ {
+ }
+
+ bool IsSetViaAutoPropagation() const { return (m_Flags & SetViaAutoPropagate) > 0; }
+};
+
+// Pair of property value flags and property value. The property value flags allow
+// us to track metadata that is
+typedef std::pair<PropertyValueFlags, SInternValue> TPropertyValuePair;
+typedef std::unordered_map<int, TPropertyValuePair> TPropertyPairHash;
+// Property pairs are referred to by property handle.
+typedef std::pair<int, TPropertyValuePair> TPropertyPair;
+typedef std::vector<TPropertyPair> TPropertyPairList;
+
+class CDataModelPropertyDefinitionObject : public CHandleObject
+{
+public:
+ SUICDMPropertyDefinition m_Definition;
+
+ CDataModelPropertyDefinitionObject(int inHandle, const SUICDMPropertyDefinition &inDefinition)
+ : CHandleObject(inHandle)
+ , m_Definition(inDefinition)
+ {
+ }
+ CDataModelPropertyDefinitionObject() {}
+
+ static const EHandleObjectType s_Type =
+ CHandleObject::EHandleObjectTypeCDataModelPropertyDefinitionObject;
+ EHandleObjectType GetType() override { return s_Type; }
+};
+
+typedef std::unordered_map<int, SInternValue> TIntStringVariantList;
+
+class CDataModelInstance : public CHandleObject
+{
+public:
+ typedef std::pair<int, std::shared_ptr<CDataModelInstance>> TInstancePair;
+ typedef std::unordered_map<int, std::shared_ptr<CDataModelInstance>> TInstancePairList;
+ typedef std::unordered_map<int, bool> TInstanceParentMap;
+
+ TInstancePairList m_Parents;
+ mutable TInstanceParentMap m_CachedParents;
+ // Properties specific to this class
+ TIntList m_Properties;
+ TPropertyPairHash m_PropertyValues;
+
+ CDataModelInstance() {}
+ CDataModelInstance(int inHandle)
+ : CHandleObject(inHandle)
+ {
+ }
+
+ void ToPropertyPairList(TPropertyPairList &outList) const
+ {
+ for (TPropertyPairHash::const_iterator iter = m_PropertyValues.begin(),
+ end = m_PropertyValues.end();
+ iter != end; ++iter)
+ outList.push_back(*iter);
+ }
+
+ void FromPropertyPairList(const TPropertyPairList &inList)
+ {
+ m_PropertyValues.clear();
+ for (TPropertyPairList::const_iterator iter = inList.begin(), end = inList.end();
+ iter != end; ++iter)
+ m_PropertyValues.insert(*iter);
+ }
+
+ void ClearParentCache() const { m_CachedParents.clear(); }
+
+ bool IsDerivedFrom(Qt3DSDMInstanceHandle inParent) const
+ {
+ std::pair<TInstanceParentMap::iterator, bool> theQueryResult =
+ m_CachedParents.insert(std::make_pair(inParent.GetHandleValue(), false));
+ // If the insert failed, returned what the hashtable already had in it
+ if (theQueryResult.second == false)
+ return theQueryResult.first->second;
+
+ // Else find a valid answer
+ if (m_Parents.find(inParent.GetHandleValue()) != m_Parents.end()) {
+ theQueryResult.first->second = true;
+ } else {
+ for (TInstancePairList::const_iterator iter = m_Parents.begin(), end = m_Parents.end();
+ iter != end; ++iter) {
+ if (iter->second->IsDerivedFrom(inParent)) {
+ theQueryResult.first->second = true;
+ break;
+ }
+ }
+ }
+
+ // Note that we inserted false to begin with. This means that
+ // we can return the insert result here safely as if it wasn't
+ // supposed to be false, we would have set it above.
+ return theQueryResult.first->second;
+ }
+
+ void RemoveCachedValues()
+ {
+ vector<int> theCachedProperties;
+
+ for (TPropertyPairHash::iterator theProperty = m_PropertyValues.begin(),
+ end = m_PropertyValues.end();
+ theProperty != end; ++theProperty) {
+ if (theProperty->second.first.IsSetViaAutoPropagation())
+ theCachedProperties.push_back(theProperty->first);
+ }
+
+ for (size_t idx = 0, end = theCachedProperties.size(); idx < end; ++idx)
+ m_PropertyValues.erase(theCachedProperties[idx]);
+ }
+
+ // CHandleObject
+ static const EHandleObjectType s_Type = CHandleObject::EHandleObjectTypeCDataModelInstance;
+ EHandleObjectType GetType() override { return s_Type; }
+};
+
+typedef std::shared_ptr<CDataModelInstance> TDataModelInstancePtr;
+
+class CSimpleDataCore : public CHandleBase, public IDataCore
+{
+ mutable TStringTablePtr m_StringTable;
+
+public:
+ CSimpleDataCore(TStringTablePtr strTable)
+ : m_StringTable(strTable)
+ {
+ }
+ CSimpleDataCore(const CSimpleDataCore &inOther)
+ : CHandleBase(inOther)
+ , m_StringTable(inOther.m_StringTable)
+ {
+ }
+
+ CSimpleDataCore &operator=(const CSimpleDataCore &inOther)
+ {
+ CHandleBase::operator=(inOther);
+ return *this;
+ }
+
+ IStringTable &GetStringTable() const override { return *m_StringTable.get(); }
+ TStringTablePtr GetStringTablePtr() const override { return m_StringTable; }
+
+ // IHandleBase
+ bool HandleValid(int inHandle) const override
+ {
+ return m_Objects.find(inHandle) != m_Objects.end();
+ }
+
+ // IInstancePropertyCore
+ Qt3DSDMPropertyHandle GetAggregateInstancePropertyByName(Qt3DSDMInstanceHandle inInstance,
+ const TCharStr &inStr) const override;
+ void GetAggregateInstanceProperties(Qt3DSDMInstanceHandle inInstance,
+ TPropertyHandleList &outProperties) const override;
+ void GetSpecificInstancePropertyValues(Qt3DSDMInstanceHandle inHandle,
+ TPropertyHandleValuePairList &outValues) override;
+ bool HasAggregateInstanceProperty(Qt3DSDMInstanceHandle inInstance,
+ Qt3DSDMPropertyHandle inProperty) const override;
+ void CheckValue(Qt3DSDMInstanceHandle inInstance, Qt3DSDMPropertyHandle inProperty,
+ const SValue &inValue) const override;
+ bool GetInstancePropertyValue(Qt3DSDMInstanceHandle inHandle,
+ Qt3DSDMPropertyHandle inProperty, SValue &outValue) const override;
+ void SetInstancePropertyValue(Qt3DSDMInstanceHandle inHandle,
+ Qt3DSDMPropertyHandle inProperty, const SValue &inValue) override;
+
+ // IDataCore
+ //===============================================================
+ Qt3DSDMInstanceHandle CreateInstance(Qt3DSDMInstanceHandle hdl = Qt3DSDMInstanceHandle()) override;
+ void DeleteInstance(Qt3DSDMInstanceHandle inHandle) override;
+ void GetInstances(TInstanceHandleList &outInstances) const override;
+ void GetInstancesDerivedFrom(TInstanceHandleList &outInstances,
+ Qt3DSDMInstanceHandle inParentHandle) const override;
+
+ void DeriveInstance(Qt3DSDMInstanceHandle inInstance, Qt3DSDMInstanceHandle inParent) override;
+ void GetInstanceParents(Qt3DSDMInstanceHandle inHandle,
+ TInstanceHandleList &outParents) const override;
+ // Returns true if inParent == inInstance || inInstance is derived from inParent somehow.
+ // Recursive.
+ bool IsInstanceOrDerivedFrom(Qt3DSDMInstanceHandle inInstance,
+ Qt3DSDMInstanceHandle inParent) const override;
+
+ Qt3DSDMPropertyHandle AddProperty(Qt3DSDMInstanceHandle inClass, TCharPtr inName,
+ DataModelDataType::Value inPropType) override;
+ const SUICDMPropertyDefinition &GetProperty(Qt3DSDMPropertyHandle inProperty) const override;
+ void GetInstanceProperties(Qt3DSDMInstanceHandle inInstance,
+ TPropertyHandleList &outProperties) const override;
+ void RemoveProperty(Qt3DSDMPropertyHandle inProperty) override;
+ void CopyInstanceProperties(Qt3DSDMInstanceHandle inSrcInstance,
+ Qt3DSDMInstanceHandle inDestInstance) override;
+ void RemoveCachedValues(Qt3DSDMInstanceHandle inInstance) override;
+
+ bool IsInstance(int inHandle) const override;
+ bool IsProperty(int inHandle) const override;
+ //===============================================================
+
+ bool GetSpecificInstancePropertyValue(Qt3DSDMInstanceHandle inInstance,
+ Qt3DSDMPropertyHandle inProperty, SValue &outValue) const;
+ void GetSpecificInstancePropertyValues(Qt3DSDMInstanceHandle inInstance,
+ TPropertyPairHash &outValues) const;
+
+ static CDataModelPropertyDefinitionObject *GetPropertyDefinitionNF(int inHandle,
+ THandleObjectMap &inObjects)
+ {
+ return const_cast<CDataModelPropertyDefinitionObject *>(
+ GetPropertyDefinitionNF(inHandle, static_cast<const THandleObjectMap &>(inObjects)));
+ }
+
+ static const CDataModelPropertyDefinitionObject *
+ GetPropertyDefinitionNF(int inHandle, const THandleObjectMap &inObjects)
+ {
+ const CDataModelPropertyDefinitionObject *theClass =
+ GetHandleObject<CDataModelPropertyDefinitionObject>(inHandle, inObjects);
+ if (theClass)
+ return theClass;
+ throw PropertyNotFound(L"");
+ }
+
+ static TDataModelInstancePtr GetInstance(int inHandle, const THandleObjectMap &inObjects)
+ {
+ THandleObjectMap::const_iterator theFind(inObjects.find(inHandle));
+ // dynamic cast isn't allowed in runtime code as the runtime doesn't enable rtti.
+ if (theFind != inObjects.end())
+ return std::static_pointer_cast<CDataModelInstance>(theFind->second);
+ return TDataModelInstancePtr();
+ }
+
+ static TDataModelInstancePtr GetInstanceNF(int inHandle, const THandleObjectMap &inObjects)
+ {
+ TDataModelInstancePtr retval = GetInstance(inHandle, inObjects);
+ if (retval)
+ return retval;
+ throw InstanceNotFound(L"");
+ }
+
+ static inline bool InstancePairMatches(int inHandle,
+ const CDataModelInstance::TInstancePair &inInstancePair)
+ {
+ return inHandle == inInstancePair.first;
+ }
+
+ // if inInstance doesn't exists in inObjects, it will push back NULL instead of throwing
+ // exception
+ static inline void UncheckAddInstancePair(CDataModelInstance::TInstancePairList &outInstances,
+ Qt3DSDMInstanceHandle inInstance,
+ THandleObjectMap &inObjects)
+ {
+ outInstances.insert(
+ std::make_pair(inInstance, CSimpleDataCore::GetInstance(inInstance, inObjects)));
+ }
+
+ static inline bool InstancePropertyMatches(int inProp, const TPropertyPair &inPropPair)
+ {
+ return inProp == inPropPair.first;
+ }
+
+ static bool CheckParentPropertyExistenceWithFail(const TDataModelInstancePtr inInstance,
+ int inProperty,
+ const THandleObjectMap &inObjects);
+
+ static void CheckPropertyExistence(const TDataModelInstancePtr inInstance, int inProperty,
+ const THandleObjectMap &inObjects);
+
+ static inline void FindRelatedItemsForDelete(int inInstance, TIntList &outProperties,
+ TIntList &outChildInstances,
+ const std::pair<int, THandleObjectPtr> &inPair)
+ {
+
+ using namespace std;
+ if (inPair.second->GetType() == CHandleObject::EHandleObjectTypeCDataModelInstance) {
+ TDataModelInstancePtr theInstance =
+ static_pointer_cast<CDataModelInstance>(inPair.second);
+ // No longer a parent class.
+ if (find_if(theInstance->m_Parents.begin(), theInstance->m_Parents.end(),
+ std::bind(InstancePairMatches, inInstance, std::placeholders::_1))
+ != theInstance->m_Parents.end())
+ outChildInstances.push_back(inPair.first);
+ } else if (inPair.second->GetType()
+ == CHandleObject::EHandleObjectTypeCDataModelPropertyDefinitionObject) {
+ const CDataModelPropertyDefinitionObject *theProperty =
+ static_cast<const CDataModelPropertyDefinitionObject *>(inPair.second.get());
+ if (theProperty->m_Definition.m_Instance.GetHandleValue() == inInstance)
+ outProperties.push_back(inPair.first);
+ }
+ }
+
+protected:
+ bool IsInstanceOrDerivedFromHelper(const TDataModelInstancePtr inInstance,
+ Qt3DSDMInstanceHandle inParent) const;
+ void AddInstanceIfDerivedFrom(const std::pair<int, THandleObjectPtr> &inItem,
+ TInstanceHandleList &outInstances,
+ Qt3DSDMInstanceHandle inParentHandle) const;
+
+ bool GetInstancePropertyValueHelper(const TDataModelInstancePtr inInstance,
+ Qt3DSDMPropertyHandle inProperty, SValue &outValue) const;
+
+ // Create an instance *at* this specific handle position
+ // This is used for special cases of serialization
+ Qt3DSDMInstanceHandle CreateInstanceWithHandle(int inHandle);
+ Qt3DSDMPropertyHandle AddPropertyWithHandle(int inHandle, Qt3DSDMInstanceHandle inClass,
+ TCharPtr inName, DataModelDataType::Value inPropType);
+
+ void UncheckedSetSpecificInstancePropertyValue(Qt3DSDMInstanceHandle inInstance,
+ Qt3DSDMPropertyHandle inProperty,
+ const SValue &inValue,
+ PropertyValueFlags inIsUserSet);
+};
+
+typedef std::shared_ptr<CSimpleDataCore> TSimpleDataCorePtr;
+}
+
+#endif
diff --git a/src/Authoring/QT3DSDM/Systems/Cores/SimpleSlideCore.cpp b/src/Authoring/QT3DSDM/Systems/Cores/SimpleSlideCore.cpp
new file mode 100644
index 00000000..cc364db7
--- /dev/null
+++ b/src/Authoring/QT3DSDM/Systems/Cores/SimpleSlideCore.cpp
@@ -0,0 +1,408 @@
+/****************************************************************************
+**
+** 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-EXCEPT$
+** 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 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** 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 "Qt3DSDMPrefix.h"
+#include "SimpleSlideCore.h"
+
+using namespace std;
+#ifdef _WIN32
+#pragma warning(disable : 4503)
+#endif
+
+namespace qt3dsdm {
+
+CUICDMSlideHandle CSimpleSlideCore::CreateSlide(Qt3DSDMInstanceHandle inInstance)
+{
+ int nextId = GetNextId();
+ return CreateSlideWithHandle(nextId, inInstance);
+}
+
+Qt3DSDMInstanceHandle CSimpleSlideCore::GetSlideInstance(CUICDMSlideHandle inSlide) const
+{
+ return GetSlideNF(inSlide, m_Objects)->m_Instance;
+}
+
+inline bool SlideInstanceMatches(const THandleObjectPair &inPair, int inInstance)
+{
+ if (inPair.second->GetType() == CHandleObject::EHandleObjectTypeSSlide
+ && static_cast<const SSlide *>(inPair.second.get())->m_Instance == inInstance)
+ return true;
+ return false;
+}
+
+CUICDMSlideHandle CSimpleSlideCore::GetSlideByInstance(Qt3DSDMInstanceHandle inInstance) const
+{
+ THandleObjectMap::const_iterator theSlide =
+ find_if(m_Objects.begin(), m_Objects.end(),
+ std::bind(SlideInstanceMatches,
+ std::placeholders::_1, inInstance.GetHandleValue()));
+ if (theSlide != m_Objects.end())
+ return theSlide->first;
+ throw SlideNotFound(L"");
+}
+
+void RecurseDeleteSlide(CUICDMSlideHandle inSlide, THandleObjectMap &inObjects,
+ TInstanceHandleList &outInstances)
+{
+ SSlide *theSlide = CSimpleSlideCore::GetSlideNF(inSlide, inObjects);
+ do_all(theSlide->m_Children,
+ std::bind(RecurseDeleteSlide, std::placeholders::_1,
+ std::ref(inObjects), std::ref(outInstances)));
+ outInstances.push_back(theSlide->m_Instance);
+ CHandleBase::EraseHandle(inSlide, inObjects);
+}
+
+void CSimpleSlideCore::DeleteSlide(CUICDMSlideHandle inSlide, TInstanceHandleList &outInstances)
+{
+ SSlide *theSlide = GetSlideNF(inSlide, m_Objects);
+ if (theSlide->m_Parent) {
+ SSlide *theParent = GetSlideNF(theSlide->m_Parent, m_Objects);
+ erase_if(theParent->m_Children, std::bind(equal_to<int>(), theSlide->m_Handle,
+ std::placeholders::_1));
+ }
+ RecurseDeleteSlide(inSlide, m_Objects, outInstances);
+}
+
+template <typename TDataType, typename TVectorType>
+inline void MaybeAddObject(const THandleObjectPair &inPair, vector<TVectorType> &outVectorItems)
+{
+ if (inPair.second->GetType() == TDataType::s_Type)
+ outVectorItems.push_back(inPair.first);
+}
+
+void CSimpleSlideCore::GetSlides(TSlideHandleList &outSlides) const
+{
+ do_all(m_Objects,
+ std::bind(MaybeAddObject<SSlide, CUICDMSlideHandle>,
+ std::placeholders::_1, std::ref(outSlides)));
+}
+
+float CSimpleSlideCore::GetSlideTime(CUICDMSlideHandle inSlide) const
+{
+ return GetSlideNF(inSlide, m_Objects)->m_Time;
+}
+
+void CSimpleSlideCore::SetSlideTime(CUICDMSlideHandle inSlide, float inNewTime)
+{
+ GetSlideNF(inSlide, m_Objects)->m_Time = inNewTime;
+}
+
+void CSimpleSlideCore::DeriveSlide(CUICDMSlideHandle inSlide, CUICDMSlideHandle inParent,
+ int inIndex)
+{
+ int oldParent = GetSlideNF(inSlide, m_Objects)->m_Parent;
+ if (oldParent)
+ erase_if(GetSlideNF(oldParent, m_Objects)->m_Children,
+ std::bind(equal_to<int>(), inSlide, std::placeholders::_1));
+ if (inParent.Valid()) {
+ SSlide *theParent = GetSlideNF(inParent, m_Objects);
+ if (exists(theParent->m_Children, std::bind(equal_to<int>(), inSlide,
+ std::placeholders::_1)))
+ throw SlideDerivationError(L"Already derived");
+ if (inIndex < 0 || inIndex >= (int)theParent->m_Children.size())
+ inIndex = (int)theParent->m_Children.size();
+ theParent->m_Children.insert(theParent->m_Children.begin() + inIndex,
+ inSlide.GetHandleValue());
+ }
+ GetSlideNF(inSlide, m_Objects)->m_Parent = inParent;
+}
+
+CUICDMSlideHandle CSimpleSlideCore::GetParentSlide(CUICDMSlideHandle inSlide) const
+{
+ return GetSlideNF(inSlide, m_Objects)->m_Parent;
+}
+
+void CSimpleSlideCore::GetChildSlides(CUICDMSlideHandle inSlide,
+ TSlideHandleList &outChildren) const
+{
+ transformv_all(GetSlideNF(inSlide, m_Objects)->m_Children, outChildren);
+}
+
+int CSimpleSlideCore::GetChildIndex(CUICDMSlideHandle inParent, CUICDMSlideHandle inChild) const
+{
+ const SSlide *theSlide = GetSlideNF(inParent, m_Objects);
+ size_t dist = distance(theSlide->m_Children.begin(),
+ find_if<TIntList::const_iterator>(
+ theSlide->m_Children, std::bind(equal_to<int>(), inChild,
+ std::placeholders::_1)));
+ if (dist == theSlide->m_Children.size())
+ throw SlideChildNotFoundError(L"");
+ return (int)dist;
+}
+
+bool CSimpleSlideCore::GetInstancePropertyValue(CUICDMSlideHandle inSlide,
+ Qt3DSDMInstanceHandle inHandle,
+ Qt3DSDMPropertyHandle inProperty,
+ SValue &outValue) const
+{
+ const SSlide *theSlide = GetSlideNF(inSlide, m_Objects);
+ SInternValue *theValue = theSlide->GetInstancePropertyValue(inHandle, inProperty);
+ if (theValue) {
+ outValue = theValue->GetValue();
+ return true;
+ }
+ if (theSlide->m_Parent)
+ return GetInstancePropertyValue(theSlide->m_Parent, inHandle, inProperty, outValue);
+ return false;
+}
+
+std::pair<SSlide *, SInternValue *> CSimpleSlideCore::ResolveSetInstancePropertyValue(
+ CUICDMSlideHandle inSlide, Qt3DSDMInstanceHandle inHandle, Qt3DSDMPropertyHandle inProperty)
+{
+ SSlide *theSlide = CSimpleSlideCore::GetSlideNF(inSlide, m_Objects);
+ SInternValue *theValue = theSlide->GetInstancePropertyValue(inHandle, inProperty);
+ // If we have the value already *or* or parent is not a valid slide, then return now
+ if (theValue || theSlide->m_Parent == 0)
+ return std::make_pair(theSlide, theValue);
+ // Else give our parent a chance.
+ return ResolveSetInstancePropertyValue(theSlide->m_Parent, inHandle, inProperty);
+}
+
+void CSimpleSlideCore::SetInstancePropertyValue(CUICDMSlideHandle inSlide,
+ Qt3DSDMInstanceHandle inHandle,
+ Qt3DSDMPropertyHandle inProperty,
+ const SValue &inValue)
+{
+ std::pair<SSlide *, SInternValue *> theTarget(
+ ResolveSetInstancePropertyValue(inSlide, inHandle, inProperty));
+ SInternValue theValue(inValue, GetStringTable());
+ if (theTarget.second)
+ *theTarget.second = theValue;
+ else
+ theTarget.first->SetInstancePropertyValue(inHandle, inProperty, theValue);
+}
+
+void CSimpleSlideCore::ForceSetInstancePropertyValue(CUICDMSlideHandle inSlide,
+ Qt3DSDMInstanceHandle inHandle,
+ Qt3DSDMPropertyHandle inProperty,
+ const SValue &inValue)
+{
+ CSimpleSlideCore::ForceSetPropertyValue(GetStringTable(), m_Objects, inSlide, inHandle,
+ inProperty, inValue);
+}
+
+bool CSimpleSlideCore::GetSpecificInstancePropertyValue(CUICDMSlideHandle inSlide,
+ Qt3DSDMInstanceHandle inInstance,
+ Qt3DSDMPropertyHandle inProperty,
+ SValue &outValue) const
+{
+ const SSlide *theSlide = GetSlideNF(inSlide, m_Objects);
+ SInternValue *theValue = theSlide->GetInstancePropertyValue(inInstance, inProperty);
+ if (theValue) {
+ outValue = theValue->GetValue();
+ return true;
+ }
+ return false;
+}
+
+void CSimpleSlideCore::GetSpecificInstancePropertyValues(CUICDMSlideHandle inSlide,
+ Qt3DSDMInstanceHandle inInstance,
+ TPropertyHandleValuePairList &outValues)
+{
+ const SSlide *theSlide = GetSlideNF(inSlide, m_Objects);
+ theSlide->GetSpecificInstancePropertyValues(inInstance, outValues);
+}
+
+void CSimpleSlideCore::GetSlidePropertyEntries(CUICDMSlideHandle inSlide,
+ TSlideEntryList &outEntries) const
+{
+ const SSlide *theSlide = GetSlideNF(inSlide, m_Objects);
+ theSlide->ToSlideEntryList(outEntries);
+}
+
+bool CSimpleSlideCore::ContainsProperty(CUICDMSlideHandle inSlide, Qt3DSDMInstanceHandle inHandle,
+ Qt3DSDMPropertyHandle inProperty) const
+{
+ const SSlide *theSlide = GetSlideNF(inSlide, m_Objects);
+ return theSlide->GetInstancePropertyValue(inHandle, inProperty) != NULL;
+}
+
+CUICDMSlideHandle CSimpleSlideCore::CreateSlideWithHandle(int inHandle,
+ Qt3DSDMInstanceHandle inInstance)
+{
+ if (HandleValid(inHandle))
+ throw HandleExists(L"");
+ m_Objects.insert(make_pair(inHandle, (THandleObjectPtr) new SSlide(inHandle, inInstance)));
+ return inHandle;
+}
+
+void CSimpleSlideCore::GetSlideProperties(CUICDMSlideHandle inSlide,
+ TSlideEntryList &outProperties) const
+{
+ outProperties.clear();
+ GetSlidePropertyEntries(inSlide, outProperties);
+}
+
+bool CSimpleSlideCore::IsSlide(CUICDMSlideHandle inSlide) const
+{
+ return m_Objects.find(inSlide) != m_Objects.end();
+}
+
+void CSimpleSlideCore::ForceSetPropertyValue(IStringTable &inStringTable,
+ THandleObjectMap &inObjects, CUICDMSlideHandle inSlide,
+ Qt3DSDMInstanceHandle inHandle,
+ Qt3DSDMPropertyHandle inProperty, const SValue &inValue)
+{
+ CSimpleSlideCore::GetSlideNF(inSlide, inObjects)
+ ->SetInstancePropertyValue(inHandle, inProperty, SInternValue(inValue, inStringTable));
+}
+
+void CSimpleSlideCore::PushPropertyValueToChildren(CUICDMSlideHandle inParent,
+ Qt3DSDMInstanceHandle inHandle,
+ Qt3DSDMPropertyHandle inProperty,
+ const SValue &inValue)
+{
+ ForceSetPropertyValue(GetStringTable(), m_Objects, inParent, inHandle, inProperty, inValue);
+ do_all(CSimpleSlideCore::GetSlideNF(inParent, m_Objects)->m_Children,
+ std::bind(ForceSetPropertyValue, std::ref(GetStringTable()), std::ref(m_Objects),
+ std::placeholders::_1, inHandle, inProperty, inValue));
+}
+
+inline void AddIntersectingEntry(TSlideEntryList &outEntries, Qt3DSDMInstanceHandle inst,
+ Qt3DSDMPropertyHandle prop, const SInternValue &inValue)
+{
+ outEntries.push_back(TSlideEntry(inst, prop, inValue.GetValue()));
+}
+
+void CSimpleSlideCore::GetIntersectingProperties(CUICDMSlideHandle inSlide1,
+ CUICDMSlideHandle inSlide2,
+ TSlideEntryList &outEntries) const
+{
+ const SSlide *theSlide1 = GetSlideNF(inSlide1, m_Objects);
+ const SSlide *theSlide2 = GetSlideNF(inSlide2, m_Objects);
+ theSlide1->IntersectProperties(
+ *theSlide2, std::bind(AddIntersectingEntry, std::ref(outEntries),
+ std::placeholders::_1, std::placeholders::_2,
+ std::placeholders::_3));
+}
+
+void CSimpleSlideCore::PushIntersectingProperties(CUICDMSlideHandle inSlide1,
+ CUICDMSlideHandle inSlide2,
+ CUICDMSlideHandle inDestination)
+{
+ const SSlide *theSlide1 = GetSlideNF(inSlide1, m_Objects);
+ const SSlide *theSlide2 = GetSlideNF(inSlide2, m_Objects);
+ SSlide *theDest = GetSlideNF(inDestination, m_Objects);
+ theSlide1->IntersectProperties(
+ *theSlide2, std::bind(&SSlide::SetInstancePropertyValue, theDest,
+ std::placeholders::_1, std::placeholders::_2,
+ std::placeholders::_3));
+}
+
+void CSimpleSlideCore::ClearPropertyValue(THandleObjectMap &inObjects, CUICDMSlideHandle inSlide,
+ Qt3DSDMInstanceHandle inInstance,
+ Qt3DSDMPropertyHandle inProperty)
+{
+ CSimpleSlideCore::GetSlideNF(inSlide, inObjects)
+ ->RemoveInstancePropertyValue(inInstance, inProperty);
+}
+
+inline void DoForEachSlide(std::pair<int, THandleObjectPtr> inObject,
+ std::function<void(SSlide *)> inFunction)
+{
+ inFunction((SSlide *)inObject.second.get());
+}
+
+void CSimpleSlideCore::ForEachSlide(std::function<void(SSlide *)> inFunction)
+{
+ do_all(m_Objects, std::bind(DoForEachSlide, std::placeholders::_1, inFunction));
+}
+
+void LookupSlideAndDoSomething(CUICDMSlideHandle inSlide, THandleObjectMap &inObjects,
+ std::function<void(SSlide *)> inFunction)
+{
+ inFunction(CSimpleSlideCore::GetSlideNF(inSlide, inObjects));
+}
+
+void CSimpleSlideCore::ForEachChild(CUICDMSlideHandle inParent,
+ std::function<void(SSlide *)> inFunction)
+{
+ do_all(GetSlideNF(inParent, m_Objects)->m_Children,
+ std::bind(LookupSlideAndDoSomething, std::placeholders::_1, m_Objects, inFunction));
+}
+
+bool InstanceMatches(Qt3DSDMInstanceHandle inTarget, Qt3DSDMInstanceHandle inHandle,
+ Qt3DSDMPropertyHandle)
+{
+ return inTarget == inHandle;
+}
+
+bool PropertyMatches(Qt3DSDMPropertyHandle inTarget, Qt3DSDMInstanceHandle,
+ Qt3DSDMPropertyHandle inProp)
+{
+ return inTarget == inProp;
+}
+
+bool InstancePropertyMatchesVector(const TInstanceHandleList &inInstances,
+ const TPropertyHandleList &inProperties,
+ Qt3DSDMInstanceHandle slideInst, Qt3DSDMPropertyHandle slideProp)
+{
+ return std::find(inInstances.begin(), inInstances.end(), slideInst) != inInstances.end()
+ && std::find(inProperties.begin(), inProperties.end(), slideProp) != inProperties.end();
+}
+
+bool InstancePropertyMatches(const Qt3DSDMInstanceHandle inInstance,
+ const Qt3DSDMPropertyHandle inProperty, Qt3DSDMInstanceHandle slideInst,
+ Qt3DSDMPropertyHandle slideProp)
+{
+ return inInstance == slideInst && inProperty == slideProp;
+}
+
+void CSimpleSlideCore::DeleteAllInstanceEntries(Qt3DSDMInstanceHandle inHandle)
+{
+ std::function<bool(Qt3DSDMInstanceHandle, Qt3DSDMPropertyHandle)> predicate(
+ std::bind(InstanceMatches, inHandle, std::placeholders::_1, std::placeholders::_2));
+ ForEachSlide(std::bind(&SSlide::ClearPropertiesIf, std::placeholders::_1, predicate));
+}
+
+void CSimpleSlideCore::DeleteAllPropertyEntries(Qt3DSDMPropertyHandle inHandle)
+{
+ std::function<bool(Qt3DSDMInstanceHandle, Qt3DSDMPropertyHandle)> predicate(
+ std::bind(PropertyMatches, inHandle, std::placeholders::_1, std::placeholders::_2));
+ ForEachSlide(std::bind(&SSlide::ClearPropertiesIf, std::placeholders::_1, predicate));
+}
+
+void CSimpleSlideCore::DeleteAllInstancePropertyEntries(const TInstanceHandleList &inInstances,
+ const TPropertyHandleList &inProperties)
+{
+ std::function<bool(Qt3DSDMInstanceHandle, Qt3DSDMPropertyHandle)> predicate(
+ std::bind(InstancePropertyMatchesVector, inInstances, inProperties,
+ std::placeholders::_1, std::placeholders::_2));
+ ForEachSlide(std::bind(&SSlide::ClearPropertiesIf, std::placeholders::_1, predicate));
+}
+
+void CSimpleSlideCore::ClearChildrenPropertyValues(CUICDMSlideHandle inParent,
+ Qt3DSDMInstanceHandle inHandle,
+ Qt3DSDMPropertyHandle inProperty)
+{
+ std::function<bool(Qt3DSDMInstanceHandle, Qt3DSDMPropertyHandle)> predicate(
+ std::bind(InstancePropertyMatches, inHandle, inProperty,
+ std::placeholders::_1, std::placeholders::_2));
+ ForEachChild(inParent, std::bind(&SSlide::ClearPropertiesIf, std::placeholders::_1, predicate));
+}
+}
diff --git a/src/Authoring/QT3DSDM/Systems/Cores/SimpleSlideCore.h b/src/Authoring/QT3DSDM/Systems/Cores/SimpleSlideCore.h
new file mode 100644
index 00000000..1188f5a0
--- /dev/null
+++ b/src/Authoring/QT3DSDM/Systems/Cores/SimpleSlideCore.h
@@ -0,0 +1,395 @@
+/****************************************************************************
+**
+** 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-EXCEPT$
+** 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 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** 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$
+**
+****************************************************************************/
+#pragma once
+#ifndef SLIDECOREH
+#define SLIDECOREH
+#include "HandleSystemBase.h"
+#include "Qt3DSDMSlideCore.h"
+#include "SimpleDataCore.h"
+#include "Qt3DSDMStringTable.h"
+#include <unordered_map>
+
+namespace std {
+
+template<> struct hash<std::pair<int,int> >
+{
+ typedef std::pair<int,int> argument_type;
+ typedef std::size_t result_type;
+ result_type operator()(std::pair<int,int> const& pa) const
+ {
+ result_type const h1 ( std::hash<int>{}(pa.first) );
+ result_type const h2 ( std::hash<int>{}(pa.second) );
+ return h1 ^ (h2 << 1);
+ }
+};
+
+}
+
+namespace qt3dsdm {
+
+// The first revision of this
+typedef std::pair<int, int> TSlideInstancePropertyPair;
+typedef std::unordered_map<TSlideInstancePropertyPair, SInternValue > TSlideEntryHash;
+
+using std::make_pair;
+
+// Abstract access to these objects a little bit because in the future we are going to
+// reorganize the data such that getting a defined set of properties for a single instance is
+// very fast.
+struct SSlide : public CHandleObject
+{
+ SSlide()
+ : m_Instance(0)
+ , m_Parent(0)
+ {
+ }
+ SSlide(int inHandle, int inInstance)
+ : CHandleObject(inHandle)
+ , m_Instance(inInstance)
+ , m_Parent(0)
+ , m_Time(0)
+ {
+ }
+ int m_Instance;
+ int m_Parent;
+ TIntList m_Children;
+ TSlideEntryHash m_Properties;
+ float m_Time;
+
+ // Returns true if it was inserted, false if the property value was set.
+ bool SetInstancePropertyValue(Qt3DSDMInstanceHandle inInstance, Qt3DSDMPropertyHandle inProperty,
+ const SInternValue &inValue)
+ {
+ TSlideInstancePropertyPair theKey(inInstance.GetHandleValue(), inProperty.GetHandleValue());
+ std::pair<TSlideEntryHash::iterator, bool> insertResult =
+ m_Properties.insert(std::make_pair(theKey, inValue));
+ if (insertResult.second == false)
+ insertResult.first->second = inValue;
+ return insertResult.second;
+ }
+ // Returns true if the property was deleted
+ bool RemoveInstancePropertyValue(Qt3DSDMInstanceHandle inInstance,
+ Qt3DSDMPropertyHandle inProperty)
+ {
+ TSlideInstancePropertyPair theKey(inInstance.GetHandleValue(), inProperty.GetHandleValue());
+ TSlideEntryHash::iterator find(m_Properties.find(theKey));
+ if (find != m_Properties.end()) {
+ m_Properties.erase(find);
+ return true;
+ }
+ return false;
+ }
+ // Return a pointer to out property value. This allows quicker checks for isset and such
+ SInternValue *GetInstancePropertyValue(Qt3DSDMInstanceHandle inInstance,
+ Qt3DSDMPropertyHandle inProperty) const
+ {
+ TSlideInstancePropertyPair theKey(inInstance.GetHandleValue(), inProperty.GetHandleValue());
+ TSlideEntryHash::const_iterator find(m_Properties.find(theKey));
+ if (find != m_Properties.end())
+ return const_cast<SInternValue *>(&find->second);
+ return NULL;
+ }
+
+ void GetSpecificInstancePropertyValues(Qt3DSDMInstanceHandle inInstance,
+ TPropertyHandleValuePairList &outProperties) const
+ {
+ for (TSlideEntryHash::const_iterator theIter = m_Properties.begin(),
+ theEnd = m_Properties.end();
+ theIter != theEnd; ++theIter) {
+ if (theIter->first.first == inInstance)
+ outProperties.push_back(
+ make_pair(theIter->first.second, theIter->second.GetValue()));
+ }
+ }
+
+ bool HasProperty(std::function<bool(const TSlideEntry &)> inPredicate) const
+ {
+ for (TSlideEntryHash::const_iterator theIter = m_Properties.begin(),
+ theEnd = m_Properties.end();
+ theIter != theEnd; ++theIter) {
+ if (inPredicate(TSlideEntry(theIter->first.first, theIter->first.second,
+ theIter->second.GetValue())))
+ return true;
+ }
+ return false;
+ }
+
+ void DeleteSlideEntries(TSlideEntryList &outList,
+ std::function<bool(const TSlideEntry &)> inPredicate)
+ {
+ for (TSlideEntryHash::const_iterator theIter = m_Properties.begin(),
+ theEnd = m_Properties.end();
+ theIter != theEnd; ++theIter) {
+ if (inPredicate(TSlideEntry(theIter->first.first, theIter->first.second,
+ theIter->second.GetValue())))
+ outList.push_back(TSlideEntry(theIter->first.first, theIter->first.second,
+ theIter->second.GetValue()));
+ }
+ DeleteEntriesFromList(outList);
+ }
+
+ void DeleteEntriesFromList(const TSlideEntryList &inList)
+ {
+ for (size_t idx = 0, end = inList.size(); idx < end; ++idx)
+ m_Properties.erase(
+ std::pair<int, int>(std::get<0>(inList[idx]), std::get<1>(inList[idx])));
+ }
+
+ void InsertSlideEntries(const TSlideEntryList &inList, IStringTable &inStringTable)
+ {
+ for (size_t idx = 0, end = inList.size(); idx < end; ++idx) {
+ TSlideInstancePropertyPair theKey(std::get<0>(inList[idx]),
+ std::get<1>(inList[idx]));
+ Q_ASSERT(m_Properties.find(theKey) == m_Properties.end());
+ m_Properties.insert(
+ std::make_pair(theKey, SInternValue(std::get<2>(inList[idx]), inStringTable)));
+ }
+ }
+
+ // Convert to the older, straight forward representation of the
+ // data in this slide.
+ void ToSlideEntryList(TSlideEntryList &outList) const
+ {
+ for (TSlideEntryHash::const_iterator theIter = m_Properties.begin(),
+ theEnd = m_Properties.end();
+ theIter != theEnd; ++theIter)
+ outList.push_back(TSlideEntry(theIter->first.first, theIter->first.second,
+ theIter->second.GetValue()));
+ }
+
+ void FromSlideEntryList(const TSlideEntryList &inList, IStringTable &inStringTable)
+ {
+ using namespace std;
+ m_Properties.clear();
+ for (TSlideEntryList::const_iterator theIter = inList.begin(), theEnd = inList.end();
+ theIter != theEnd; ++theIter)
+ SetInstancePropertyValue(get<0>(*theIter), get<1>(*theIter),
+ SInternValue(get<2>(*theIter), inStringTable));
+ }
+
+ // result is the instance, property, myvalue, othervalue
+ void IntersectProperties(const SSlide &inOther,
+ std::function<void(Qt3DSDMInstanceHandle, Qt3DSDMPropertyHandle,
+ SInternValue, SInternValue)>
+ inResult) const
+ {
+ for (TSlideEntryHash::const_iterator theIter = m_Properties.begin(),
+ theEnd = m_Properties.end();
+ theIter != theEnd; ++theIter) {
+ SInternValue *otherValue =
+ inOther.GetInstancePropertyValue(theIter->first.first, theIter->first.second);
+ if (otherValue)
+ inResult(theIter->first.first, theIter->first.second, theIter->second, *otherValue);
+ }
+ }
+
+ // Call the predicate, if it returns true set the property for all properties.
+ // This allows a third party to manipulate the property values during the process.
+ void SetPropertyValuesIf(
+ IStringTable &inStringTable,
+ std::function<bool(Qt3DSDMInstanceHandle, Qt3DSDMPropertyHandle, SValue &)> inPredIntercept)
+ {
+ for (TSlideEntryHash::iterator theIter = m_Properties.begin(), theEnd = m_Properties.end();
+ theIter != theEnd; ++theIter) {
+ SValue theValue(theIter->second.GetValue());
+ if (inPredIntercept(theIter->first.first, theIter->first.second, theValue))
+ theIter->second = SInternValue(theValue, inStringTable);
+ }
+ }
+
+ void
+ ClearPropertiesIf(std::function<bool(Qt3DSDMInstanceHandle, Qt3DSDMPropertyHandle)> inPredicate)
+ {
+ bool foundOne;
+ do {
+ foundOne = false;
+ for (TSlideEntryHash::iterator theIter = m_Properties.begin(),
+ theEnd = m_Properties.end();
+ theIter != theEnd; ++theIter) {
+ if (inPredicate(theIter->first.first, theIter->first.second)) {
+ foundOne = true;
+ m_Properties.erase(theIter->first);
+ break;
+ }
+ }
+
+ } while (foundOne);
+ }
+
+ static const EHandleObjectType s_Type = CHandleObject::EHandleObjectTypeSSlide;
+ EHandleObjectType GetType() override { return s_Type; }
+};
+
+class CSimpleSlideCore : public CHandleBase, public ISlideCore
+{
+ TStringTablePtr m_StringTable;
+
+public: // use
+ CSimpleSlideCore(TStringTablePtr inStrTable)
+ : m_StringTable(inStrTable)
+ {
+ }
+
+ TStringTablePtr GetStringTablePtr() const override { return m_StringTable; }
+ IStringTable &GetStringTable() const override { return *m_StringTable.get(); }
+ CUICDMSlideHandle CreateSlide(Qt3DSDMInstanceHandle inInstance) override;
+ Qt3DSDMInstanceHandle GetSlideInstance(CUICDMSlideHandle inSlide) const override;
+ CUICDMSlideHandle GetSlideByInstance(Qt3DSDMInstanceHandle inInstance) const override;
+ void DeleteSlide(CUICDMSlideHandle inSlide, TInstanceHandleList &outInstances) override;
+ void GetSlides(TSlideHandleList &outSlides) const override;
+
+ float GetSlideTime(CUICDMSlideHandle inSlide) const override;
+ void SetSlideTime(CUICDMSlideHandle inSlide, float inNewTime) override;
+
+ void DeriveSlide(CUICDMSlideHandle inSlide, CUICDMSlideHandle inParent, int inIndex = -1) override;
+ CUICDMSlideHandle GetParentSlide(CUICDMSlideHandle inSlide) const override;
+ void GetChildSlides(CUICDMSlideHandle inSlide, TSlideHandleList &outChildren) const override;
+ int GetChildIndex(CUICDMSlideHandle inParent, CUICDMSlideHandle inChild) const override;
+
+ bool GetInstancePropertyValue(CUICDMSlideHandle inSlide, Qt3DSDMInstanceHandle inHandle,
+ Qt3DSDMPropertyHandle inProperty, SValue &outValue) const override;
+ void SetInstancePropertyValue(CUICDMSlideHandle inSlide, Qt3DSDMInstanceHandle inHandle,
+ Qt3DSDMPropertyHandle inProperty, const SValue &inValue) override;
+
+ // Return the slide this property should be set on, along with the previous value if any.
+ // Set the value on the slide.
+ std::pair<SSlide *, SInternValue *>
+ ResolveSetInstancePropertyValue(CUICDMSlideHandle inSlide, Qt3DSDMInstanceHandle inHandle,
+ Qt3DSDMPropertyHandle inProperty);
+ void ForceSetInstancePropertyValue(CUICDMSlideHandle inSlide, Qt3DSDMInstanceHandle inHandle,
+ Qt3DSDMPropertyHandle inProperty, const SValue &inValue) override;
+
+ bool GetSpecificInstancePropertyValue(CUICDMSlideHandle inSlide,
+ Qt3DSDMInstanceHandle inInstance,
+ Qt3DSDMPropertyHandle inProperty, SValue &outValue) const override;
+
+ void GetSpecificInstancePropertyValues(CUICDMSlideHandle inSlide,
+ Qt3DSDMInstanceHandle inInstance,
+ TPropertyHandleValuePairList &outValues) override;
+
+ void GetSlidePropertyEntries(CUICDMSlideHandle inSlide, TSlideEntryList &outEntries) const override;
+
+ void PushPropertyValueToChildren(CUICDMSlideHandle inParent, Qt3DSDMInstanceHandle inHandle,
+ Qt3DSDMPropertyHandle inProperty, const SValue &inValue) override;
+
+ void GetIntersectingProperties(CUICDMSlideHandle inSlide1, CUICDMSlideHandle inSlide2,
+ TSlideEntryList &outEntries) const override;
+ void PushIntersectingProperties(CUICDMSlideHandle inSlide1, CUICDMSlideHandle inSlide2,
+ CUICDMSlideHandle inDestination) override;
+
+ void ClearChildrenPropertyValues(CUICDMSlideHandle inParent, Qt3DSDMInstanceHandle inHandle,
+ Qt3DSDMPropertyHandle inProperty) override;
+
+ void DeleteAllInstanceEntries(Qt3DSDMInstanceHandle inHandle) override;
+ void DeleteAllPropertyEntries(Qt3DSDMPropertyHandle inHandle) override;
+ void DeleteAllInstancePropertyEntries(const TInstanceHandleList &inInstances,
+ const TPropertyHandleList &inProperties) override;
+
+ bool ContainsProperty(CUICDMSlideHandle inSlide, Qt3DSDMInstanceHandle inHandle,
+ Qt3DSDMPropertyHandle inProperty) const override;
+ bool HandleValid(int inHandle) const override { return CHandleBase::HandleValid(inHandle); }
+
+ CUICDMSlideHandle CreateSlideWithHandle(int inHandle, Qt3DSDMInstanceHandle inInstance);
+ void GetSlideProperties(CUICDMSlideHandle inSlide, TSlideEntryList &outProperties) const;
+
+ bool IsSlide(CUICDMSlideHandle inSlide) const override;
+
+ // Possibly alter every slide in the database
+ void ForEachSlide(std::function<void(SSlide *)> inFunction);
+ void ForEachChild(CUICDMSlideHandle inSlide, std::function<void(SSlide *)> inFunction);
+
+ // Only implemented at the producer level, not at this lower level.
+ void CopyProperties(CUICDMSlideHandle /*inSourceSlide*/,
+ Qt3DSDMInstanceHandle /*inSourceInstance*/,
+ CUICDMSlideHandle /*inDestSlide*/, Qt3DSDMInstanceHandle /*inDestInstance*/) override
+ {
+ throw SlideNotFound(L"");
+ }
+
+ static SSlide *GetSlideNF(int inHandle, THandleObjectMap &inObjects)
+ {
+ return const_cast<SSlide *>(
+ GetSlideNF(inHandle, static_cast<const THandleObjectMap &>(inObjects)));
+ }
+
+ static const SSlide *GetSlideNF(int inHandle, const THandleObjectMap &inObjects)
+ {
+ const SSlide *theSlide = GetHandleObject<SSlide>(inHandle, inObjects);
+ if (theSlide)
+ return theSlide;
+ throw SlideNotFound(L"");
+ }
+
+ static inline bool PropertyFound(int inInstance, int inProperty, const TSlideEntry &inEntry)
+ {
+ if (inInstance == std::get<0>(inEntry) && inProperty == std::get<1>(inEntry))
+ return true;
+ return false;
+ }
+
+ static void ForceSetPropertyValue(IStringTable &inStringTable, THandleObjectMap &inObjects,
+ CUICDMSlideHandle inSlide, Qt3DSDMInstanceHandle inHandle,
+ Qt3DSDMPropertyHandle inProperty, const SValue &inValue);
+
+ static void ClearPropertyValue(THandleObjectMap &inObjects, CUICDMSlideHandle inSlide,
+ Qt3DSDMInstanceHandle inInstance,
+ Qt3DSDMPropertyHandle inProperty);
+
+ static inline bool SlideEntryInstanceMatches(const TSlideEntry &inEntry,
+ Qt3DSDMInstanceHandle inHandle)
+ {
+ using namespace std;
+ if (inHandle.GetHandleValue() == get<0>(inEntry))
+ return true;
+ return false;
+ }
+
+ static inline bool SlideEntryPropertyMatches(const TSlideEntry &inEntry,
+ Qt3DSDMPropertyHandle inProperty)
+ {
+ using namespace std;
+ return inProperty.GetHandleValue() == get<1>(inEntry);
+ }
+
+ static inline bool SlideEntryInstancePropertyMatches(const TSlideEntry &inEntry,
+ const TInstanceHandleList &inInstances,
+ const TPropertyHandleList &inProperties)
+ {
+ using namespace std;
+ return exists(inInstances, std::bind(equal_to<int>(), get<0>(inEntry),
+ std::placeholders::_1))
+ && exists(inProperties, std::bind(equal_to<int>(), get<1>(inEntry),
+ std::placeholders::_1));
+ }
+};
+
+typedef std::shared_ptr<CSimpleSlideCore> TSimpleSlideCorePtr;
+}
+
+#endif
diff --git a/src/Authoring/QT3DSDM/Systems/Cores/SimpleSlideGraphCore.cpp b/src/Authoring/QT3DSDM/Systems/Cores/SimpleSlideGraphCore.cpp
new file mode 100644
index 00000000..ce7159a5
--- /dev/null
+++ b/src/Authoring/QT3DSDM/Systems/Cores/SimpleSlideGraphCore.cpp
@@ -0,0 +1,169 @@
+/****************************************************************************
+**
+** 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-EXCEPT$
+** 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 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** 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 "Qt3DSDMPrefix.h"
+#include "SimpleSlideGraphCore.h"
+
+using namespace std;
+
+namespace qt3dsdm {
+
+CUICDMSlideGraphHandle CSimpleSlideGraphCore::CreateSlideGraph(CUICDMSlideHandle inRoot)
+{
+ int nextId = GetNextId();
+ return CreateSlideGraphWithHandle(nextId, inRoot);
+}
+
+CUICDMSlideHandle CSimpleSlideGraphCore::GetGraphRoot(CUICDMSlideGraphHandle inGraph) const
+{
+ return GetSlideGraphNF(inGraph, m_Objects)->m_Root;
+}
+
+inline bool RootSlideMatches(const THandleObjectPair &inPair, CUICDMSlideHandle inSlide)
+{
+ const SSlideGraph *theGraph = static_cast<SSlideGraph *>(inPair.second.get());
+ if (theGraph->m_Root == inSlide)
+ return true;
+ return false;
+}
+
+CUICDMSlideGraphHandle CSimpleSlideGraphCore::GetSlideGraph(CUICDMSlideHandle inSlide) const
+{
+ THandleObjectMap::const_iterator theFind = find_if<THandleObjectMap::const_iterator>(
+ m_Objects, std::bind(RootSlideMatches, std::placeholders::_1, inSlide));
+ if (theFind != m_Objects.end())
+ return theFind->first;
+ return 0;
+}
+
+inline CUICDMSlideGraphHandle ToGraphHandle(const THandleObjectPair &inPair)
+{
+ return inPair.first;
+}
+
+void CSimpleSlideGraphCore::GetSlideGraphs(TSlideGraphHandleList &outGraphs) const
+{
+ outGraphs.resize(m_Objects.size());
+ transform(m_Objects.begin(), m_Objects.end(), outGraphs.begin(), ToGraphHandle);
+}
+
+void CSimpleSlideGraphCore::DeleteSlideGraph(CUICDMSlideGraphHandle inHandle)
+{
+ TSlideInstancePairList theAssociatedInstances;
+ GetAssociatedInstances(inHandle, theAssociatedInstances);
+ for (size_t idx = 0, end = theAssociatedInstances.size(); idx < end; ++idx)
+ DissociateInstance(theAssociatedInstances[idx].second);
+ EraseHandle(inHandle, m_Objects);
+}
+
+void CSimpleSlideGraphCore::AssociateInstance(CUICDMSlideGraphHandle inSlideGraph,
+ CUICDMSlideHandle inSlide,
+ Qt3DSDMInstanceHandle inInstance)
+{
+ pair<TInstanceToGraphMap::iterator, bool> theResult =
+ m_InstanceToGraph.insert(make_pair(inInstance, make_pair(inSlideGraph, inSlide)));
+ Q_ASSERT(theResult.second);
+ if (theResult.second == false) {
+ theResult.first->second.first = inSlideGraph;
+ theResult.first->second.second = inSlide;
+ }
+ pair<TGraphToInstanceMap::iterator, bool> theGraphResult =
+ m_GraphToInstances.insert(make_pair(inSlideGraph, TSlideInstancePairList()));
+ insert_unique(theGraphResult.first->second, make_pair(inSlide, inInstance));
+}
+
+void CSimpleSlideGraphCore::GetAssociatedInstances(CUICDMSlideGraphHandle inSlideGraph,
+ TSlideInstancePairList &outAssociations) const
+{
+ TGraphToInstanceMap::const_iterator theFind = m_GraphToInstances.find(inSlideGraph);
+ if (theFind != m_GraphToInstances.end())
+ outAssociations.insert(outAssociations.end(), theFind->second.begin(),
+ theFind->second.end());
+}
+
+TGraphSlidePair CSimpleSlideGraphCore::GetAssociatedGraph(Qt3DSDMInstanceHandle inInstance) const
+{
+ TInstanceToGraphMap::const_iterator theResult = m_InstanceToGraph.find(inInstance);
+ if (theResult != m_InstanceToGraph.end())
+ return theResult->second;
+ return TGraphSlidePair();
+}
+
+struct SInstanceMatcher
+{
+ Qt3DSDMInstanceHandle m_Instance;
+ SInstanceMatcher(Qt3DSDMInstanceHandle inInst)
+ : m_Instance(inInst)
+ {
+ }
+ bool operator()(const pair<CUICDMSlideHandle, Qt3DSDMInstanceHandle> &inItem) const
+ {
+ return m_Instance == inItem.second;
+ }
+};
+
+void CSimpleSlideGraphCore::DissociateInstance(Qt3DSDMInstanceHandle inInstance)
+{
+ TGraphSlidePair theAssociatedGraph(GetAssociatedGraph(inInstance));
+
+ TGraphToInstanceMap::iterator theFind = m_GraphToInstances.find(theAssociatedGraph.first);
+ if (theFind != m_GraphToInstances.end()) {
+ erase_if(theFind->second, SInstanceMatcher(inInstance));
+ if (theFind->second.size() == 0)
+ m_GraphToInstances.erase(theAssociatedGraph.first);
+ }
+
+ m_InstanceToGraph.erase(inInstance);
+}
+
+void CSimpleSlideGraphCore::SetGraphActiveSlide(CUICDMSlideGraphHandle inGraph,
+ CUICDMSlideHandle inSlide)
+{
+ GetSlideGraphNF(inGraph, m_Objects)->m_ActiveSlide = inSlide;
+}
+
+CUICDMSlideHandle CSimpleSlideGraphCore::GetGraphActiveSlide(CUICDMSlideGraphHandle inGraph) const
+{
+ const SSlideGraph *theSlide = GetSlideGraphNF(inGraph, m_Objects);
+ if (theSlide->m_ActiveSlide)
+ return theSlide->m_ActiveSlide;
+ return theSlide->m_Root;
+}
+
+bool CSimpleSlideGraphCore::HandleValid(int inHandle) const
+{
+ return CHandleBase::HandleValid(inHandle);
+}
+
+CUICDMSlideGraphHandle CSimpleSlideGraphCore::CreateSlideGraphWithHandle(int inHandle,
+ CUICDMSlideHandle inRoot)
+{
+ m_Objects.insert(make_pair(inHandle, (THandleObjectPtr) new SSlideGraph(inHandle, inRoot)));
+ return inHandle;
+}
+}
diff --git a/src/Authoring/QT3DSDM/Systems/Cores/SimpleSlideGraphCore.h b/src/Authoring/QT3DSDM/Systems/Cores/SimpleSlideGraphCore.h
new file mode 100644
index 00000000..b4e82c76
--- /dev/null
+++ b/src/Authoring/QT3DSDM/Systems/Cores/SimpleSlideGraphCore.h
@@ -0,0 +1,134 @@
+/****************************************************************************
+**
+** 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-EXCEPT$
+** 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 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** 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$
+**
+****************************************************************************/
+#pragma once
+#ifndef SLIDEGRAPHCOREH
+#define SLIDEGRAPHCOREH
+#include "Qt3DSDMStringTable.h"
+#include "Qt3DSDMSlideGraphCore.h"
+#include "HandleSystemBase.h"
+#include "Qt3DSDMErrors.h"
+
+namespace qt3dsdm {
+using namespace std;
+struct SSlideGraph : public CHandleObject
+{
+ SSlideGraph()
+ : m_Root(0)
+ , m_ActiveSlide(0)
+ {
+ }
+ SSlideGraph(int inHandle, int inSlideRoot)
+ : CHandleObject(inHandle)
+ , m_Root(inSlideRoot)
+ , m_ActiveSlide(0)
+ {
+ }
+ CUICDMSlideHandle m_Root;
+ CUICDMSlideHandle m_ActiveSlide;
+
+ static const EHandleObjectType s_Type = CHandleObject::EHandleObjectTypeSSlideGraph;
+ EHandleObjectType GetType() override { return s_Type; }
+};
+
+class CSimpleSlideGraphCore : public CHandleBase, public ISlideGraphCore
+{
+ TStringTablePtr m_StringTable;
+ typedef std::unordered_map<Qt3DSDMInstanceHandle,
+ pair<CUICDMSlideGraphHandle, CUICDMSlideHandle>, std::hash<int>>
+ TInstanceToGraphMap;
+ typedef std::unordered_map<CUICDMSlideGraphHandle, TSlideInstancePairList, std::hash<int>>
+ TGraphToInstanceMap;
+
+ TInstanceToGraphMap m_InstanceToGraph;
+ TGraphToInstanceMap m_GraphToInstances;
+
+public:
+ CSimpleSlideGraphCore(TStringTablePtr strTable = TStringTablePtr())
+ : m_StringTable(strTable)
+ {
+ }
+ TStringTablePtr GetStringTablePtr() { return m_StringTable; }
+ /**
+ * A slide graph is used to associate a set of instances to a set of slides.
+ * This allows rapid lookup of properties, as an implementation of these.
+ * There are a few assumptions here. First is that a given slide can be a member
+ * of one and only one graph (i.e. it does not derive from another slide outside of the graph).
+ * Second is that an instance is a member of one and only one graph.
+ */
+ CUICDMSlideGraphHandle CreateSlideGraph(CUICDMSlideHandle inRoot) override;
+ CUICDMSlideHandle GetGraphRoot(CUICDMSlideGraphHandle inGraph) const override;
+ CUICDMSlideGraphHandle GetSlideGraph(CUICDMSlideHandle inSlide) const override;
+ void GetSlideGraphs(TSlideGraphHandleList &outGraphs) const override;
+ void DeleteSlideGraph(CUICDMSlideGraphHandle inHandle) override;
+
+ /**
+ * Associate a given instance handle with a given graph. This will ensure that property
+ *lookups
+ * will travel through this graph before they hit the main data core. Instances may be
+ *associated
+ * with a sub-slide of a given graph, not just the root. An instance associated with the root
+ *is
+ * implicitly associated with any root-derived slides.
+ */
+ void AssociateInstance(CUICDMSlideGraphHandle inSlideGraph, CUICDMSlideHandle inSlide,
+ Qt3DSDMInstanceHandle inInstance) override;
+ void GetAssociatedInstances(CUICDMSlideGraphHandle inSlideGraph,
+ TSlideInstancePairList &outAssociations) const override;
+ TGraphSlidePair GetAssociatedGraph(Qt3DSDMInstanceHandle inInstance) const override;
+ void DissociateInstance(Qt3DSDMInstanceHandle inInstance) override;
+
+ /**
+ * All graphs always have an active slide. This is assumed to be the root right off the bat.
+ */
+ void SetGraphActiveSlide(CUICDMSlideGraphHandle inGraph, CUICDMSlideHandle inSlide) override;
+ CUICDMSlideHandle GetGraphActiveSlide(CUICDMSlideGraphHandle inGraph) const override;
+
+ bool HandleValid(int inHandle) const override;
+
+ CUICDMSlideGraphHandle CreateSlideGraphWithHandle(int inHandle, CUICDMSlideHandle inRoot);
+
+ static SSlideGraph *GetSlideGraphNF(int inHandle, THandleObjectMap &inObjects)
+ {
+ return const_cast<SSlideGraph *>(
+ GetSlideGraphNF(inHandle, static_cast<const THandleObjectMap &>(inObjects)));
+ }
+
+ static const SSlideGraph *GetSlideGraphNF(int inHandle, const THandleObjectMap &inObjects)
+ {
+ const SSlideGraph *theSlide = GetHandleObject<SSlideGraph>(inHandle, inObjects);
+ if (theSlide)
+ return theSlide;
+ throw SlideGraphNotFound(L"");
+ }
+};
+
+typedef std::shared_ptr<CSimpleSlideGraphCore> TSimpleSlideGraphCorePtr;
+}
+
+#endif
diff --git a/src/Authoring/QT3DSDM/Systems/Cores/SlideCoreProducer.cpp b/src/Authoring/QT3DSDM/Systems/Cores/SlideCoreProducer.cpp
new file mode 100644
index 00000000..b23ba012
--- /dev/null
+++ b/src/Authoring/QT3DSDM/Systems/Cores/SlideCoreProducer.cpp
@@ -0,0 +1,555 @@
+/****************************************************************************
+**
+** 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-EXCEPT$
+** 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 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** 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 "Qt3DSDMPrefix.h"
+#ifdef _WIN32
+#pragma warning(disable : 4503) // decorated name length exceeded
+#endif
+#include "SlideCoreProducer.h"
+#include "HandleSystemTransactions.h"
+#include "VectorTransactions.h"
+#include "SignalsImpl.h"
+
+using namespace std;
+
+namespace qt3dsdm {
+
+CUICDMSlideHandle CSlideCoreProducer::CreateSlide(Qt3DSDMInstanceHandle inInstance)
+{
+ CUICDMSlideHandle retval = m_Data->CreateSlide(inInstance);
+ CREATE_HANDLE_CREATE_TRANSACTION(m_Consumer, retval, m_Data->m_Objects);
+ GetSignalSender()->SendSlideCreated(retval);
+ return retval;
+}
+
+Qt3DSDMInstanceHandle CSlideCoreProducer::GetSlideInstance(CUICDMSlideHandle inSlide) const
+{
+ return m_Data->GetSlideInstance(inSlide);
+}
+
+CUICDMSlideHandle CSlideCoreProducer::GetSlideByInstance(Qt3DSDMInstanceHandle inSlide) const
+{
+ return m_Data->GetSlideByInstance(inSlide);
+}
+
+void SendPropertyRemoved(const TSlideEntry &inEntry, CUICDMSlideHandle inSlide,
+ ISlideCoreSignalSender *inSender)
+{
+ inSender->SendPropertyValueRemoved(inSlide, get<0>(inEntry), get<1>(inEntry), get<2>(inEntry));
+}
+
+void RecurseCreateDeleteTransactions(TTransactionConsumerPtr inConsumer, CUICDMSlideHandle inSlide,
+ THandleObjectMap &inObjects, ISlideCoreSignalSender *inSender)
+{
+ SSlide *theSlide = CSimpleSlideCore::GetSlideNF(inSlide, inObjects);
+ inSender->SendBeforeSlideDeleted(theSlide->m_Handle);
+ do_all(theSlide->m_Children, std::bind(RecurseCreateDeleteTransactions, inConsumer,
+ std::placeholders::_1,
+ std::ref(inObjects), inSender));
+ if (inConsumer)
+ CREATE_HANDLE_DELETE_TRANSACTION(inConsumer, inSlide, inObjects);
+ inSender->SendSlideDeleted(theSlide->m_Handle);
+}
+
+void CSlideCoreProducer::DeleteSlide(CUICDMSlideHandle inSlide, TInstanceHandleList &outInstances)
+{
+ // Ensure exists
+ SSlide *theSlide = CSimpleSlideCore::GetSlideNF(inSlide, m_Data->m_Objects);
+ if (theSlide->m_Parent) {
+ SSlide *theParent = CSimpleSlideCore::GetSlideNF(theSlide->m_Parent, m_Data->m_Objects);
+ CreateVecEraseTransaction<int>(__FILE__, __LINE__, m_Consumer, inSlide,
+ theParent->m_Children);
+ }
+ RecurseCreateDeleteTransactions(m_Consumer, inSlide, m_Data->m_Objects, GetSignalSender());
+ // Not any more...
+ m_Data->DeleteSlide(inSlide, outInstances);
+}
+
+void CSlideCoreProducer::GetSlides(TSlideHandleList &outSlides) const
+{
+ m_Data->GetSlides(outSlides);
+}
+
+float CSlideCoreProducer::GetSlideTime(CUICDMSlideHandle inSlide) const
+{
+ return m_Data->GetSlideTime(inSlide);
+}
+
+void CSlideCoreProducer::SetSlideTime(CUICDMSlideHandle inSlide, float inNewTime)
+{
+ SSlide *theSlide = CSimpleSlideCore::GetSlideNF(inSlide, m_Data->m_Objects);
+ float oldTime = theSlide->m_Time;
+ theSlide->m_Time = inNewTime;
+ if (m_Consumer) {
+ m_Consumer->OnTransaction(std::shared_ptr<ITransaction>(CREATE_GENERIC_TRANSACTION(
+ std::bind(&CSlideCoreProducer::SetSlideTime, this, inSlide, inNewTime),
+ std::bind(&CSlideCoreProducer::SetSlideTime, this, inSlide, oldTime))));
+ } else
+ GetSignalSender()->SendSlideTimeChanged(inSlide);
+}
+
+inline void SetSlideParent(THandleObjectMap &inObjects, int inSlide, int inParent)
+{
+ CSimpleSlideCore::GetSlideNF(inSlide, inObjects)->m_Parent = inParent;
+}
+
+void CSlideCoreProducer::DeriveSlide(CUICDMSlideHandle inSlide, CUICDMSlideHandle inParent,
+ int inIndex)
+{
+ // Integrity checks to ensure operation will proceed
+ SSlide *theSlide = CSimpleSlideCore::GetSlideNF(inSlide, m_Data->m_Objects);
+ SSlide *theNewParent = NULL;
+ if (inParent)
+ theNewParent = CSimpleSlideCore::GetSlideNF(inParent, m_Data->m_Objects);
+ SSlide *theOldParent = NULL;
+ if (theSlide->m_Parent)
+ theOldParent = CSimpleSlideCore::GetSlideNF(theSlide->m_Parent, m_Data->m_Objects);
+
+ if (theSlide->m_Parent && m_Consumer) {
+ m_Consumer->OnTransaction(TTransactionPtr(CREATE_GENERIC_TRANSACTION(
+ std::bind(SetSlideParent, std::ref(m_Data->m_Objects), inSlide, inParent),
+ std::bind(SetSlideParent, std::ref(m_Data->m_Objects), inSlide,
+ theSlide->m_Parent))));
+ if (theOldParent)
+ CreateVecEraseTransaction<int>(__FILE__, __LINE__, m_Consumer, inSlide,
+ theOldParent->m_Children);
+ GetSignalSender()->SendSlideDerived(inSlide, 0, inIndex);
+ }
+ m_Data->DeriveSlide(inSlide, inParent, inIndex);
+ if (theNewParent)
+ CreateVecInsertTransaction<int>(__FILE__, __LINE__, m_Consumer, inSlide,
+ theNewParent->m_Children);
+ GetSignalSender()->SendSlideDerived(inSlide, inParent, inIndex);
+}
+
+CUICDMSlideHandle CSlideCoreProducer::GetParentSlide(CUICDMSlideHandle inSlide) const
+{
+ return m_Data->GetParentSlide(inSlide);
+}
+
+void CSlideCoreProducer::GetChildSlides(CUICDMSlideHandle inSlide,
+ TSlideHandleList &outChildren) const
+{
+ m_Data->GetChildSlides(inSlide, outChildren);
+}
+
+int CSlideCoreProducer::GetChildIndex(CUICDMSlideHandle inParent, CUICDMSlideHandle inChild) const
+{
+ return m_Data->GetChildIndex(inParent, inChild);
+}
+
+bool CSlideCoreProducer::GetInstancePropertyValue(CUICDMSlideHandle inSlide,
+ Qt3DSDMInstanceHandle inHandle,
+ Qt3DSDMPropertyHandle inProperty,
+ SValue &outValue) const
+{
+ return m_Data->GetInstancePropertyValue(inSlide, inHandle, inProperty, outValue);
+}
+
+inline void EraseProperty(TSlideEntryList &inProperties, int inInstance, int inProperty)
+{
+ erase_if(inProperties,
+ std::bind(CSimpleSlideCore::PropertyFound, inInstance, inProperty,
+ std::placeholders::_1));
+}
+
+void CSlideCoreProducer::SetInstancePropertyValue(CUICDMSlideHandle inSlide,
+ Qt3DSDMInstanceHandle inHandle,
+ Qt3DSDMPropertyHandle inProperty,
+ const SValue &inValue)
+{
+ std::pair<SSlide *, SInternValue *> slideAndProp(
+ m_Data->ResolveSetInstancePropertyValue(inSlide, inHandle, inProperty));
+ DoForceSetInstancePropertyValue(slideAndProp.first->m_Handle, inHandle, inProperty, inValue);
+}
+
+struct HashMapDataValueInsertTransaction
+ : public HashMapInsertTransaction<TSlideInstancePropertyPair, SInternValue,
+ TSlideEntryHash::hasher>
+{
+ typedef HashMapInsertTransaction<TSlideInstancePropertyPair, SInternValue,
+ TSlideEntryHash::hasher>
+ TBase;
+ HashMapDataValueInsertTransaction(
+ const char *inFile, int inLine, TSlideEntryHash &map,
+ const std::pair<TSlideInstancePropertyPair, SInternValue> &val)
+ : TBase(inFile, inLine, map, val)
+ {
+ }
+ void Do() override
+ {
+ std::pair<int, int> theKey = m_Value.first;
+ SValue theTempValue = m_Value.second.GetValue();
+ TDataStrPtr theStrPtr;
+ if (GetValueType(theTempValue) == DataModelDataType::String) {
+ theStrPtr = qt3dsdm::get<TDataStrPtr>(theTempValue);
+ }
+ (void)theStrPtr;
+ TBase::Add();
+ }
+};
+
+inline void CSlideCoreProducer::DoForceSetInstancePropertyValue(CUICDMSlideHandle inSlide,
+ Qt3DSDMInstanceHandle inHandle,
+ Qt3DSDMPropertyHandle inProperty,
+ const SValue &inValue)
+{
+ SSlide *theSlide = CSimpleSlideCore::GetSlideNF(inSlide, m_Data->m_Objects);
+ SInternValue theNewValue(inValue, m_Data->GetStringTable());
+ SInternValue *theCurrentValue(theSlide->GetInstancePropertyValue(inHandle, inProperty));
+
+ std::pair<int, int> theKey(inHandle, inProperty);
+ SlideInstancePropertyKey mergeMapKey(inSlide, inHandle, inProperty);
+ TSlidePropertyMergeMap::iterator iter = m_PropertyMergeMap.find(mergeMapKey);
+ if (iter != m_PropertyMergeMap.end()) {
+ const SValue &theTempValue(theNewValue.GetValue());
+ CSimpleSlideCore::ForceSetPropertyValue(m_Data->GetStringTable(), m_Data->m_Objects,
+ inSlide, inHandle, inProperty, theTempValue);
+ iter->second->Update(theNewValue);
+ if (GetValueType(theTempValue) == DataModelDataType::String) {
+ TDataStrPtr theStrPtr = qt3dsdm::get<TDataStrPtr>(theTempValue);
+ UICDM_DEBUG_LOG(m_Data->GetStringTable().GetNarrowStr(theStrPtr->GetData()));
+ }
+ return; // don't signal
+ } else {
+ TSlidePropertyMergeMapEntry theEntry;
+ if (theCurrentValue) {
+ theEntry =
+ CreateHashMapSwapTransaction(__FILE__, __LINE__, m_Consumer, theKey,
+ *theCurrentValue, theNewValue, theSlide->m_Properties);
+ } else {
+ if (m_Consumer) {
+ std::shared_ptr<HashMapDataValueInsertTransaction> theTransaction =
+ std::make_shared<HashMapDataValueInsertTransaction>(
+ __FILE__, __LINE__, std::ref(theSlide->m_Properties),
+ std::make_pair(theKey, theNewValue));
+ m_Consumer->OnTransaction(theTransaction);
+ theEntry = theTransaction;
+ }
+ }
+ if (theEntry)
+ m_PropertyMergeMap.insert(make_pair(mergeMapKey, theEntry));
+ CSimpleSlideCore::ForceSetPropertyValue(m_Data->GetStringTable(), m_Data->m_Objects,
+ inSlide, inHandle, inProperty,
+ theNewValue.GetValue());
+ GetSignalSender()->SendPropertyValueSet(inSlide, inHandle, inProperty,
+ theNewValue.GetValue());
+ }
+}
+
+void CSlideCoreProducer::ForceSetInstancePropertyValue(CUICDMSlideHandle inSlide,
+ Qt3DSDMInstanceHandle inHandle,
+ Qt3DSDMPropertyHandle inProperty,
+ const SValue &inValue)
+{
+ if (m_Consumer)
+ DoForceSetInstancePropertyValue(inSlide, inHandle, inProperty, inValue);
+ else
+ m_Data->ForceSetInstancePropertyValue(inSlide, inHandle, inProperty, inValue);
+}
+
+bool CSlideCoreProducer::GetSpecificInstancePropertyValue(CUICDMSlideHandle inSlide,
+ Qt3DSDMInstanceHandle inInstance,
+ Qt3DSDMPropertyHandle inProperty,
+ SValue &outValue) const
+{
+ return m_Data->GetSpecificInstancePropertyValue(inSlide, inInstance, inProperty, outValue);
+}
+
+bool CSlideCoreProducer::ContainsProperty(CUICDMSlideHandle inSlide, Qt3DSDMInstanceHandle inHandle,
+ Qt3DSDMPropertyHandle inProperty) const
+{
+ return m_Data->ContainsProperty(inSlide, inHandle, inProperty);
+}
+
+void CSlideCoreProducer::GetSlidePropertyEntries(CUICDMSlideHandle inSlide,
+ TSlideEntryList &outEntries) const
+{
+ return m_Data->GetSlidePropertyEntries(inSlide, outEntries);
+}
+
+void CSlideCoreProducer::PushPropertyValueToChildren(CUICDMSlideHandle inParent,
+ Qt3DSDMInstanceHandle inHandle,
+ Qt3DSDMPropertyHandle inProperty,
+ const SValue &inValue)
+{
+ SSlide *theParent = CSimpleSlideCore::GetSlideNF(inParent, m_Data->m_Objects);
+ DoForceSetInstancePropertyValue(inParent, inHandle, inProperty, inValue);
+ do_all(theParent->m_Children, std::bind(&CSlideCoreProducer::DoForceSetInstancePropertyValue,
+ this, std::placeholders::_1,
+ inHandle, inProperty, inValue));
+}
+
+inline void ClearValueWithTransactions(TTransactionConsumerPtr inConsumer,
+ THandleObjectMap &inObjects,
+ ISlideCoreSignalSender *inSignalSender, int inSlide,
+ Qt3DSDMInstanceHandle inHandle,
+ Qt3DSDMPropertyHandle inProperty)
+{
+ SSlide *theSlide = CSimpleSlideCore::GetSlideNF(inSlide, inObjects);
+ SInternValue *theCurrentValue(theSlide->GetInstancePropertyValue(inHandle, inProperty));
+ if (theCurrentValue) {
+ SValue theValue(theCurrentValue->GetValue());
+ std::pair<int, int> theKey(inHandle, inProperty);
+ CreateHashMapEraseTransaction(__FILE__, __LINE__, inConsumer,
+ std::make_pair(theKey, *theCurrentValue),
+ theSlide->m_Properties);
+ CSimpleSlideCore::ClearPropertyValue(inObjects, inSlide, inHandle, inProperty);
+ inSignalSender->SendPropertyValueRemoved(inSlide, inHandle, inProperty, theValue);
+ }
+}
+
+void CSlideCoreProducer::ClearChildrenPropertyValues(CUICDMSlideHandle inParent,
+ Qt3DSDMInstanceHandle inHandle,
+ Qt3DSDMPropertyHandle inProperty)
+{
+ SSlide *theParent = CSimpleSlideCore::GetSlideNF(inParent, m_Data->m_Objects);
+ do_all(theParent->m_Children,
+ std::bind(ClearValueWithTransactions, m_Consumer, std::ref(m_Data->m_Objects),
+ GetSignalSender(), std::placeholders::_1, inHandle, inProperty));
+}
+
+typedef tuple<int, TSlideEntryList, TSlideEntryList> TSlideSlideEntryTuple;
+typedef std::vector<TSlideSlideEntryTuple> TSlideSlideEntryTupleList;
+
+inline void CreateVectorPreReplaceData(THandleObjectPair inPair,
+ TSlideSlideEntryTupleList &outSlideSlideEntries,
+ function<bool(const TSlideEntry &)> inPredicate)
+{
+ if (inPair.second->GetType() == CHandleObject::EHandleObjectTypeSSlide) {
+ SSlide *theSlide = static_cast<SSlide *>(inPair.second.get());
+ if (theSlide->HasProperty(inPredicate)) {
+ outSlideSlideEntries.push_back(
+ TSlideSlideEntryTuple(inPair.first, TSlideEntryList(), TSlideEntryList()));
+ theSlide->DeleteSlideEntries(get<1>(outSlideSlideEntries.back()), inPredicate);
+ }
+ }
+}
+
+inline void RunInsert(tuple<int, TSlideEntryList, TSlideEntryList> &inTuple,
+ THandleObjectMap &inObjects, IStringTable &inStringTable)
+{
+ SSlide *theSlide = CSimpleSlideCore::GetSlideNF(get<0>(inTuple), inObjects);
+ theSlide->InsertSlideEntries(get<1>(inTuple), inStringTable);
+}
+
+inline void RunFullInsert(std::shared_ptr<TSlideSlideEntryTupleList> inList,
+ THandleObjectMap &inObjects, IStringTable &inStringTable)
+{
+ for (TSlideSlideEntryTupleList::iterator theIter = inList->begin(); theIter != inList->end();
+ ++theIter)
+ RunInsert(*theIter, inObjects, inStringTable);
+}
+
+inline void RunFullErase(std::shared_ptr<TSlideSlideEntryTupleList> inList,
+ THandleObjectMap &inObjects)
+{
+ for (TSlideSlideEntryTupleList::iterator theIter = inList->begin(); theIter != inList->end();
+ ++theIter) {
+ SSlide *theSlide = CSimpleSlideCore::GetSlideNF(get<0>(*theIter), inObjects);
+ theSlide->DeleteEntriesFromList(std::get<1>(*theIter));
+ }
+}
+
+void DeleteAllSlideEntriesWithUndo(TTransactionConsumerPtr inConsumer, IStringTable &inStringTable,
+ THandleObjectMap &inObjects,
+ function<bool(const TSlideEntry &)> inPredicate)
+{
+ std::shared_ptr<TSlideSlideEntryTupleList> theEntries(new TSlideSlideEntryTupleList);
+ do_all(inObjects,
+ std::bind(CreateVectorPreReplaceData,
+ std::placeholders::_1, std::ref(*theEntries), inPredicate));
+ if (inConsumer)
+ CreateGenericTransactionWithConsumer(
+ __FILE__, __LINE__, inConsumer,
+ std::bind(RunFullErase, theEntries, std::ref(inObjects)),
+ std::bind(RunFullInsert, theEntries, std::ref(inObjects),
+ std::ref(inStringTable)));
+}
+
+void CSlideCoreProducer::DeleteAllInstanceEntries(Qt3DSDMInstanceHandle inInstance)
+{
+ DeleteAllSlideEntriesWithUndo(
+ m_Consumer, GetStringTable(), m_Data->m_Objects,
+ std::bind(CSimpleSlideCore::SlideEntryInstanceMatches, std::placeholders::_1, inInstance));
+}
+void CSlideCoreProducer::DeleteAllPropertyEntries(Qt3DSDMPropertyHandle inHandle)
+{
+ DeleteAllSlideEntriesWithUndo(
+ m_Consumer, GetStringTable(), m_Data->m_Objects,
+ std::bind(CSimpleSlideCore::SlideEntryPropertyMatches, std::placeholders::_1, inHandle));
+}
+
+void CSlideCoreProducer::DeleteAllInstancePropertyEntries(const TInstanceHandleList &inInstances,
+ const TPropertyHandleList &inProperties)
+{
+ DeleteAllSlideEntriesWithUndo(m_Consumer, GetStringTable(), m_Data->m_Objects,
+ std::bind(CSimpleSlideCore::SlideEntryInstancePropertyMatches,
+ std::placeholders::_1, std::cref(inInstances),
+ std::cref(inProperties)));
+}
+
+void CSlideCoreProducer::GetIntersectingProperties(CUICDMSlideHandle inSlide1,
+ CUICDMSlideHandle inSlide2,
+ TSlideEntryList &outEntries) const
+{
+ return m_Data->GetIntersectingProperties(inSlide1, inSlide2, outEntries);
+}
+
+bool InstancePropMatches(Qt3DSDMInstanceHandle instance, Qt3DSDMPropertyHandle prop,
+ const TSlideEntry &entry)
+{
+ return instance == get<0>(entry) && prop == get<1>(entry);
+}
+
+bool SendPropertyAddedIfNotInList(Qt3DSDMInstanceHandle instance, Qt3DSDMPropertyHandle prop,
+ SValue & /*value*/, const TSlideEntryList &inList,
+ CUICDMSlideHandle inSource, CUICDMSlideHandle inSlide,
+ ISlideCoreSignalSender * /*inSignalSender*/)
+{
+ if (find_if<TSlideEntryList::const_iterator>(
+ inList, std::bind(InstancePropMatches, instance, prop, std::placeholders::_1))
+ == inList.end()) {
+ return true;
+ }
+ return false;
+}
+
+// destination gets the properties from slide 1 that have corresponding entries in slide 2
+void CSlideCoreProducer::PushIntersectingProperties(CUICDMSlideHandle inSlide1,
+ CUICDMSlideHandle inSlide2,
+ CUICDMSlideHandle inDestination)
+{
+ SSlide *theDest = CSimpleSlideCore::GetSlideNF(inDestination, m_Data->m_Objects);
+ TSlideEntryList theProperties;
+ theDest->ToSlideEntryList(theProperties);
+ m_Data->PushIntersectingProperties(inSlide1, inSlide2, inDestination);
+ theDest->SetPropertyValuesIf(GetStringTable(), std::bind(SendPropertyAddedIfNotInList,
+ std::placeholders::_1,
+ std::placeholders::_2,
+ std::placeholders::_3,
+ theProperties, inSlide1,
+ inDestination, GetSignalSender()));
+ if (m_Consumer) {
+ TSlideEntryList theResult;
+ theDest->ToSlideEntryList(theResult);
+ m_Consumer->OnTransaction(TTransactionPtr(
+ CREATE_GENERIC_TRANSACTION(std::bind(&SSlide::FromSlideEntryList, theDest, theResult,
+ std::ref(GetStringTable())),
+ std::bind(&SSlide::FromSlideEntryList, theDest,
+ theProperties, std::ref(GetStringTable())))));
+ }
+}
+
+void CSlideCoreProducer::CopyProperties(CUICDMSlideHandle inSourceSlide,
+ Qt3DSDMInstanceHandle inSourceInstance,
+ CUICDMSlideHandle inDestSlide,
+ Qt3DSDMInstanceHandle inDestInstance)
+{
+ SSlide *sourceSlide = CSimpleSlideCore::GetSlideNF(inSourceSlide, m_Data->m_Objects);
+
+ for (TSlideEntryHash::iterator theIter = sourceSlide->m_Properties.begin(),
+ theEnd = sourceSlide->m_Properties.end();
+ theIter != theEnd; ++theIter) {
+ if (theIter->first.first == inSourceInstance) {
+ // Set it once so it appears in the slide
+ // Then call the main method that will send the events.
+ DoForceSetInstancePropertyValue(inDestSlide, inDestInstance, theIter->first.second,
+ theIter->second.GetValue());
+ }
+ }
+}
+
+bool CSlideCoreProducer::HandleValid(int inHandle) const
+{
+ return m_Data->HandleValid(inHandle);
+}
+
+bool CSlideCoreProducer::IsSlide(CUICDMSlideHandle inSlide) const
+{
+ return m_Data->IsSlide(inSlide);
+}
+
+void CSlideCoreProducer::SetConsumer(TTransactionConsumerPtr inConsumer)
+{
+ m_Consumer = inConsumer;
+ m_PropertyMergeMap.clear();
+}
+
+TSignalConnectionPtr
+CSlideCoreProducer::ConnectSlideCreated(const std::function<void(CUICDMSlideHandle)> &inCallback)
+{
+ return GetSignalProvider()->ConnectSlideCreated(inCallback);
+}
+TSignalConnectionPtr CSlideCoreProducer::ConnectBeforeSlideDeleted(
+ const std::function<void(CUICDMSlideHandle)> &inCallback)
+{
+ return GetSignalProvider()->ConnectBeforeSlideDeleted(inCallback);
+}
+TSignalConnectionPtr
+CSlideCoreProducer::ConnectSlideDeleted(const std::function<void(CUICDMSlideHandle)> &inCallback)
+{
+ return GetSignalProvider()->ConnectSlideDeleted(inCallback);
+}
+TSignalConnectionPtr CSlideCoreProducer::ConnectSlideDerived(
+ const std::function<void(CUICDMSlideHandle, CUICDMSlideHandle, int)> &inCallback)
+{
+ return GetSignalProvider()->ConnectSlideDerived(inCallback);
+}
+TSignalConnectionPtr CSlideCoreProducer::ConnectInstancePropertyValueSet(
+ const std::function<void(CUICDMSlideHandle, Qt3DSDMInstanceHandle, Qt3DSDMPropertyHandle,
+ const SValue &)> &inCallback)
+{
+ return GetSignalProvider()->ConnectInstancePropertyValueSet(inCallback);
+}
+TSignalConnectionPtr CSlideCoreProducer::ConnectInstancePropertyValueRemoved(
+ const std::function<void(CUICDMSlideHandle, Qt3DSDMInstanceHandle, Qt3DSDMPropertyHandle,
+ const SValue &)> &inCallback)
+{
+ return GetSignalProvider()->ConnectInstancePropertyValueRemoved(inCallback);
+}
+TSignalConnectionPtr CSlideCoreProducer::ConnectSlideTimeChanged(
+ const std::function<void(CUICDMSlideHandle)> &inCallback)
+{
+ return GetSignalProvider()->ConnectSlideTimeChanged(inCallback);
+}
+
+void CSlideCoreProducer::InitSignaller()
+{
+ m_SlideCoreSignaller = CreateSlideCoreSignaller();
+}
+
+ISlideCoreSignalProvider *CSlideCoreProducer::GetSignalProvider()
+{
+ return dynamic_cast<ISlideCoreSignalProvider *>(m_SlideCoreSignaller.get());
+}
+ISlideCoreSignalSender *CSlideCoreProducer::GetSignalSender()
+{
+ return dynamic_cast<ISlideCoreSignalSender *>(m_SlideCoreSignaller.get());
+}
+}
diff --git a/src/Authoring/QT3DSDM/Systems/Cores/SlideCoreProducer.h b/src/Authoring/QT3DSDM/Systems/Cores/SlideCoreProducer.h
new file mode 100644
index 00000000..848ed2a1
--- /dev/null
+++ b/src/Authoring/QT3DSDM/Systems/Cores/SlideCoreProducer.h
@@ -0,0 +1,187 @@
+/****************************************************************************
+**
+** 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-EXCEPT$
+** 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 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** 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$
+**
+****************************************************************************/
+#pragma once
+#ifndef SLIDECOREPRODUCERH
+#define SLIDECOREPRODUCERH
+#include "Qt3DSDMTransactions.h"
+#include "SimpleSlideCore.h"
+#include "Qt3DSDMSignals.h"
+
+namespace qt3dsdm {
+struct SlideInstancePropertyKey
+{
+ int m_Slide;
+ int m_Instance;
+ int m_Property;
+ SlideInstancePropertyKey(int slide, int inst, int prop)
+ : m_Slide(slide)
+ , m_Instance(inst)
+ , m_Property(prop)
+ {
+ }
+ SlideInstancePropertyKey()
+ : m_Slide(0)
+ , m_Instance(0)
+ , m_Property(0)
+ {
+ }
+
+ bool operator==(const SlideInstancePropertyKey &inOther) const
+ {
+ return m_Slide == inOther.m_Slide && m_Instance == inOther.m_Instance
+ && m_Property == inOther.m_Property;
+ }
+};
+
+struct SlideInstancePropertyKeyHasher
+{
+ std::size_t operator()(const SlideInstancePropertyKey &inEntry) const
+ {
+ return std::hash<int>()(inEntry.m_Slide) ^ std::hash<int>()(inEntry.m_Instance)
+ ^ std::hash<int>()(inEntry.m_Property);
+ }
+};
+
+typedef std::shared_ptr<IMergeableTransaction<SInternValue>> TSlidePropertyMergeMapEntry;
+typedef std::unordered_map<SlideInstancePropertyKey, TSlidePropertyMergeMapEntry,
+ SlideInstancePropertyKeyHasher>
+ TSlidePropertyMergeMap;
+
+class CSlideCoreProducer : public ISlideCore,
+ public ITransactionProducer,
+ public ISlideCoreSignalProvider
+{
+ Q_DISABLE_COPY(CSlideCoreProducer)
+
+ TTransactionConsumerPtr m_Consumer;
+ TSimpleSlideCorePtr m_Data;
+ TSignalItemPtr m_SlideCoreSignaller;
+ TSlidePropertyMergeMap m_PropertyMergeMap;
+
+public:
+ CSlideCoreProducer(TStringTablePtr inStrTable)
+ : m_Data(new CSimpleSlideCore(inStrTable))
+ {
+ InitSignaller();
+ }
+
+ IStringTable &GetStringTable() const override { return m_Data->GetStringTable(); }
+ TStringTablePtr GetStringTablePtr() const override { return m_Data->GetStringTablePtr(); }
+
+ TSimpleSlideCorePtr GetTransactionlessSlideCore() { return m_Data; }
+ TSimpleSlideCorePtr GetTransactionlessSlideCore() const { return m_Data; }
+
+ CUICDMSlideHandle CreateSlide(Qt3DSDMInstanceHandle inInstance) override;
+ Qt3DSDMInstanceHandle GetSlideInstance(CUICDMSlideHandle inSlide) const override;
+ CUICDMSlideHandle GetSlideByInstance(Qt3DSDMInstanceHandle inSlide) const override;
+ void DeleteSlide(CUICDMSlideHandle inSlide, TInstanceHandleList &outInstances) override;
+ void GetSlides(TSlideHandleList &outSlides) const override;
+
+ float GetSlideTime(CUICDMSlideHandle inSlide) const override;
+ void SetSlideTime(CUICDMSlideHandle inSlide, float inNewTime) override;
+
+ void DeriveSlide(CUICDMSlideHandle inSlide, CUICDMSlideHandle inParent, int inIndex = -1) override;
+ CUICDMSlideHandle GetParentSlide(CUICDMSlideHandle inSlide) const override;
+ void GetChildSlides(CUICDMSlideHandle inSlide, TSlideHandleList &outChildren) const override;
+ int GetChildIndex(CUICDMSlideHandle inParent, CUICDMSlideHandle inChild) const override;
+
+ bool GetInstancePropertyValue(CUICDMSlideHandle inSlide, Qt3DSDMInstanceHandle inHandle,
+ Qt3DSDMPropertyHandle inProperty, SValue &outValue) const override;
+ void SetInstancePropertyValue(CUICDMSlideHandle inSlide, Qt3DSDMInstanceHandle inHandle,
+ Qt3DSDMPropertyHandle inProperty, const SValue &inValue) override;
+ void ForceSetInstancePropertyValue(CUICDMSlideHandle inSlide, Qt3DSDMInstanceHandle inHandle,
+ Qt3DSDMPropertyHandle inProperty, const SValue &inValue) override;
+ bool GetSpecificInstancePropertyValue(CUICDMSlideHandle inSlide,
+ Qt3DSDMInstanceHandle inInstance,
+ Qt3DSDMPropertyHandle inProperty, SValue &outValue) const override;
+ void GetSpecificInstancePropertyValues(CUICDMSlideHandle inSlide,
+ Qt3DSDMInstanceHandle inInstance,
+ TPropertyHandleValuePairList &outValues) override
+ {
+ return m_Data->GetSpecificInstancePropertyValues(inSlide, inInstance, outValues);
+ }
+ bool ContainsProperty(CUICDMSlideHandle inSlide, Qt3DSDMInstanceHandle inHandle,
+ Qt3DSDMPropertyHandle inProperty) const override;
+ void GetSlidePropertyEntries(CUICDMSlideHandle inSlide, TSlideEntryList &outEntries) const override;
+
+ void PushPropertyValueToChildren(CUICDMSlideHandle inParent, Qt3DSDMInstanceHandle inHandle,
+ Qt3DSDMPropertyHandle inProperty, const SValue &inValue) override;
+ void ClearChildrenPropertyValues(CUICDMSlideHandle inParent, Qt3DSDMInstanceHandle inHandle,
+ Qt3DSDMPropertyHandle inProperty) override;
+ void DeleteAllInstanceEntries(Qt3DSDMInstanceHandle inHandle) override;
+ void DeleteAllPropertyEntries(Qt3DSDMPropertyHandle inHandle) override;
+ void DeleteAllInstancePropertyEntries(const TInstanceHandleList &inInstances,
+ const TPropertyHandleList &inProperties) override;
+
+ void GetIntersectingProperties(CUICDMSlideHandle inSlide1, CUICDMSlideHandle inSlide2,
+ TSlideEntryList &outEntries) const override;
+ void PushIntersectingProperties(CUICDMSlideHandle inSlide1, CUICDMSlideHandle inSlide2,
+ CUICDMSlideHandle inDestination) override;
+ void CopyProperties(CUICDMSlideHandle inSourceSlide, Qt3DSDMInstanceHandle inSourceInstance,
+ CUICDMSlideHandle inDestSlide, Qt3DSDMInstanceHandle inDestInstance) override;
+
+ bool IsSlide(CUICDMSlideHandle inSlide) const override;
+
+ bool HandleValid(int inHandle) const override;
+
+ void SetConsumer(TTransactionConsumerPtr inConsumer) override;
+
+ //===================================================================
+ // Signals
+ //===================================================================
+
+ virtual TSignalConnectionPtr
+ ConnectSlideCreated(const std::function<void(CUICDMSlideHandle)> &inCallback) override;
+ virtual TSignalConnectionPtr
+ ConnectBeforeSlideDeleted(const std::function<void(CUICDMSlideHandle)> &inCallback) override;
+ virtual TSignalConnectionPtr
+ ConnectSlideDeleted(const std::function<void(CUICDMSlideHandle)> &inCallback) override;
+ TSignalConnectionPtr ConnectSlideDerived(
+ const std::function<void(CUICDMSlideHandle, CUICDMSlideHandle, int)> &inCallback) override;
+ TSignalConnectionPtr ConnectInstancePropertyValueSet(
+ const std::function<void(CUICDMSlideHandle, Qt3DSDMInstanceHandle, Qt3DSDMPropertyHandle,
+ const SValue &)> &inCallback) override;
+ TSignalConnectionPtr ConnectInstancePropertyValueRemoved(
+ const std::function<void(CUICDMSlideHandle, Qt3DSDMInstanceHandle, Qt3DSDMPropertyHandle,
+ const SValue &)> &inCallback) override;
+ virtual TSignalConnectionPtr
+ ConnectSlideTimeChanged(const std::function<void(CUICDMSlideHandle)> &inCallback) override;
+
+private:
+ inline void DoForceSetInstancePropertyValue(CUICDMSlideHandle inSlide,
+ Qt3DSDMInstanceHandle inHandle,
+ Qt3DSDMPropertyHandle inProperty,
+ const SValue &inValue);
+ void InitSignaller();
+ ISlideCoreSignalProvider *GetSignalProvider();
+ ISlideCoreSignalSender *GetSignalSender();
+};
+}
+
+#endif
diff --git a/src/Authoring/QT3DSDM/Systems/Cores/SlideGraphCoreProducer.cpp b/src/Authoring/QT3DSDM/Systems/Cores/SlideGraphCoreProducer.cpp
new file mode 100644
index 00000000..52ea12b5
--- /dev/null
+++ b/src/Authoring/QT3DSDM/Systems/Cores/SlideGraphCoreProducer.cpp
@@ -0,0 +1,245 @@
+/****************************************************************************
+**
+** 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-EXCEPT$
+** 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 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** 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 "Qt3DSDMPrefix.h"
+#include "SlideGraphCoreProducer.h"
+#include "HandleSystemTransactions.h"
+#include "VectorTransactions.h"
+#include "SignalsImpl.h"
+using namespace std;
+
+namespace qt3dsdm {
+
+CUICDMSlideGraphHandle CSlideGraphCoreProducer::CreateSlideGraph(CUICDMSlideHandle inRoot)
+{
+ CUICDMSlideGraphHandle retval(m_Data->CreateSlideGraph(inRoot));
+ CREATE_HANDLE_CREATE_TRANSACTION(m_Consumer, retval, m_Data->m_Objects);
+ GetSignalSender()->SendGraphCreated(retval, inRoot);
+ return retval;
+}
+
+CUICDMSlideHandle CSlideGraphCoreProducer::GetGraphRoot(CUICDMSlideGraphHandle inGraph) const
+{
+ return m_Data->GetGraphRoot(inGraph);
+}
+
+CUICDMSlideGraphHandle CSlideGraphCoreProducer::GetSlideGraph(CUICDMSlideHandle inSlide) const
+{
+ return m_Data->GetSlideGraph(inSlide);
+}
+
+void CSlideGraphCoreProducer::GetSlideGraphs(TSlideGraphHandleList &outGraphs) const
+{
+ return m_Data->GetSlideGraphs(outGraphs);
+}
+
+struct DissocateAllInstanceTrans : public ITransaction
+{
+ std::shared_ptr<CSimpleSlideGraphCore> m_Graph;
+ CUICDMSlideGraphHandle m_Handle;
+ TSlideInstancePairList m_Instances;
+ DissocateAllInstanceTrans(const char *inFile, int inLine,
+ std::shared_ptr<CSimpleSlideGraphCore> inGraph,
+ CUICDMSlideGraphHandle inHandle)
+ : ITransaction(inFile, inLine)
+ , m_Graph(inGraph)
+ , m_Handle(inHandle)
+ {
+ inGraph->GetAssociatedInstances(m_Handle, m_Instances);
+ }
+ void Do() override
+ {
+ for (size_t idx = 0, end = m_Instances.size(); idx < end; ++idx)
+ m_Graph->DissociateInstance(m_Instances[idx].second);
+ }
+ void Undo() override
+ {
+ for (size_t idx = 0, end = m_Instances.size(); idx < end; ++idx)
+ m_Graph->AssociateInstance(m_Handle, m_Instances[idx].first, m_Instances[idx].second);
+ }
+};
+
+void CSlideGraphCoreProducer::DeleteSlideGraph(CUICDMSlideGraphHandle inHandle)
+{
+ SSlideGraph *theGraph = CSimpleSlideGraphCore::GetSlideGraphNF(inHandle, m_Data->m_Objects);
+ CUICDMSlideHandle theRootSlide(theGraph->m_Root);
+ if (m_Consumer)
+ m_Consumer->OnTransaction(
+ make_shared<DissocateAllInstanceTrans>(__FILE__, __LINE__, m_Data, inHandle));
+ CREATE_HANDLE_DELETE_TRANSACTION(m_Consumer, inHandle, m_Data->m_Objects);
+ m_Data->DeleteSlideGraph(inHandle);
+ GetSignalSender()->SendGraphDeleted(inHandle, theRootSlide);
+}
+
+struct SInstanceAssociateTrans : public ITransaction
+{
+ std::shared_ptr<CSimpleSlideGraphCore> m_Graph;
+ CUICDMSlideGraphHandle m_GraphHandle;
+ CUICDMSlideHandle m_Slide;
+ Qt3DSDMInstanceHandle m_Instance;
+ bool m_InsertOnDo;
+ SInstanceAssociateTrans(const char *inFile, int inLine,
+ std::shared_ptr<CSimpleSlideGraphCore> inGraph,
+ CUICDMSlideGraphHandle inGraphHandle, CUICDMSlideHandle inSlideHandle,
+ Qt3DSDMInstanceHandle inInstance, bool inInsertOnDo)
+ : ITransaction(inFile, inLine)
+ , m_Graph(inGraph)
+ , m_GraphHandle(inGraphHandle)
+ , m_Slide(inSlideHandle)
+ , m_Instance(inInstance)
+ , m_InsertOnDo(inInsertOnDo)
+ {
+ }
+ void Insert() { m_Graph->AssociateInstance(m_GraphHandle, m_Slide, m_Instance); }
+ void Remove() { m_Graph->DissociateInstance(m_Instance); }
+
+ void Do() override
+ {
+ if (m_InsertOnDo)
+ Insert();
+ else
+ Remove();
+ }
+ void Undo() override
+ {
+ if (m_InsertOnDo)
+ Remove();
+ else
+ Insert();
+ }
+};
+
+void CSlideGraphCoreProducer::AssociateInstance(CUICDMSlideGraphHandle inSlideGraph,
+ CUICDMSlideHandle inSlide,
+ Qt3DSDMInstanceHandle inInstance)
+{
+ m_Data->AssociateInstance(inSlideGraph, inSlide, inInstance);
+ if (m_Consumer)
+ m_Consumer->OnTransaction(make_shared<SInstanceAssociateTrans>(
+ __FILE__, __LINE__, m_Data, inSlideGraph, inSlide, inInstance, true));
+
+ GetSignalSender()->SendInstanceAssociated(inSlideGraph, inSlide, inInstance);
+}
+void CSlideGraphCoreProducer::GetAssociatedInstances(CUICDMSlideGraphHandle inSlideGraph,
+ TSlideInstancePairList &outAssociations) const
+{
+ m_Data->GetAssociatedInstances(inSlideGraph, outAssociations);
+}
+
+TGraphSlidePair CSlideGraphCoreProducer::GetAssociatedGraph(Qt3DSDMInstanceHandle inInstance) const
+{
+ return m_Data->GetAssociatedGraph(inInstance);
+}
+
+void CSlideGraphCoreProducer::DissociateInstance(Qt3DSDMInstanceHandle inInstance)
+{
+ TGraphSlidePair theAssociatedGraph(m_Data->GetAssociatedGraph(inInstance));
+
+ if (theAssociatedGraph.first.Valid()) {
+ m_Data->DissociateInstance(inInstance);
+ if (m_Consumer)
+ m_Consumer->OnTransaction(make_shared<SInstanceAssociateTrans>(
+ __FILE__, __LINE__, m_Data, theAssociatedGraph.first, theAssociatedGraph.second,
+ inInstance, false));
+ GetSignalSender()->SendInstanceDissociated(theAssociatedGraph.first,
+ theAssociatedGraph.second, inInstance);
+ }
+}
+
+void CSlideGraphCoreProducer::SetGraphActiveSlide(CUICDMSlideGraphHandle inGraph,
+ CUICDMSlideHandle inSlide)
+{
+ if (m_Consumer) {
+ CUICDMSlideHandle current = m_Data->GetGraphActiveSlide(inGraph);
+ TTransactionPtr theTransaction(CREATE_GENERIC_TRANSACTION(
+ bind(&CSimpleSlideGraphCore::SetGraphActiveSlide, m_Data, inGraph, inSlide),
+ bind(&CSimpleSlideGraphCore::SetGraphActiveSlide, m_Data, inGraph, current)));
+ m_Consumer->OnTransaction(theTransaction);
+ }
+ m_Data->SetGraphActiveSlide(inGraph, inSlide);
+ GetSignalSender()->SendGraphActiveSlide(inGraph, inSlide);
+}
+
+CUICDMSlideHandle CSlideGraphCoreProducer::GetGraphActiveSlide(CUICDMSlideGraphHandle inGraph) const
+{
+ return m_Data->GetGraphActiveSlide(inGraph);
+}
+
+bool CSlideGraphCoreProducer::HandleValid(int inHandle) const
+{
+ return m_Data->HandleValid(inHandle);
+}
+
+void CSlideGraphCoreProducer::SetConsumer(TTransactionConsumerPtr inConsumer)
+{
+ m_Consumer = inConsumer;
+}
+
+TSignalConnectionPtr CSlideGraphCoreProducer::ConnectGraphCreated(
+ const std::function<void(CUICDMSlideGraphHandle, CUICDMSlideHandle)> &inCallback)
+{
+ return GetSignalProvider()->ConnectGraphCreated(inCallback);
+}
+TSignalConnectionPtr CSlideGraphCoreProducer::ConnectGraphDeleted(
+ const std::function<void(CUICDMSlideGraphHandle, CUICDMSlideHandle)> &inCallback)
+{
+ return GetSignalProvider()->ConnectGraphDeleted(inCallback);
+}
+TSignalConnectionPtr CSlideGraphCoreProducer::ConnectInstanceAssociated(
+ const std::function<void(CUICDMSlideGraphHandle, CUICDMSlideHandle, Qt3DSDMInstanceHandle)>
+ &inCallback)
+{
+ return GetSignalProvider()->ConnectInstanceAssociated(inCallback);
+}
+TSignalConnectionPtr CSlideGraphCoreProducer::ConnectInstanceDissociated(
+ const std::function<void(CUICDMSlideGraphHandle, CUICDMSlideHandle, Qt3DSDMInstanceHandle)>
+ &inCallback)
+{
+ return GetSignalProvider()->ConnectInstanceDissociated(inCallback);
+}
+TSignalConnectionPtr CSlideGraphCoreProducer::ConnectGraphActiveSlide(
+ const std::function<void(CUICDMSlideGraphHandle, CUICDMSlideHandle)> &inCallback)
+{
+ return GetSignalProvider()->ConnectGraphActiveSlide(inCallback);
+}
+
+void CSlideGraphCoreProducer::InitSignaller()
+{
+ m_Signaller = CreateSlideGraphCoreSignaller();
+}
+
+ISlideGraphCoreSignalProvider *CSlideGraphCoreProducer::GetSignalProvider()
+{
+ return dynamic_cast<ISlideGraphCoreSignalProvider *>(m_Signaller.get());
+}
+
+ISlideGraphCoreSignalSender *CSlideGraphCoreProducer::GetSignalSender()
+{
+ return dynamic_cast<ISlideGraphCoreSignalSender *>(m_Signaller.get());
+}
+}
diff --git a/src/Authoring/QT3DSDM/Systems/Cores/SlideGraphCoreProducer.h b/src/Authoring/QT3DSDM/Systems/Cores/SlideGraphCoreProducer.h
new file mode 100644
index 00000000..2cc50436
--- /dev/null
+++ b/src/Authoring/QT3DSDM/Systems/Cores/SlideGraphCoreProducer.h
@@ -0,0 +1,98 @@
+/****************************************************************************
+**
+** 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-EXCEPT$
+** 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 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** 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$
+**
+****************************************************************************/
+#pragma once
+#ifndef SLIDEGRAPHCOREPRODUCERH
+#define SLIDEGRAPHCOREPRODUCERH
+#include "SimpleSlideGraphCore.h"
+#include "Qt3DSDMTransactions.h"
+#include "Qt3DSDMSignals.h"
+
+namespace qt3dsdm {
+class CSlideGraphCoreProducer : public ISlideGraphCore,
+ public ITransactionProducer,
+ public ISlideGraphCoreSignalProvider
+{
+ Q_DISABLE_COPY(CSlideGraphCoreProducer)
+
+ TSimpleSlideGraphCorePtr m_Data;
+ TTransactionConsumerPtr m_Consumer;
+ TSignalItemPtr m_Signaller;
+
+public:
+ CSlideGraphCoreProducer(TStringTablePtr strTable = TStringTablePtr())
+ : m_Data(new CSimpleSlideGraphCore(strTable))
+ {
+ InitSignaller();
+ }
+ TSimpleSlideGraphCorePtr GetTransactionlessSlideGraphCore() { return m_Data; }
+ TSimpleSlideGraphCorePtr GetTransactionlessSlideGraphCore() const { return m_Data; }
+
+ CUICDMSlideGraphHandle CreateSlideGraph(CUICDMSlideHandle inRoot) override;
+ CUICDMSlideHandle GetGraphRoot(CUICDMSlideGraphHandle inGraph) const override;
+ CUICDMSlideGraphHandle GetSlideGraph(CUICDMSlideHandle inSlide) const override;
+ void GetSlideGraphs(TSlideGraphHandleList &outGraphs) const override;
+ void DeleteSlideGraph(CUICDMSlideGraphHandle inHandle) override;
+
+ void AssociateInstance(CUICDMSlideGraphHandle inSlideGraph, CUICDMSlideHandle inSlide,
+ Qt3DSDMInstanceHandle inInstance) override;
+ void GetAssociatedInstances(CUICDMSlideGraphHandle inSlideGraph,
+ TSlideInstancePairList &outAssociations) const override;
+ TGraphSlidePair GetAssociatedGraph(Qt3DSDMInstanceHandle inInstance) const override;
+ void DissociateInstance(Qt3DSDMInstanceHandle inInstance) override;
+
+ void SetGraphActiveSlide(CUICDMSlideGraphHandle inGraph, CUICDMSlideHandle inSlide) override;
+ CUICDMSlideHandle GetGraphActiveSlide(CUICDMSlideGraphHandle inGraph) const override;
+
+ bool HandleValid(int inHandle) const override;
+ void SetConsumer(TTransactionConsumerPtr inConsumer) override;
+
+ //===================================================================
+ // Signals
+ //===================================================================
+ TSignalConnectionPtr ConnectGraphCreated(
+ const std::function<void(CUICDMSlideGraphHandle, CUICDMSlideHandle)> &inCallback) override;
+ TSignalConnectionPtr ConnectGraphDeleted(
+ const std::function<void(CUICDMSlideGraphHandle, CUICDMSlideHandle)> &inCallback) override;
+ TSignalConnectionPtr ConnectInstanceAssociated(
+ const std::function<void(CUICDMSlideGraphHandle, CUICDMSlideHandle, Qt3DSDMInstanceHandle)>
+ &inCallback) override;
+ TSignalConnectionPtr ConnectInstanceDissociated(
+ const std::function<void(CUICDMSlideGraphHandle, CUICDMSlideHandle, Qt3DSDMInstanceHandle)>
+ &inCallback) override;
+ TSignalConnectionPtr ConnectGraphActiveSlide(
+ const std::function<void(CUICDMSlideGraphHandle, CUICDMSlideHandle)> &inCallback) override;
+
+private:
+ void InitSignaller();
+ ISlideGraphCoreSignalProvider *GetSignalProvider();
+ ISlideGraphCoreSignalSender *GetSignalSender();
+};
+}
+
+#endif