summaryrefslogtreecommitdiffstats
path: root/src/dm
diff options
context:
space:
mode:
Diffstat (limited to 'src/dm')
-rw-r--r--src/dm/EASTL_new.cpp40
-rw-r--r--src/dm/Qt3DSDMPrefix.h81
-rw-r--r--src/dm/dm.pro58
-rw-r--r--src/dm/systems/ActionSystem.cpp131
-rw-r--r--src/dm/systems/ActionSystem.h84
-rw-r--r--src/dm/systems/HandleSystemBase.h169
-rw-r--r--src/dm/systems/HandleSystemTransactions.h88
-rw-r--r--src/dm/systems/Qt3DSDMActionCore.h99
-rw-r--r--src/dm/systems/Qt3DSDMActionInfo.h96
-rw-r--r--src/dm/systems/Qt3DSDMActionSystem.h68
-rw-r--r--src/dm/systems/Qt3DSDMAnimation.h841
-rw-r--r--src/dm/systems/Qt3DSDMComposerTypeDefinitions.cpp579
-rw-r--r--src/dm/systems/Qt3DSDMComposerTypeDefinitions.h956
-rw-r--r--src/dm/systems/Qt3DSDMDataCore.h320
-rw-r--r--src/dm/systems/Qt3DSDMDataTypes.h891
-rw-r--r--src/dm/systems/Qt3DSDMErrors.h308
-rw-r--r--src/dm/systems/Qt3DSDMGuides.cpp222
-rw-r--r--src/dm/systems/Qt3DSDMGuides.h102
-rw-r--r--src/dm/systems/Qt3DSDMHandles.h459
-rw-r--r--src/dm/systems/Qt3DSDMMetaData.cpp4170
-rw-r--r--src/dm/systems/Qt3DSDMMetaData.h400
-rw-r--r--src/dm/systems/Qt3DSDMMetaDataTypes.h350
-rw-r--r--src/dm/systems/Qt3DSDMMetaDataValue.h251
-rw-r--r--src/dm/systems/Qt3DSDMPropertyDefinition.h75
-rw-r--r--src/dm/systems/Qt3DSDMSignalStructImpl.h305
-rw-r--r--src/dm/systems/Qt3DSDMSignalStructs.h89
-rw-r--r--src/dm/systems/Qt3DSDMSignalSystem.cpp184
-rw-r--r--src/dm/systems/Qt3DSDMSignalSystem.h52
-rw-r--r--src/dm/systems/Qt3DSDMSignals.h611
-rw-r--r--src/dm/systems/Qt3DSDMSlideCore.h239
-rw-r--r--src/dm/systems/Qt3DSDMSlideGraphCore.h89
-rw-r--r--src/dm/systems/Qt3DSDMSlides.h202
-rw-r--r--src/dm/systems/Qt3DSDMStringTable.cpp85
-rw-r--r--src/dm/systems/Qt3DSDMStringTable.h71
-rw-r--r--src/dm/systems/Qt3DSDMTestOps.h61
-rw-r--r--src/dm/systems/Qt3DSDMTransactions.h244
-rw-r--r--src/dm/systems/Qt3DSDMValue.cpp178
-rw-r--r--src/dm/systems/Qt3DSDMValue.h341
-rw-r--r--src/dm/systems/Qt3DSDMWStrOps.h40
-rw-r--r--src/dm/systems/Qt3DSDMWStrOpsImpl.h761
-rw-r--r--src/dm/systems/Qt3DSDMWindowsCompatibility.h182
-rw-r--r--src/dm/systems/Qt3DSDMXML.cpp1253
-rw-r--r--src/dm/systems/Qt3DSDMXML.h506
-rw-r--r--src/dm/systems/SignalsImpl.cpp1565
-rw-r--r--src/dm/systems/SignalsImpl.h50
-rw-r--r--src/dm/systems/SlideSystem.cpp867
-rw-r--r--src/dm/systems/SlideSystem.h179
-rw-r--r--src/dm/systems/StandardExtensions.h196
-rw-r--r--src/dm/systems/StudioAnimationSystem.cpp610
-rw-r--r--src/dm/systems/StudioAnimationSystem.h134
-rw-r--r--src/dm/systems/StudioCoreSystem.cpp409
-rw-r--r--src/dm/systems/StudioCoreSystem.h94
-rw-r--r--src/dm/systems/StudioFullSystem.cpp647
-rw-r--r--src/dm/systems/StudioFullSystem.h164
-rw-r--r--src/dm/systems/StudioPropertySystem.cpp233
-rw-r--r--src/dm/systems/StudioPropertySystem.h132
-rw-r--r--src/dm/systems/VectorTransactions.h235
-rw-r--r--src/dm/systems/cores/ActionCoreProducer.cpp289
-rw-r--r--src/dm/systems/cores/ActionCoreProducer.h125
-rw-r--r--src/dm/systems/cores/AnimationCoreProducer.cpp488
-rw-r--r--src/dm/systems/cores/AnimationCoreProducer.h148
-rw-r--r--src/dm/systems/cores/DataCoreProducer.cpp457
-rw-r--r--src/dm/systems/cores/DataCoreProducer.h175
-rw-r--r--src/dm/systems/cores/SimpleActionCore.cpp240
-rw-r--r--src/dm/systems/cores/SimpleActionCore.h165
-rw-r--r--src/dm/systems/cores/SimpleAnimationCore.cpp618
-rw-r--r--src/dm/systems/cores/SimpleAnimationCore.h230
-rw-r--r--src/dm/systems/cores/SimpleDataCore.cpp574
-rw-r--r--src/dm/systems/cores/SimpleDataCore.h373
-rw-r--r--src/dm/systems/cores/SimpleSlideCore.cpp420
-rw-r--r--src/dm/systems/cores/SimpleSlideCore.h408
-rw-r--r--src/dm/systems/cores/SimpleSlideGraphCore.cpp169
-rw-r--r--src/dm/systems/cores/SimpleSlideGraphCore.h134
-rw-r--r--src/dm/systems/cores/SlideCoreProducer.cpp562
-rw-r--r--src/dm/systems/cores/SlideCoreProducer.h190
-rw-r--r--src/dm/systems/cores/SlideGraphCoreProducer.cpp245
-rw-r--r--src/dm/systems/cores/SlideGraphCoreProducer.h98
77 files changed, 27954 insertions, 0 deletions
diff --git a/src/dm/EASTL_new.cpp b/src/dm/EASTL_new.cpp
new file mode 100644
index 0000000..1ca308e
--- /dev/null
+++ b/src/dm/EASTL_new.cpp
@@ -0,0 +1,40 @@
+/****************************************************************************
+**
+** 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 "EASTL/allocator.h"
+
+void *operator new[](size_t size, const char *, int, unsigned, const char *, int)
+{
+ return malloc(size);
+}
+
+void *operator new[](size_t size, size_t, size_t, const char *, int, unsigned, const char *, int)
+{
+ return malloc(size);
+}
diff --git a/src/dm/Qt3DSDMPrefix.h b/src/dm/Qt3DSDMPrefix.h
new file mode 100644
index 0000000..4164d64
--- /dev/null
+++ b/src/dm/Qt3DSDMPrefix.h
@@ -0,0 +1,81 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 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$
+**
+****************************************************************************/
+
+#ifdef __cplusplus
+#pragma once
+
+#ifndef _WIN32_WINNT // Allow use of features specific to Windows XP or later.
+#define _WIN32_WINNT \
+ 0x0501 // Change this to the appropriate value to target other versions of Windows.
+#endif
+
+#define WIN32_LEAN_AND_MEAN // Exclude rarely-used stuff from Windows headers
+
+// TODO: reference additional headers your program requires here
+#if defined(WIN32) && defined(MSVC)
+#pragma warning(push)
+#pragma warning(disable : 4100)
+#pragma warning(disable : 4512)
+#pragma warning(disable : 4702)
+#pragma warning(disable : 4996)
+#endif
+
+// std includes
+#include <map>
+#include <vector>
+#include <string>
+#include <exception>
+#include <set>
+#include <iostream>
+#include <sstream>
+#include <fstream>
+#include <memory>
+#include <functional>
+
+// Project includes
+#include "StandardExtensions.h"
+
+namespace qt3dsdm {
+using std::ref;
+using std::get;
+using std::bind;
+using std::tuple;
+using std::static_pointer_cast;
+using std::make_pair;
+using std::equal_to;
+using std::vector;
+using std::make_tuple;
+using std::function;
+using std::shared_ptr;
+using std::make_shared;
+}
+#if defined(WIN32) && defined(MSVC)
+#pragma warning(pop)
+#endif
+#endif
diff --git a/src/dm/dm.pro b/src/dm/dm.pro
new file mode 100644
index 0000000..2e57f30
--- /dev/null
+++ b/src/dm/dm.pro
@@ -0,0 +1,58 @@
+TEMPLATE = lib
+TARGET = QT3DSDM
+CONFIG += staticlib
+include(../commoninclude.pri)
+
+DEFINES += QT3DS_AUTHORING _AFXDLL PCRE_STATIC _UNICODE
+
+linux {
+ DEFINES += QT3DSDM_META_DATA_NO_SIGNALS
+}
+
+INCLUDEPATH += \
+ \
+ systems \
+ systems/cores \
+ ../system \
+ ../foundation \
+ ../runtimerender \
+ ../datamodel \
+ ../render \
+ ../3rdparty/EASTL/UnknownVersion/include \
+ ../3rdparty/color \
+
+PRECOMPILED_HEADER = Qt3DSDMPrefix.h
+
+SOURCES += \
+ EASTL_new.cpp \
+ systems/ActionSystem.cpp \
+ systems/SignalsImpl.cpp \
+ systems/SlideSystem.cpp \
+ systems/StudioAnimationSystem.cpp \
+ systems/StudioCoreSystem.cpp \
+ systems/StudioFullSystem.cpp \
+ systems/StudioPropertySystem.cpp \
+ systems/Qt3DSDMComposerTypeDefinitions.cpp \
+ systems/Qt3DSDMGuides.cpp \
+ systems/Qt3DSDMMetaData.cpp \
+ systems/Qt3DSDMSignalSystem.cpp \
+ systems/Qt3DSDMStringTable.cpp \
+ systems/Qt3DSDMValue.cpp \
+ systems/Qt3DSDMXML.cpp \
+ systems/cores/ActionCoreProducer.cpp \
+ systems/cores/AnimationCoreProducer.cpp \
+ systems/cores/DataCoreProducer.cpp \
+ systems/cores/SimpleActionCore.cpp \
+ systems/cores/SimpleAnimationCore.cpp \
+ systems/cores/SimpleDataCore.cpp \
+ systems/cores/SimpleSlideCore.cpp \
+ systems/cores/SimpleSlideGraphCore.cpp \
+ systems/cores/SlideCoreProducer.cpp \
+ systems/cores/SlideGraphCoreProducer.cpp \
+
+HEADERS += \
+ systems/Qt3DSDMDataTypes.h \
+ systems/Qt3DSDMMetaDataTypes.h \
+ systems/Qt3DSDMMetaDataValue.h \
+ systems/Qt3DSDMMetaData.h \
+ systems/Qt3DSDMWStrOpsImpl.h
diff --git a/src/dm/systems/ActionSystem.cpp b/src/dm/systems/ActionSystem.cpp
new file mode 100644
index 0000000..fbd2593
--- /dev/null
+++ b/src/dm/systems/ActionSystem.cpp
@@ -0,0 +1,131 @@
+/****************************************************************************
+**
+** 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 "ActionSystem.h"
+
+using namespace std;
+
+namespace qt3dsdm {
+
+CActionSystem::CActionSystem(TDataCorePtr inDataCore, TSlideCorePtr inSlideCore,
+ TSlideGraphCorePtr inSlideGraphCore, TActionCorePtr inActionCore,
+ TSlideSystemPtr inSlideSystem, Qt3DSDMInstanceHandle inActionInstance,
+ Qt3DSDMPropertyHandle inActionEyeball)
+ : m_DataCore(inDataCore)
+ , m_SlideCore(inSlideCore)
+ , m_SlideGraphCore(inSlideGraphCore)
+ , m_ActionCore(inActionCore)
+ , m_SlideSystem(inSlideSystem)
+ , m_ActionInstance(inActionInstance)
+ , m_ActionEyeball(inActionEyeball)
+{
+ m_Signaller = CreateActionSystemSignaller();
+}
+
+Qt3DSDMActionHandle CActionSystem::CreateAction(Qt3DSDMSlideHandle inSlide,
+ Qt3DSDMInstanceHandle inOwner,
+ SLong4 inTriggerTargetObjects)
+{
+ Q_ASSERT(inSlide.Valid() && inOwner.Valid());
+
+ // Create Action instance handle that derives from Action instance
+ Qt3DSDMInstanceHandle theActionInstance = m_DataCore->CreateInstance();
+ m_DataCore->DeriveInstance(theActionInstance, m_ActionInstance);
+
+ // Associate Action instance handle with Slide
+ m_SlideSystem->AssociateInstanceWithSlide(inSlide, theActionInstance);
+
+ // Unlink the eyeball property because Action can be eyeballed-on/off per-slide
+ m_SlideSystem->UnlinkProperty(theActionInstance, m_ActionEyeball);
+
+ // Create the Action handle
+ Qt3DSDMActionHandle retval =
+ m_ActionCore->CreateAction(theActionInstance, inSlide, inOwner, inTriggerTargetObjects);
+
+ GetSignalSender()->SendActionCreated(retval, inSlide, inOwner);
+ return retval;
+}
+
+void CActionSystem::DeleteAction(Qt3DSDMActionHandle inAction)
+{
+ Qt3DSDMInstanceHandle theActionInstance;
+ SActionInfo theActionInfo = m_ActionCore->GetActionInfo(inAction);
+ m_ActionCore->DeleteAction(inAction, theActionInstance);
+ m_DataCore->DeleteInstance(theActionInstance);
+ GetSignalSender()->SendActionDeleted(inAction, theActionInfo.m_Slide, theActionInfo.m_Owner);
+}
+
+void CActionSystem::GetActions(Qt3DSDMSlideHandle inSlide, Qt3DSDMInstanceHandle inOwner,
+ TActionHandleList &outActions) const
+{
+ // Get all actions that exist in inSlide
+ m_ActionCore->GetActions(inSlide, inOwner, outActions);
+
+ // if inSlide is not master, get all actions that exist in master slide
+ Qt3DSDMSlideHandle theMaster = m_SlideSystem->GetMasterSlide(inSlide);
+ if (theMaster != inSlide) {
+ TActionHandleList theMasterActions;
+ m_ActionCore->GetActions(theMaster, inOwner, theMasterActions);
+ outActions.insert(outActions.end(), theMasterActions.begin(), theMasterActions.end());
+ sort(outActions.begin(), outActions.end());
+ }
+}
+
+bool CActionSystem::GetActionEyeballValue(Qt3DSDMSlideHandle inActiveSlide,
+ Qt3DSDMActionHandle inAction) const
+{
+ SValue theValue;
+ Qt3DSDMInstanceHandle theInstance = m_ActionCore->GetActionInstance(inAction);
+ // Get the eyeball property value from SlideCore. There is no animation on eyeball so we can
+ // query SlideCore directly.
+ m_SlideCore->GetInstancePropertyValue(inActiveSlide, theInstance, m_ActionEyeball, theValue);
+ if (m_SlideCore->IsSlide(inActiveSlide))
+ return qt3dsdm::get<bool>(theValue);
+ return false;
+}
+
+void CActionSystem::SetActionEyeballValue(Qt3DSDMSlideHandle inActiveSlide,
+ Qt3DSDMActionHandle inAction, bool inValue)
+{
+ Qt3DSDMInstanceHandle theInstance = m_ActionCore->GetActionInstance(inAction);
+ // Set the eyeball property value to SlideCore.
+ m_SlideCore->ForceSetInstancePropertyValue(inActiveSlide, theInstance, m_ActionEyeball,
+ inValue);
+}
+
+IActionSystemSignalProvider *CActionSystem::GetSignalProvider()
+{
+ return dynamic_cast<IActionSystemSignalProvider *>(m_Signaller.get());
+}
+
+IActionSystemSignalSender *CActionSystem::GetSignalSender()
+{
+ return dynamic_cast<IActionSystemSignalSender *>(m_Signaller.get());
+}
+}
diff --git a/src/dm/systems/ActionSystem.h b/src/dm/systems/ActionSystem.h
new file mode 100644
index 0000000..fea9894
--- /dev/null
+++ b/src/dm/systems/ActionSystem.h
@@ -0,0 +1,84 @@
+/****************************************************************************
+**
+** 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 ACTIONSYSTEMH
+#define ACTIONSYSTEMH
+#include "Qt3DSDMActionSystem.h"
+#include "Qt3DSDMActionCore.h"
+#include "Qt3DSDMDataCore.h"
+#include "Qt3DSDMSlideCore.h"
+#include "Qt3DSDMSlideGraphCore.h"
+#include "Qt3DSDMSlides.h"
+#include "Qt3DSDMTransactions.h"
+#include "SignalsImpl.h"
+
+namespace qt3dsdm {
+
+class CActionSystem : public IActionSystem
+{
+ TDataCorePtr m_DataCore;
+ TSlideCorePtr m_SlideCore;
+ TSlideGraphCorePtr m_SlideGraphCore;
+ TActionCorePtr m_ActionCore;
+
+ TSlideSystemPtr m_SlideSystem;
+
+ Qt3DSDMInstanceHandle m_ActionInstance;
+ Qt3DSDMPropertyHandle m_ActionEyeball;
+
+ std::shared_ptr<ISignalItem> m_Signaller;
+
+public:
+ CActionSystem(TDataCorePtr inDataCore, TSlideCorePtr inSlideCore,
+ TSlideGraphCorePtr inSlideGraphCore, TActionCorePtr inActionCore,
+ TSlideSystemPtr inSlideSystem, Qt3DSDMInstanceHandle inActionInstance,
+ Qt3DSDMPropertyHandle inActionEyeball);
+
+ Qt3DSDMActionHandle CreateAction(Qt3DSDMSlideHandle inSlide, Qt3DSDMInstanceHandle inOwner,
+ SLong4 inTriggerTargetObjects) override;
+ void DeleteAction(Qt3DSDMActionHandle inAction) override;
+ void GetActions(Qt3DSDMSlideHandle inSlide, Qt3DSDMInstanceHandle inOwner,
+ TActionHandleList &outActions) const override;
+
+ bool GetActionEyeballValue(Qt3DSDMSlideHandle inActiveSlide,
+ Qt3DSDMActionHandle inAction) const override;
+ void SetActionEyeballValue(Qt3DSDMSlideHandle inActiveSlide, Qt3DSDMActionHandle inAction,
+ bool inValue) override;
+
+ virtual IActionSystemSignalProvider *GetSignalProvider();
+
+private:
+ virtual IActionSystemSignalSender *GetSignalSender();
+
+ CActionSystem(const CActionSystem&) = delete;
+ CActionSystem& operator=(const CActionSystem&) = delete;
+};
+}
+
+#endif
diff --git a/src/dm/systems/HandleSystemBase.h b/src/dm/systems/HandleSystemBase.h
new file mode 100644
index 0000000..cb8e0f6
--- /dev/null
+++ b/src/dm/systems/HandleSystemBase.h
@@ -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$
+**
+****************************************************************************/
+#pragma once
+#ifndef HANDLESYSTEMIMPLH
+#define HANDLESYSTEMIMPLH
+
+#include <unordered_map>
+
+namespace qt3dsdm {
+
+class CHandleObject
+{
+public:
+ // Type of CHandleObject
+ // Each subclass needs to specify what type it is
+ // This is used to avoid dynamic_cast (RTTI) which is expensive
+ enum EHandleObjectType {
+ EHandleObjectTypeUnknown = 0,
+ EHandleObjectTypeCDataModelInstance,
+ EHandleObjectTypeCDataModelPropertyDefinitionObject,
+ EHandleObjectTypeSAnimationTrack,
+ EHandleObjectTypeSKeyframe,
+ EHandleObjectTypeSSlide,
+ EHandleObjectTypeSSlideGraph,
+ EHandleObjectTypeAction,
+ EHandleObjectTypeActionHandlerArgument,
+ EHandleObjectTypeCustomProperty,
+ EHandleObjectTypeEvent,
+ EHandleObjectTypeCustomHandler,
+ EHandleObjectTypeHandlerParam,
+ EHandleObjectTypeEnd,
+ };
+
+ CHandleObject(int inHandle = 0)
+ : m_Handle(inHandle)
+ {
+ }
+ virtual ~CHandleObject() {}
+
+ virtual EHandleObjectType GetType() = 0;
+
+ int m_Handle;
+
+private: //noncopyable
+ CHandleObject(const CHandleObject&) = delete;
+ CHandleObject& operator=(const CHandleObject&) = delete;
+
+};
+
+typedef std::shared_ptr<CHandleObject> THandleObjectPtr;
+
+// Note that maps don't need to copy their objects.
+typedef std::unordered_map<int, THandleObjectPtr> THandleObjectMap;
+typedef std::pair<int, THandleObjectPtr> THandleObjectPair;
+
+class IHandleBase
+{
+public:
+ /**
+ * Check whether a given handle exists
+ */
+ virtual bool HandleValid(int inHandle) const = 0;
+};
+
+struct CHandleBase : public IHandleBase
+{
+ THandleObjectMap m_Objects;
+ int m_NextId;
+
+ CHandleBase()
+ : m_NextId(1)
+ {
+ }
+ CHandleBase(const CHandleBase &inOther)
+ : m_Objects(inOther.m_Objects)
+ , m_NextId(inOther.m_NextId)
+ {
+ }
+
+ CHandleBase &operator=(const CHandleBase &inOther)
+ {
+ m_Objects = inOther.m_Objects;
+ m_NextId = inOther.m_NextId;
+ return *this;
+ }
+
+ // IHandleBase
+ bool HandleValid(int inHandle) const override
+ {
+ return m_Objects.find(inHandle) != m_Objects.end();
+ }
+
+ template <typename T>
+ static inline bool HandleObjectValid(int inHandle, const THandleObjectMap &inMap)
+ {
+ THandleObjectMap::const_iterator theIter = inMap.find(inHandle);
+ if (theIter != inMap.end()) {
+ if (theIter->second->GetType() == T::s_Type)
+ return true;
+ }
+ return false;
+ }
+
+ template <typename T>
+ static inline const T *GetHandleObject(int inHandle, const THandleObjectMap &inMap)
+ {
+ THandleObjectMap::const_iterator theIter = inMap.find(inHandle);
+ if (theIter != inMap.end()) {
+ if (theIter->second->GetType() == T::s_Type)
+ return static_cast<const T *>(theIter->second.get());
+ }
+ return NULL;
+ }
+
+ template <typename ObjectType, typename HandleType>
+ static inline void MaybeAddObject(const std::pair<int, THandleObjectPtr> &inItem,
+ std::vector<HandleType> &outHandles)
+ {
+ if (inItem.second->GetType() == ObjectType::s_Type)
+ outHandles.push_back(HandleType(inItem.first));
+ }
+
+ static void EraseHandle(int inHandle, THandleObjectMap &inObjects)
+ {
+ THandleObjectMap::iterator theFind = inObjects.find(inHandle);
+ if (theFind != inObjects.end())
+ inObjects.erase(theFind);
+ }
+
+ // Return the next unused id. There are no guarantees whether positive or negative; what this
+ // will
+ // guarantee is that it isn't currently used in the object map and it is non-zero.
+ int GetNextId()
+ {
+ do {
+ ++m_NextId;
+ } while (m_Objects.find(m_NextId) != m_Objects.end());
+ return m_NextId;
+ }
+};
+}
+
+#endif
diff --git a/src/dm/systems/HandleSystemTransactions.h b/src/dm/systems/HandleSystemTransactions.h
new file mode 100644
index 0000000..9d77884
--- /dev/null
+++ b/src/dm/systems/HandleSystemTransactions.h
@@ -0,0 +1,88 @@
+/****************************************************************************
+**
+** 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 HANDLESYSTEMTRANSACTIONSH
+#define HANDLESYSTEMTRANSACTIONSH
+#include "HandleSystemBase.h"
+#include "Qt3DSDMTransactions.h"
+
+namespace qt3dsdm {
+inline void InsertItemInMap(THandleObjectMap &inObjects,
+ const std::pair<int, THandleObjectPtr> &inItem)
+{
+ inObjects.insert(inItem);
+}
+inline void HandleCreateTransaction(const char *inFile, int inLine, int inHandle,
+ THandleObjectMap &inObjects,
+ TTransactionConsumerPtr &inConsumer)
+{
+ std::pair<int, THandleObjectPtr> theEntry = *inObjects.find(inHandle);
+ std::function<void()> doOp(std::bind(InsertItemInMap, std::ref(inObjects), theEntry));
+ std::function<void()> undoOp(
+ std::bind(CHandleBase::EraseHandle, inHandle, std::ref(inObjects)));
+ TTransactionPtr theTransaction(DoCreateGenericTransaction(inFile, inLine, doOp, undoOp));
+ inConsumer->OnTransaction(theTransaction);
+}
+
+inline void HandleDeleteTransaction(const char *inFile, int inLine, int inHandle,
+ THandleObjectMap &inObjects,
+ TTransactionConsumerPtr &inConsumer)
+{
+ using namespace std;
+ pair<int, THandleObjectPtr> theEntry = *inObjects.find(inHandle);
+ TTransactionPtr theTransaction(DoCreateGenericTransaction(
+ inFile, inLine, std::bind(CHandleBase::EraseHandle, inHandle, std::ref(inObjects)),
+ std::bind(InsertItemInMap, std::ref(inObjects), theEntry)));
+ inConsumer->OnTransaction(theTransaction);
+}
+
+inline void DoCreateHandleCreateTransaction(const char *inFile, int inLine,
+ TTransactionConsumerPtr inConsumer, int inHandle,
+ THandleObjectMap &inObjects)
+{
+ RunWithConsumer(inConsumer, std::bind(HandleCreateTransaction, inFile, inLine, inHandle,
+ std::ref(inObjects), std::placeholders::_1));
+}
+
+#define CREATE_HANDLE_CREATE_TRANSACTION(inConsumer, inHandle, inObjects) \
+ DoCreateHandleCreateTransaction(__FILE__, __LINE__, inConsumer, inHandle, inObjects);
+
+inline void DoCreateHandleDeleteTransaction(const char *inFile, int inLine,
+ TTransactionConsumerPtr inConsumer, int inHandle,
+ THandleObjectMap &inObjects)
+{
+ RunWithConsumer(inConsumer, std::bind(HandleDeleteTransaction, inFile, inLine, inHandle,
+ std::ref(inObjects), std::placeholders::_1));
+}
+
+#define CREATE_HANDLE_DELETE_TRANSACTION(inConsumer, inHandle, inObjects) \
+ DoCreateHandleDeleteTransaction(__FILE__, __LINE__, inConsumer, inHandle, inObjects);
+}
+
+#endif
diff --git a/src/dm/systems/Qt3DSDMActionCore.h b/src/dm/systems/Qt3DSDMActionCore.h
new file mode 100644
index 0000000..a920146
--- /dev/null
+++ b/src/dm/systems/Qt3DSDMActionCore.h
@@ -0,0 +1,99 @@
+/****************************************************************************
+**
+** 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 QT3DSDM_ACTION_CORE_H
+#define QT3DSDM_ACTION_CORE_H
+
+#include "Qt3DSDMHandles.h"
+#include "HandleSystemBase.h"
+#include "Qt3DSDMActionInfo.h"
+
+namespace qt3dsdm {
+const long REFERENCED_AS_OWNER = 0x01;
+const long REFERENCED_AS_TRIGGER = 0x02;
+const long REFERENCED_AS_TARGET = 0x04;
+class IStringTable;
+
+/**
+ * ActionCore
+ */
+class IActionCore : public IHandleBase
+{
+public:
+ virtual ~IActionCore() {}
+
+ virtual TStringTablePtr GetStringTablePtr() const = 0;
+ virtual IStringTable &GetStringTable() const = 0;
+ // Action
+ virtual Qt3DSDMActionHandle CreateAction(Qt3DSDMInstanceHandle inInstance,
+ Qt3DSDMSlideHandle inSlide, Qt3DSDMInstanceHandle inOwner,
+ SLong4 inTriggerTargetObjects) = 0;
+ virtual void DeleteAction(Qt3DSDMActionHandle inAction, Qt3DSDMInstanceHandle &outInstance) = 0;
+ virtual const SActionInfo &GetActionInfo(Qt3DSDMActionHandle inAction) const = 0;
+ virtual void GetActions(Qt3DSDMSlideHandle inSlide, Qt3DSDMInstanceHandle inOwner,
+ TActionHandleList &outActions) const = 0;
+ virtual void GetActions(Qt3DSDMSlideHandle inSlide, TActionHandleList &outActions) const = 0;
+ virtual void GetActions(Qt3DSDMInstanceHandle inOwner, TActionHandleList &outActions) const = 0;
+ virtual void GetActions(TActionHandleList &outActions) const = 0;
+
+ // Return the instance that was allocated for this action.
+ virtual Qt3DSDMInstanceHandle GetActionInstance(Qt3DSDMActionHandle inAction) const = 0;
+ // Reverse lookup into the action system so you can match actions to instances.
+ virtual Qt3DSDMActionHandle GetActionByInstance(Qt3DSDMInstanceHandle inActionInstance) const = 0;
+
+ // Action Properties
+ virtual void SetTriggerObject(Qt3DSDMActionHandle inAction,
+ const SObjectRefType &inTriggerObject) = 0;
+ virtual void SetTargetObject(Qt3DSDMActionHandle inAction,
+ const SObjectRefType &inTargetObject) = 0;
+ virtual void SetEvent(Qt3DSDMActionHandle inAction, const wstring &inEventName) = 0;
+ virtual void SetHandler(Qt3DSDMActionHandle inAction, const wstring &inHandlerName) = 0;
+
+ // Handler Argument
+ virtual Qt3DSDMHandlerArgHandle AddHandlerArgument(Qt3DSDMActionHandle inAction,
+ const TCharStr &inName,
+ HandlerArgumentType::Value inArgType,
+ DataModelDataType::Value inValueType) = 0;
+ virtual void RemoveHandlerArgument(Qt3DSDMHandlerArgHandle inHandlerArgument) = 0;
+ virtual const SHandlerArgumentInfo &
+ GetHandlerArgumentInfo(Qt3DSDMHandlerArgHandle inHandlerArgument) const = 0;
+ virtual void GetHandlerArguments(Qt3DSDMActionHandle inAction,
+ THandlerArgHandleList &outHandlerArguments) const = 0;
+
+ // Handler Argument Properties
+ virtual void GetHandlerArgumentValue(Qt3DSDMHandlerArgHandle inHandlerArgument,
+ SValue &outValue) const = 0;
+ virtual void SetHandlerArgumentValue(Qt3DSDMHandlerArgHandle inHandlerArgument,
+ const SValue &inValue) = 0;
+};
+
+typedef std::shared_ptr<IActionCore> TActionCorePtr;
+}
+
+#endif
diff --git a/src/dm/systems/Qt3DSDMActionInfo.h b/src/dm/systems/Qt3DSDMActionInfo.h
new file mode 100644
index 0000000..40fd964
--- /dev/null
+++ b/src/dm/systems/Qt3DSDMActionInfo.h
@@ -0,0 +1,96 @@
+/****************************************************************************
+**
+** 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 QT3DSDM_ACTION_INFO_H
+#define QT3DSDM_ACTION_INFO_H
+
+#include "Qt3DSDMDataTypes.h"
+#include "Qt3DSDMMetaDataTypes.h"
+
+namespace qt3dsdm {
+using std::wstring;
+struct SActionInfo
+{
+ // InstanceHandle corresponding to this action (to store other properties not listed here)
+ Qt3DSDMInstanceHandle m_Instance;
+
+ // Where the action is added to
+ Qt3DSDMSlideHandle m_Slide; // the slide that the action is added to
+ Qt3DSDMInstanceHandle
+ m_Owner; // the object that the action is added to (the owner of the action)
+
+ // Trigger object
+ SObjectRefType m_TriggerObject; // trigger object
+ wstring m_Event; // the list of applicable events is based on object type and stored, by type,
+ // in metadata
+
+ // Target object
+ SObjectRefType m_TargetObject; // target object
+ wstring m_Handler; // the list of applicable action handlers is loaded from metadata xml file
+ // and based on object type
+ THandlerArgHandleList m_HandlerArgs; // the list of applicable action arguments is dependent on
+ // the handler and loaded from the metadata xml file.
+
+ SActionInfo() {}
+
+ SActionInfo(Qt3DSDMInstanceHandle inInstance, Qt3DSDMSlideHandle inSlide,
+ Qt3DSDMInstanceHandle inOwner)
+ : m_Instance(inInstance)
+ , m_Slide(inSlide)
+ , m_Owner(inOwner)
+ {
+ }
+};
+
+struct SHandlerArgumentInfo
+{
+ Qt3DSDMActionHandle m_Action; // Action that owns this Action Argument
+ TCharStr m_Name; // Name of the Action Argument
+ HandlerArgumentType::Value m_ArgType; // m_ArgType will override m_ValueType
+ DataModelDataType::Value m_ValueType; // m_ValueType is ignored if ArgType is specified
+ SValue m_Value; // Value of the Action Argument
+
+ SHandlerArgumentInfo()
+ : m_ArgType(HandlerArgumentType::None)
+ , m_ValueType(DataModelDataType::None)
+ {
+ }
+
+ SHandlerArgumentInfo(Qt3DSDMActionHandle inAction, const TCharStr &inName,
+ HandlerArgumentType::Value inArgType, DataModelDataType::Value inValueType)
+ : m_Action(inAction)
+ , m_Name(inName)
+ , m_ArgType(inArgType)
+ , m_ValueType(inValueType)
+ {
+ }
+};
+}
+
+#endif
diff --git a/src/dm/systems/Qt3DSDMActionSystem.h b/src/dm/systems/Qt3DSDMActionSystem.h
new file mode 100644
index 0000000..8713729
--- /dev/null
+++ b/src/dm/systems/Qt3DSDMActionSystem.h
@@ -0,0 +1,68 @@
+/****************************************************************************
+**
+** 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 QT3DSDM_ACTION_SYSTEM_H
+#define QT3DSDM_ACTION_SYSTEM_H
+#include "Qt3DSDMHandles.h"
+#include "Qt3DSDMActionCore.h"
+
+namespace qt3dsdm {
+/**
+ * ActionSystem acts as a wrapper or helper around ActionCore. ActionSystem will call
+ * ActionCore and perform other necessary setups. It also has the knowledge of other
+ * system or core so there are some synchronization being done here.
+ *
+ * When in doubts which one to use (ActionSystem or ActionCore), always use ActionSystem
+ */
+class IActionSystem
+{
+public:
+ virtual ~IActionSystem() {}
+
+ // CreateAction will create Action's InstanceHandle and Action's ActionHandle and do some
+ // necessary setup
+ virtual Qt3DSDMActionHandle CreateAction(Qt3DSDMSlideHandle inSlide, Qt3DSDMInstanceHandle inOwner,
+ SLong4 inTriggerTargetObjects) = 0;
+ // DeleteAction will delete both Action's ActionHandle and Action's InstanceHandle
+ virtual void DeleteAction(Qt3DSDMActionHandle inAction) = 0;
+ // Return all actions that belong to a certain instance in a certain slide + the master slide
+ virtual void GetActions(Qt3DSDMSlideHandle inSlide, Qt3DSDMInstanceHandle inOwner,
+ TActionHandleList &outActions) const = 0;
+
+ // Get/set action eyeball property value
+ virtual bool GetActionEyeballValue(Qt3DSDMSlideHandle inActiveSlide,
+ Qt3DSDMActionHandle inAction) const = 0;
+ virtual void SetActionEyeballValue(Qt3DSDMSlideHandle inActiveSlide, Qt3DSDMActionHandle inAction,
+ bool inValue) = 0;
+};
+
+typedef std::shared_ptr<IActionSystem> TActionSystemPtr;
+}
+
+#endif
diff --git a/src/dm/systems/Qt3DSDMAnimation.h b/src/dm/systems/Qt3DSDMAnimation.h
new file mode 100644
index 0000000..457b042
--- /dev/null
+++ b/src/dm/systems/Qt3DSDMAnimation.h
@@ -0,0 +1,841 @@
+/****************************************************************************
+**
+** 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$
+**
+****************************************************************************/
+#ifndef QT3DSDM_ANIMATION_H
+#define QT3DSDM_ANIMATION_H
+
+#include "Qt3DSDMHandles.h"
+#include "Qt3DSDMDataTypes.h"
+#include "Qt3DSDMValue.h"
+
+namespace qt3dsdm {
+
+struct SLinearKeyframe
+{
+ float m_KeyframeSeconds;
+ float m_KeyframeValue;
+};
+
+struct SBezierKeyframe : public SLinearKeyframe
+{
+ float m_InTangentTime; // time
+ float m_InTangentValue; // value offset
+ float m_OutTangentTime; // time offset in seconds
+ float m_OutTangentValue; // value offset
+};
+
+typedef std::vector<SBezierKeyframe> TBezierKeyframeList;
+
+/**
+ * Ease in/out are parameters that affect the bezier evaluation.
+ * Ease in/out at 100 means that the control values are at the end points thus creating
+ * a gradual deceleration. Ease in/out at 0 means that interpolation is linear, the
+ * control points are at 1/3 and 2/3's the distance to the next value.
+ * Ease in/out go from 0.f to 100.0f
+ */
+struct SEaseInEaseOutKeyframe : public SLinearKeyframe
+{
+ float m_EaseIn;
+ float m_EaseOut;
+};
+
+} // namespace qt3dsdm
+
+namespace qt3ds {
+namespace foundation {
+ // Disable calling destructor of these pod types
+ template <>
+ struct DestructTraits<qt3dsdm::SEaseInEaseOutKeyframe>
+ {
+ void destruct(qt3dsdm::SEaseInEaseOutKeyframe &) {}
+ };
+ template <>
+ struct DestructTraits<qt3dsdm::SBezierKeyframe>
+ {
+ void destruct(qt3dsdm::SBezierKeyframe &) {}
+ };
+ template <>
+ struct DestructTraits<qt3dsdm::SLinearKeyframe>
+ {
+ void destruct(qt3dsdm::SLinearKeyframe &) {}
+ };
+}
+}
+
+namespace qt3dsdm {
+
+enum EAnimationType {
+ EAnimationTypeNone = 0,
+ EAnimationTypeLinear,
+ EAnimationTypeBezier,
+ EAnimationTypeEaseInOut,
+};
+
+template <typename TDataType>
+struct SAnimationTypeTraits
+{
+};
+
+template <>
+struct SAnimationTypeTraits<SBezierKeyframe>
+{
+ EAnimationType getType() { return EAnimationTypeBezier; }
+};
+template <>
+struct SAnimationTypeTraits<SLinearKeyframe>
+{
+ EAnimationType getType() { return EAnimationTypeLinear; }
+};
+template <>
+struct SAnimationTypeTraits<SEaseInEaseOutKeyframe>
+{
+ EAnimationType getType() { return EAnimationTypeEaseInOut; }
+};
+
+struct SKeyframeUnionTraits
+{
+ typedef EAnimationType TIdType;
+ enum {
+ TBufferSize = sizeof(SBezierKeyframe),
+ };
+ static TIdType getNoDataId() { return EAnimationTypeNone; }
+ template <typename TDataType>
+ static TIdType getType()
+ {
+ return SAnimationTypeTraits<TDataType>().getType();
+ }
+
+ template <typename TRetType, typename TVisitorType>
+ static TRetType visit(char *inData, TIdType inType, TVisitorType inVisitor)
+ {
+ switch (inType) {
+ case EAnimationTypeBezier:
+ return inVisitor(*reinterpret_cast<SBezierKeyframe *>(inData));
+ case EAnimationTypeLinear:
+ return inVisitor(*reinterpret_cast<SLinearKeyframe *>(inData));
+ case EAnimationTypeEaseInOut:
+ return inVisitor(*reinterpret_cast<SEaseInEaseOutKeyframe *>(inData));
+ default:
+ QT3DS_ASSERT(false);
+ case EAnimationTypeNone:
+ return inVisitor();
+ }
+ }
+
+ template <typename TRetType, typename TVisitorType>
+ static TRetType visit(const char *inData, TIdType inType, TVisitorType inVisitor)
+ {
+ switch (inType) {
+ case EAnimationTypeBezier:
+ return inVisitor(*reinterpret_cast<const SBezierKeyframe *>(inData));
+ case EAnimationTypeLinear:
+ return inVisitor(*reinterpret_cast<const SLinearKeyframe *>(inData));
+ case EAnimationTypeEaseInOut:
+ return inVisitor(*reinterpret_cast<const SEaseInEaseOutKeyframe *>(inData));
+ default:
+ QT3DS_ASSERT(false);
+ case EAnimationTypeNone:
+ return inVisitor();
+ }
+ }
+};
+
+typedef qt3ds::foundation::
+ DiscriminatedUnion<qt3ds::foundation::
+ DiscriminatedUnionGenericBase<SKeyframeUnionTraits,
+ SKeyframeUnionTraits::TBufferSize>,
+ SKeyframeUnionTraits::TBufferSize>
+ TKeyframe;
+
+template <>
+struct Qt3DSDMGetter<TKeyframe>
+{
+ template <typename TRetType>
+ TRetType doGet(const TKeyframe &inValue)
+ {
+ return inValue.getData<TRetType>();
+ }
+};
+
+typedef std::vector<TKeyframe> TKeyframeList;
+
+struct SAnimationInfo
+{
+ Qt3DSDMSlideHandle m_Slide;
+ Qt3DSDMInstanceHandle m_Instance;
+ Qt3DSDMPropertyHandle m_Property;
+ size_t m_Index;
+ EAnimationType m_AnimationType;
+ // Use the existing value for the value of the first keyframe.
+ // Not reflected in studio at this time, purely a runtime problem.
+ // Defaults to false
+ bool m_DynamicFirstKeyframe;
+ bool m_ArtistEdited;
+ SAnimationInfo()
+ : m_Index(0)
+ , m_AnimationType(EAnimationTypeLinear)
+ , m_DynamicFirstKeyframe(false)
+ // Animations are assumed to be artist edited.
+ // And any change will force this flag to true.
+ , m_ArtistEdited(true)
+
+ {
+ }
+ SAnimationInfo(Qt3DSDMSlideHandle inSlide, Qt3DSDMInstanceHandle inInstance,
+ Qt3DSDMPropertyHandle inProperty, size_t inIndex, EAnimationType inAnimationType,
+ bool inDynamicFirstKeyframe, bool inArtistEdited)
+ : m_Slide(inSlide)
+ , m_Instance(inInstance)
+ , m_Property(inProperty)
+ , m_Index(inIndex)
+ , m_AnimationType(inAnimationType)
+ , m_DynamicFirstKeyframe(inDynamicFirstKeyframe)
+ , m_ArtistEdited(inArtistEdited)
+ {
+ }
+};
+
+typedef std::pair<SAnimationInfo, TKeyframeList> TAnimationKeyframesPair;
+typedef std::vector<TAnimationKeyframesPair> TAnimationKeyframesPairList;
+typedef std::vector<SAnimationInfo> TAnimationInfoList;
+
+/**
+ * Pure animation core. Not wrapped in any niceties.
+ */
+class IAnimationCore
+{
+public:
+ virtual ~IAnimationCore() {}
+ virtual Qt3DSDMAnimationHandle CreateAnimation(Qt3DSDMSlideHandle inSlide,
+ Qt3DSDMInstanceHandle inInstance,
+ Qt3DSDMPropertyHandle inProperty, size_t inIndex,
+ EAnimationType inAnimationType,
+ bool inFirstKeyframeDynamic) = 0;
+ virtual void DeleteAnimation(Qt3DSDMAnimationHandle inAnimation) = 0;
+ virtual Qt3DSDMAnimationHandle GetAnimation(Qt3DSDMSlideHandle inSlide,
+ Qt3DSDMInstanceHandle inInstance,
+ Qt3DSDMPropertyHandle inProperty,
+ size_t inIndex) const = 0;
+ virtual SAnimationInfo GetAnimationInfo(Qt3DSDMAnimationHandle inAnimation) const = 0;
+ virtual void GetAnimations(TAnimationHandleList &outAnimations) const = 0;
+ virtual void GetAnimations(TAnimationInfoList &outAnimations,
+ Qt3DSDMSlideHandle inMaster = Qt3DSDMSlideHandle(),
+ Qt3DSDMSlideHandle inSlide = Qt3DSDMSlideHandle()) const = 0;
+
+ virtual void GetSpecificInstanceAnimations(Qt3DSDMSlideHandle inSlide,
+ Qt3DSDMInstanceHandle inInstance,
+ TAnimationHandleList &outAnimations) = 0;
+
+ virtual void SetFirstKeyframeDynamic(Qt3DSDMAnimationHandle inAnimation, bool inValue) = 0;
+
+ // keyframe manipulation
+ virtual Qt3DSDMKeyframeHandle InsertKeyframe(Qt3DSDMAnimationHandle inAnimation,
+ const TKeyframe &inKeyframe) = 0;
+ virtual void EraseKeyframe(Qt3DSDMKeyframeHandle inKeyframe) = 0;
+ virtual void DeleteAllKeyframes(Qt3DSDMAnimationHandle inAnimation) = 0;
+
+ // All of these mutators will force the artist edited property
+ // of the animation to true.
+ virtual Qt3DSDMAnimationHandle
+ GetAnimationForKeyframe(Qt3DSDMKeyframeHandle inKeyframe) const = 0;
+ virtual TKeyframe GetKeyframeData(Qt3DSDMKeyframeHandle inKeyframe) const = 0;
+ virtual void SetKeyframeData(Qt3DSDMKeyframeHandle inKeyframe, const TKeyframe &inData) = 0;
+ virtual void GetKeyframes(Qt3DSDMAnimationHandle inAnimation,
+ TKeyframeHandleList &outKeyframes) const = 0;
+ virtual size_t GetKeyframeCount(Qt3DSDMAnimationHandle inAnimation) const = 0;
+ virtual bool IsFirstKeyframe(Qt3DSDMKeyframeHandle inKeyframe) const = 0;
+
+ virtual void OffsetAnimations(Qt3DSDMSlideHandle inSlide, Qt3DSDMInstanceHandle inInstance,
+ long inOffset) = 0;
+
+ // Direct mutators of the artist edited feature of animations
+ virtual void SetIsArtistEdited(Qt3DSDMAnimationHandle inAnimation, bool inEdited = true) = 0;
+ virtual bool IsArtistEdited(Qt3DSDMAnimationHandle inAnimation) const = 0;
+
+ // Animation Evaluation.
+ virtual float EvaluateAnimation(Qt3DSDMAnimationHandle inAnimation, float inSeconds) const = 0;
+
+ virtual bool KeyframeValid(Qt3DSDMKeyframeHandle inKeyframe) const = 0;
+ virtual bool AnimationValid(Qt3DSDMAnimationHandle inAnimation) const = 0;
+
+ virtual void CopyAnimations(Qt3DSDMSlideHandle inSourceSlide,
+ Qt3DSDMInstanceHandle inSourceInstance,
+ Qt3DSDMSlideHandle inDestSlide,
+ Qt3DSDMInstanceHandle inDestInstance) = 0;
+};
+
+typedef std::shared_ptr<IAnimationCore> TAnimationCorePtr;
+
+struct SGetOrSetKeyframeInfo
+{
+ float m_Value = 0.0;
+ float m_EaseIn = -1.f;
+ float m_EaseOut = -1.f;
+ bool m_AnimationTrackIsDynamic = false;
+
+ SGetOrSetKeyframeInfo(float inValue, float inEaseIn = -1.f, float inEaseOut = -1.f,
+ bool inDynamic = false)
+ : m_Value(inValue)
+ , m_EaseIn(inEaseIn)
+ , m_EaseOut(inEaseOut)
+ , m_AnimationTrackIsDynamic(inDynamic)
+ {
+ }
+ SGetOrSetKeyframeInfo() = default;
+
+};
+/**
+ * Interface from studio into the animation system that speaks
+ * a language near to that of studio. Public interface.
+ */
+class IStudioAnimationSystem
+{
+public:
+ virtual ~IStudioAnimationSystem() {}
+
+ /**
+ * When auto-keyframing is on, all calls to setinstancepropertyvalue will
+ * case a keyframe to be set if the instance is a member of a slide graph.
+ */
+ virtual void SetAutoKeyframe(bool inAutoKeyframe) = 0;
+ /**
+ * Returns true when auto keyframing is set.
+ */
+ virtual bool GetAutoKeyframe() const = 0;
+ /**
+ * Create animation on the property on this instance. If the property was animated and had
+ *keyframes previously,
+ * this function will also set the keyframes accordingly.
+ */
+ virtual void Animate(Qt3DSDMInstanceHandle inInstance, Qt3DSDMPropertyHandle inProperty) = 0;
+ /**
+ * Delete animation on the property on this instance
+ */
+ virtual void Deanimate(Qt3DSDMInstanceHandle inInstance, Qt3DSDMPropertyHandle inProperty) = 0;
+ /**
+ * Set a keyframe on this property. Uses the current time of the slide graph.
+ * If the keyframe is within a given time distance of another, this function will simply change
+ * the keyframed value of the other property to match the current value of this property.
+ */
+ virtual void KeyframeProperty(Qt3DSDMInstanceHandle inInstance, Qt3DSDMPropertyHandle inProperty,
+ bool inDoDiffValue) = 0;
+ /**
+ * Set the value of a existing a keyframe or create a new one, on this property, at the given
+ *time.
+ * If ease in or ease out are unset then the keyframe gets the default ease in or out.
+ */
+ virtual void SetOrCreateKeyframe(Qt3DSDMInstanceHandle inInstance,
+ Qt3DSDMPropertyHandle inProperty, float inTimeInSeconds,
+ SGetOrSetKeyframeInfo *inKeyframeInfo, size_t inNumInfos) = 0;
+ /**
+ * Return the animation that is currently controlling this property. This function will return
+ * an invalid handle value if there is currently no animation controlling this property.
+ */
+ virtual Qt3DSDMAnimationHandle GetControllingAnimation(Qt3DSDMInstanceHandle inInstance,
+ Qt3DSDMPropertyHandle inProperty,
+ size_t inIndex) const = 0;
+
+ /**
+ * Return true if the given property is animatable. You can begin animation by calling
+ *KeyframeProperty *or*
+ * by setting auto keyframe to on and setting a property value through the
+ *IInstancePropertyCore system.
+ */
+ virtual bool IsPropertyAnimatable(Qt3DSDMInstanceHandle inInstance,
+ Qt3DSDMPropertyHandle inProperty) const = 0;
+
+ /**
+ * Return true if the given property is animated. Currently, either 0 or ALL channels are
+ *animated. Hence, checking for index = 0 suffices.
+ * And if that changes, this function can be updated accordingly.
+ */
+ virtual bool IsPropertyAnimated(Qt3DSDMInstanceHandle inInstance,
+ Qt3DSDMPropertyHandle inProperty) const = 0;
+
+ /**
+ * Specify if new keyframes should be created with smooth ( ie Ease In/Out values = 100 ) or
+ *linear ( Ease In/Out values = 0 )
+ */
+ virtual void SetInterpolation(bool inSmooth) = 0;
+
+ /**
+ * Get an instance property value. Will override outValue only if the slide, instance,
+ *property is animated.
+ */
+ virtual bool GetAnimatedInstancePropertyValue(Qt3DSDMSlideHandle inSlide,
+ Qt3DSDMInstanceHandle inInstance,
+ Qt3DSDMPropertyHandle inProperty,
+ SValue &outValue) const = 0;
+ /**
+ * Set an instance property value. Will return true in the cases where
+ * the property is actually animated. May only set local values, or may auto set a keyframed
+ *value.
+ */
+ virtual bool SetAnimatedInstancePropertyValue(Qt3DSDMSlideHandle inSlide,
+ Qt3DSDMInstanceHandle inInstance,
+ Qt3DSDMPropertyHandle inProperty,
+ const SValue &inValue) = 0;
+
+ typedef std::function<void(Qt3DSDMInstanceHandle instance)> TRefreshCallbackFunc;
+ virtual void setRefreshCallback(TRefreshCallbackFunc func) = 0;
+};
+
+typedef std::shared_ptr<IStudioAnimationSystem> TStudioAnimationSystemPtr;
+
+inline SLinearKeyframe CreateLinearKeyframe(float inSeconds, float inValue)
+{
+ SLinearKeyframe retval = { inSeconds, inValue };
+ return retval;
+}
+
+inline SBezierKeyframe CreateBezierKeyframe(float inSeconds, float inValue, float inInTangentTime,
+ float inInTangentValue, float inOutTangentTime,
+ float inOutTangentValue)
+{
+ SBezierKeyframe theBezierKeyframe;
+ theBezierKeyframe.m_KeyframeSeconds = inSeconds;
+ theBezierKeyframe.m_KeyframeValue = inValue;
+ theBezierKeyframe.m_InTangentTime = inInTangentTime;
+ theBezierKeyframe.m_InTangentValue = inInTangentValue;
+ theBezierKeyframe.m_OutTangentTime = inOutTangentTime;
+ theBezierKeyframe.m_OutTangentValue = inOutTangentValue;
+ return theBezierKeyframe;
+}
+
+inline SEaseInEaseOutKeyframe CreateEaseInEaseOutKeyframe(float inSeconds, float inValue,
+ float inEaseIn, float inEaseOut)
+{
+ SEaseInEaseOutKeyframe retval;
+ retval.m_KeyframeSeconds = inSeconds;
+ retval.m_KeyframeValue = inValue;
+ retval.m_EaseIn = inEaseIn;
+ retval.m_EaseOut = inEaseOut;
+ return retval;
+}
+
+inline SAnimationInfo CreateAnimationInfo(Qt3DSDMSlideHandle inSlide,
+ Qt3DSDMInstanceHandle inInstance,
+ Qt3DSDMPropertyHandle inProperty, size_t inIndex,
+ EAnimationType inAnimationType,
+ bool inFirstKeyframeDynamic, bool inArtistEdited)
+{
+ SAnimationInfo retval(inSlide, inInstance, inProperty, inIndex, inAnimationType,
+ inFirstKeyframeDynamic, inArtistEdited);
+ return retval;
+}
+
+struct SKeyframeValueVisitor
+{
+ float operator()(const SLinearKeyframe &inKeyframe) const { return inKeyframe.m_KeyframeValue; }
+ float operator()(const SBezierKeyframe &inKeyframe) const { return inKeyframe.m_KeyframeValue; }
+ float operator()(const SEaseInEaseOutKeyframe &inKeyframe) const
+ {
+ return inKeyframe.m_KeyframeValue;
+ }
+ float operator()()
+ {
+ QT3DS_ASSERT(false);
+ return 0.0f;
+ }
+};
+
+inline float KeyframeValueValue(const TKeyframe &inKeyframe)
+{
+ return inKeyframe.visit<float>(SKeyframeValueVisitor());
+}
+
+struct SKeyframeTimeAnalyzer
+{
+ float operator()(const SLinearKeyframe &inValue) const { return inValue.m_KeyframeSeconds; }
+ float operator()(const SBezierKeyframe &inValue) const { return inValue.m_KeyframeSeconds; }
+ float operator()(const SEaseInEaseOutKeyframe &inValue) const
+ {
+ return inValue.m_KeyframeSeconds;
+ }
+ float operator()()
+ {
+ QT3DS_ASSERT(false);
+ return 0.0f;
+ }
+};
+
+inline float KeyframeTime(const TKeyframe &inValue)
+{
+ return inValue.visit<float>(SKeyframeTimeAnalyzer());
+}
+
+inline EAnimationType GetKeyframeType(const TKeyframe &inKeyframe)
+{
+ return inKeyframe.getType();
+}
+
+struct SAnimatableArityVisitor
+{
+ std::tuple<bool, size_t> operator()(bool) const
+ {
+ return std::tuple<bool, size_t>(true, 1);
+ }
+ std::tuple<bool, size_t> operator()(long) const
+ {
+ return std::tuple<bool, size_t>(true, 1);
+ }
+ std::tuple<bool, size_t> operator()(float) const
+ {
+ return std::tuple<bool, size_t>(true, 1);
+ }
+ std::tuple<bool, size_t> operator()(const SFloat2 &) const
+ {
+ return std::tuple<bool, size_t>(true, 2);
+ }
+ std::tuple<bool, size_t> operator()(const SFloat3 &) const
+ {
+ return std::tuple<bool, size_t>(true, 3);
+ }
+ std::tuple<bool, size_t> operator()(const SFloat4 &) const
+ {
+ return std::tuple<bool, size_t>(true, 4);
+ }
+ template <typename TDataType>
+ std::tuple<bool, size_t> operator()(const TDataType &) const
+ {
+ return std::tuple<bool, size_t>(false, 0);
+ }
+ std::tuple<bool, size_t> operator()()
+ {
+ QT3DS_ASSERT(false);
+ return std::tuple<bool, size_t>(false, 0);
+ }
+};
+
+inline std::tuple<bool, size_t> GetVariantAnimatableAndArity(const SValue &inValue)
+{
+ return inValue.visit<std::tuple<bool, size_t>>(SAnimatableArityVisitor());
+}
+
+inline std::tuple<bool, size_t> GetDatatypeAnimatableAndArity(DataModelDataType::Value inDataType)
+{
+ switch (inDataType) {
+ case DataModelDataType::Long:
+ case DataModelDataType::Float:
+ return std::make_tuple(true, 1);
+
+ case DataModelDataType::Float2:
+ return std::make_tuple(true, 2);
+
+ case DataModelDataType::Float3:
+ return std::make_tuple(true, 3);
+
+ case DataModelDataType::Float4:
+ return std::make_tuple(true, 4);
+
+ default:
+ return std::make_tuple(false, 0);
+ }
+}
+
+template <typename TDataType>
+inline TDataType SetFloatValue(float inValue, size_t inIndex, const TDataType &inDataType)
+{
+ TDataType retval(inDataType);
+ retval[inIndex] = inValue;
+ return retval;
+}
+
+struct SAnimationApplier
+{
+ float m_Value;
+ size_t m_Index;
+ SValue operator()(const bool &) { return m_Value > 0.5f; }
+ SValue operator()(const qt3ds::QT3DSI32 &) { return static_cast<qt3ds::QT3DSI32>(m_Value + .5f); }
+ SValue operator()(const float &) { return m_Value; }
+ SValue operator()(const SFloat2 &inValue) { return SetFloatValue(m_Value, m_Index, inValue); }
+ SValue operator()(const SFloat3 &inValue) { return SetFloatValue(m_Value, m_Index, inValue); }
+ SValue operator()(const SFloat4 &inValue) { return SetFloatValue(m_Value, m_Index, inValue); }
+ template <typename TDataType>
+ SValue operator()(const TDataType &inValue)
+ {
+ return inValue;
+ }
+ SValue operator()()
+ {
+ QT3DS_ASSERT(false);
+ return SValue();
+ }
+};
+
+inline void SetAnimationValue(float inValue, size_t inIndex, SValue &ioValue)
+{
+ using namespace std;
+ SAnimationApplier theApplier;
+ theApplier.m_Value = inValue;
+ theApplier.m_Index = inIndex;
+ ioValue = ioValue.visit<SValue>(theApplier);
+}
+
+template <typename TDataType>
+inline float GetFloatValue(const TDataType &inValue, size_t inIndex)
+{
+ return inValue[inIndex];
+}
+
+struct SAnimationGetter
+{
+ size_t m_Index;
+ float operator()(const bool &inValue) const { return inValue ? 1.f : 0.f; }
+ float operator()(const long &inValue) const { return static_cast<float>(inValue); }
+ float operator()(const float &inValue) const { return inValue; }
+ float operator()(const SFloat2 &inValue) const { return GetFloatValue(inValue, m_Index); }
+ float operator()(const SFloat3 &inValue) const { return GetFloatValue(inValue, m_Index); }
+ float operator()(const SFloat4 &inValue) const { return GetFloatValue(inValue, m_Index); }
+ template <typename TDataType>
+ float operator()(const TDataType & /*inValue*/) const
+ {
+ return 0.f;
+ }
+ float operator()()
+ {
+ QT3DS_ASSERT(false);
+ return 0.0f;
+ }
+};
+
+inline float GetAnimationValue(size_t inIndex, const SValue &ioValue)
+{
+ SAnimationGetter theGetter;
+ theGetter.m_Index = inIndex;
+ return ioValue.visit<float>(theGetter);
+}
+
+struct SKeyframeTimeSetter
+{
+ float m_Seconds;
+ TKeyframe operator()(const SLinearKeyframe &inValue) const
+ {
+ return CreateLinearKeyframe(m_Seconds, inValue.m_KeyframeValue);
+ }
+ TKeyframe operator()(const SBezierKeyframe &inValue) const
+ {
+ return CreateBezierKeyframe(m_Seconds, inValue.m_KeyframeValue, inValue.m_InTangentTime,
+ inValue.m_InTangentValue, inValue.m_OutTangentTime,
+ inValue.m_OutTangentValue);
+ }
+ TKeyframe operator()(const SEaseInEaseOutKeyframe &inValue) const
+ {
+ return CreateEaseInEaseOutKeyframe(m_Seconds, inValue.m_KeyframeValue, inValue.m_EaseIn,
+ inValue.m_EaseOut);
+ }
+ TKeyframe operator()()
+ {
+ QT3DS_ASSERT(false);
+ return TKeyframe();
+ }
+};
+
+inline TKeyframe SetKeyframeSeconds(const TKeyframe &inKeyframe, float inSeconds)
+{
+ SKeyframeTimeSetter theSetter;
+ theSetter.m_Seconds = inSeconds;
+ return inKeyframe.visit<TKeyframe>(theSetter);
+}
+
+struct SKeyframeTimeGetter
+{
+ template <typename TKeyframeType>
+ float operator()(const TKeyframeType &inValue) const
+ {
+ return inValue.m_KeyframeSeconds;
+ }
+ float operator()()
+ {
+ QT3DS_ASSERT(false);
+ return 0.0f;
+ }
+};
+
+inline float GetKeyframeSeconds(const TKeyframe &inKeyframe)
+{
+ SKeyframeTimeGetter theGetter;
+ return inKeyframe.visit<float>(theGetter);
+}
+
+struct SKeyframeValueSetter
+{
+ float m_Value;
+ TKeyframe operator()(const SLinearKeyframe &inValue) const
+ {
+ return CreateLinearKeyframe(inValue.m_KeyframeSeconds, m_Value);
+ }
+ TKeyframe operator()(const SBezierKeyframe &inValue) const
+ {
+ return CreateBezierKeyframe(inValue.m_KeyframeSeconds, m_Value, inValue.m_InTangentTime,
+ inValue.m_InTangentValue, inValue.m_OutTangentTime,
+ inValue.m_OutTangentValue);
+ }
+ TKeyframe operator()(const SEaseInEaseOutKeyframe &inValue) const
+ {
+ return CreateEaseInEaseOutKeyframe(inValue.m_KeyframeSeconds, m_Value, inValue.m_EaseIn,
+ inValue.m_EaseOut);
+ }
+ TKeyframe operator()()
+ {
+ QT3DS_ASSERT(false);
+ return TKeyframe();
+ }
+};
+
+inline TKeyframe SetKeyframeValue(const TKeyframe &inKeyframe, float inValue)
+{
+ SKeyframeValueSetter theSetter;
+ theSetter.m_Value = inValue;
+ return inKeyframe.visit<TKeyframe>(theSetter);
+}
+
+inline float AnimationClamp(float inLowerBound, float inUpperBound, float inValue)
+{
+ if (inValue < inLowerBound)
+ return inLowerBound;
+ if (inValue > inUpperBound)
+ return inUpperBound;
+ return inValue;
+}
+
+inline SBezierKeyframe
+CreateBezierKeyframeFromEaseInEaseOutKeyframe(float *inPreviousValue,
+ SEaseInEaseOutKeyframe inCurrent, float *inNextValue)
+{
+ float theValue = inCurrent.m_KeyframeValue;
+ float theSeconds = inCurrent.m_KeyframeSeconds;
+ float inSeconds = 0.f;
+ float inValue = 0.f;
+ float outSeconds = 0.f;
+ float outValue = 0.f;
+ if (inPreviousValue) {
+ float thePercent = 1.0f - AnimationClamp(0.0f, 1.0f, inCurrent.m_EaseIn / 100.f);
+ double theAmount = 1.0f - thePercent * .333333333334;
+ inValue = (float)(*inPreviousValue
+ + ((inCurrent.m_KeyframeValue - *inPreviousValue) * theAmount));
+ }
+ if (inNextValue) {
+ float thePercent = 1.0f - AnimationClamp(0.0f, 1.0f, inCurrent.m_EaseOut / 100.f);
+ double theAmount = thePercent * .3333333333334;
+ outValue = (float)(inCurrent.m_KeyframeValue
+ + ((*inNextValue - inCurrent.m_KeyframeValue) * theAmount));
+ }
+ return CreateBezierKeyframe(theSeconds, theValue, inSeconds, inValue, outSeconds, outValue);
+}
+
+void CopyKeyframes(const IAnimationCore &inSourceAnimationCore, IAnimationCore &inDestAnimationCore,
+ Qt3DSDMAnimationHandle inDestAnimation, const TKeyframeHandleList &inKeyframes);
+
+Qt3DSDMAnimationHandle CopyAnimation(TAnimationCorePtr inSourceAnimationCore,
+ Qt3DSDMAnimationHandle inAnimation,
+ Qt3DSDMSlideHandle inNewSlide,
+ Qt3DSDMInstanceHandle inNewInstance,
+ Qt3DSDMPropertyHandle inNewProperty, size_t inNewIndex);
+
+struct SEaseInGetter
+{
+ float operator()(const SLinearKeyframe &) const { return 0.f; }
+ float operator()(const SBezierKeyframe &) const { return 0.f; }
+ float operator()(const SEaseInEaseOutKeyframe &inValue) const { return inValue.m_EaseIn; }
+ float operator()()
+ {
+ QT3DS_ASSERT(false);
+ return 0.0f;
+ }
+};
+struct SEaseOutGetter
+{
+ float operator()(const SLinearKeyframe &) const { return 0.f; }
+ float operator()(const SBezierKeyframe &) const { return 0.f; }
+ float operator()(const SEaseInEaseOutKeyframe &inValue) const { return inValue.m_EaseOut; }
+ float operator()()
+ {
+ QT3DS_ASSERT(false);
+ return 0.0f;
+ }
+};
+inline void GetEaseInOutValues(const TKeyframe &inValue, float &outEaseIn, float &outEaseOut)
+{
+ SEaseInGetter theGetter;
+ outEaseIn = inValue.visit<float>(theGetter);
+
+ SEaseOutGetter theEaseOutGetter;
+ outEaseOut = inValue.visit<float>(theEaseOutGetter);
+}
+
+struct SEaseInSetter
+{
+ float m_Value;
+ TKeyframe operator()(SLinearKeyframe &inValue) const { return inValue; }
+ TKeyframe operator()(SBezierKeyframe &inValue) const { return inValue; }
+ TKeyframe operator()(SEaseInEaseOutKeyframe &inKeyframe) const
+ {
+ inKeyframe.m_EaseIn = m_Value;
+ return inKeyframe;
+ }
+ TKeyframe operator()()
+ {
+ QT3DS_ASSERT(false);
+ return TKeyframe();
+ }
+};
+struct SEaseOutSetter
+{
+ float m_Value;
+ TKeyframe operator()(SLinearKeyframe &inValue) const { return inValue; }
+ TKeyframe operator()(SBezierKeyframe &inValue) const { return inValue; }
+ TKeyframe operator()(SEaseInEaseOutKeyframe &inKeyframe) const
+ {
+ inKeyframe.m_EaseOut = m_Value;
+ return inKeyframe;
+ }
+ TKeyframe operator()()
+ {
+ QT3DS_ASSERT(false);
+ return TKeyframe();
+ }
+};
+inline TKeyframe SetEaseInOutValues(TKeyframe &inKeyframe, float inEaseIn, float inEaseOut)
+{
+ SEaseInSetter theSetter;
+ theSetter.m_Value = inEaseIn;
+ inKeyframe.visit<TKeyframe>(theSetter);
+
+ SEaseOutSetter theEaseOutSetter;
+ theEaseOutSetter.m_Value = inEaseOut;
+ inKeyframe.visit<TKeyframe>(theEaseOutSetter);
+
+ return inKeyframe;
+}
+
+void GetKeyframesAsBezier(Qt3DSDMAnimationHandle inAnimation, const IAnimationCore &inAnimationCore,
+ TBezierKeyframeList &outKeyframes);
+}
+
+#endif
diff --git a/src/dm/systems/Qt3DSDMComposerTypeDefinitions.cpp b/src/dm/systems/Qt3DSDMComposerTypeDefinitions.cpp
new file mode 100644
index 0000000..2bd8941
--- /dev/null
+++ b/src/dm/systems/Qt3DSDMComposerTypeDefinitions.cpp
@@ -0,0 +1,579 @@
+/****************************************************************************
+**
+** Copyright (C) 2008 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 "Qt3DSDMComposerTypeDefinitions.h"
+#include <memory>
+#include "Qt3DSDMDataCore.h"
+#include "SimpleDataCore.h"
+#include "DataCoreProducer.h"
+#include "Qt3DSDMSlideCore.h"
+
+#include <QtGlobal>
+
+using namespace qt3dsdm;
+using std::make_shared;
+using std::shared_ptr;
+
+#ifdef _WIN32
+#pragma warning(disable : 4100)
+#endif
+
+// SComposerTypePropertyDefinition constructors
+
+namespace {
+
+template <typename TDataType>
+struct DataConstructor
+{
+ template <typename TInputType>
+ TDataType Construct(const TInputType &inInput)
+ {
+ return TDataType(inInput);
+ }
+};
+
+template <>
+struct DataConstructor<SLong4>
+{
+ SLong4 Construct(int inValue)
+ {
+ unsigned long theValue((unsigned long)inValue);
+ return SLong4(theValue, theValue, theValue, theValue);
+ }
+};
+
+template <>
+struct DataConstructor<TDataStrPtr>
+{
+ TDataStrPtr Construct(const wchar_t *inData)
+ {
+ if (IsTrivial(inData))
+ return make_shared<CDataStr>();
+ return make_shared<CDataStr>(inData);
+ }
+};
+template <>
+struct DataConstructor<SStringOrInt>
+{
+ SStringOrInt Construct(const wchar_t *inData)
+ {
+ if (IsTrivial(inData))
+ return make_shared<CDataStr>();
+ return make_shared<CDataStr>(inData);
+ }
+};
+template <>
+struct DataConstructor<SObjectRefType>
+{
+ SObjectRefType Construct(const wchar_t *) { return SObjectRefType(); }
+};
+}
+
+#define QT3DS_WCHAR_T_Typed L"Typed"
+#define QT3DS_WCHAR_T_Guided L"Guided"
+#define QT3DS_WCHAR_T_Named L"Named"
+#define QT3DS_WCHAR_T_SlideOwner L"SlideOwner"
+#define QT3DS_WCHAR_T_Slide L"Slide"
+#define QT3DS_WCHAR_T_Action L"Action"
+#define QT3DS_WCHAR_T_Asset L"Asset"
+#define QT3DS_WCHAR_T_Scene L"Scene"
+#define QT3DS_WCHAR_T_Image L"Image"
+#define QT3DS_WCHAR_T_Material L"Material"
+#define QT3DS_WCHAR_T_Behavior L"Behavior"
+#define QT3DS_WCHAR_T_Node L"Node"
+#define QT3DS_WCHAR_T_Layer L"Layer"
+#define QT3DS_WCHAR_T_Group L"Group"
+#define QT3DS_WCHAR_T_Model L"Model"
+#define QT3DS_WCHAR_T_Light L"Light"
+#define QT3DS_WCHAR_T_Camera L"Camera"
+#define QT3DS_WCHAR_T_Component L"Component"
+#define QT3DS_WCHAR_T_Text L"Text"
+#define QT3DS_WCHAR_T_Effect L"Effect"
+#define QT3DS_WCHAR_T_RenderPlugin L"RenderPlugin"
+#define QT3DS_WCHAR_T_MaterialBase L"MaterialBase"
+#define QT3DS_WCHAR_T_CustomMaterial L"CustomMaterial"
+#define QT3DS_WCHAR_T_ReferencedMaterial L"ReferencedMaterial"
+#define QT3DS_WCHAR_T_Alias L"Alias"
+#define QT3DS_WCHAR_T_Lightmaps L"Lightmaps"
+
+#define QT3DS_WCHAR_T_type L"type"
+#define QT3DS_WCHAR_T_id L"id"
+#define QT3DS_WCHAR_T_name L"name"
+#define QT3DS_WCHAR_T_componentid L"componentid"
+#define QT3DS_WCHAR_T_playmode L"playmode"
+#define QT3DS_WCHAR_T_playthroughto L"playthroughto"
+#define QT3DS_WCHAR_T_initialplaystate L"initialplaystate"
+#define QT3DS_WCHAR_T_actioneyeball L"actioneyeball"
+#define QT3DS_WCHAR_T_sourcepath L"sourcepath"
+#define QT3DS_WCHAR_T_importid L"importid"
+#define QT3DS_WCHAR_T_starttime L"starttime"
+#define QT3DS_WCHAR_T_endtime L"endtime"
+#define QT3DS_WCHAR_T_eyeball L"eyeball"
+#define QT3DS_WCHAR_T_shy L"shy"
+#define QT3DS_WCHAR_T_locked L"locked"
+#define QT3DS_WCHAR_T_timebarcolor L"timebarcolor"
+#define QT3DS_WCHAR_T_timebartext L"timebartext"
+#define QT3DS_WCHAR_T_bgcolorenable L"bgcolorenable"
+#define QT3DS_WCHAR_T_background L"background"
+#define QT3DS_WCHAR_T_backgroundcolor L"backgroundcolor"
+#define QT3DS_WCHAR_T_blendtype L"blendtype"
+#define QT3DS_WCHAR_T_scaleu L"scaleu"
+#define QT3DS_WCHAR_T_scalev L"scalev"
+#define QT3DS_WCHAR_T_mappingmode L"mappingmode"
+#define QT3DS_WCHAR_T_tilingmodehorz L"tilingmodehorz"
+#define QT3DS_WCHAR_T_tilingmodevert L"tilingmodevert"
+#define QT3DS_WCHAR_T_rotationuv L"rotationuv"
+#define QT3DS_WCHAR_T_positionu L"positionu"
+#define QT3DS_WCHAR_T_positionv L"positionv"
+#define QT3DS_WCHAR_T_pivotu L"pivotu"
+#define QT3DS_WCHAR_T_pivotv L"pivotv"
+#define QT3DS_WCHAR_T_subpresentation L"subpresentation"
+#define QT3DS_WCHAR_T_iblprobe L"iblprobe"
+#define QT3DS_WCHAR_T_shaderlighting L"shaderlighting"
+#define QT3DS_WCHAR_T_blendmode L"blendmode"
+#define QT3DS_WCHAR_T_vertexcolors L"vertexcolors"
+#define QT3DS_WCHAR_T_diffuse L"diffuse"
+#define QT3DS_WCHAR_T_diffusemap L"diffusemap"
+#define QT3DS_WCHAR_T_diffusemap2 L"diffusemap2"
+#define QT3DS_WCHAR_T_diffusemap3 L"diffusemap3"
+#define QT3DS_WCHAR_T_specularreflection L"specularreflection"
+#define QT3DS_WCHAR_T_specularmap L"specularmap"
+#define QT3DS_WCHAR_T_specularmodel L"specularmodel"
+#define QT3DS_WCHAR_T_speculartint L"speculartint"
+#define QT3DS_WCHAR_T_ior L"ior"
+#define QT3DS_WCHAR_T_specularamount L"specularamount"
+#define QT3DS_WCHAR_T_specularroughness L"specularroughness"
+#define QT3DS_WCHAR_T_roughnessmap L"roughnessmap"
+#define QT3DS_WCHAR_T_opacitymap L"opacitymap"
+#define QT3DS_WCHAR_T_emissivepower L"emissivepower"
+#define QT3DS_WCHAR_T_emissivecolor L"emissivecolor"
+#define QT3DS_WCHAR_T_emissivemap L"emissivemap"
+#define QT3DS_WCHAR_T_emissivemap2 L"emissivemap2"
+#define QT3DS_WCHAR_T_normalmap L"normalmap"
+#define QT3DS_WCHAR_T_normalstrength L"normalstrength"
+#define QT3DS_WCHAR_T_position L"position"
+#define QT3DS_WCHAR_T_rotation L"rotation"
+#define QT3DS_WCHAR_T_scale L"scale"
+#define QT3DS_WCHAR_T_pivot L"pivot"
+#define QT3DS_WCHAR_T_opacity L"opacity"
+#define QT3DS_WCHAR_T_rotationorder L"rotationorder"
+#define QT3DS_WCHAR_T_orientation L"orientation"
+#define QT3DS_WCHAR_T_progressiveaa L"progressiveaa"
+#define QT3DS_WCHAR_T_multisampleaa L"multisampleaa"
+#define QT3DS_WCHAR_T_disabledepthtest L"disabledepthtest"
+#define QT3DS_WCHAR_T_disabledepthprepass L"disabledepthprepass"
+#define QT3DS_WCHAR_T_layerwidth L"layerwidth"
+#define QT3DS_WCHAR_T_layerheight L"layerheight"
+#define QT3DS_WCHAR_T_lighttype L"lighttype"
+#define QT3DS_WCHAR_T_lightdiffuse L"lightdiffuse"
+#define QT3DS_WCHAR_T_lightspecular L"lightspecular"
+#define QT3DS_WCHAR_T_lightambient L"lightambient"
+#define QT3DS_WCHAR_T_brightness L"brightness"
+#define QT3DS_WCHAR_T_linearfade L"linearfade"
+#define QT3DS_WCHAR_T_expfade L"expfade"
+#define QT3DS_WCHAR_T_areawidth L"areawidth"
+#define QT3DS_WCHAR_T_areaheight L"areaheight"
+#define QT3DS_WCHAR_T_castshadow L"castshadow"
+#define QT3DS_WCHAR_T_shdwbias L"shdwbias"
+#define QT3DS_WCHAR_T_shdwfactor L"shdwfactor"
+#define QT3DS_WCHAR_T_shdwmapres L"shdwmapres"
+#define QT3DS_WCHAR_T_shdwmapfar L"shdwmapfar"
+#define QT3DS_WCHAR_T_shdwmapfov L"shdwmapfov"
+#define QT3DS_WCHAR_T_shdwfilter L"shdwfilter"
+#define QT3DS_WCHAR_T_orthographic L"orthographic"
+#define QT3DS_WCHAR_T_fov L"fov"
+#define QT3DS_WCHAR_T_fovhorizontal L"fovhorizontal"
+#define QT3DS_WCHAR_T_clipnear L"clipnear"
+#define QT3DS_WCHAR_T_clipfar L"clipfar"
+#define QT3DS_WCHAR_T_lookatlock L"lookatlock"
+#define QT3DS_WCHAR_T_lookatpoint L"lookatpoint"
+#define QT3DS_WCHAR_T_textstring L"textstring"
+#define QT3DS_WCHAR_T_textcolor L"textcolor"
+#define QT3DS_WCHAR_T_font L"font"
+#define QT3DS_WCHAR_T_size L"size"
+#define QT3DS_WCHAR_T_horzalign L"horzalign"
+#define QT3DS_WCHAR_T_vertalign L"vertalign"
+#define QT3DS_WCHAR_T_leading L"leading"
+#define QT3DS_WCHAR_T_tracking L"tracking"
+#define QT3DS_WCHAR_T_dropshadow L"dropshadow"
+#define QT3DS_WCHAR_T_dropshadowstrength L"dropshadowstrength"
+#define QT3DS_WCHAR_T_dropshadowoffsetx L"dropshadowoffsetx"
+#define QT3DS_WCHAR_T_dropshadowoffsety L"dropshadowoffsety"
+#define QT3DS_WCHAR_T_wordwrap L"wordwrap"
+#define QT3DS_WCHAR_T_boundingbox L"boundingbox"
+#define QT3DS_WCHAR_T_elide L"elide"
+#define QT3DS_WCHAR_T_enableacceleratedfont L"enableacceleratedfont"
+#define QT3DS_WCHAR_T_importfile L"importfile"
+#define QT3DS_WCHAR_T_fileid L"fileid"
+#define QT3DS_WCHAR_T_size L"size"
+#define QT3DS_WCHAR_T_location L"location"
+#define QT3DS_WCHAR_T_boneid L"boneid"
+#define QT3DS_WCHAR_T_poseroot L"poseroot"
+#define QT3DS_WCHAR_T_ignoresparent L"ignoresparent"
+#define QT3DS_WCHAR_T_shadowcaster L"shadowcaster"
+#define QT3DS_WCHAR_T_tessellation L"tessellation"
+#define QT3DS_WCHAR_T_edgetess L"edgetess"
+#define QT3DS_WCHAR_T_innertess L"innertess"
+#define QT3DS_WCHAR_T_scalemode L"scalemode"
+#define QT3DS_WCHAR_T_scaleanchor L"scaleanchor"
+#define QT3DS_WCHAR_T_horzfields L"horzfields"
+#define QT3DS_WCHAR_T_left L"left"
+#define QT3DS_WCHAR_T_leftunits L"leftunits"
+#define QT3DS_WCHAR_T_width L"width"
+#define QT3DS_WCHAR_T_widthunits L"widthunits"
+#define QT3DS_WCHAR_T_right L"right"
+#define QT3DS_WCHAR_T_rightunits L"rightunits"
+#define QT3DS_WCHAR_T_vertfields L"vertfields"
+#define QT3DS_WCHAR_T_top L"top"
+#define QT3DS_WCHAR_T_topunits L"topunits"
+#define QT3DS_WCHAR_T_height L"height"
+#define QT3DS_WCHAR_T_heightunits L"heightunits"
+#define QT3DS_WCHAR_T_bottom L"bottom"
+#define QT3DS_WCHAR_T_bottomunits L"bottomunits"
+#define QT3DS_WCHAR_T_aostrength L"aostrength"
+#define QT3DS_WCHAR_T_aodistance L"aodistance"
+#define QT3DS_WCHAR_T_aosoftness L"aosoftness"
+#define QT3DS_WCHAR_T_aobias L"aobias"
+#define QT3DS_WCHAR_T_aosamplerate L"aosamplerate"
+#define QT3DS_WCHAR_T_aodither L"aodither"
+#define QT3DS_WCHAR_T_shadowstrength L"shadowstrength"
+#define QT3DS_WCHAR_T_shadowdist L"shadowdist"
+#define QT3DS_WCHAR_T_shadowsoftness L"shadowsoftness"
+#define QT3DS_WCHAR_T_shadowbias L"shadowbias"
+#define QT3DS_WCHAR_T_source L"source"
+#define QT3DS_WCHAR_T_referencedmaterial L"referencedmaterial"
+#define QT3DS_WCHAR_T_lightprobe L"lightprobe"
+#define QT3DS_WCHAR_T_probebright L"probebright"
+#define QT3DS_WCHAR_T_fastibl L"fastibl"
+#define QT3DS_WCHAR_T_probehorizon L"probehorizon"
+#define QT3DS_WCHAR_T_probefov L"probefov"
+#define QT3DS_WCHAR_T_lightprobe2 L"lightprobe2"
+#define QT3DS_WCHAR_T_probe2fade L"probe2fade"
+#define QT3DS_WCHAR_T_probe2window L"probe2window"
+#define QT3DS_WCHAR_T_probe2pos L"probe2pos"
+#define QT3DS_WCHAR_T_bumpmap L"bumpmap"
+#define QT3DS_WCHAR_T_bumpamount L"bumpamount"
+#define QT3DS_WCHAR_T_normalmap L"normalmap"
+#define QT3DS_WCHAR_T_displacementmap L"displacementmap"
+#define QT3DS_WCHAR_T_displaceamount L"displaceamount"
+#define QT3DS_WCHAR_T_translucencymap L"translucencymap"
+#define QT3DS_WCHAR_T_translucentfalloff L"translucentfalloff"
+#define QT3DS_WCHAR_T_diffuselightwrap L"diffuselightwrap"
+#define QT3DS_WCHAR_T_fresnelPower L"fresnelPower"
+#define QT3DS_WCHAR_T_referencednode L"referencednode"
+#define QT3DS_WCHAR_T_temporalaa L"temporalaa"
+#define QT3DS_WCHAR_T_scope L"scope"
+#define QT3DS_WCHAR_T_Path L"Path"
+#define QT3DS_WCHAR_T_pathdata L"pathdata"
+#define QT3DS_WCHAR_T_PathAnchorPoint L"PathAnchorPoint"
+#define QT3DS_WCHAR_T_incomingangle L"incomingangle"
+#define QT3DS_WCHAR_T_incomingdistance L"incomingdistance"
+#define QT3DS_WCHAR_T_outgoingdistance L"outgoingdistance"
+#define QT3DS_WCHAR_T_linearerror L"linearerror"
+#define QT3DS_WCHAR_T_edgetessamount L"edgetessamount"
+#define QT3DS_WCHAR_T_innertessamount L"innertessamount"
+#define QT3DS_WCHAR_T_begincap L"begincap"
+#define QT3DS_WCHAR_T_begincapoffset L"begincapoffset"
+#define QT3DS_WCHAR_T_begincapopacity L"begincapopacity"
+#define QT3DS_WCHAR_T_begincapwidth L"begincapwidth"
+#define QT3DS_WCHAR_T_endcap L"endcap"
+#define QT3DS_WCHAR_T_endcapoffset L"endcapoffset"
+#define QT3DS_WCHAR_T_endcapopacity L"endcapopacity"
+#define QT3DS_WCHAR_T_endcapwidth L"endcapwidth"
+#define QT3DS_WCHAR_T_pathtype L"pathtype"
+#define QT3DS_WCHAR_T_closed L"closed"
+#define QT3DS_WCHAR_T_paintstyle L"paintstyle"
+#define QT3DS_WCHAR_T_SubPath L"SubPath"
+#define QT3DS_WCHAR_T_lightmapindirect L"lightmapindirect"
+#define QT3DS_WCHAR_T_lightmapradiosity L"lightmapradiosity"
+#define QT3DS_WCHAR_T_lightmapshadow L"lightmapshadow"
+#define QT3DS_WCHAR_T_controlledproperty L"controlledproperty"
+#define QT3DS_WCHAR_T_variants L"variants"
+
+const wchar_t *ComposerObjectTypes::Convert(ComposerObjectTypes::Enum inType)
+{
+ switch (inType) {
+#define HANDLE_COMPOSER_OBJECT_TYPE(name, propmacro) \
+ case name: \
+ return QT3DS_WCHAR_T_##name;
+ ITERATE_COMPOSER_OBJECT_TYPES
+#undef HANDLE_COMPOSER_OBJECT_TYPE
+ default:
+ break;
+ }
+
+ QT3DS_ASSERT(false);
+ return L"Unknown";
+}
+
+ComposerObjectTypes::Enum ComposerObjectTypes::Convert(const wchar_t *inType)
+{
+
+#define HANDLE_COMPOSER_OBJECT_TYPE(name, propmacro) \
+ if (AreEqual(QT3DS_WCHAR_T_##name, inType)) \
+ return ComposerObjectTypes::name;
+ ITERATE_COMPOSER_OBJECT_TYPES
+#undef HANDLE_COMPOSER_OBJECT_TYPE
+
+ QT3DS_ASSERT(false);
+ return ComposerObjectTypes::Unknown;
+}
+
+ComposerObjectTypes::Enum ComposerObjectTypes::Convert(const char8_t *inType)
+{
+
+#define HANDLE_COMPOSER_OBJECT_TYPE(name, propmacro) \
+ if (AreEqual(#name, inType)) \
+ return ComposerObjectTypes::name;
+ ITERATE_COMPOSER_OBJECT_TYPES
+#undef HANDLE_COMPOSER_OBJECT_TYPE
+
+ QT3DS_ASSERT(false);
+ return ComposerObjectTypes::Unknown;
+}
+
+const wchar_t *ComposerPropertyNames::Convert(ComposerPropertyNames::Enum inType)
+{
+ switch (inType) {
+#define HANDLE_COMPOSER_PROPERTY_DUPLICATE(name, memberName, type, defaultValue)
+#define HANDLE_COMPOSER_PROPERTY_NO_DEFAULT(name, memberName, type) \
+ case name: \
+ return QT3DS_WCHAR_T_##name;
+#define HANDLE_COMPOSER_PROPERTY(name, memberName, type, defaultValue) \
+ HANDLE_COMPOSER_PROPERTY_NO_DEFAULT(name, memberName, type)
+#define HANDLE_COMPOSER_OBJECT_TYPE(name, propmacro) propmacro
+ ITERATE_COMPOSER_OBJECT_TYPES
+#undef HANDLE_COMPOSER_OBJECT_TYPE
+#undef HANDLE_COMPOSER_PROPERTY
+#undef HANDLE_COMPOSER_PROPERTY_NO_DEFAULT
+#undef HANDLE_COMPOSER_PROPERTY_DUPLICATE
+ default:
+ break;
+ }
+ QT3DS_ASSERT(false);
+ return L"Unknown";
+}
+
+ComposerPropertyNames::Enum ComposerPropertyNames::Convert(const wchar_t *inType)
+{
+#define HANDLE_COMPOSER_PROPERTY_DUPLICATE(name, memberName, type, defaultValue)
+#define HANDLE_COMPOSER_PROPERTY_NO_DEFAULT(name, memberName, type) \
+ if (AreEqual(inType, QT3DS_WCHAR_T_##name)) \
+ return name;
+#define HANDLE_COMPOSER_PROPERTY(name, memberName, type, defaultValue) \
+ HANDLE_COMPOSER_PROPERTY_NO_DEFAULT(name, memberName, type)
+#define HANDLE_COMPOSER_OBJECT_TYPE(name, propmacro) propmacro
+ ITERATE_COMPOSER_OBJECT_TYPES
+#undef HANDLE_COMPOSER_OBJECT_TYPE
+#undef HANDLE_COMPOSER_PROPERTY
+#undef HANDLE_COMPOSER_PROPERTY_NO_DEFAULT
+#undef HANDLE_COMPOSER_PROPERTY_DUPLICATE
+ QT3DS_ASSERT(false);
+ return ComposerPropertyNames::Unknown;
+}
+
+const char8_t *ComposerPropertyNames::ConvertNarrow(ComposerPropertyNames::Enum inType)
+{
+ switch (inType) {
+#define HANDLE_COMPOSER_PROPERTY_DUPLICATE(name, memberName, type, defaultValue)
+#define HANDLE_COMPOSER_PROPERTY_NO_DEFAULT(name, memberName, type) \
+ case name: \
+ return #name;
+#define HANDLE_COMPOSER_PROPERTY(name, memberName, type, defaultValue) \
+ HANDLE_COMPOSER_PROPERTY_NO_DEFAULT(name, memberName, type)
+#define HANDLE_COMPOSER_OBJECT_TYPE(name, propmacro) propmacro
+ ITERATE_COMPOSER_OBJECT_TYPES
+#undef HANDLE_COMPOSER_OBJECT_TYPE
+#undef HANDLE_COMPOSER_PROPERTY
+#undef HANDLE_COMPOSER_PROPERTY_NO_DEFAULT
+#undef HANDLE_COMPOSER_PROPERTY_DUPLICATE
+ default:
+ break;
+ }
+ QT3DS_ASSERT(false);
+ return "Unknown";
+}
+
+ComposerPropertyNames::Enum ComposerPropertyNames::Convert(const char8_t *inType)
+{
+#define HANDLE_COMPOSER_PROPERTY_DUPLICATE(name, memberName, type, defaultValue)
+#define HANDLE_COMPOSER_PROPERTY_NO_DEFAULT(name, memberName, type) \
+ if (AreEqual(inType, #name)) \
+ return name;
+#define HANDLE_COMPOSER_PROPERTY(name, memberName, type, defaultValue) \
+ HANDLE_COMPOSER_PROPERTY_NO_DEFAULT(name, memberName, type)
+#define HANDLE_COMPOSER_OBJECT_TYPE(name, propmacro) propmacro
+ ITERATE_COMPOSER_OBJECT_TYPES
+#undef HANDLE_COMPOSER_OBJECT_TYPE
+#undef HANDLE_COMPOSER_PROPERTY
+#undef HANDLE_COMPOSER_PROPERTY_NO_DEFAULT
+#undef HANDLE_COMPOSER_PROPERTY_DUPLICATE
+ QT3DS_ASSERT(false);
+ return ComposerPropertyNames::Unknown;
+}
+
+#define HANDLE_COMPOSER_PROPERTY(name, memberName, dtype, defaultValue) \
+ , memberName(inCore, inInstance, DataConstructor<dtype>().Construct(defaultValue))
+
+#define HANDLE_COMPOSER_PROPERTY_NO_DEFAULT(name, memberName, dtype) \
+ , memberName(inCore, inInstance)
+
+#define HANDLE_COMPOSER_PROPERTY_DUPLICATE(name, memberName, dtype, defaultValue) \
+ HANDLE_COMPOSER_PROPERTY(name, memberName, dtype, defaultValue)
+
+#define HANDLE_COMPOSER_OBJECT_TYPE(name, propmacro) \
+ SComposerTypePropertyDefinition<ComposerObjectTypes::name>::SComposerTypePropertyDefinition( \
+ IDataCore &inCore, Qt3DSDMInstanceHandle inInstance) \
+ : reserved(false) propmacro \
+ { \
+ Q_UNUSED(inCore); \
+ Q_UNUSED(inInstance); \
+ }
+ITERATE_COMPOSER_OBJECT_TYPES
+#undef HANDLE_COMPOSER_OBJECT_TYPE
+#undef HANDLE_COMPOSER_PROPERTY
+#undef HANDLE_COMPOSER_PROPERTY_NO_DEFAULT
+#undef HANDLE_COMPOSER_PROPERTY_DUPLICATE
+
+void ComposerTypeDefinitionsHelper::SetInstanceAsCanonical(IMetaData &inMetaData,
+ Qt3DSDMInstanceHandle inInstance,
+ ComposerObjectTypes::Enum inObjectType)
+{
+ inMetaData.SetInstanceAsCanonical(inInstance, ComposerObjectTypes::Convert(inObjectType));
+}
+
+void ComposerTypeDefinitionsHelper::SetInstancePropertyValue(IDataCore &inDataCore,
+ Qt3DSDMInstanceHandle inInstance,
+ Qt3DSDMPropertyHandle inProperty,
+ const wchar_t *inPropValue)
+{
+ inDataCore.SetInstancePropertyValue(inInstance, inProperty, make_shared<CDataStr>(inPropValue));
+}
+
+void ComposerTypeDefinitionsHelper::DeriveInstance(IDataCore &inDataCore,
+ Qt3DSDMInstanceHandle inInstance,
+ Qt3DSDMInstanceHandle inParent)
+{
+ inDataCore.DeriveInstance(inInstance, inParent);
+}
+
+// Container object for all of the object definitions
+SComposerObjectDefinitions::SComposerObjectDefinitions(IDataCore &inCore, IMetaData &inMetaData)
+ : m_Typed(inCore, inMetaData, inCore.CreateInstance())
+ , m_Guided(inCore, inMetaData, inCore.CreateInstance())
+ , m_Named(inCore, inMetaData, inCore.CreateInstance())
+ , m_SlideOwner(inCore, inMetaData, inCore.CreateInstance())
+ , m_Slide(inCore, inMetaData, inCore.CreateInstance(), m_Typed, m_Named)
+ , m_Action(inCore, inMetaData, inCore.CreateInstance(), m_Typed)
+ , m_Asset(inCore, inMetaData, inCore.CreateInstance(), m_Typed, m_Guided, m_Named)
+ , m_Scene(inCore, inMetaData, inCore.CreateInstance(), m_Typed, m_Asset, m_SlideOwner)
+ , m_Image(inCore, inMetaData, inCore.CreateInstance(), m_Typed, m_Asset)
+ , m_MaterialBase(inCore, inMetaData, inCore.CreateInstance(), m_Typed, m_Asset)
+ , m_Lightmaps(inCore, inMetaData, inCore.CreateInstance(), m_Typed, m_MaterialBase)
+ , m_Material(inCore, inMetaData, inCore.CreateInstance(), m_Typed, m_Lightmaps)
+ , m_CustomMaterial(inCore, inMetaData, inCore.CreateInstance(), m_Typed, m_Lightmaps)
+ , m_ReferencedMaterial(inCore, inMetaData, inCore.CreateInstance(), m_Typed, m_Lightmaps)
+ , m_Behavior(inCore, inMetaData, inCore.CreateInstance(), m_Typed, m_Asset)
+ , m_Effect(inCore, inMetaData, inCore.CreateInstance(), m_Typed, m_Asset)
+ , m_Node(inCore, inMetaData, inCore.CreateInstance(), m_Typed, m_Asset)
+ , m_Layer(inCore, inMetaData, inCore.CreateInstance(), m_Typed, m_Node)
+ , m_Group(inCore, inMetaData, inCore.CreateInstance(), m_Typed, m_Node)
+ , m_Model(inCore, inMetaData, inCore.CreateInstance(), m_Typed, m_Node)
+ , m_Light(inCore, inMetaData, inCore.CreateInstance(), m_Typed, m_Node)
+ , m_Camera(inCore, inMetaData, inCore.CreateInstance(), m_Typed, m_Node)
+ , m_Component(inCore, inMetaData, inCore.CreateInstance(), m_Typed, m_Node, m_SlideOwner)
+ , m_Text(inCore, inMetaData, inCore.CreateInstance(), m_Typed, m_Node)
+ , m_RenderPlugin(inCore, inMetaData, inCore.CreateInstance(), m_Typed, m_Asset)
+ , m_Alias(inCore, inMetaData, inCore.CreateInstance(), m_Typed, m_Node)
+ , m_Path(inCore, inMetaData, inCore.CreateInstance(), m_Typed, m_Node)
+ , m_PathAnchorPoint(inCore, inMetaData, inCore.CreateInstance(), m_Typed, m_Asset)
+ , m_SubPath(inCore, inMetaData, inCore.CreateInstance(), m_Typed, m_Asset)
+ , m_DataCore(inCore)
+{
+}
+
+bool SComposerObjectDefinitions::IsA(Qt3DSDMInstanceHandle inInstance,
+ ComposerObjectTypes::Enum inType)
+{
+ if (m_DataCore.IsInstance(inInstance) == false)
+ return false;
+
+ switch (inType) {
+#define HANDLE_COMPOSER_OBJECT_TYPE(name, propmacro) \
+ case ComposerObjectTypes::name: \
+ return m_DataCore.IsInstanceOrDerivedFrom(inInstance, m_##name.m_Instance);
+ ITERATE_COMPOSER_OBJECT_TYPES
+#undef HANDLE_COMPOSER_OBJECT_TYPE
+ default:
+ break;
+ }
+
+ QT3DS_ASSERT(false);
+ return false;
+}
+
+// Could easily return None, meaning we can't identify the object type.
+// Checks the type of the first derivation parent, so this won't ever return
+// SlideOwner, for instance.
+ComposerObjectTypes::Enum SComposerObjectDefinitions::GetType(Qt3DSDMInstanceHandle inInstance)
+{
+ if (m_DataCore.IsInstance(inInstance) == false)
+ return ComposerObjectTypes::Unknown;
+
+ Qt3DSDMInstanceHandle theTargetInstance = inInstance;
+ TInstanceHandleList theHandleList;
+ m_DataCore.GetInstanceParents(inInstance, theHandleList);
+ if (theHandleList.empty() == false)
+ theTargetInstance = theHandleList[0];
+
+#define HANDLE_COMPOSER_OBJECT_TYPE(name, propmacro) \
+ if (m_##name.m_Instance == theTargetInstance) \
+ return ComposerObjectTypes::name;
+ ITERATE_COMPOSER_OBJECT_TYPES
+#undef HANDLE_COMPOSER_OBJECT_TYPE
+
+ return ComposerObjectTypes::Unknown;
+}
+
+Qt3DSDMInstanceHandle
+SComposerObjectDefinitions::GetInstanceForType(ComposerObjectTypes::Enum inType)
+{
+ switch (inType) {
+#define HANDLE_COMPOSER_OBJECT_TYPE(name, propmacro) \
+ case ComposerObjectTypes::name: \
+ return m_##name.m_Instance;
+ ITERATE_COMPOSER_OBJECT_TYPES
+#undef HANDLE_COMPOSER_OBJECT_TYPE
+ default:
+ break;
+ }
+
+ QT3DS_ASSERT(false);
+ return 0;
+}
diff --git a/src/dm/systems/Qt3DSDMComposerTypeDefinitions.h b/src/dm/systems/Qt3DSDMComposerTypeDefinitions.h
new file mode 100644
index 0000000..1a07940
--- /dev/null
+++ b/src/dm/systems/Qt3DSDMComposerTypeDefinitions.h
@@ -0,0 +1,956 @@
+/****************************************************************************
+**
+** Copyright (C) 2008 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
+#include "Qt3DSDMHandles.h"
+#include "Qt3DSDMDataTypes.h"
+#include "foundation/Qt3DSOption.h"
+#include "Qt3DSDMDataCore.h"
+#include <utility>
+
+// Defines the minimal property model that UIComposer needs to
+// run off of.
+namespace qt3dsdm {
+class IDataCore;
+class IMetaData;
+class ISlideCore;
+class IPropertySystem;
+
+// Extensible macro definitions
+// Enumerations *have* to be in derivation order
+// else initialization of the SComposerObjectDefinitions class
+// will fail catastrophically
+// Specific type documentation is below
+#define ITERATE_COMPOSER_OBJECT_TYPES \
+ HANDLE_COMPOSER_OBJECT_TYPE(Typed, ITERATE_COMPOSER_TYPED_PROPERTIES) \
+ HANDLE_COMPOSER_OBJECT_TYPE(Guided, ITERATE_COMPOSER_GUIDED_PROPERTIES) \
+ HANDLE_COMPOSER_OBJECT_TYPE(Named, ITERATE_COMPOSER_NAMED_PROPERTIES) \
+ HANDLE_COMPOSER_OBJECT_TYPE(SlideOwner, ITERATE_COMPOSER_NO_ADDITIONAL_PROPERTIES) \
+ HANDLE_COMPOSER_OBJECT_TYPE(Slide, ITERATE_COMPOSER_SLIDE_PROPERTIES) \
+ HANDLE_COMPOSER_OBJECT_TYPE(Action, ITERATE_COMPOSER_ACTION_PROPERTIES) \
+ HANDLE_COMPOSER_OBJECT_TYPE(Asset, ITERATE_COMPOSER_ASSET_PROPERTIES) \
+ HANDLE_COMPOSER_OBJECT_TYPE(Scene, ITERATE_COMPOSER_SCENE_PROPERTIES) \
+ HANDLE_COMPOSER_OBJECT_TYPE(Image, ITERATE_COMPOSER_IMAGE_PROPERTIES) \
+ HANDLE_COMPOSER_OBJECT_TYPE(MaterialBase, ITERATE_COMPOSER_MATERIAL_BASE_PROPERTIES) \
+ HANDLE_COMPOSER_OBJECT_TYPE(Lightmaps, ITERATE_COMPOSER_LIGHTMAP_PROPERTIES) \
+ HANDLE_COMPOSER_OBJECT_TYPE(Material, ITERATE_COMPOSER_MATERIAL_PROPERTIES) \
+ HANDLE_COMPOSER_OBJECT_TYPE(CustomMaterial, ITERATE_COMPOSER_NO_ADDITIONAL_PROPERTIES) \
+ HANDLE_COMPOSER_OBJECT_TYPE(ReferencedMaterial, \
+ ITERATE_COMPOSER_REFERENCED_MATERIAL_PROPERTIES) \
+ HANDLE_COMPOSER_OBJECT_TYPE(Behavior, ITERATE_COMPOSER_NO_ADDITIONAL_PROPERTIES) \
+ HANDLE_COMPOSER_OBJECT_TYPE(Effect, ITERATE_COMPOSER_NO_ADDITIONAL_PROPERTIES) \
+ HANDLE_COMPOSER_OBJECT_TYPE(Node, ITERATE_COMPOSER_NODE_PROPERTIES) \
+ HANDLE_COMPOSER_OBJECT_TYPE(Layer, ITERATE_COMPOSER_LAYER_PROPERTIES) \
+ HANDLE_COMPOSER_OBJECT_TYPE(Group, ITERATE_COMPOSER_GROUP_PROPERTIES) \
+ HANDLE_COMPOSER_OBJECT_TYPE(Model, ITERATE_COMPOSER_MODEL_PROPERTIES) \
+ HANDLE_COMPOSER_OBJECT_TYPE(Light, ITERATE_COMPOSER_LIGHT_PROPERTIES) \
+ HANDLE_COMPOSER_OBJECT_TYPE(Camera, ITERATE_COMPOSER_CAMERA_PROPERTIES) \
+ HANDLE_COMPOSER_OBJECT_TYPE(Component, ITERATE_COMPOSER_COMPONENT_PROPERTIES) \
+ HANDLE_COMPOSER_OBJECT_TYPE(Text, ITERATE_COMPOSER_TEXT_PROPERTIES) \
+ HANDLE_COMPOSER_OBJECT_TYPE(RenderPlugin, ITERATE_COMPOSER_NO_ADDITIONAL_PROPERTIES) \
+ HANDLE_COMPOSER_OBJECT_TYPE(Alias, ITERATE_COMPOSER_ALIAS_PROPERTIES) \
+ HANDLE_COMPOSER_OBJECT_TYPE(Path, ITERATE_COMPOSER_PATH_PROPERTIES) \
+ HANDLE_COMPOSER_OBJECT_TYPE(PathAnchorPoint, ITERATE_COMPOSER_PATH_ANCHOR_POINT_PROPERTIES) \
+ HANDLE_COMPOSER_OBJECT_TYPE(SubPath, ITERATE_COMPOSER_PATH_SUBPATH_PROPERTIES)
+
+#define ITERATE_COMPOSER_NO_ADDITIONAL_PROPERTIES
+
+#define ITERATE_COMPOSER_TYPED_PROPERTIES \
+ HANDLE_COMPOSER_PROPERTY(type, m_TypeProp, TDataStrPtr, L"Typed")
+
+#define ITERATE_COMPOSER_GUIDED_PROPERTIES \
+ HANDLE_COMPOSER_PROPERTY(id, m_GuidProp, SLong4, 0)
+
+#define ITERATE_COMPOSER_NAMED_PROPERTIES \
+ HANDLE_COMPOSER_PROPERTY(name, m_NameProp, TDataStrPtr, L"Unnamed")
+
+#define ITERATE_COMPOSER_ASSET_PROPERTIES \
+ HANDLE_COMPOSER_PROPERTY(sourcepath, m_SourcePath, TDataStrPtr, L"") \
+ HANDLE_COMPOSER_PROPERTY(importid, m_ImportId, TDataStrPtr, L"") \
+ HANDLE_COMPOSER_PROPERTY(importfile, m_ImportFile, TDataStrPtr, L"") \
+ HANDLE_COMPOSER_PROPERTY(fileid, m_FileId, TDataStrPtr, L"") \
+ HANDLE_COMPOSER_PROPERTY(starttime, m_StartTime, qt3ds::QT3DSI32, 0) \
+ HANDLE_COMPOSER_PROPERTY(endtime, m_EndTime, qt3ds::QT3DSI32, 10000) \
+ HANDLE_COMPOSER_PROPERTY(eyeball, m_Eyeball, bool, true) \
+ HANDLE_COMPOSER_PROPERTY(shy, m_Shy, bool, false) \
+ HANDLE_COMPOSER_PROPERTY(locked, m_Locked, bool, false) \
+ HANDLE_COMPOSER_PROPERTY_NO_DEFAULT(timebarcolor, m_TimebarColor, SFloat4) \
+ HANDLE_COMPOSER_PROPERTY(timebartext, m_TimebarText, TDataStrPtr, L"") \
+ HANDLE_COMPOSER_PROPERTY(controlledproperty, m_ControlledProperty, TDataStrPtr, L"")
+
+#define ITERATE_COMPOSER_SCENE_PROPERTIES \
+ HANDLE_COMPOSER_PROPERTY(bgcolorenable, m_BgColorEnable, bool, true) \
+ HANDLE_COMPOSER_PROPERTY(backgroundcolor, m_BackgroundColor, SFloat4, SFloat4(0, 0, 0, 1)) \
+ HANDLE_COMPOSER_PROPERTY_DUPLICATE(controlledproperty, m_ControlledProperty, TDataStrPtr, L"")
+
+#define ITERATE_COMPOSER_COMPONENT_PROPERTIES \
+ HANDLE_COMPOSER_PROPERTY_DUPLICATE(variants, m_variants, TDataStrPtr, L"") \
+ HANDLE_COMPOSER_PROPERTY_DUPLICATE(controlledproperty, m_ControlledProperty, TDataStrPtr, L"")
+
+#define ITERATE_COMPOSER_NODE_PROPERTIES \
+ HANDLE_COMPOSER_PROPERTY(position, m_Position, SFloat3, SFloat3(0, 0, 0)) \
+ HANDLE_COMPOSER_PROPERTY(rotation, m_Rotation, SFloat3, SFloat3(0, 0, 0)) \
+ HANDLE_COMPOSER_PROPERTY(scale, m_Scale, SFloat3, SFloat3(1, 1, 1)) \
+ HANDLE_COMPOSER_PROPERTY(pivot, m_Pivot, SFloat3, SFloat3(0, 0, 0)) \
+ HANDLE_COMPOSER_PROPERTY(opacity, m_Opacity, float, 100.f) \
+ HANDLE_COMPOSER_PROPERTY(rotationorder, m_RotationOrder, TDataStrPtr, L"YXZ") \
+ HANDLE_COMPOSER_PROPERTY(orientation, m_Orientation, TDataStrPtr, L"Left Handed") \
+ HANDLE_COMPOSER_PROPERTY(boneid, m_BoneId, qt3ds::QT3DSI32, 0) \
+ HANDLE_COMPOSER_PROPERTY(ignoresparent, m_IgnoresParent, bool, false) \
+ HANDLE_COMPOSER_PROPERTY_DUPLICATE(controlledproperty, m_ControlledProperty, TDataStrPtr, L"")
+
+#define ITERATE_COMPOSER_MODEL_PROPERTIES \
+ HANDLE_COMPOSER_PROPERTY(shadowcaster, m_ShadowCaster, bool, true) \
+ HANDLE_COMPOSER_PROPERTY(poseroot, m_PoseRoot, qt3ds::QT3DSI32, -1) \
+ HANDLE_COMPOSER_PROPERTY(tessellation, m_Tessellation, TDataStrPtr, L"None") \
+ HANDLE_COMPOSER_PROPERTY(edgetess, m_EdgeTess, float, 1.0) \
+ HANDLE_COMPOSER_PROPERTY(innertess, m_InnerTess, float, 1.0) \
+ HANDLE_COMPOSER_PROPERTY_DUPLICATE(variants, m_variants, TDataStrPtr, L"") \
+ HANDLE_COMPOSER_PROPERTY_DUPLICATE(controlledproperty, m_ControlledProperty, TDataStrPtr, L"")
+
+#define ITERATE_COMPOSER_IMAGE_PROPERTIES \
+ HANDLE_COMPOSER_PROPERTY(scaleu, m_RepeatU, float, 1.0f) \
+ HANDLE_COMPOSER_PROPERTY(scalev, m_RepeatV, float, 1.0f) \
+ HANDLE_COMPOSER_PROPERTY(mappingmode, m_TextureMapping, TDataStrPtr, L"UV Mapping") \
+ HANDLE_COMPOSER_PROPERTY(tilingmodehorz, m_TilingU, TDataStrPtr, L"No Tiling") \
+ HANDLE_COMPOSER_PROPERTY(tilingmodevert, m_TilingV, TDataStrPtr, L"No Tiling") \
+ HANDLE_COMPOSER_PROPERTY(rotationuv, m_RotationUV, float, 0.f) \
+ HANDLE_COMPOSER_PROPERTY(positionu, m_PositionU, float, 0.f) \
+ HANDLE_COMPOSER_PROPERTY(positionv, m_PositionV, float, 0.f) \
+ HANDLE_COMPOSER_PROPERTY(pivotu, m_PivotU, float, 0.f) \
+ HANDLE_COMPOSER_PROPERTY(pivotv, m_PivotV, float, 0.f) \
+ HANDLE_COMPOSER_PROPERTY(subpresentation, m_SubPresentation, TDataStrPtr, L"") \
+ HANDLE_COMPOSER_PROPERTY_DUPLICATE(controlledproperty, m_ControlledProperty, TDataStrPtr, L"")
+
+#define ITERATE_COMPOSER_LIGHTMAP_PROPERTIES \
+ HANDLE_COMPOSER_PROPERTY(lightmapindirect, m_LightmapIndirect, SLong4, 0) \
+ HANDLE_COMPOSER_PROPERTY(lightmapradiosity, m_LightmapRadiosity, SLong4, 0) \
+ HANDLE_COMPOSER_PROPERTY(lightmapshadow, m_LightmapShadow, SLong4, 0) \
+ HANDLE_COMPOSER_PROPERTY_DUPLICATE(controlledproperty, m_ControlledProperty, TDataStrPtr, L"")
+
+#define ITERATE_COMPOSER_CUSTOM_MATERIAL_PROPERTIES \
+ HANDLE_QT3DS_RENDER_PROPERTY(iblprobe, m_IblProbe, SLong4, 0)
+
+#define ITERATE_COMPOSER_MATERIAL_BASE_PROPERTIES \
+ HANDLE_COMPOSER_PROPERTY(iblprobe, m_IblProbe, SLong4, 0)
+
+#define ITERATE_COMPOSER_MATERIAL_PROPERTIES \
+ HANDLE_COMPOSER_PROPERTY(shaderlighting, m_ShaderLighting, TDataStrPtr, L"Vertex") \
+ HANDLE_COMPOSER_PROPERTY(blendmode, m_BlendMode, TDataStrPtr, L"Normal") \
+ HANDLE_COMPOSER_PROPERTY(diffuse, m_DiffuseColor, SFloat4, SFloat4(1, 1, 1, 1)) \
+ HANDLE_COMPOSER_PROPERTY(diffusemap, m_DiffuseMap1, SLong4, 0) \
+ HANDLE_COMPOSER_PROPERTY(diffusemap2, m_DiffuseMap2, SLong4, 0) \
+ HANDLE_COMPOSER_PROPERTY(diffusemap3, m_DiffuseMap3, SLong4, 0) \
+ HANDLE_COMPOSER_PROPERTY(specularreflection, m_SpecularReflection, SLong4, 0) \
+ HANDLE_COMPOSER_PROPERTY(specularamount, m_SpecularAmount, float, 0.f) \
+ HANDLE_COMPOSER_PROPERTY(specularroughness, m_SpecularRoughness, float, 50.f) \
+ HANDLE_COMPOSER_PROPERTY(roughnessmap, m_RoughnessMap, SLong4, 0) \
+ HANDLE_COMPOSER_PROPERTY_DUPLICATE(opacity, m_Opacity, float, 100.f) \
+ HANDLE_COMPOSER_PROPERTY(opacitymap, m_OpacityMap, SLong4, 0) \
+ HANDLE_COMPOSER_PROPERTY(emissivecolor, m_EmissiveColor, SFloat4, SFloat4(1, 1, 1, 1)) \
+ HANDLE_COMPOSER_PROPERTY(emissivepower, m_EmissivePower, float, 0.f) \
+ HANDLE_COMPOSER_PROPERTY(emissivemap, m_EmissiveMap, SLong4, 0) \
+ HANDLE_COMPOSER_PROPERTY(emissivemap2, m_EmissiveMap2, SLong4, 0) \
+ HANDLE_COMPOSER_PROPERTY(bumpmap, m_BumpMap, SLong4, 0) \
+ HANDLE_COMPOSER_PROPERTY(bumpamount, m_BumpAmount, float, 9.0f) \
+ HANDLE_COMPOSER_PROPERTY(normalmap, m_NormalMap, SLong4, 0) \
+ HANDLE_COMPOSER_PROPERTY(displacementmap, m_DisplacementMap, SLong4, 0) \
+ HANDLE_COMPOSER_PROPERTY(displaceamount, m_DisplaceAmount, float, 0.5f) \
+ HANDLE_COMPOSER_PROPERTY(translucencymap, m_TranslucencyMap, SLong4, 0) \
+ HANDLE_COMPOSER_PROPERTY(translucentfalloff, m_TranslucentFalloff, float, 1.f) \
+ HANDLE_COMPOSER_PROPERTY(diffuselightwrap, m_DiffuseLightWrap, float, 0.f) \
+ HANDLE_COMPOSER_PROPERTY(specularmap, m_SpecularMap, SLong4, 0) \
+ HANDLE_COMPOSER_PROPERTY(specularmodel, m_SpecularModel, TDataStrPtr, L"Default") \
+ HANDLE_COMPOSER_PROPERTY(speculartint, m_SpecularTint, SFloat4, SFloat4(1, 1, 1, 1)) \
+ HANDLE_COMPOSER_PROPERTY(ior, m_IOR, float, 0) \
+ HANDLE_COMPOSER_PROPERTY(fresnelPower, m_FresnelPower, float, 0) \
+ HANDLE_COMPOSER_PROPERTY(vertexcolors, m_VertexColors, bool, false) \
+ HANDLE_COMPOSER_PROPERTY_DUPLICATE(controlledproperty, m_ControlledProperty, TDataStrPtr, L"")
+
+#define ITERATE_COMPOSER_REFERENCED_MATERIAL_PROPERTIES \
+ HANDLE_COMPOSER_PROPERTY(referencedmaterial, m_ReferencedMaterial, SObjectRefType, L"")
+
+#define ITERATE_COMPOSER_LAYER_PROPERTIES \
+ HANDLE_COMPOSER_PROPERTY(progressiveaa, m_ProgressiveAA, TDataStrPtr, L"None") \
+ HANDLE_COMPOSER_PROPERTY(multisampleaa, m_MultisampleAA, TDataStrPtr, L"None") \
+ HANDLE_COMPOSER_PROPERTY(temporalaa, m_TemporalAA, bool, false) \
+ HANDLE_COMPOSER_PROPERTY(disabledepthtest, m_DisableDepthTest, bool, false) \
+ HANDLE_COMPOSER_PROPERTY(disabledepthprepass, m_DisableDepthPrepass, bool, false) \
+ HANDLE_COMPOSER_PROPERTY(background, m_Background, TDataStrPtr, L"Transparent") \
+ HANDLE_COMPOSER_PROPERTY_DUPLICATE(backgroundcolor, m_BackgroundColor, SFloat4, \
+ SFloat4(0, 0, 0, 1)) \
+ HANDLE_COMPOSER_PROPERTY(blendtype, m_BlendType, TDataStrPtr, L"Normal") \
+ HANDLE_COMPOSER_PROPERTY(horzfields, m_HorizontalFieldValues, TDataStrPtr, L"Left/Width") \
+ HANDLE_COMPOSER_PROPERTY(left, m_Left, float, 0) \
+ HANDLE_COMPOSER_PROPERTY(leftunits, m_LeftUnits, TDataStrPtr, L"percent") \
+ HANDLE_COMPOSER_PROPERTY(width, m_Width, float, 100.0f) \
+ HANDLE_COMPOSER_PROPERTY(widthunits, m_WidthUnits, TDataStrPtr, L"percent") \
+ HANDLE_COMPOSER_PROPERTY(right, m_Right, float, 0) \
+ HANDLE_COMPOSER_PROPERTY(rightunits, m_RightUnits, TDataStrPtr, L"percent") \
+ HANDLE_COMPOSER_PROPERTY(vertfields, m_VerticalFieldValues, TDataStrPtr, L"Top/Height") \
+ HANDLE_COMPOSER_PROPERTY(top, m_Top, float, 0) \
+ HANDLE_COMPOSER_PROPERTY(topunits, m_TopUnits, TDataStrPtr, L"percent") \
+ HANDLE_COMPOSER_PROPERTY(height, m_Height, float, 100.0f) \
+ HANDLE_COMPOSER_PROPERTY(heightunits, m_HeightUnits, TDataStrPtr, L"percent") \
+ HANDLE_COMPOSER_PROPERTY(bottom, m_Bottom, float, 0) \
+ HANDLE_COMPOSER_PROPERTY(bottomunits, m_BottomUnits, TDataStrPtr, L"percent") \
+ HANDLE_COMPOSER_PROPERTY(aostrength, m_AoStrength, float, 0) \
+ HANDLE_COMPOSER_PROPERTY(aodistance, m_AoDistance, float, 0) \
+ HANDLE_COMPOSER_PROPERTY(aosoftness, m_AoSoftness, float, 0) \
+ HANDLE_COMPOSER_PROPERTY(aobias, m_AoBias, float, 0) \
+ HANDLE_COMPOSER_PROPERTY(aosamplerate, m_AoSamplerate, qt3ds::QT3DSI32, 1) \
+ HANDLE_COMPOSER_PROPERTY(aodither, m_AoDither, bool, false) \
+ HANDLE_COMPOSER_PROPERTY(shadowstrength, m_ShadowStrength, float, 0) \
+ HANDLE_COMPOSER_PROPERTY(shadowdist, m_ShadowDist, float, 0) \
+ HANDLE_COMPOSER_PROPERTY(shadowsoftness, m_ShadowSoftness, float, 0) \
+ HANDLE_COMPOSER_PROPERTY(shadowbias, m_ShadowBias, float, 0) \
+ HANDLE_COMPOSER_PROPERTY(lightprobe, m_LightProbe, SLong4, 0) \
+ HANDLE_COMPOSER_PROPERTY(probebright, m_ProbeBright, float, 100.0f) \
+ HANDLE_COMPOSER_PROPERTY(fastibl, m_FastIbl, bool, true) \
+ HANDLE_COMPOSER_PROPERTY(probehorizon, m_ProbeHorizon, float, -1) \
+ HANDLE_COMPOSER_PROPERTY(probefov, m_ProbeFov, float, 180.0f) \
+ HANDLE_COMPOSER_PROPERTY(lightprobe2, m_LightProbe2, SLong4, 0) \
+ HANDLE_COMPOSER_PROPERTY(probe2fade, m_Probe2Fade, float, 1) \
+ HANDLE_COMPOSER_PROPERTY(probe2window, m_Probe2Window, float, 1) \
+ HANDLE_COMPOSER_PROPERTY(probe2pos, m_Probe2Pos, float, 0.5f) \
+ HANDLE_COMPOSER_PROPERTY(variants, m_variants, TDataStrPtr, L"") \
+ HANDLE_COMPOSER_PROPERTY_DUPLICATE(controlledproperty, m_ControlledProperty, TDataStrPtr, L"")
+
+#define ITERATE_COMPOSER_GROUP_PROPERTIES \
+ HANDLE_COMPOSER_PROPERTY_DUPLICATE(variants, m_variants, TDataStrPtr, L"") \
+
+#define ITERATE_COMPOSER_LIGHT_PROPERTIES \
+ HANDLE_COMPOSER_PROPERTY(lighttype, m_LightType, TDataStrPtr, L"Directional") \
+ HANDLE_COMPOSER_PROPERTY(scope, m_Scope, SObjectRefType, L"") \
+ HANDLE_COMPOSER_PROPERTY(lightdiffuse, m_LightColor, SFloat4, SFloat4(1, 1, 1, 1)) \
+ HANDLE_COMPOSER_PROPERTY(lightspecular, m_SpecularColor, SFloat4, SFloat4(1, 1, 1, 1)) \
+ HANDLE_COMPOSER_PROPERTY(lightambient, m_AmbientColor, SFloat4, SFloat4(0, 0, 0, 1)) \
+ HANDLE_COMPOSER_PROPERTY(brightness, m_Brightness, float, 100.0f) \
+ HANDLE_COMPOSER_PROPERTY(linearfade, m_LinearFade, float, 0.0f) \
+ HANDLE_COMPOSER_PROPERTY(expfade, m_ExpFade, float, 0.0f) \
+ HANDLE_COMPOSER_PROPERTY(areawidth, m_AreaWidth, float, 0.0f) \
+ HANDLE_COMPOSER_PROPERTY(areaheight, m_AreaHeight, float, 0.0f) \
+ HANDLE_COMPOSER_PROPERTY(castshadow, m_CastShadow, bool, false) \
+ HANDLE_COMPOSER_PROPERTY(shdwbias, m_ShadowBias, float, 0.0f) \
+ HANDLE_COMPOSER_PROPERTY(shdwfactor, m_ShadowFactor, float, 5.0f) \
+ HANDLE_COMPOSER_PROPERTY(shdwmapres, m_ShadowMapRes, qt3ds::QT3DSI32, 9) \
+ HANDLE_COMPOSER_PROPERTY(shdwmapfar, m_ShadowMapFar, float, 5000.0f) \
+ HANDLE_COMPOSER_PROPERTY(shdwmapfov, m_ShadowMapFov, float, 90.0f) \
+ HANDLE_COMPOSER_PROPERTY(shdwfilter, m_ShadowFilter, float, 35.0f) \
+ HANDLE_COMPOSER_PROPERTY_DUPLICATE(controlledproperty, m_ControlledProperty, TDataStrPtr, L"")
+
+#define ITERATE_COMPOSER_CAMERA_PROPERTIES \
+ HANDLE_COMPOSER_PROPERTY(orthographic, m_Orthographic, bool, false) \
+ HANDLE_COMPOSER_PROPERTY(fov, m_Fov, float, 60.f) \
+ HANDLE_COMPOSER_PROPERTY(fovhorizontal, m_FovHorizontal, bool, false) \
+ HANDLE_COMPOSER_PROPERTY(clipnear, m_ClipNear, float, 10.f) \
+ HANDLE_COMPOSER_PROPERTY(clipfar, m_ClipFar, float, 100000.f) \
+ HANDLE_COMPOSER_PROPERTY(scalemode, m_ScaleMode, TDataStrPtr, L"Fit") \
+ HANDLE_COMPOSER_PROPERTY(scaleanchor, m_ScaleAnchor, TDataStrPtr, L"Center") \
+ HANDLE_COMPOSER_PROPERTY_DUPLICATE(controlledproperty, m_ControlledProperty, TDataStrPtr, L"")
+
+#define ITERATE_COMPOSER_EDIT_CAMERA_PROPERTIES HANDLE_COMPOSER_PROPERTY(is3d, m_Is3d, bool, false)
+
+#define ITERATE_COMPOSER_TEXT_PROPERTIES \
+ HANDLE_COMPOSER_PROPERTY(textstring, m_TextString, TDataStrPtr, L"Text") \
+ HANDLE_COMPOSER_PROPERTY(textcolor, m_TextColor, SFloat4, SFloat4(1, 1, 1, 1)) \
+ HANDLE_COMPOSER_PROPERTY(font, m_Font, TDataStrPtr, L"arial") \
+ HANDLE_COMPOSER_PROPERTY(size, m_Size, float, 24.f) \
+ HANDLE_COMPOSER_PROPERTY(horzalign, m_HorzAlign, TDataStrPtr, L"Center") \
+ HANDLE_COMPOSER_PROPERTY(vertalign, m_VertAlign, TDataStrPtr, L"Middle") \
+ HANDLE_COMPOSER_PROPERTY(leading, m_Leading, float, 0.f) \
+ HANDLE_COMPOSER_PROPERTY(tracking, m_Tracking, float, 0.f) \
+ HANDLE_COMPOSER_PROPERTY(dropshadow, m_DropShadow, bool, false) \
+ HANDLE_COMPOSER_PROPERTY(dropshadowstrength, m_DropShadowStrength, float, 80.f) \
+ HANDLE_COMPOSER_PROPERTY(dropshadowoffsetx, m_DropShadowOffsetX, float, 0.f) \
+ HANDLE_COMPOSER_PROPERTY(dropshadowoffsety, m_DropShadowOffsetY, float, 0.f) \
+ HANDLE_COMPOSER_PROPERTY(wordwrap, m_WordWrap, TDataStrPtr, L"WrapWord") \
+ HANDLE_COMPOSER_PROPERTY(boundingbox, m_BoundingBox, SFloat2, SFloat2(0, 0)) \
+ HANDLE_COMPOSER_PROPERTY(elide, m_Elide, TDataStrPtr, L"ElideNone") \
+ HANDLE_COMPOSER_PROPERTY(enableacceleratedfont, m_EnableAcceleratedFont, bool, false) \
+ HANDLE_COMPOSER_PROPERTY_DUPLICATE(variants, m_variants, TDataStrPtr, L"") \
+ HANDLE_COMPOSER_PROPERTY_DUPLICATE(controlledproperty, m_ControlledProperty, TDataStrPtr, L"")
+
+#define ITERATE_COMPOSER_SLIDE_PROPERTIES \
+ HANDLE_COMPOSER_PROPERTY(componentid, m_ComponentId, SLong4, 0) \
+ HANDLE_COMPOSER_PROPERTY(playmode, m_PlayMode, TDataStrPtr, L"Looping") \
+ HANDLE_COMPOSER_PROPERTY(playthroughto, m_PlaythroughTo, SStringOrInt, L"Next") \
+ HANDLE_COMPOSER_PROPERTY(initialplaystate, m_InitialPlayState, TDataStrPtr, L"Play") \
+ HANDLE_COMPOSER_PROPERTY_DUPLICATE(controlledproperty, m_ControlledProperty, TDataStrPtr, L"")
+
+#define ITERATE_COMPOSER_ACTION_PROPERTIES \
+ HANDLE_COMPOSER_PROPERTY(actioneyeball, m_ActionEyeball, bool, true)
+
+#define ITERATE_COMPOSER_ALIAS_PROPERTIES \
+ HANDLE_COMPOSER_PROPERTY(referencednode, m_ReferencedNode, SObjectRefType, L"") \
+ HANDLE_COMPOSER_PROPERTY_DUPLICATE(controlledproperty, m_ControlledProperty, TDataStrPtr, L"")
+
+#define ITERATE_COMPOSER_PATH_PROPERTIES \
+ HANDLE_COMPOSER_PROPERTY(pathtype, m_PathType, TDataStrPtr, L"Geometry") \
+ HANDLE_COMPOSER_PROPERTY_DUPLICATE(width, m_Width, float, 5.0f) \
+ HANDLE_COMPOSER_PROPERTY(linearerror, m_LinearError, float, 10) \
+ HANDLE_COMPOSER_PROPERTY(edgetessamount, m_EdgeTessAmount, float, 8) \
+ HANDLE_COMPOSER_PROPERTY(innertessamount, m_InnerTessAmount, float, 8) \
+ HANDLE_COMPOSER_PROPERTY(begincap, m_BeginCap, TDataStrPtr, L"None") \
+ HANDLE_COMPOSER_PROPERTY(begincapoffset, m_BeginCapOffset, float, 0.0f) \
+ HANDLE_COMPOSER_PROPERTY(begincapopacity, m_BeginCapOpacity, float, 0.0f) \
+ HANDLE_COMPOSER_PROPERTY(begincapwidth, m_BeginCapWidth, float, 0.0f) \
+ HANDLE_COMPOSER_PROPERTY(endcap, m_EndCap, TDataStrPtr, L"None") \
+ HANDLE_COMPOSER_PROPERTY(endcapoffset, m_EndCapOffset, float, 0.0f) \
+ HANDLE_COMPOSER_PROPERTY(endcapopacity, m_EndCapOpacity, float, 0.0f) \
+ HANDLE_COMPOSER_PROPERTY(endcapwidth, m_EndCapWidth, float, 0.0f) \
+ HANDLE_COMPOSER_PROPERTY(paintstyle, m_PaintStyle, TDataStrPtr, L"Stroked") \
+ HANDLE_COMPOSER_PROPERTY_DUPLICATE(controlledproperty, m_ControlledProperty, TDataStrPtr, L"")
+
+#define ITERATE_COMPOSER_PATH_ANCHOR_POINT_PROPERTIES \
+ HANDLE_COMPOSER_PROPERTY_DUPLICATE(position, m_Position, SFloat2, SFloat2(0.0f, 0.0f)) \
+ HANDLE_COMPOSER_PROPERTY(incomingangle, m_IncomingAngle, float, 0.0f) \
+ HANDLE_COMPOSER_PROPERTY(incomingdistance, m_IncomingDistance, float, 0.0f) \
+ HANDLE_COMPOSER_PROPERTY(outgoingdistance, m_OutgoingDistance, float, 0.0f)
+
+#define ITERATE_COMPOSER_PATH_SUBPATH_PROPERTIES \
+ HANDLE_COMPOSER_PROPERTY(closed, m_Closed, bool, true)
+
+struct ComposerObjectTypes
+{
+ enum Enum {
+ Unknown = 0,
+#define HANDLE_COMPOSER_OBJECT_TYPE(name, propmacro) name,
+ ITERATE_COMPOSER_OBJECT_TYPES
+#undef HANDLE_COMPOSER_OBJECT_TYPE
+ ControllableObject
+ };
+ static const wchar_t *Convert(ComposerObjectTypes::Enum inType);
+ static ComposerObjectTypes::Enum Convert(const wchar_t *inType);
+ static ComposerObjectTypes::Enum Convert(const char8_t *inType);
+};
+
+struct ComposerPropertyNames
+{
+ enum Enum {
+ Unknown = 0,
+#define HANDLE_COMPOSER_PROPERTY_NO_DEFAULT(name, memberName, type) name,
+#define HANDLE_COMPOSER_PROPERTY_DUPLICATE(name, memberName, type, defaultValue)
+#define HANDLE_COMPOSER_PROPERTY(name, memberName, type, defaultValue) name,
+#define HANDLE_COMPOSER_OBJECT_TYPE(name, propmacro) propmacro
+ ITERATE_COMPOSER_OBJECT_TYPES
+#undef HANDLE_COMPOSER_OBJECT_TYPE
+#undef HANDLE_COMPOSER_PROPERTY_NO_DEFAULT
+#undef HANDLE_COMPOSER_PROPERTY
+#undef HANDLE_COMPOSER_PROPERTY_DUPLICATE
+ };
+
+ static const wchar_t *Convert(ComposerPropertyNames::Enum inType);
+ static ComposerPropertyNames::Enum Convert(const wchar_t *inType);
+ static const char8_t *ConvertNarrow(ComposerPropertyNames::Enum inType);
+ static ComposerPropertyNames::Enum Convert(const char8_t *inType);
+};
+
+template <typename TDataType>
+struct TypeToDataTypeMap
+{
+ bool force_compile_error;
+};
+template <DataModelDataType::Value TEnum>
+struct DataTypeToTypeMap
+{
+ bool force_compile_error;
+};
+
+#define QT3DSDM_DEFINE_TYPE_TO_DATA_TYPE(enumName, type) \
+ template <> \
+ struct TypeToDataTypeMap<type> \
+ { \
+ static DataModelDataType::Value GetDataType() { return enumName; } \
+ }; \
+ template <> \
+ struct DataTypeToTypeMap<enumName> \
+ { \
+ typedef type TDataType; \
+ };
+
+QT3DSDM_DEFINE_TYPE_TO_DATA_TYPE(DataModelDataType::Float, float)
+QT3DSDM_DEFINE_TYPE_TO_DATA_TYPE(DataModelDataType::Float2, SFloat2)
+QT3DSDM_DEFINE_TYPE_TO_DATA_TYPE(DataModelDataType::Float3, SFloat3)
+QT3DSDM_DEFINE_TYPE_TO_DATA_TYPE(DataModelDataType::Float4, SFloat4)
+QT3DSDM_DEFINE_TYPE_TO_DATA_TYPE(DataModelDataType::Long, qt3ds::QT3DSI32)
+QT3DSDM_DEFINE_TYPE_TO_DATA_TYPE(DataModelDataType::String, TDataStrPtr)
+QT3DSDM_DEFINE_TYPE_TO_DATA_TYPE(DataModelDataType::Bool, bool)
+QT3DSDM_DEFINE_TYPE_TO_DATA_TYPE(DataModelDataType::Long4, SLong4)
+QT3DSDM_DEFINE_TYPE_TO_DATA_TYPE(DataModelDataType::StringRef, SStringRef)
+QT3DSDM_DEFINE_TYPE_TO_DATA_TYPE(DataModelDataType::StringOrInt, SStringOrInt)
+QT3DSDM_DEFINE_TYPE_TO_DATA_TYPE(DataModelDataType::ObjectRef, SObjectRefType)
+QT3DSDM_DEFINE_TYPE_TO_DATA_TYPE(DataModelDataType::FloatList, TFloatList)
+
+#undef QT3DSDM_DEFINE_TYPE_TO_DATA_TYPE
+
+template <typename TDataType>
+inline DataModelDataType::Value TypeToDataType()
+{
+ return TypeToDataTypeMap<TDataType>::GetDataType();
+}
+
+template <ComposerPropertyNames::Enum TPropName, typename TDataType>
+struct SComposerPropertyDefinition
+{
+ qt3ds::foundation::Option<TDataType> m_DefaultValue;
+ Qt3DSDMPropertyHandle m_Property;
+ SComposerPropertyDefinition(IDataCore &inDataCore, Qt3DSDMInstanceHandle inInstance,
+ const TDataType &inDefault)
+ : m_DefaultValue(inDefault)
+ {
+ QT3DSDM_LOG_FUNCTION("SComposerPropertyDefinition-1");
+ m_Property = inDataCore.AddProperty(inInstance, ComposerPropertyNames::Convert(TPropName),
+ TypeToDataType<TDataType>());
+ if (m_DefaultValue.hasValue())
+ inDataCore.SetInstancePropertyValue(inInstance, m_Property, m_DefaultValue.getValue());
+ }
+ SComposerPropertyDefinition(IDataCore &inDataCore, Qt3DSDMInstanceHandle inInstance)
+ {
+ QT3DSDM_LOG_FUNCTION("SComposerPropertyDefinition-2");
+ m_Property = inDataCore.AddProperty(inInstance, ComposerPropertyNames::Convert(TPropName),
+ TypeToDataType<TDataType>());
+ }
+ operator Qt3DSDMPropertyHandle() const { return m_Property; }
+};
+
+// Define all the objects with their properties
+
+template <ComposerObjectTypes::Enum>
+struct SComposerTypePropertyDefinition
+{
+ bool force_compile_error;
+};
+
+#define HANDLE_COMPOSER_PROPERTY_NO_DEFAULT(name, memberName, dtype) \
+ SComposerPropertyDefinition<ComposerPropertyNames::name, dtype> memberName;
+
+#define HANDLE_COMPOSER_PROPERTY(name, memberName, dtype, defaultValue) \
+ HANDLE_COMPOSER_PROPERTY_NO_DEFAULT(name, memberName, dtype)
+#define HANDLE_COMPOSER_PROPERTY_DUPLICATE(name, memberName, dtype, defaultValue) \
+ HANDLE_COMPOSER_PROPERTY(name, memberName, dtype, defaultValue)
+
+#define HANDLE_COMPOSER_OBJECT_TYPE(name, propmacro) \
+ template <> \
+ struct SComposerTypePropertyDefinition<ComposerObjectTypes::name> \
+ { \
+ bool reserved; \
+ propmacro SComposerTypePropertyDefinition(IDataCore &inCore, \
+ Qt3DSDMInstanceHandle inInstance); \
+ };
+
+ITERATE_COMPOSER_OBJECT_TYPES
+
+#undef HANDLE_COMPOSER_OBJECT_TYPE
+#undef HANDLE_COMPOSER_PROPERTY
+#undef HANDLE_COMPOSER_PROPERTY_NO_DEFAULT
+#undef HANDLE_COMPOSER_PROPERTY_DUPLICATE
+
+struct ComposerTypeDefinitionsHelper
+{
+ // Functions here so we don't have to include UICDMDataCore.h or UICDMMetaData.h
+ static void SetInstanceAsCanonical(IMetaData &inMetaData, Qt3DSDMInstanceHandle inInstance,
+ ComposerObjectTypes::Enum inObjectType);
+ static void SetInstancePropertyValue(IDataCore &inDataCore, Qt3DSDMInstanceHandle inInstance,
+ Qt3DSDMPropertyHandle inProperty,
+ const wchar_t *inPropValue);
+ static void DeriveInstance(IDataCore &inDataCore, Qt3DSDMInstanceHandle inInstance,
+ Qt3DSDMInstanceHandle inParent);
+};
+
+template <ComposerObjectTypes::Enum TEnumType>
+struct SComposerBaseObjectDefinition : public SComposerTypePropertyDefinition<TEnumType>
+{
+ Qt3DSDMInstanceHandle m_Instance;
+ SComposerBaseObjectDefinition(IDataCore &inCore, IMetaData &inMetaData,
+ Qt3DSDMInstanceHandle inInstance)
+ : SComposerTypePropertyDefinition<TEnumType>(inCore, inInstance)
+ , m_Instance(inInstance)
+ {
+ QT3DSDM_LOG_FUNCTION("SComposerBaseObjectDefinition");
+ ComposerTypeDefinitionsHelper::SetInstanceAsCanonical(inMetaData, inInstance, TEnumType);
+ }
+
+ template <ComposerObjectTypes::Enum TBaseType>
+ void Derive(IDataCore &inCore, const SComposerBaseObjectDefinition<TBaseType> &inParent)
+ {
+ QT3DSDM_LOG_FUNCTION("SComposerBaseObjectDefinition::Derive");
+ ComposerTypeDefinitionsHelper::DeriveInstance(inCore, m_Instance, inParent.m_Instance);
+ }
+ void SetType(IDataCore &inCore,
+ const SComposerBaseObjectDefinition<ComposerObjectTypes::Typed> &inParent)
+ {
+ QT3DSDM_LOG_FUNCTION("SComposerBaseObjectDefinition::SetInstancePropertyValue");
+ ComposerTypeDefinitionsHelper::SetInstancePropertyValue(
+ inCore, m_Instance, inParent.m_TypeProp, ComposerObjectTypes::Convert(TEnumType));
+ }
+ void TypedDerive(IDataCore &inCore,
+ const SComposerBaseObjectDefinition<ComposerObjectTypes::Typed> &inParent)
+ {
+ QT3DSDM_LOG_FUNCTION("SComposerBaseObjectDefinition::TypedDerive");
+ Derive(inCore, inParent);
+ SetType(inCore, inParent);
+ }
+};
+
+template <ComposerObjectTypes::Enum TEnumType>
+struct SComposerObjectDefinition : public SComposerBaseObjectDefinition<TEnumType>
+{
+ SComposerObjectDefinition(IDataCore &inCore, IMetaData &inMetaData,
+ Qt3DSDMInstanceHandle inInstance)
+ : SComposerBaseObjectDefinition<TEnumType>(inCore, inMetaData, inInstance)
+ {
+ }
+};
+
+// Base class of slides
+template <>
+struct SComposerObjectDefinition<ComposerObjectTypes::Slide>
+ : public SComposerBaseObjectDefinition<ComposerObjectTypes::Slide>
+{
+ SComposerObjectDefinition(IDataCore &inCore, IMetaData &inMetaData,
+ Qt3DSDMInstanceHandle inInstance,
+ SComposerObjectDefinition<ComposerObjectTypes::Typed> &inTyped,
+ SComposerObjectDefinition<ComposerObjectTypes::Named> &inNamed)
+ : SComposerBaseObjectDefinition<ComposerObjectTypes::Slide>(inCore, inMetaData, inInstance)
+ {
+ TypedDerive(inCore, inTyped);
+ Derive(inCore, inNamed);
+ }
+};
+
+// Base class of actions
+template <>
+struct SComposerObjectDefinition<ComposerObjectTypes::Action>
+ : public SComposerBaseObjectDefinition<ComposerObjectTypes::Action>
+{
+ SComposerObjectDefinition(IDataCore &inCore, IMetaData &inMetaData,
+ Qt3DSDMInstanceHandle inInstance,
+ SComposerObjectDefinition<ComposerObjectTypes::Typed> &inTyped)
+ : SComposerBaseObjectDefinition<ComposerObjectTypes::Action>(inCore, inMetaData, inInstance)
+ {
+ TypedDerive(inCore, inTyped);
+ }
+};
+
+// Base class of assets
+template <>
+struct SComposerObjectDefinition<ComposerObjectTypes::Asset>
+ : public SComposerBaseObjectDefinition<ComposerObjectTypes::Asset>
+{
+ SComposerObjectDefinition(IDataCore &inCore, IMetaData &inMetaData,
+ Qt3DSDMInstanceHandle inInstance,
+ SComposerObjectDefinition<ComposerObjectTypes::Typed> &inTyped,
+ SComposerObjectDefinition<ComposerObjectTypes::Guided> &inGuided,
+ SComposerObjectDefinition<ComposerObjectTypes::Named> &inNamed)
+ : SComposerBaseObjectDefinition<ComposerObjectTypes::Asset>(inCore, inMetaData, inInstance)
+ {
+ TypedDerive(inCore, inTyped);
+ Derive(inCore, inGuided);
+ Derive(inCore, inNamed);
+ }
+};
+
+template <>
+struct SComposerObjectDefinition<ComposerObjectTypes::Scene>
+ : public SComposerBaseObjectDefinition<ComposerObjectTypes::Scene>
+{
+ SComposerObjectDefinition(
+ IDataCore &inCore, IMetaData &inMetaData, Qt3DSDMInstanceHandle inInstance,
+ SComposerObjectDefinition<ComposerObjectTypes::Typed> &inTyped,
+ SComposerObjectDefinition<ComposerObjectTypes::Asset> &inAsset,
+ SComposerObjectDefinition<ComposerObjectTypes::SlideOwner> &inSlideOwner)
+ : SComposerBaseObjectDefinition<ComposerObjectTypes::Scene>(inCore, inMetaData, inInstance)
+ {
+ Derive(inCore, inAsset);
+ Derive(inCore, inSlideOwner);
+ SetType(inCore, inTyped);
+ }
+};
+
+template <>
+struct SComposerObjectDefinition<ComposerObjectTypes::Image>
+ : public SComposerBaseObjectDefinition<ComposerObjectTypes::Image>
+{
+ SComposerObjectDefinition(IDataCore &inCore, IMetaData &inMetaData,
+ Qt3DSDMInstanceHandle inInstance,
+ SComposerObjectDefinition<ComposerObjectTypes::Typed> &inTyped,
+ SComposerObjectDefinition<ComposerObjectTypes::Asset> &inAsset)
+ : SComposerBaseObjectDefinition<ComposerObjectTypes::Image>(inCore, inMetaData, inInstance)
+ {
+ Derive(inCore, inAsset);
+ SetType(inCore, inTyped);
+ }
+};
+
+template <>
+struct SComposerObjectDefinition<ComposerObjectTypes::MaterialBase>
+ : public SComposerBaseObjectDefinition<ComposerObjectTypes::MaterialBase>
+
+{
+ SComposerObjectDefinition(IDataCore &inCore, IMetaData &inMetaData,
+ Qt3DSDMInstanceHandle inInstance,
+ SComposerObjectDefinition<ComposerObjectTypes::Typed> &inTyped,
+ SComposerObjectDefinition<ComposerObjectTypes::Asset> &inAsset)
+ : SComposerBaseObjectDefinition<ComposerObjectTypes::MaterialBase>(inCore, inMetaData,
+ inInstance)
+ {
+ Derive(inCore, inAsset);
+ SetType(inCore, inTyped);
+ }
+};
+
+template <>
+struct SComposerObjectDefinition<ComposerObjectTypes::Lightmaps>
+ : public SComposerBaseObjectDefinition<ComposerObjectTypes::Lightmaps>
+
+{
+ SComposerObjectDefinition(IDataCore &inCore, IMetaData &inMetaData,
+ Qt3DSDMInstanceHandle inInstance,
+ SComposerObjectDefinition<ComposerObjectTypes::Typed> &inTyped,
+ SComposerObjectDefinition<ComposerObjectTypes::MaterialBase> &inBase)
+ : SComposerBaseObjectDefinition<ComposerObjectTypes::Lightmaps>(inCore, inMetaData,
+ inInstance)
+ {
+ Derive(inCore, inBase);
+ SetType(inCore, inTyped);
+ }
+};
+
+template <>
+struct SComposerObjectDefinition<ComposerObjectTypes::Material>
+ : public SComposerBaseObjectDefinition<ComposerObjectTypes::Material>
+
+{
+ SComposerObjectDefinition(IDataCore &inCore, IMetaData &inMetaData,
+ Qt3DSDMInstanceHandle inInstance,
+ SComposerObjectDefinition<ComposerObjectTypes::Typed> &inTyped,
+ SComposerObjectDefinition<ComposerObjectTypes::Lightmaps> &inBase)
+ : SComposerBaseObjectDefinition<ComposerObjectTypes::Material>(inCore, inMetaData,
+ inInstance)
+ {
+ Derive(inCore, inBase);
+ SetType(inCore, inTyped);
+ }
+};
+
+template <>
+struct SComposerObjectDefinition<ComposerObjectTypes::CustomMaterial>
+ : public SComposerBaseObjectDefinition<ComposerObjectTypes::CustomMaterial>
+
+{
+ SComposerObjectDefinition(IDataCore &inCore, IMetaData &inMetaData,
+ Qt3DSDMInstanceHandle inInstance,
+ SComposerObjectDefinition<ComposerObjectTypes::Typed> &inTyped,
+ SComposerObjectDefinition<ComposerObjectTypes::Lightmaps> &inBase)
+ : SComposerBaseObjectDefinition<ComposerObjectTypes::CustomMaterial>(inCore, inMetaData,
+ inInstance)
+ {
+ Derive(inCore, inBase);
+ SetType(inCore, inTyped);
+ }
+};
+
+template <>
+struct SComposerObjectDefinition<ComposerObjectTypes::ReferencedMaterial>
+ : public SComposerBaseObjectDefinition<ComposerObjectTypes::ReferencedMaterial>
+
+{
+ SComposerObjectDefinition(IDataCore &inCore, IMetaData &inMetaData,
+ Qt3DSDMInstanceHandle inInstance,
+ SComposerObjectDefinition<ComposerObjectTypes::Typed> &inTyped,
+ SComposerObjectDefinition<ComposerObjectTypes::Lightmaps> &inBase)
+ : SComposerBaseObjectDefinition<ComposerObjectTypes::ReferencedMaterial>(inCore, inMetaData,
+ inInstance)
+ {
+ Derive(inCore, inBase);
+ SetType(inCore, inTyped);
+ }
+};
+
+template <>
+struct SComposerObjectDefinition<ComposerObjectTypes::Behavior>
+ : public SComposerBaseObjectDefinition<ComposerObjectTypes::Behavior>
+
+{
+ SComposerObjectDefinition(IDataCore &inCore, IMetaData &inMetaData,
+ Qt3DSDMInstanceHandle inInstance,
+ SComposerObjectDefinition<ComposerObjectTypes::Typed> &inTyped,
+ SComposerObjectDefinition<ComposerObjectTypes::Asset> &inAsset)
+ : SComposerBaseObjectDefinition<ComposerObjectTypes::Behavior>(inCore, inMetaData,
+ inInstance)
+ {
+ Derive(inCore, inAsset);
+ SetType(inCore, inTyped);
+ }
+};
+
+template <>
+struct SComposerObjectDefinition<ComposerObjectTypes::Effect>
+ : public SComposerBaseObjectDefinition<ComposerObjectTypes::Effect>
+
+{
+ SComposerObjectDefinition(IDataCore &inCore, IMetaData &inMetaData,
+ Qt3DSDMInstanceHandle inInstance,
+ SComposerObjectDefinition<ComposerObjectTypes::Typed> &inTyped,
+ SComposerObjectDefinition<ComposerObjectTypes::Asset> &inAsset)
+ : SComposerBaseObjectDefinition<ComposerObjectTypes::Effect>(inCore, inMetaData, inInstance)
+ {
+ Derive(inCore, inAsset);
+ SetType(inCore, inTyped);
+ }
+};
+
+template <>
+struct SComposerObjectDefinition<ComposerObjectTypes::Node>
+ : public SComposerBaseObjectDefinition<ComposerObjectTypes::Node>
+{
+ SComposerObjectDefinition(IDataCore &inCore, IMetaData &inMetaData,
+ Qt3DSDMInstanceHandle inInstance,
+ SComposerObjectDefinition<ComposerObjectTypes::Typed> &inTyped,
+ SComposerObjectDefinition<ComposerObjectTypes::Asset> &inAsset)
+ : SComposerBaseObjectDefinition<ComposerObjectTypes::Node>(inCore, inMetaData, inInstance)
+ {
+ Derive(inCore, inAsset);
+ SetType(inCore, inTyped);
+ }
+};
+
+template <>
+struct SComposerObjectDefinition<ComposerObjectTypes::Layer>
+ : public SComposerBaseObjectDefinition<ComposerObjectTypes::Layer>
+{
+ SComposerObjectDefinition(IDataCore &inCore, IMetaData &inMetaData,
+ Qt3DSDMInstanceHandle inInstance,
+ SComposerObjectDefinition<ComposerObjectTypes::Typed> &inTyped,
+ SComposerObjectDefinition<ComposerObjectTypes::Node> &inNode)
+ : SComposerBaseObjectDefinition<ComposerObjectTypes::Layer>(inCore, inMetaData, inInstance)
+ {
+ Derive(inCore, inNode);
+ SetType(inCore, inTyped);
+ }
+};
+
+template <>
+struct SComposerObjectDefinition<ComposerObjectTypes::Model>
+ : public SComposerBaseObjectDefinition<ComposerObjectTypes::Model>
+{
+ SComposerObjectDefinition(IDataCore &inCore, IMetaData &inMetaData,
+ Qt3DSDMInstanceHandle inInstance,
+ SComposerObjectDefinition<ComposerObjectTypes::Typed> &inTyped,
+ SComposerObjectDefinition<ComposerObjectTypes::Node> &inNode)
+ : SComposerBaseObjectDefinition<ComposerObjectTypes::Model>(inCore, inMetaData, inInstance)
+ {
+ Derive(inCore, inNode);
+ SetType(inCore, inTyped);
+ }
+};
+
+template <>
+struct SComposerObjectDefinition<ComposerObjectTypes::Group>
+ : public SComposerBaseObjectDefinition<ComposerObjectTypes::Group>
+{
+ SComposerObjectDefinition(IDataCore &inCore, IMetaData &inMetaData,
+ Qt3DSDMInstanceHandle inInstance,
+ SComposerObjectDefinition<ComposerObjectTypes::Typed> &inTyped,
+ SComposerObjectDefinition<ComposerObjectTypes::Node> &inNode)
+ : SComposerBaseObjectDefinition<ComposerObjectTypes::Group>(inCore, inMetaData, inInstance)
+ {
+ Derive(inCore, inNode);
+ SetType(inCore, inTyped);
+ }
+};
+
+template <>
+struct SComposerObjectDefinition<ComposerObjectTypes::Light>
+ : public SComposerBaseObjectDefinition<ComposerObjectTypes::Light>
+{
+ SComposerObjectDefinition(IDataCore &inCore, IMetaData &inMetaData,
+ Qt3DSDMInstanceHandle inInstance,
+ SComposerObjectDefinition<ComposerObjectTypes::Typed> &inTyped,
+ SComposerObjectDefinition<ComposerObjectTypes::Node> &inNode)
+ : SComposerBaseObjectDefinition<ComposerObjectTypes::Light>(inCore, inMetaData, inInstance)
+ {
+ Derive(inCore, inNode);
+ SetType(inCore, inTyped);
+ }
+};
+
+template <>
+struct SComposerObjectDefinition<ComposerObjectTypes::Camera>
+ : public SComposerBaseObjectDefinition<ComposerObjectTypes::Camera>
+{
+ SComposerObjectDefinition(IDataCore &inCore, IMetaData &inMetaData,
+ Qt3DSDMInstanceHandle inInstance,
+ SComposerObjectDefinition<ComposerObjectTypes::Typed> &inTyped,
+ SComposerObjectDefinition<ComposerObjectTypes::Node> &inNode)
+ : SComposerBaseObjectDefinition<ComposerObjectTypes::Camera>(inCore, inMetaData, inInstance)
+ {
+ Derive(inCore, inNode);
+ SetType(inCore, inTyped);
+ }
+};
+
+template <>
+struct SComposerObjectDefinition<ComposerObjectTypes::Text>
+ : public SComposerBaseObjectDefinition<ComposerObjectTypes::Text>
+{
+ SComposerObjectDefinition(IDataCore &inCore, IMetaData &inMetaData,
+ Qt3DSDMInstanceHandle inInstance,
+ SComposerObjectDefinition<ComposerObjectTypes::Typed> &inTyped,
+ SComposerObjectDefinition<ComposerObjectTypes::Node> &inNode)
+ : SComposerBaseObjectDefinition<ComposerObjectTypes::Text>(inCore, inMetaData, inInstance)
+ {
+ Derive(inCore, inNode);
+ SetType(inCore, inTyped);
+ }
+};
+
+template <>
+struct SComposerObjectDefinition<ComposerObjectTypes::Component>
+ : public SComposerBaseObjectDefinition<ComposerObjectTypes::Component>
+{
+ SComposerObjectDefinition(
+ IDataCore &inCore, IMetaData &inMetaData, Qt3DSDMInstanceHandle inInstance,
+ SComposerObjectDefinition<ComposerObjectTypes::Typed> &inTyped,
+ SComposerObjectDefinition<ComposerObjectTypes::Node> &inNode,
+ SComposerObjectDefinition<ComposerObjectTypes::SlideOwner> &inSlideOwner)
+ : SComposerBaseObjectDefinition<ComposerObjectTypes::Component>(inCore, inMetaData,
+ inInstance)
+ {
+ Derive(inCore, inNode);
+ Derive(inCore, inSlideOwner);
+ SetType(inCore, inTyped);
+ }
+};
+
+template <>
+struct SComposerObjectDefinition<ComposerObjectTypes::RenderPlugin>
+ : public SComposerBaseObjectDefinition<ComposerObjectTypes::RenderPlugin>
+{
+ SComposerObjectDefinition(IDataCore &inCore, IMetaData &inMetaData,
+ Qt3DSDMInstanceHandle inInstance,
+ SComposerObjectDefinition<ComposerObjectTypes::Typed> &inTyped,
+ SComposerObjectDefinition<ComposerObjectTypes::Asset> &inAsset)
+ : SComposerBaseObjectDefinition<ComposerObjectTypes::RenderPlugin>(inCore, inMetaData,
+ inInstance)
+ {
+ Derive(inCore, inAsset);
+ SetType(inCore, inTyped);
+ }
+};
+
+template <>
+struct SComposerObjectDefinition<ComposerObjectTypes::Alias>
+ : public SComposerBaseObjectDefinition<ComposerObjectTypes::Alias>
+{
+ SComposerObjectDefinition(IDataCore &inCore, IMetaData &inMetaData,
+ Qt3DSDMInstanceHandle inInstance,
+ SComposerObjectDefinition<ComposerObjectTypes::Typed> &inTyped,
+ SComposerObjectDefinition<ComposerObjectTypes::Node> &inNode)
+ : SComposerBaseObjectDefinition<ComposerObjectTypes::Alias>(inCore, inMetaData, inInstance)
+ {
+ Derive(inCore, inNode);
+ SetType(inCore, inTyped);
+ }
+};
+
+template <>
+struct SComposerObjectDefinition<ComposerObjectTypes::Path>
+ : public SComposerBaseObjectDefinition<ComposerObjectTypes::Path>
+{
+ SComposerObjectDefinition(IDataCore &inCore, IMetaData &inMetaData,
+ Qt3DSDMInstanceHandle inInstance,
+ SComposerObjectDefinition<ComposerObjectTypes::Typed> &inTyped,
+ SComposerObjectDefinition<ComposerObjectTypes::Node> &inNode)
+ : SComposerBaseObjectDefinition<ComposerObjectTypes::Path>(inCore, inMetaData, inInstance)
+ {
+ Derive(inCore, inNode);
+ SetType(inCore, inTyped);
+ }
+};
+
+template <>
+struct SComposerObjectDefinition<ComposerObjectTypes::PathAnchorPoint>
+ : public SComposerBaseObjectDefinition<ComposerObjectTypes::PathAnchorPoint>
+{
+ SComposerObjectDefinition(IDataCore &inCore, IMetaData &inMetaData,
+ Qt3DSDMInstanceHandle inInstance,
+ SComposerObjectDefinition<ComposerObjectTypes::Typed> &inTyped,
+ SComposerObjectDefinition<ComposerObjectTypes::Asset> &inAsset)
+ : SComposerBaseObjectDefinition<ComposerObjectTypes::PathAnchorPoint>(inCore, inMetaData,
+ inInstance)
+ {
+ Derive(inCore, inAsset);
+ SetType(inCore, inTyped);
+ }
+};
+
+template <>
+struct SComposerObjectDefinition<ComposerObjectTypes::SubPath>
+ : public SComposerBaseObjectDefinition<ComposerObjectTypes::SubPath>
+{
+ SComposerObjectDefinition(IDataCore &inCore, IMetaData &inMetaData,
+ Qt3DSDMInstanceHandle inInstance,
+ SComposerObjectDefinition<ComposerObjectTypes::Typed> &inTyped,
+ SComposerObjectDefinition<ComposerObjectTypes::Asset> &inAsset)
+ : SComposerBaseObjectDefinition<ComposerObjectTypes::SubPath>(inCore, inMetaData,
+ inInstance)
+ {
+ Derive(inCore, inAsset);
+ SetType(inCore, inTyped);
+ }
+};
+
+// Container object for all of the object definitions
+class SComposerObjectDefinitions
+{
+public:
+#define HANDLE_COMPOSER_OBJECT_TYPE(name, propmacro) \
+ SComposerObjectDefinition<ComposerObjectTypes::name> m_##name;
+ ITERATE_COMPOSER_OBJECT_TYPES
+#undef HANDLE_COMPOSER_OBJECT_TYPE
+
+ SComposerObjectDefinitions(IDataCore &inDataCore, IMetaData &inMetaData);
+ SComposerObjectDefinitions() = default;
+ ~SComposerObjectDefinitions() = default;
+
+ // RTTI API
+ bool IsA(Qt3DSDMInstanceHandle inInstance, ComposerObjectTypes::Enum inType);
+ // Could easily return None, meaning we can't identify the object type.
+ // Checks the type of the first derivation parent, so this won't ever return
+ // SlideOwner, for instance.
+ ComposerObjectTypes::Enum GetType(Qt3DSDMInstanceHandle inInstance);
+
+ Qt3DSDMInstanceHandle GetInstanceForType(ComposerObjectTypes::Enum inType);
+private:
+ IDataCore &m_DataCore;
+ SComposerObjectDefinitions(const SComposerObjectDefinitions&) = delete;
+ SComposerObjectDefinitions& operator=(const SComposerObjectDefinitions&) = delete;
+};
+}
diff --git a/src/dm/systems/Qt3DSDMDataCore.h b/src/dm/systems/Qt3DSDMDataCore.h
new file mode 100644
index 0000000..793cddb
--- /dev/null
+++ b/src/dm/systems/Qt3DSDMDataCore.h
@@ -0,0 +1,320 @@
+/****************************************************************************
+**
+** 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 QT3DSDM_DATACORE_H
+#define QT3DSDM_DATACORE_H
+#include "Qt3DSDMHandles.h"
+#include "Qt3DSDMPropertyDefinition.h"
+#include "HandleSystemBase.h"
+#include "Qt3DSDMMetaData.h"
+#include "Qt3DSDMValue.h"
+
+namespace qt3dsdm {
+
+typedef std::pair<Qt3DSDMPropertyHandle, SValue> TPropertyHandleValuePair;
+typedef std::vector<TPropertyHandleValuePair> TPropertyHandleValuePairList;
+
+class IInstancePropertyCore
+{
+public:
+ virtual ~IInstancePropertyCore() {}
+
+ /**
+ * Find a given instance property by name. May return an invalid handle.
+ */
+ virtual Qt3DSDMPropertyHandle
+ GetAggregateInstancePropertyByName(Qt3DSDMInstanceHandle inInstance,
+ const TCharStr &inStr) const = 0;
+ /**
+ * Get the entire list of instance properties;
+ */
+ virtual void GetAggregateInstanceProperties(Qt3DSDMInstanceHandle inInstance,
+ TPropertyHandleList &outProperties) const = 0;
+ // Get the properties that are stored only on this instance, not on any parents.
+ virtual void GetSpecificInstancePropertyValues(Qt3DSDMInstanceHandle inHandle,
+ TPropertyHandleValuePairList &outValues) = 0;
+ /**
+ * Return true if this property is on this instance or one of its parents.
+ */
+ virtual bool HasAggregateInstanceProperty(Qt3DSDMInstanceHandle inInstance,
+ Qt3DSDMPropertyHandle inProperty) const = 0;
+
+ /**
+ * Does this value match the approperty property type.
+ * error - PropertyNotFound
+ * error - ValueTypeError
+ */
+ virtual void CheckValue(Qt3DSDMInstanceHandle inInstance, Qt3DSDMPropertyHandle inProperty,
+ const SValue &inValue) const = 0;
+ /**
+ * Get this property from this instance. This includes looking up the default value. If the
+ *instance doesn't have the property
+ * and it has no default the return value is false.
+ * error - InstanceNotFound
+ * error - PropertyNotFound if this property doesn't exist on this instance or doesn't exist.
+ */
+ virtual bool GetInstancePropertyValue(Qt3DSDMInstanceHandle inHandle,
+ Qt3DSDMPropertyHandle inProperty,
+ SValue &outValue) const = 0;
+ /**
+ * Set this property on this instance.
+ * error - InstanceNotFound
+ * error - PropertyNotFound if this property doesn't exist on this instance or doesn't exist.
+ * error - ValueTypeError if this value is of the wrong type
+ */
+ virtual void SetInstancePropertyValue(Qt3DSDMInstanceHandle inHandle,
+ Qt3DSDMPropertyHandle inProperty,
+ const SValue &inValue) = 0;
+};
+
+typedef std::shared_ptr<IInstancePropertyCore> TInstancePropertyCorePtr;
+
+class IStringTable;
+
+/**
+ * Primary interface to data model system. This allows you to define 'classes', which are
+ *really just
+ * collections of properties, and instances of those classes. A zero handle value is regarded
+ *as empty.
+ */
+class IDataCore : public IHandleBase, public IInstancePropertyCore
+{
+public:
+ virtual ~IDataCore() {}
+
+ // Bookkeeping
+ virtual IStringTable &GetStringTable() const = 0;
+ virtual std::shared_ptr<IStringTable> GetStringTablePtr() const = 0;
+
+ //===============================================================
+ // Instances
+ //===============================================================
+ /**
+ * Create a new instance of a class. Instances can be named, in which case
+ * they are sometimes treated differently when serialized. If the name is null
+ * or has no length then it is ignored. If the name is non-null, then a check is
+ * run as named instances must have unique names. When a named instance is a parent
+ * of another instance, only its name is serialized out; not its handle thus you can safely
+ * use names as inter-application instance handles.
+ * May use a target id to specify what the ideal id is; id must not exist.
+ * - error DuplicateInstanceName
+ */
+ virtual Qt3DSDMInstanceHandle
+ CreateInstance(Qt3DSDMInstanceHandle inTargetId = Qt3DSDMInstanceHandle()) = 0;
+ /**
+ * Delete an instance.
+ * error - InstanceNotFound
+ */
+ virtual void DeleteInstance(Qt3DSDMInstanceHandle inHandle) = 0;
+ /**
+ * Return all the instances in the system.
+ */
+ virtual void GetInstances(TInstanceHandleList &outInstances) const = 0;
+ /**
+ * Return all the instances in the system that is derived from parent.
+ */
+ virtual void GetInstancesDerivedFrom(TInstanceHandleList &outInstances,
+ Qt3DSDMInstanceHandle inParentHandle) const = 0;
+
+ //===============================================================
+ // Instance Derivation
+ //===============================================================
+ /**
+ * Derive an instance from another instance. This implies a rebuild of
+ * the aggregate properties of a given instance.
+ * error - InstanceNotFound if either instance or parent aren't found
+ */
+ virtual void DeriveInstance(Qt3DSDMInstanceHandle inInstance, Qt3DSDMInstanceHandle inParent) = 0;
+ /**
+ * Return a count of the parent's of a given instance.
+ * error - InstanceNotFound
+ */
+ virtual void GetInstanceParents(Qt3DSDMInstanceHandle inHandle,
+ TInstanceHandleList &outParents) const = 0;
+
+ /**
+ * Returns true if the instance is derived from the parent somehow.
+ */
+ virtual bool IsInstanceOrDerivedFrom(Qt3DSDMInstanceHandle inInstance,
+ Qt3DSDMInstanceHandle inParent) const = 0;
+ //===============================================================
+
+ //===============================================================
+ // Class Properties
+ //===============================================================
+ /**
+ * Add a new property to a given instances. You can use this to overshadow properties
+ * on base instances but you can't add two properties of the same name to a given
+ * instance.
+ * error - InstanceNotFound
+ * error - PropertyExists if the property already exists on this class
+ * error - ValueTypeError if the default value exists and is if a different type than
+ *inPropType
+ */
+ virtual Qt3DSDMPropertyHandle AddProperty(Qt3DSDMInstanceHandle inInstance, TCharPtr inName,
+ DataModelDataType::Value inPropType) = 0;
+ /**
+ * Return the property definition that corresponds to a given property value.
+ */
+ virtual const Qt3DSDMPropertyDefinition &GetProperty(Qt3DSDMPropertyHandle inProperty) const = 0;
+ /**
+ * Return the properties specific to this instance, not including properties
+ * gained by derivation
+ */
+ virtual void GetInstanceProperties(Qt3DSDMInstanceHandle inInstance,
+ TPropertyHandleList &outProperties) const = 0;
+ /**
+ * Remove a property from an instance. Instances will no long have this property accessible
+ *nor will
+ * child instances.
+ */
+ virtual void RemoveProperty(Qt3DSDMPropertyHandle inProperty) = 0;
+ /**
+ * Copy properties (definitions & values) specific to one instance, not including properties
+ * gained by derivation, to another instance.
+ */
+ virtual void CopyInstanceProperties(Qt3DSDMInstanceHandle inSrcInstance,
+ Qt3DSDMInstanceHandle inDestInstance) = 0;
+ /**
+ * Removed cached intermediate values from the instance. DataModel pull properties from the
+ *inheritance hierarchy chain
+ * up to the current instance when someone requests a property in order to make the next
+ *request quicker. This breaks
+ * some forms of updating where a parent's default value gets changed and the instance won't
+ *reflect it (until you
+ * save/load the file).
+ */
+ //===============================================================
+ virtual void RemoveCachedValues(Qt3DSDMInstanceHandle inInstance) = 0;
+
+ //===============================================================
+ // Handle validation
+ //===============================================================
+ /**
+ * Is valid and is instances
+ */
+ virtual bool IsInstance(int inHandle) const = 0;
+ /**
+ * is valid and is property
+ */
+ virtual bool IsProperty(int inHandle) const = 0;
+};
+
+typedef std::shared_ptr<IDataCore> TDataCorePtr;
+
+class IPropertySystem : public IHandleBase
+{
+public:
+ virtual ~IPropertySystem() {}
+
+ virtual Qt3DSDMInstanceHandle CreateInstance() = 0;
+ virtual void DeleteInstance(Qt3DSDMInstanceHandle inHandle) = 0;
+ virtual void DeriveInstance(Qt3DSDMInstanceHandle inInstance, Qt3DSDMInstanceHandle inParent) = 0;
+
+ virtual void GetInstances(TInstanceHandleList &outInstances) const = 0;
+
+ virtual Qt3DSDMPropertyHandle AddProperty(Qt3DSDMInstanceHandle inInstance, TCharPtr inName,
+ DataModelDataType::Value inPropType) = 0;
+
+ virtual Qt3DSDMPropertyHandle
+ GetAggregateInstancePropertyByName(Qt3DSDMInstanceHandle inInstance,
+ const TCharStr &inStr) const = 0;
+ virtual void GetAggregateInstanceProperties(Qt3DSDMInstanceHandle inInstance,
+ TPropertyHandleList &outProperties) const = 0;
+ virtual bool HasAggregateInstanceProperty(Qt3DSDMInstanceHandle inInstance,
+ Qt3DSDMPropertyHandle inProperty) const = 0;
+
+ virtual bool GetInstancePropertyValue(Qt3DSDMInstanceHandle inHandle,
+ Qt3DSDMPropertyHandle inProperty,
+ SValue &outValue) const = 0;
+ virtual void SetInstancePropertyValue(Qt3DSDMInstanceHandle inHandle,
+ Qt3DSDMPropertyHandle inProperty,
+ const SValue &inValue) = 0;
+
+ virtual bool IsInstanceOrDerivedFrom(Qt3DSDMInstanceHandle inInstance,
+ Qt3DSDMInstanceHandle inParent) const = 0;
+
+ virtual DataModelDataType::Value GetDataType(Qt3DSDMPropertyHandle inProperty) const = 0;
+ virtual TCharStr GetName(Qt3DSDMPropertyHandle inProperty) const = 0;
+ virtual TCharStr GetFormalName(Qt3DSDMInstanceHandle inInstance,
+ Qt3DSDMPropertyHandle inProperty) const = 0;
+ virtual AdditionalMetaDataType::Value
+ GetAdditionalMetaDataType(Qt3DSDMInstanceHandle inInstance,
+ Qt3DSDMPropertyHandle inProperty) const = 0;
+ virtual TMetaDataData GetAdditionalMetaDataData(Qt3DSDMInstanceHandle inInstance,
+ Qt3DSDMPropertyHandle inProperty) const = 0;
+ virtual Qt3DSDMInstanceHandle GetPropertyOwner(Qt3DSDMPropertyHandle inProperty) const = 0;
+
+ virtual QVector<Qt3DSDMPropertyHandle> GetControllableProperties(
+ Qt3DSDMInstanceHandle inInst) const = 0;
+
+};
+typedef std::shared_ptr<IPropertySystem> TPropertySystemPtr;
+
+template <typename TCoreType>
+inline SValue GetInstancePropertyValue(TCoreType inCore, Qt3DSDMInstanceHandle inInstance,
+ Qt3DSDMPropertyHandle inProperty)
+{
+ SValue retval;
+ if (!inCore->GetInstancePropertyValue(inInstance, inProperty, retval))
+ throw PropertyNotFound(L"");
+ return retval;
+}
+
+template <typename TDataType, typename TCoreType>
+inline TDataType GetSpecificInstancePropertyValue(TCoreType inDataCore,
+ Qt3DSDMInstanceHandle inInstance,
+ Qt3DSDMPropertyHandle inProperty)
+{
+ return qt3dsdm::get<TDataType>(GetInstancePropertyValue(inDataCore, inInstance, inProperty));
+}
+
+template <typename TDataType, typename TCoreType>
+inline TDataType GetNamedInstancePropertyValue(TCoreType inDataCore,
+ Qt3DSDMInstanceHandle inInstance,
+ const TCharStr &inName)
+{
+ Qt3DSDMPropertyHandle theProperty =
+ inDataCore->GetAggregateInstancePropertyByName(inInstance, inName);
+ return GetSpecificInstancePropertyValue<TDataType, TCoreType>(inDataCore, inInstance,
+ theProperty);
+}
+
+inline Qt3DSDMPropertyHandle AddPropertyWithValue(IPropertySystem &inPropertySystem,
+ Qt3DSDMInstanceHandle inInstance, TCharPtr inName,
+ DataModelDataType::Value inDataType,
+ const SValue &inValue)
+{
+ Qt3DSDMPropertyHandle theProperty(inPropertySystem.AddProperty(inInstance, inName, inDataType));
+ inPropertySystem.SetInstancePropertyValue(inInstance, theProperty, inValue);
+ return theProperty;
+}
+}
+
+#endif
diff --git a/src/dm/systems/Qt3DSDMDataTypes.h b/src/dm/systems/Qt3DSDMDataTypes.h
new file mode 100644
index 0000000..7a7157f
--- /dev/null
+++ b/src/dm/systems/Qt3DSDMDataTypes.h
@@ -0,0 +1,891 @@
+/****************************************************************************
+**
+** 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 QT3DSDM_DATA_H
+#define QT3DSDM_DATA_H
+
+#include <memory>
+#include <functional>
+
+#include "Qt3DSDMErrors.h"
+#include "Qt3DSDMStringTable.h"
+#include "Qt3DSDMWindowsCompatibility.h"
+#include <stdexcept>
+#include <vector>
+#include <map>
+#include <set>
+#include <EABase/eabase.h> //char8_t, etc.
+#include <EASTL/string.h>
+#include <EASTL/vector.h>
+#include "foundation/StrConvertUTF.h"
+#include "foundation/Qt3DSDiscriminatedUnion.h"
+
+#include <QObject>
+
+namespace qt3dsdm {
+
+typedef const wchar_t *TCharPtr;
+struct Qt3DSDMStr : public eastl::basic_string<qt3ds::foundation::TWCharEASTLConverter::TCharType>
+{
+ typedef qt3ds::foundation::TWCharEASTLConverter::TCharType TCharType;
+ typedef eastl::basic_string<qt3ds::foundation::TWCharEASTLConverter::TCharType> TStrType;
+ Qt3DSDMStr() {}
+ Qt3DSDMStr(const wchar_t *inStr)
+ : TStrType(qt3ds::NVUnionCast<const TCharType *>(inStr))
+ {
+ }
+ Qt3DSDMStr(const TStrType &inOther)
+ : TStrType(inOther)
+ {
+ }
+
+ const wchar_t *wide_str() const { return reinterpret_cast<const wchar_t *>(c_str()); }
+ bool operator==(const Qt3DSDMStr &inOther) const { return TStrType::compare(inOther) == 0; }
+ bool operator!=(const Qt3DSDMStr &inOther) const { return TStrType::compare(inOther) != 0; }
+ bool operator==(const wchar_t *inOther) const
+ {
+ return TStrType::compare(reinterpret_cast<const TCharType *>(inOther)) == 0;
+ }
+ bool operator!=(const wchar_t *inOther) const
+ {
+ return TStrType::compare(reinterpret_cast<const TCharType *>(inOther)) != 0;
+ }
+
+ TStrType::size_type find_first_of(const wchar_t *p, size_type position = 0) const
+ {
+ return TStrType::find_first_of(reinterpret_cast<const TCharType *>(p), position);
+ }
+ TStrType::size_type find_first_not_of(const wchar_t *p, size_type position = 0) const
+ {
+ return TStrType::find_first_not_of(reinterpret_cast<const TCharType *>(p), position);
+ }
+ TStrType::size_type find_last_not_of(const wchar_t *p,
+ size_type position = TStrType::npos) const
+ {
+ return TStrType::find_last_not_of(reinterpret_cast<const TCharType *>(p), position);
+ }
+ TStrType::size_type find(const wchar_t *p, size_type position = 0) const
+ {
+ return TStrType::find(reinterpret_cast<const TCharType *>(p), position);
+ }
+ TStrType::size_type find(wchar_t p, size_type position = 0) const
+ {
+ return TStrType::find(static_cast<TCharType>(p), position);
+ }
+ TStrType::size_type rfind(const wchar_t *p, size_type position = TStrType::npos) const
+ {
+ return TStrType::rfind(reinterpret_cast<const TCharType *>(p), position);
+ }
+ TStrType::size_type rfind(wchar_t p, size_type position = TStrType::npos) const
+ {
+ return TStrType::rfind(p, position);
+ }
+ Qt3DSDMStr replace(size_type position, size_type length, const wchar_t *inNewStr)
+ {
+ return TStrType::replace(position, length, reinterpret_cast<const TCharType *>(inNewStr));
+ }
+
+ void append(const wchar_t *p) { TStrType::append(reinterpret_cast<const TCharType *>(p)); }
+ void append(const wchar_t *p, size_type position, size_type n)
+ {
+ TStrType::append(reinterpret_cast<const TCharType *>(p), position, n);
+ }
+ void append(const Qt3DSDMStr &p) { TStrType::append(p); }
+ void assign(const wchar_t *p) { TStrType::assign(reinterpret_cast<const TCharType *>(p)); }
+ void assign(const Qt3DSDMStr &p) { TStrType::assign(p); }
+};
+typedef Qt3DSDMStr TCharStr;
+typedef std::vector<wchar_t> TCharList;
+typedef eastl::vector<TCharStr> TCharStrList;
+typedef std::map<TCharStr, int> TCharStrIntMap;
+typedef std::map<int, TCharStr> TIntTCharStrMap;
+typedef std::vector<int> TIntList;
+typedef std::set<int> TIntSet;
+typedef eastl::vector<float> TFloatList;
+
+template <typename TDataType>
+class CImmutableVector : private std::vector<TDataType>
+{
+public:
+ typedef std::vector<TDataType> base;
+
+ CImmutableVector(const std::vector<TDataType> &inSrc)
+ : base(inSrc)
+ {
+ }
+ CImmutableVector(const CImmutableVector &inSrc)
+ : base(inSrc)
+ {
+ }
+
+ CImmutableVector &operator=(const CImmutableVector &inSrc)
+ {
+ base::operator=(inSrc);
+ return *this;
+ }
+
+ typename std::vector<TDataType>::const_iterator begin() const { return base::begin(); }
+ typename std::vector<TDataType>::const_iterator end() const { return base::end(); }
+
+ size_t size() const { return base::size(); }
+
+ const TDataType &at(int inIndex) const { return base::at(inIndex); }
+ const TDataType &operator[](int inIndex) const { return base::at(inIndex); }
+};
+
+typedef CImmutableVector<TCharStr> TImmutableCharStrList;
+typedef std::shared_ptr<TImmutableCharStrList> TImmutableCharStrListPtr;
+
+class CDataStr
+{
+ TCharList m_Data;
+
+public:
+ CDataStr() {}
+ CDataStr(TCharList &inData) { m_Data.swap(inData); }
+ CDataStr(const wchar_t *inData)
+ {
+ if (inData && *inData)
+ m_Data.insert(m_Data.begin(), inData, inData + wcslen(inData));
+ m_Data.push_back(0);
+ }
+ CDataStr(const wchar_t *inData, size_t inLen)
+ {
+ if (inData && *inData)
+ m_Data.insert(m_Data.begin(), inData, inData + inLen);
+ if (m_Data.size() > 0 && m_Data.back() != 0)
+ m_Data.push_back(0);
+ }
+ CDataStr(const CDataStr &inOther)
+ : m_Data(inOther.m_Data)
+ {
+ }
+ virtual ~CDataStr() {}
+
+ CDataStr &operator=(const CDataStr &inOther)
+ {
+ m_Data = inOther.m_Data;
+ return *this;
+ }
+ const wchar_t *GetData() const { return m_Data.size() <= 1 ? L"" : &(*m_Data.begin()); }
+ size_t GetLength() const { return m_Data.size() > 1 ? m_Data.size() - 1 : 0; }
+ bool operator==(const CDataStr &inOther) const { return m_Data == inOther.m_Data; }
+ QString toQString() const { return QString::fromWCharArray(GetData()); }
+};
+
+typedef std::shared_ptr<CDataStr> TDataStrPtr;
+
+struct SFloat2
+{
+ float m_Floats[2];
+ SFloat2(float f1 = 0, float f2 = 0)
+ {
+ m_Floats[0] = f1;
+ m_Floats[1] = f2;
+ }
+ SFloat2(const SFloat2 &inOther) { operator=(inOther); }
+ SFloat2 &operator=(const SFloat2 &inOther)
+ {
+ m_Floats[0] = inOther.m_Floats[0];
+ m_Floats[1] = inOther.m_Floats[1];
+ return *this;
+ }
+ bool operator==(const SFloat2 &other) const
+ {
+ return m_Floats[0] == other.m_Floats[0] && m_Floats[1] == other.m_Floats[1];
+ }
+ float &operator[](size_t inIndex)
+ {
+ switch (inIndex) {
+ default:
+ throw std::out_of_range("");
+ case 0:
+ case 1:
+ return m_Floats[inIndex];
+ }
+ }
+ const float &operator[](size_t inIndex) const
+ {
+ switch (inIndex) {
+ default:
+ throw std::out_of_range("");
+ case 0:
+ case 1:
+ return m_Floats[inIndex];
+ }
+ }
+};
+
+struct SFloat3
+{
+ float m_Floats[3];
+
+ SFloat3(float f1 = 0, float f2 = 0, float f3 = 0)
+ {
+ m_Floats[0] = f1;
+ m_Floats[1] = f2;
+ m_Floats[2] = f3;
+ }
+ SFloat3(const SFloat3 &inOther) { operator=(inOther); }
+ SFloat3 &operator=(const SFloat3 &inOther)
+ {
+ m_Floats[0] = inOther.m_Floats[0];
+ m_Floats[1] = inOther.m_Floats[1];
+ m_Floats[2] = inOther.m_Floats[2];
+ return *this;
+ }
+
+ bool operator==(const SFloat3 &other) const
+ {
+ return m_Floats[0] == other.m_Floats[0] && m_Floats[1] == other.m_Floats[1]
+ && m_Floats[2] == other.m_Floats[2];
+ }
+
+ float &operator[](size_t inIndex)
+ {
+ switch (inIndex) {
+ default:
+ throw std::out_of_range("");
+ case 0:
+ case 1:
+ case 2:
+ return m_Floats[inIndex];
+ }
+ }
+ const float &operator[](size_t inIndex) const
+ {
+ switch (inIndex) {
+ default:
+ throw std::out_of_range("");
+ case 0:
+ case 1:
+ case 2:
+ return m_Floats[inIndex];
+ }
+ }
+};
+
+struct SFloat4
+{
+ float m_Floats[4];
+
+ SFloat4(float f1 = 0, float f2 = 0, float f3 = 0, float f4 = 1)
+ {
+ m_Floats[0] = f1;
+ m_Floats[1] = f2;
+ m_Floats[2] = f3;
+ m_Floats[3] = f4;
+ }
+ SFloat4(const SFloat4 &inOther) { operator=(inOther); }
+ SFloat4 &operator=(const SFloat4 &inOther)
+ {
+ m_Floats[0] = inOther.m_Floats[0];
+ m_Floats[1] = inOther.m_Floats[1];
+ m_Floats[2] = inOther.m_Floats[2];
+ m_Floats[3] = inOther.m_Floats[3];
+ return *this;
+ }
+
+ bool operator==(const SFloat4 &other) const
+ {
+ return m_Floats[0] == other.m_Floats[0] && m_Floats[1] == other.m_Floats[1]
+ && m_Floats[2] == other.m_Floats[2] && m_Floats[3] == other.m_Floats[3];
+ }
+
+ float &operator[](size_t inIndex)
+ {
+ if (inIndex < 4)
+ return m_Floats[inIndex];
+
+ throw std::out_of_range("");
+ }
+ const float &operator[](size_t inIndex) const
+ {
+ if (inIndex < 4)
+ return m_Floats[inIndex];
+
+ throw std::out_of_range("");
+ }
+};
+
+struct SLong4
+{
+ qt3ds::QT3DSU32 m_Longs[4];
+
+ SLong4(qt3ds::QT3DSU32 l1 = 0,
+ qt3ds::QT3DSU32 l2 = 0,
+ qt3ds::QT3DSU32 l3 = 0,
+ qt3ds::QT3DSU32 l4 = 0)
+ {
+ m_Longs[0] = l1;
+ m_Longs[1] = l2;
+ m_Longs[2] = l3;
+ m_Longs[3] = l4;
+ }
+ SLong4(const SLong4 &inOther) { operator=(inOther); }
+ SLong4 &operator=(const SLong4 &inOther)
+ {
+ m_Longs[0] = inOther.m_Longs[0];
+ m_Longs[1] = inOther.m_Longs[1];
+ m_Longs[2] = inOther.m_Longs[2];
+ m_Longs[3] = inOther.m_Longs[3];
+ return *this;
+ }
+
+ bool operator==(const SLong4 &other) const
+ {
+ return m_Longs[0] == other.m_Longs[0] && m_Longs[1] == other.m_Longs[1]
+ && m_Longs[2] == other.m_Longs[2] && m_Longs[3] == other.m_Longs[3];
+ }
+
+ bool operator<(const SLong4 &other) const
+ {
+ if (m_Longs[0] < other.m_Longs[0])
+ return true;
+ else if (m_Longs[0] == other.m_Longs[0]) {
+ if (m_Longs[1] < other.m_Longs[1])
+ return true;
+ else if (m_Longs[1] == other.m_Longs[1]) {
+ if (m_Longs[2] < other.m_Longs[2])
+ return true;
+ else if (m_Longs[3] < other.m_Longs[3])
+ return true;
+ }
+ }
+ return false;
+ }
+
+ bool Valid() const
+ {
+ bool retval = false;
+ for (int idx = 0; idx < 4; ++idx)
+ retval = retval || m_Longs[0] > 0;
+ return retval;
+ }
+};
+
+typedef std::vector<SLong4> TLong4Vec;
+
+struct SSizet4
+{
+ size_t m_Longs[4];
+
+ SSizet4(size_t l1 = 0, size_t l2 = 0, size_t l3 = 0, size_t l4 = 0)
+ {
+ m_Longs[0] = l1;
+ m_Longs[1] = l2;
+ m_Longs[2] = l3;
+ m_Longs[3] = l4;
+ }
+ SSizet4(const SSizet4 &inOther) { operator=(inOther); }
+ SSizet4 &operator=(const SSizet4 &inOther)
+ {
+ m_Longs[0] = inOther.m_Longs[0];
+ m_Longs[1] = inOther.m_Longs[1];
+ m_Longs[2] = inOther.m_Longs[2];
+ m_Longs[3] = inOther.m_Longs[3];
+ return *this;
+ }
+
+ bool operator==(const SSizet4 &other) const
+ {
+ return m_Longs[0] == other.m_Longs[0] && m_Longs[1] == other.m_Longs[1]
+ && m_Longs[2] == other.m_Longs[2] && m_Longs[3] == other.m_Longs[3];
+ }
+
+ bool operator<(const SSizet4 &other) const
+ {
+ if (m_Longs[0] < other.m_Longs[0])
+ return true;
+ else if (m_Longs[0] == other.m_Longs[0]) {
+ if (m_Longs[1] < other.m_Longs[1])
+ return true;
+ else if (m_Longs[1] == other.m_Longs[1]) {
+ if (m_Longs[2] < other.m_Longs[2])
+ return true;
+ else if (m_Longs[3] < other.m_Longs[3])
+ return true;
+ }
+ }
+ return false;
+ }
+
+ bool Valid() const
+ {
+ bool retval = false;
+ for (int idx = 0; idx < 4; ++idx)
+ retval = retval || m_Longs[0] > 0;
+ return retval;
+ }
+};
+
+inline bool IsTrivial(const wchar_t *inStr)
+{
+ return inStr == NULL || *inStr == 0;
+}
+inline const wchar_t *NonNull(const wchar_t *inStr)
+{
+ return inStr ? inStr : L"";
+}
+inline bool AreEqual(const wchar_t *lhs, const wchar_t *rhs)
+{
+ return wcscmp(NonNull(lhs), NonNull(rhs)) == 0;
+}
+
+inline bool IsTrivial(const char8_t *inStr)
+{
+ return inStr == NULL || *inStr == 0;
+}
+inline const char8_t *NonNull(const char8_t *inStr)
+{
+ return inStr ? inStr : "";
+}
+inline bool AreEqual(const char8_t *lhs, const char8_t *rhs)
+{
+ return strcmp(NonNull(lhs), NonNull(rhs)) == 0;
+}
+
+inline bool AreEqualCaseless(const char8_t *lhs, const char8_t *rhs)
+{
+ if (IsTrivial(lhs) && IsTrivial(rhs))
+ return true;
+ if (IsTrivial(lhs) || IsTrivial(rhs))
+ return false;
+ for (; *lhs && *rhs; ++lhs, ++rhs)
+ if (tolower(*lhs) != tolower(*rhs))
+ return false;
+ if (*lhs || *rhs)
+ return false;
+ return true;
+}
+
+struct SStringRef
+{
+ const wchar_t *m_Id;
+
+ SStringRef(const wchar_t *id = L"")
+ : m_Id(NonNull(id))
+ {
+ }
+
+ operator const wchar_t *() const { return m_Id; }
+ bool operator==(const SStringRef &inOther) const { return AreEqual(m_Id, inOther.m_Id); }
+};
+}
+
+// Traits specializations have to be in the same namespace as they were first declared.
+namespace qt3ds {
+namespace foundation {
+
+ template <>
+ struct DestructTraits<qt3dsdm::SFloat2>
+ {
+ void destruct(qt3dsdm::SFloat2 &) {}
+ };
+ template <>
+ struct DestructTraits<qt3dsdm::SFloat3>
+ {
+ void destruct(qt3dsdm::SFloat3 &) {}
+ };
+ template <>
+ struct DestructTraits<qt3dsdm::SFloat4>
+ {
+ void destruct(qt3dsdm::SFloat4 &) {}
+ };
+ template <>
+ struct DestructTraits<qt3dsdm::SLong4>
+ {
+ void destruct(qt3dsdm::SLong4 &) {}
+ };
+ template <>
+ struct DestructTraits<qt3dsdm::SStringRef>
+ {
+ void destruct(qt3dsdm::SStringRef &) {}
+ };
+
+ template <>
+ struct EqualVisitorTraits<qt3dsdm::TDataStrPtr>
+ {
+ bool operator()(const qt3dsdm::TDataStrPtr &lhs, const qt3dsdm::TDataStrPtr &rhs)
+ {
+ if (lhs && rhs)
+ return *lhs == *rhs;
+ if (lhs || rhs)
+ return false;
+ return true;
+ }
+ };
+}
+}
+
+namespace qt3dsdm {
+
+using qt3ds::NVUnionCast;
+
+struct ObjectReferenceType
+{
+ enum Enum {
+ Unknown = 0,
+ Absolute = 1,
+ Relative = 2,
+ };
+};
+
+template <typename TDataType>
+struct SObjectRefTypeTraits
+{
+};
+
+template <>
+struct SObjectRefTypeTraits<SLong4>
+{
+ ObjectReferenceType::Enum getType() { return ObjectReferenceType::Absolute; }
+};
+template <>
+struct SObjectRefTypeTraits<TDataStrPtr>
+{
+ ObjectReferenceType::Enum getType() { return ObjectReferenceType::Relative; }
+};
+
+struct SObjectRefUnionTraits
+{
+ typedef ObjectReferenceType::Enum TIdType;
+ enum {
+ TBufferSize = sizeof(SSizet4),
+ };
+
+ static ObjectReferenceType::Enum getNoDataId() { return ObjectReferenceType::Unknown; }
+
+ template <typename TDataType>
+ static TIdType getType()
+ {
+ return SObjectRefTypeTraits<TDataType>().getType();
+ }
+
+ template <typename TRetType, typename TVisitorType>
+ static TRetType visit(char *inData, TIdType inType, TVisitorType inVisitor)
+ {
+ switch (inType) {
+ case ObjectReferenceType::Absolute:
+ return inVisitor(*NVUnionCast<SLong4 *>(inData));
+ case ObjectReferenceType::Relative:
+ return inVisitor(*NVUnionCast<TDataStrPtr *>(inData));
+ default:
+ QT3DS_ASSERT(false);
+ case ObjectReferenceType::Unknown:
+ return inVisitor();
+ }
+ }
+
+ template <typename TRetType, typename TVisitorType>
+ static TRetType visit(const char *inData, TIdType inType, TVisitorType inVisitor)
+ {
+ switch (inType) {
+ case ObjectReferenceType::Absolute:
+ return inVisitor(*NVUnionCast<const SLong4 *>(inData));
+ case ObjectReferenceType::Relative:
+ return inVisitor(*NVUnionCast<const TDataStrPtr *>(inData));
+ default:
+ QT3DS_ASSERT(false);
+ case ObjectReferenceType::Unknown:
+ return inVisitor();
+ }
+ }
+};
+
+typedef qt3ds::foundation::
+ DiscriminatedUnion<qt3ds::foundation::
+ DiscriminatedUnionGenericBase<SObjectRefUnionTraits,
+ SObjectRefUnionTraits::TBufferSize>,
+ SObjectRefUnionTraits::TBufferSize>
+ TObjRefUnionType;
+
+template <typename TDataType>
+struct Qt3DSDMGetter
+{
+};
+
+template <typename TRetType, typename TDataType>
+TRetType get(const TDataType &inType)
+{
+ return Qt3DSDMGetter<TDataType>().template doGet<TRetType>(inType);
+}
+
+template <>
+struct Qt3DSDMGetter<TObjRefUnionType>
+{
+ template <typename TRetType>
+ TRetType doGet(const TObjRefUnionType &inValue)
+ {
+ return inValue.getData<TRetType>();
+ }
+};
+
+// Either an absolute reference (SLong4) or a relative reference (string)
+struct SObjectRefType
+{
+ TObjRefUnionType m_Value;
+
+ SObjectRefType(const TDataStrPtr &inValue)
+ : m_Value(inValue)
+ {
+ }
+ SObjectRefType(const SLong4 &inValue)
+ : m_Value(inValue)
+ {
+ }
+ SObjectRefType(const SObjectRefType &inOther)
+ : m_Value(inOther.m_Value)
+ {
+ }
+ SObjectRefType() {}
+ SObjectRefType &operator=(const SObjectRefType &inOther)
+ {
+ m_Value = inOther.m_Value;
+ return *this;
+ }
+ ObjectReferenceType::Enum GetReferenceType() const { return m_Value.getType(); }
+ bool operator==(const SObjectRefType &inOther) const { return m_Value == inOther.m_Value; }
+};
+
+inline bool Equals(const SObjectRefType &lhs, const SObjectRefType &rhs)
+{
+ return lhs == rhs;
+}
+
+struct SStringOrIntTypes
+{
+ enum Enum {
+ Unknown = 0,
+ Int,
+ String,
+ };
+};
+
+template <typename TDataType>
+struct SStringOrIntTypeTraits
+{
+};
+
+template <>
+struct SStringOrIntTypeTraits<long>
+{
+ SStringOrIntTypes::Enum getType() { return SStringOrIntTypes::Int; }
+};
+template <>
+struct SStringOrIntTypeTraits<int>
+{
+ SStringOrIntTypes::Enum getType() { return SStringOrIntTypes::Int; }
+};
+template <>
+struct SStringOrIntTypeTraits<TDataStrPtr>
+{
+ SStringOrIntTypes::Enum getType() { return SStringOrIntTypes::String; }
+};
+
+struct SStringOrIntUnionTraits
+{
+ typedef SStringOrIntTypes::Enum TIdType;
+ enum {
+ TBufferSize = sizeof(TDataStrPtr),
+ };
+
+ static SStringOrIntTypes::Enum getNoDataId() { return SStringOrIntTypes::Unknown; }
+
+ template <typename TDataType>
+ static TIdType getType()
+ {
+ return SStringOrIntTypeTraits<TDataType>().getType();
+ }
+
+ template <typename TRetType, typename TVisitorType>
+ static TRetType visit(char *inData, TIdType inType, TVisitorType inVisitor)
+ {
+ switch (inType) {
+ case SStringOrIntTypes::Int:
+ return inVisitor(*NVUnionCast<long *>(inData));
+ case SStringOrIntTypes::String:
+ return inVisitor(*NVUnionCast<TDataStrPtr *>(inData));
+ default:
+ QT3DS_ASSERT(false);
+ case SStringOrIntTypes::Unknown:
+ return inVisitor();
+ }
+ }
+
+ template <typename TRetType, typename TVisitorType>
+ static TRetType visit(const char *inData, TIdType inType, TVisitorType inVisitor)
+ {
+ switch (inType) {
+ case SStringOrIntTypes::Int:
+ return inVisitor(*NVUnionCast<const qt3ds::QT3DSI32 *>(inData));
+ case SStringOrIntTypes::String:
+ return inVisitor(*NVUnionCast<const TDataStrPtr *>(inData));
+ default:
+ QT3DS_ASSERT(false);
+ case SStringOrIntTypes::Unknown:
+ return inVisitor();
+ }
+ }
+};
+
+typedef qt3ds::foundation::
+ DiscriminatedUnion<qt3ds::foundation::
+ DiscriminatedUnionGenericBase<SStringOrIntUnionTraits,
+ SStringOrIntUnionTraits::TBufferSize>,
+ SStringOrIntUnionTraits::TBufferSize>
+ TStringOrIntUnionType;
+
+template <>
+struct Qt3DSDMGetter<TStringOrIntUnionType>
+{
+ template <typename TRetType>
+ TRetType doGet(const TStringOrIntUnionType &inValue)
+ {
+ return inValue.getData<TRetType>();
+ }
+};
+
+struct SStringOrInt
+{
+ TStringOrIntUnionType m_Value;
+
+ SStringOrInt() {}
+ SStringOrInt(int inValue)
+ : m_Value(inValue)
+ {
+ }
+ SStringOrInt(TDataStrPtr inValue)
+ : m_Value(inValue)
+ {
+ }
+ SStringOrInt(const SStringOrInt &inOther)
+ : m_Value(inOther.m_Value)
+ {
+ }
+
+ SStringOrInt &operator=(const SStringOrInt &inOther)
+ {
+ m_Value = inOther.m_Value;
+ return *this;
+ }
+
+ SStringOrIntTypes::Enum GetType() const { return m_Value.getType(); }
+
+ bool operator==(const SStringOrInt &inOther) const { return m_Value == inOther.m_Value; }
+};
+
+inline bool Equals(const SStringOrInt &lhs, const SStringOrInt &rhs)
+{
+ return lhs == rhs;
+}
+
+//comes from broken X.h
+#ifdef None
+#undef None
+#endif
+
+#ifdef Bool
+#undef Bool
+#endif
+
+struct DataModelDataType {
+
+ enum Value {
+ None,
+ Float,
+ Float2,
+ Float3,
+ Float4,
+ Long,
+ String,
+ Bool,
+ Long4,
+ StringRef,
+ ObjectRef,
+ StringOrInt,
+ FloatList,
+ RangedNumber // datainput-specific type for editor only
+ };
+
+
+ Q_ENUM(Value)
+ Q_GADGET
+};
+
+
+class IStringTable;
+
+template <typename TDataType>
+struct Qt3DSDMValueTyper
+{
+};
+
+template <typename TDataType>
+inline DataModelDataType::Value GetValueType(const TDataType &inValue)
+{
+ return Qt3DSDMValueTyper<TDataType>().Get(inValue);
+}
+
+template <typename TDataType>
+struct SDefaulter
+{
+};
+
+template <typename TDataType>
+inline bool SetDefault(DataModelDataType::Value inDataType, TDataType &outValue)
+{
+ return SDefaulter<TDataType>().SetDefault(inDataType, outValue);
+}
+
+typedef void (*Qt3DSDMDebugLogFunction)(const char *message);
+// UICDMSimpleDataCore.cpp
+extern Qt3DSDMDebugLogFunction g_DataModelDebugLogger;
+
+#define QT3DSDM_DEBUG_LOG(msg) \
+ { \
+ if (g_DataModelDebugLogger) { \
+ g_DataModelDebugLogger(msg); \
+ } \
+ }
+struct Qt3DSDMLogScope
+{
+ const char *m_EndMessage;
+ Qt3DSDMLogScope(const char *inStartMessage, const char *inEndMessage)
+ : m_EndMessage(inEndMessage)
+ {
+ QT3DSDM_DEBUG_LOG(inStartMessage);
+ }
+ ~Qt3DSDMLogScope() { QT3DSDM_DEBUG_LOG(m_EndMessage); }
+};
+
+#define QT3DSDM_LOG_FUNCTION(fnname) Qt3DSDMLogScope __fn_scope(fnname " Enter", fnname " Leave");
+}
+
+#endif
diff --git a/src/dm/systems/Qt3DSDMErrors.h b/src/dm/systems/Qt3DSDMErrors.h
new file mode 100644
index 0000000..77ea7bf
--- /dev/null
+++ b/src/dm/systems/Qt3DSDMErrors.h
@@ -0,0 +1,308 @@
+/****************************************************************************
+**
+** 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 QT3DSDM_ERRORS_H
+#define QT3DSDM_ERRORS_H
+#include "Qt3DSDMWindowsCompatibility.h"
+
+namespace qt3dsdm {
+class Qt3DSDMError : public std::exception
+{
+public:
+ Qt3DSDMError(const wchar_t *inMessage)
+ : std::exception()
+ {
+ wcscpy_s(m_Message, inMessage);
+ }
+ wchar_t m_Message[1024];
+};
+
+class HandleExists : public Qt3DSDMError
+{
+public:
+ HandleExists(const wchar_t *inMessage)
+ : Qt3DSDMError(inMessage)
+ {
+ }
+};
+
+class PropertyNotFound : public Qt3DSDMError
+{
+public:
+ PropertyNotFound(const wchar_t *inMessage)
+ : Qt3DSDMError(inMessage)
+ {
+ }
+};
+
+class PropertyExists : public Qt3DSDMError
+{
+public:
+ PropertyExists(const wchar_t *inMessage)
+ : Qt3DSDMError(inMessage)
+ {
+ }
+};
+
+class DuplicateInstanceName : public Qt3DSDMError
+{
+public:
+ DuplicateInstanceName(const wchar_t *inMessage)
+ : Qt3DSDMError(inMessage)
+ {
+ }
+};
+
+class InstanceNotFound : public Qt3DSDMError
+{
+public:
+ InstanceNotFound(const wchar_t *inMessage)
+ : Qt3DSDMError(inMessage)
+ {
+ }
+};
+
+class ValueTypeError : public Qt3DSDMError
+{
+public:
+ ValueTypeError(const wchar_t *inMessage)
+ : Qt3DSDMError(inMessage)
+ {
+ }
+};
+
+class SerializationError : public Qt3DSDMError
+{
+public:
+ SerializationError(const wchar_t *inMessage)
+ : Qt3DSDMError(inMessage)
+ {
+ }
+};
+
+class SlideNotFound : public Qt3DSDMError
+{
+public:
+ SlideNotFound(const wchar_t *inMessage)
+ : Qt3DSDMError(inMessage)
+ {
+ }
+};
+
+class SlideExists : public Qt3DSDMError
+{
+public:
+ SlideExists(const wchar_t *inMessage)
+ : Qt3DSDMError(inMessage)
+ {
+ }
+};
+
+class SlideDerivationError : public Qt3DSDMError
+{
+public:
+ SlideDerivationError(const wchar_t *inMessage)
+ : Qt3DSDMError(inMessage)
+ {
+ }
+};
+
+class SlideChildNotFoundError : public Qt3DSDMError
+{
+public:
+ SlideChildNotFoundError(const wchar_t *inMessage)
+ : Qt3DSDMError(inMessage)
+ {
+ }
+};
+
+class SlideGraphNotFound : public Qt3DSDMError
+{
+public:
+ SlideGraphNotFound(const wchar_t *inMessage)
+ : Qt3DSDMError(inMessage)
+ {
+ }
+};
+
+class SlideGraphExists : public Qt3DSDMError
+{
+public:
+ SlideGraphExists(const wchar_t *inMessage)
+ : Qt3DSDMError(inMessage)
+ {
+ }
+};
+
+class PropertyLinkError : public Qt3DSDMError
+{
+public:
+ PropertyLinkError(const wchar_t *inMessage)
+ : Qt3DSDMError(inMessage)
+ {
+ }
+};
+
+class RearrangeSlideArgumentsMustNotBeZero : public Qt3DSDMError
+{
+public:
+ RearrangeSlideArgumentsMustNotBeZero(const wchar_t *inMessage)
+ : Qt3DSDMError(inMessage)
+ {
+ }
+};
+
+class AnimationNotFound : public Qt3DSDMError
+{
+public:
+ AnimationNotFound(const wchar_t *inMessage)
+ : Qt3DSDMError(inMessage)
+ {
+ }
+};
+
+class AnimationExists : public Qt3DSDMError
+{
+public:
+ AnimationExists(const wchar_t *inMessage)
+ : Qt3DSDMError(inMessage)
+ {
+ }
+};
+
+class AnimationKeyframeTypeError : public Qt3DSDMError
+{
+public:
+ AnimationKeyframeTypeError(const wchar_t *inMessage)
+ : Qt3DSDMError(inMessage)
+ {
+ }
+};
+
+class AnimationKeyframeNotFound : public Qt3DSDMError
+{
+public:
+ AnimationKeyframeNotFound(const wchar_t *inMessage)
+ : Qt3DSDMError(inMessage)
+ {
+ }
+};
+
+class AnimationEvaluationError : public Qt3DSDMError
+{
+public:
+ AnimationEvaluationError(const wchar_t *inMessage)
+ : Qt3DSDMError(inMessage)
+ {
+ }
+};
+
+class ActionNotFound : public Qt3DSDMError
+{
+public:
+ ActionNotFound(const wchar_t *inMessage)
+ : Qt3DSDMError(inMessage)
+ {
+ }
+};
+
+class ActionExists : public Qt3DSDMError
+{
+public:
+ ActionExists(const wchar_t *inMessage)
+ : Qt3DSDMError(inMessage)
+ {
+ }
+};
+
+class HandlerArgumentNotFound : public Qt3DSDMError
+{
+public:
+ HandlerArgumentNotFound(const wchar_t *inMessage)
+ : Qt3DSDMError(inMessage)
+ {
+ }
+};
+
+class HandlerArgumentExists : public Qt3DSDMError
+{
+public:
+ HandlerArgumentExists(const wchar_t *inMessage)
+ : Qt3DSDMError(inMessage)
+ {
+ }
+};
+
+class CustomPropertyNotFound : public Qt3DSDMError
+{
+public:
+ CustomPropertyNotFound(const wchar_t *inMessage)
+ : Qt3DSDMError(inMessage)
+ {
+ }
+};
+
+class CustomEventNotFound : public Qt3DSDMError
+{
+public:
+ CustomEventNotFound(const wchar_t *inMessage)
+ : Qt3DSDMError(inMessage)
+ {
+ }
+};
+
+class CustomHandlerNotFound : public Qt3DSDMError
+{
+public:
+ CustomHandlerNotFound(const wchar_t *inMessage)
+ : Qt3DSDMError(inMessage)
+ {
+ }
+};
+
+class CustomHandlerParamNotFound : public Qt3DSDMError
+{
+public:
+ CustomHandlerParamNotFound(const wchar_t *inMessage)
+ : Qt3DSDMError(inMessage)
+ {
+ }
+};
+
+class AttributeTypeNotFound : public Qt3DSDMError
+{
+public:
+ AttributeTypeNotFound(const wchar_t *inMessage)
+ : Qt3DSDMError(inMessage)
+ {
+ }
+};
+}
+
+#endif
diff --git a/src/dm/systems/Qt3DSDMGuides.cpp b/src/dm/systems/Qt3DSDMGuides.cpp
new file mode 100644
index 0000000..e8ea421
--- /dev/null
+++ b/src/dm/systems/Qt3DSDMGuides.cpp
@@ -0,0 +1,222 @@
+/****************************************************************************
+**
+** 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 "Qt3DSDMGuides.h"
+#include <unordered_map>
+#include "VectorTransactions.h"
+
+using namespace qt3dsdm;
+
+namespace {
+
+#define CONNECT(x) std::make_shared<qt3dsdm::QtSignalConnection>(QObject::connect(this, x, inCallback))
+
+class SGuideSystem : public QObject, public IGuideSystem
+{
+ Q_OBJECT
+public:
+ typedef std::unordered_map<long, SGuideInfo> TGuideMap;
+ typedef std::shared_ptr<IMergeableTransaction<SGuideInfo>> TMergeableTransaction;
+ typedef std::unordered_map<long, TMergeableTransaction> TGuideInfoMergeMap;
+
+ long m_NextHandleValue;
+ TGuideMap m_Guides;
+ bool m_GuidesEditable;
+
+ std::shared_ptr<ITransactionConsumer> m_CurrentTransaction;
+ TGuideInfoMergeMap m_GuideMergeMap;
+Q_SIGNALS:
+ void guideCreated(Qt3DSDMGuideHandle, SGuideInfo);
+ void guideDestroyed(Qt3DSDMGuideHandle, SGuideInfo);
+ void guideModified(Qt3DSDMGuideHandle, SGuideInfo);
+ void guideModifiedImmediate(Qt3DSDMGuideHandle, SGuideInfo);
+public:
+ SGuideSystem()
+ : m_NextHandleValue(0)
+ , m_GuidesEditable(true)
+ {
+ }
+
+ void SignalGuideCreated(long hdl, const SGuideInfo &inInfo) { Q_EMIT guideCreated(hdl, inInfo); }
+
+ void SignalGuideDestroyed(long hdl, const SGuideInfo &inInfo) { Q_EMIT guideDestroyed(hdl, inInfo); }
+
+ void SignalGuideModified(long hdl, const SGuideInfo &inInfo) { Q_EMIT guideModified(hdl, inInfo); }
+
+ Qt3DSDMGuideHandle CreateGuide() override
+ {
+ ++m_NextHandleValue;
+ std::pair<long, SGuideInfo> entry(std::make_pair(m_NextHandleValue, SGuideInfo()));
+ m_Guides.insert(entry);
+ if (m_CurrentTransaction) {
+ CreateHashMapInsertTransaction(__FILE__, __LINE__, m_CurrentTransaction, entry,
+ m_Guides);
+ m_CurrentTransaction->OnDoNotification(std::bind(
+ &SGuideSystem::SignalGuideCreated, this, m_NextHandleValue, SGuideInfo()));
+ m_CurrentTransaction->OnUndoNotification(std::bind(
+ &SGuideSystem::SignalGuideDestroyed, this, m_NextHandleValue, SGuideInfo()));
+ }
+
+ return m_NextHandleValue;
+ }
+
+ SGuideInfo *InternalGetGuideInfo(Qt3DSDMGuideHandle inGuideHandle)
+ {
+ TGuideMap::iterator theFind = m_Guides.find((long)inGuideHandle.GetHandleValue());
+ if (theFind != m_Guides.end())
+ return &theFind->second;
+ return NULL;
+ }
+
+ const SGuideInfo *InternalGetGuideInfo(Qt3DSDMGuideHandle inGuideHandle) const
+ {
+ return const_cast<SGuideSystem &>(*this).InternalGetGuideInfo(inGuideHandle);
+ }
+
+ void SetGuideInfo(Qt3DSDMGuideHandle inGuideHandle, const SGuideInfo &info) override
+ {
+ SGuideInfo *existing = InternalGetGuideInfo(inGuideHandle);
+ long theHdlValue = (long)inGuideHandle.GetHandleValue();
+ TGuideInfoMergeMap::iterator iter = m_GuideMergeMap.find(theHdlValue);
+ if (iter != m_GuideMergeMap.end()) {
+ iter->second->Update(info);
+ *existing = info;
+ } else {
+ if (!existing) {
+ QT3DS_ASSERT(false);
+ return;
+ }
+ SGuideInfo oldValue(*existing);
+ *existing = info;
+ if (m_CurrentTransaction) {
+ TMergeableTransaction newTransaction =
+ CreateHashMapSwapTransaction(__FILE__, __LINE__, m_CurrentTransaction,
+ theHdlValue, oldValue, info, m_Guides);
+ m_GuideMergeMap.insert(std::make_pair(theHdlValue, newTransaction));
+ m_CurrentTransaction->OnDoNotification(
+ std::bind(&SGuideSystem::SignalGuideModified, this, theHdlValue, info));
+ m_CurrentTransaction->OnUndoNotification(
+ std::bind(&SGuideSystem::SignalGuideModified, this, theHdlValue, oldValue));
+ }
+ }
+ if (AreDataModelSignalsEnabled())
+ Q_EMIT guideModifiedImmediate(theHdlValue, info);
+ }
+
+ SGuideInfo GetGuideInfo(Qt3DSDMGuideHandle inGuideHandle) const override
+ {
+ const SGuideInfo *existing = InternalGetGuideInfo(inGuideHandle);
+ if (existing)
+ return *existing;
+ QT3DS_ASSERT(false);
+ return SGuideInfo();
+ }
+
+ void DeleteGuide(Qt3DSDMGuideHandle inGuideHandle) override
+ {
+
+ SGuideInfo *existing = InternalGetGuideInfo(inGuideHandle);
+ if (!existing) {
+ QT3DS_ASSERT(false);
+ return;
+ }
+ long theHdlValue = (long)inGuideHandle.GetHandleValue();
+ SGuideInfo oldValue = *existing;
+ m_Guides.erase(theHdlValue);
+
+ if (m_CurrentTransaction) {
+ std::pair<long, SGuideInfo> entry(std::make_pair(theHdlValue, oldValue));
+ CreateHashMapEraseTransaction(__FILE__, __LINE__, m_CurrentTransaction, entry,
+ m_Guides);
+ m_CurrentTransaction->OnDoNotification(
+ std::bind(&SGuideSystem::SignalGuideDestroyed, this, theHdlValue, oldValue));
+ m_CurrentTransaction->OnUndoNotification(
+ std::bind(&SGuideSystem::SignalGuideCreated, this, theHdlValue, oldValue));
+ }
+ }
+
+ TGuideHandleList GetAllGuides() const override
+ {
+ TGuideHandleList retval;
+ for (TGuideMap::const_iterator iter = m_Guides.begin(), end = m_Guides.end(); iter != end;
+ ++iter)
+ retval.push_back(iter->first);
+ return retval;
+ }
+
+ bool IsGuideValid(Qt3DSDMGuideHandle inGuideHandle) const override
+ {
+ return InternalGetGuideInfo(inGuideHandle) != NULL;
+ }
+ bool AreGuidesEditable() const override { return m_GuidesEditable; }
+ void SetGuidesEditable(bool val) override { m_GuidesEditable = val; }
+
+ // Undo/Redo
+ void SetConsumer(std::shared_ptr<ITransactionConsumer> inConsumer) override
+ {
+ m_CurrentTransaction = inConsumer;
+ m_GuideMergeMap.clear();
+ }
+
+ // These are events coming from undo/redo operations, not events coming directly from the
+ // modification of the guides
+ virtual TSignalConnectionPtr
+ ConnectGuideCreated(const std::function<void(Qt3DSDMGuideHandle, SGuideInfo)> &inCallback) override
+ {
+ return CONNECT(&SGuideSystem::guideCreated);
+ }
+
+ virtual TSignalConnectionPtr
+ ConnectGuideDestroyed(const std::function<void(Qt3DSDMGuideHandle, SGuideInfo)> &inCallback) override
+ {
+ return CONNECT(&SGuideSystem::guideDestroyed);
+ }
+
+ virtual TSignalConnectionPtr
+ ConnectGuideModified(const std::function<void(Qt3DSDMGuideHandle, SGuideInfo)> &inCallback) override
+ {
+ return CONNECT(&SGuideSystem::guideModified);
+ }
+
+ // Signal happens immediately instead of on undo/redo, used for live-update of the inspector
+ // palette
+ TSignalConnectionPtr ConnectGuideModifiedImmediate(
+ const std::function<void(Qt3DSDMGuideHandle, SGuideInfo)> &inCallback) override
+ {
+ return CONNECT(&SGuideSystem::guideModifiedImmediate);
+ }
+};
+}
+
+shared_ptr<IGuideSystem> IGuideSystem::CreateGuideSystem()
+{
+ return std::make_shared<SGuideSystem>();
+}
+
+#include "Qt3DSDMGuides.moc"
diff --git a/src/dm/systems/Qt3DSDMGuides.h b/src/dm/systems/Qt3DSDMGuides.h
new file mode 100644
index 0000000..0362abf
--- /dev/null
+++ b/src/dm/systems/Qt3DSDMGuides.h
@@ -0,0 +1,102 @@
+/****************************************************************************
+**
+** 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 QT3DSDM_GUIDES_H
+#define QT3DSDM_GUIDES_H
+#include "Qt3DSDMDataTypes.h"
+#include "foundation/Qt3DSSimpleTypes.h"
+#include "Qt3DSDMSignals.h"
+#include "Qt3DSDMHandles.h"
+#include "Qt3DSDMTransactions.h"
+#include <functional>
+
+namespace qt3dsdm {
+struct GuideDirections
+{
+ enum Enum {
+ UnknownDirection = 0,
+ Vertical,
+ Horizontal,
+ };
+};
+
+struct SGuideInfo
+{
+ qt3ds::QT3DSF32 m_Position;
+ GuideDirections::Enum m_Direction;
+ qt3ds::QT3DSI32 m_Width;
+ SGuideInfo(qt3ds::QT3DSF32 pos = 0.0f, GuideDirections::Enum dir = GuideDirections::UnknownDirection,
+ qt3ds::QT3DSI32 width = 1)
+ : m_Position(pos)
+ , m_Direction(dir)
+ , m_Width(width)
+ {
+ }
+};
+
+class IGuideSystem : public ITransactionProducer
+{
+protected:
+ virtual ~IGuideSystem() {}
+public:
+ friend class std::shared_ptr<IGuideSystem>;
+
+ virtual Qt3DSDMGuideHandle CreateGuide() = 0;
+ virtual void SetGuideInfo(Qt3DSDMGuideHandle inGuideHandle, const SGuideInfo &info) = 0;
+ virtual SGuideInfo GetGuideInfo(Qt3DSDMGuideHandle inGuideHandle) const = 0;
+ virtual void DeleteGuide(Qt3DSDMGuideHandle inGuideHandle) = 0;
+ virtual TGuideHandleList GetAllGuides() const = 0;
+ virtual bool IsGuideValid(Qt3DSDMGuideHandle inGuideHandle) const = 0;
+ // No real effect on datamodel because you can still create guides when they are locked.
+ // Just used in the UI.
+ virtual bool AreGuidesEditable() const = 0;
+ virtual void SetGuidesEditable(bool val) = 0;
+
+ // Undo/Redo
+ void SetConsumer(std::shared_ptr<ITransactionConsumer> inConsumer) override = 0;
+
+ // These are events coming from undo/redo operations, not events coming directly from the
+ // modification of the guides
+ virtual TSignalConnectionPtr
+ ConnectGuideCreated(const std::function<void(Qt3DSDMGuideHandle, SGuideInfo)> &inCallback) = 0;
+ virtual TSignalConnectionPtr ConnectGuideDestroyed(
+ const std::function<void(Qt3DSDMGuideHandle, SGuideInfo)> &inCallback) = 0;
+ virtual TSignalConnectionPtr ConnectGuideModified(
+ const std::function<void(Qt3DSDMGuideHandle, SGuideInfo)> &inCallback) = 0;
+
+ // Signal happens immediately instead of on undo/redo, used for live-update of the inspector
+ // palette
+ virtual TSignalConnectionPtr ConnectGuideModifiedImmediate(
+ const std::function<void(Qt3DSDMGuideHandle, SGuideInfo)> &inCallback) = 0;
+
+ static std::shared_ptr<IGuideSystem> CreateGuideSystem();
+};
+}
+
+#endif
diff --git a/src/dm/systems/Qt3DSDMHandles.h b/src/dm/systems/Qt3DSDMHandles.h
new file mode 100644
index 0000000..05867a1
--- /dev/null
+++ b/src/dm/systems/Qt3DSDMHandles.h
@@ -0,0 +1,459 @@
+/****************************************************************************
+**
+** 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 QT3DSDM_HANDLES_H
+#define QT3DSDM_HANDLES_H
+
+#include <QMetaType>
+
+namespace qt3dsdm {
+
+class IDataCore;
+
+class CDataModelHandle
+{
+ int m_Handle;
+
+public:
+ inline CDataModelHandle(int inHandle = 0);
+ inline CDataModelHandle(const CDataModelHandle &other);
+ virtual ~CDataModelHandle();
+
+ // Operators
+ inline CDataModelHandle &operator=(const CDataModelHandle &other);
+ inline bool operator==(const CDataModelHandle &other) const;
+ inline bool operator<(const CDataModelHandle &other) const;
+ inline operator int() const { return GetHandleValue(); }
+
+ // Use
+ inline bool Valid() const { return m_Handle != 0; }
+ int GetHandleValue() const { return m_Handle; }
+};
+
+inline CDataModelHandle::CDataModelHandle(int inHandle)
+ : m_Handle(inHandle)
+{
+}
+inline CDataModelHandle::CDataModelHandle(const CDataModelHandle &other)
+ : m_Handle(other.m_Handle)
+{
+}
+inline CDataModelHandle::~CDataModelHandle()
+{
+}
+
+inline CDataModelHandle &CDataModelHandle::operator=(const CDataModelHandle &other)
+{
+ if (this != &other) {
+ m_Handle = other.m_Handle;
+ }
+ return *this;
+}
+
+inline bool CDataModelHandle::operator==(const CDataModelHandle &other) const
+{
+ return m_Handle == other.m_Handle;
+}
+
+inline bool CDataModelHandle::operator<(const CDataModelHandle &other) const
+{
+ return m_Handle < other.m_Handle;
+}
+
+class Qt3DSDMInstanceHandle : public CDataModelHandle
+{
+public:
+ Qt3DSDMInstanceHandle(int inHandle = 0)
+ : CDataModelHandle(inHandle)
+ {
+ }
+
+ Qt3DSDMInstanceHandle(const CDataModelHandle &inOther)
+ : CDataModelHandle(inOther)
+ {
+ }
+
+ Qt3DSDMInstanceHandle(const Qt3DSDMInstanceHandle &inOther)
+ : CDataModelHandle(inOther)
+ {
+ }
+
+ Qt3DSDMInstanceHandle &operator=(const Qt3DSDMInstanceHandle &inOther)
+ {
+ return static_cast<Qt3DSDMInstanceHandle &>(CDataModelHandle::operator=(inOther));
+ }
+
+ inline bool operator==(const Qt3DSDMInstanceHandle &other) const
+ {
+ return CDataModelHandle::operator==(other);
+ }
+};
+
+typedef std::vector<Qt3DSDMInstanceHandle> TInstanceHandleList;
+
+class Qt3DSDMPropertyHandle : public CDataModelHandle
+{
+public:
+ Qt3DSDMPropertyHandle(int inHandle = 0)
+ : CDataModelHandle(inHandle)
+ {
+ }
+
+ Qt3DSDMPropertyHandle(const CDataModelHandle &inOther)
+ : CDataModelHandle(inOther)
+ {
+ }
+
+ Qt3DSDMPropertyHandle(const Qt3DSDMInstanceHandle &inOther)
+ : CDataModelHandle(inOther)
+ {
+ }
+
+ Qt3DSDMPropertyHandle &operator=(const Qt3DSDMPropertyHandle &inOther)
+ {
+ return static_cast<Qt3DSDMPropertyHandle &>(CDataModelHandle::operator=(inOther));
+ }
+};
+
+typedef std::vector<Qt3DSDMPropertyHandle> TPropertyHandleList;
+
+class Qt3DSDMSlideHandle : public CDataModelHandle
+{
+public:
+ Qt3DSDMSlideHandle(int inHandle = 0)
+ : CDataModelHandle(inHandle)
+ {
+ }
+
+ Qt3DSDMSlideHandle(const CDataModelHandle &inOther)
+ : CDataModelHandle(inOther)
+ {
+ }
+
+ Qt3DSDMSlideHandle(const Qt3DSDMSlideHandle &inOther)
+ : CDataModelHandle(inOther)
+ {
+ }
+
+ Qt3DSDMSlideHandle &operator=(const Qt3DSDMSlideHandle &inOther)
+ {
+ return static_cast<Qt3DSDMSlideHandle &>(CDataModelHandle::operator=(inOther));
+ }
+};
+
+typedef std::vector<Qt3DSDMSlideHandle> TSlideHandleList;
+
+class Qt3DSDMSlideGraphHandle : public CDataModelHandle
+{
+public:
+ Qt3DSDMSlideGraphHandle(int inHandle = 0)
+ : CDataModelHandle(inHandle)
+ {
+ }
+
+ Qt3DSDMSlideGraphHandle(const CDataModelHandle &inOther)
+ : CDataModelHandle(inOther)
+ {
+ }
+
+ Qt3DSDMSlideGraphHandle(const Qt3DSDMSlideGraphHandle &inOther)
+ : CDataModelHandle(inOther)
+ {
+ }
+
+ Qt3DSDMSlideGraphHandle &operator=(const Qt3DSDMSlideGraphHandle &inOther)
+ {
+ return static_cast<Qt3DSDMSlideGraphHandle &>(CDataModelHandle::operator=(inOther));
+ }
+};
+
+typedef std::vector<Qt3DSDMSlideGraphHandle> TSlideGraphHandleList;
+
+class Qt3DSDMAnimationHandle : public CDataModelHandle
+{
+public:
+ Qt3DSDMAnimationHandle(int inHandle = 0)
+ : CDataModelHandle(inHandle)
+ {
+ }
+
+ Qt3DSDMAnimationHandle(const CDataModelHandle &inOther)
+ : CDataModelHandle(inOther)
+ {
+ }
+
+ Qt3DSDMAnimationHandle(const Qt3DSDMAnimationHandle &inOther)
+ : CDataModelHandle(inOther)
+ {
+ }
+
+ Qt3DSDMAnimationHandle &operator=(const Qt3DSDMAnimationHandle &inOther)
+ {
+ return static_cast<Qt3DSDMAnimationHandle &>(CDataModelHandle::operator=(inOther));
+ }
+};
+
+typedef std::vector<Qt3DSDMAnimationHandle> TAnimationHandleList;
+
+class Qt3DSDMKeyframeHandle : public CDataModelHandle
+{
+public:
+ Qt3DSDMKeyframeHandle(int inHandle = 0)
+ : CDataModelHandle(inHandle)
+ {
+ }
+
+ Qt3DSDMKeyframeHandle(const CDataModelHandle &inOther)
+ : CDataModelHandle(inOther)
+ {
+ }
+
+ Qt3DSDMKeyframeHandle(const Qt3DSDMKeyframeHandle &inOther)
+ : CDataModelHandle(inOther)
+ {
+ }
+
+ Qt3DSDMKeyframeHandle &operator=(const Qt3DSDMKeyframeHandle &inOther)
+ {
+ return static_cast<Qt3DSDMKeyframeHandle &>(CDataModelHandle::operator=(inOther));
+ }
+};
+
+typedef std::vector<Qt3DSDMKeyframeHandle> TKeyframeHandleList;
+
+class Qt3DSDMActionHandle : public CDataModelHandle
+{
+public:
+ Qt3DSDMActionHandle(int inHandle = 0)
+ : CDataModelHandle(inHandle)
+ {
+ }
+
+ Qt3DSDMActionHandle(const CDataModelHandle &inOther)
+ : CDataModelHandle(inOther)
+ {
+ }
+
+ Qt3DSDMActionHandle(const Qt3DSDMActionHandle &inOther)
+ : CDataModelHandle(inOther)
+ {
+ }
+
+ Qt3DSDMActionHandle &operator=(const Qt3DSDMActionHandle &inOther)
+ {
+ return static_cast<Qt3DSDMActionHandle &>(CDataModelHandle::operator=(inOther));
+ }
+};
+
+typedef std::vector<Qt3DSDMActionHandle> TActionHandleList;
+
+class Qt3DSDMHandlerArgHandle : public CDataModelHandle
+{
+public:
+ Qt3DSDMHandlerArgHandle(int inHandle = 0)
+ : CDataModelHandle(inHandle)
+ {
+ }
+
+ Qt3DSDMHandlerArgHandle(const CDataModelHandle &inOther)
+ : CDataModelHandle(inOther)
+ {
+ }
+
+ Qt3DSDMHandlerArgHandle(const Qt3DSDMHandlerArgHandle &inOther)
+ : CDataModelHandle(inOther)
+ {
+ }
+ Qt3DSDMHandlerArgHandle &operator=(const Qt3DSDMHandlerArgHandle &inOther)
+ {
+ return static_cast<Qt3DSDMHandlerArgHandle &>(CDataModelHandle::operator=(inOther));
+ }
+};
+
+typedef std::vector<Qt3DSDMHandlerArgHandle> THandlerArgHandleList;
+
+class Qt3DSDMEventHandle : public CDataModelHandle
+{
+public:
+ Qt3DSDMEventHandle(int inHandle = 0)
+ : CDataModelHandle(inHandle)
+ {
+ }
+
+ Qt3DSDMEventHandle(const CDataModelHandle &inOther)
+ : CDataModelHandle(inOther)
+ {
+ }
+
+ Qt3DSDMEventHandle(const Qt3DSDMEventHandle &inOther)
+ : CDataModelHandle(inOther)
+ {
+ }
+
+ Qt3DSDMEventHandle &operator=(const Qt3DSDMEventHandle &inOther)
+ {
+ return static_cast<Qt3DSDMEventHandle &>(CDataModelHandle::operator=(inOther));
+ }
+};
+
+typedef std::vector<Qt3DSDMEventHandle> TEventHandleList;
+
+class Qt3DSDMHandlerHandle : public CDataModelHandle
+{
+public:
+ Qt3DSDMHandlerHandle(int inHandle = 0)
+ : CDataModelHandle(inHandle)
+ {
+ }
+
+ Qt3DSDMHandlerHandle(const CDataModelHandle &inOther)
+ : CDataModelHandle(inOther)
+ {
+ }
+
+ Qt3DSDMHandlerHandle(const Qt3DSDMHandlerHandle &inOther)
+ : CDataModelHandle(inOther)
+ {
+ }
+
+ Qt3DSDMHandlerHandle &operator=(const Qt3DSDMHandlerHandle &inOther)
+ {
+ return static_cast<Qt3DSDMHandlerHandle &>(CDataModelHandle::operator=(inOther));
+ }
+};
+
+typedef std::vector<Qt3DSDMHandlerHandle> THandlerHandleList;
+
+class Qt3DSDMHandlerParamHandle : public CDataModelHandle
+{
+public:
+ Qt3DSDMHandlerParamHandle(int inHandle = 0)
+ : CDataModelHandle(inHandle)
+ {
+ }
+
+ Qt3DSDMHandlerParamHandle(const CDataModelHandle &inOther)
+ : CDataModelHandle(inOther)
+ {
+ }
+
+ Qt3DSDMHandlerParamHandle(const Qt3DSDMHandlerParamHandle &inOther)
+ : CDataModelHandle(inOther)
+ {
+ }
+
+ Qt3DSDMHandlerParamHandle &operator=(const Qt3DSDMHandlerParamHandle &inOther)
+ {
+ return static_cast<Qt3DSDMHandlerParamHandle &>(CDataModelHandle::operator=(inOther));
+ }
+};
+
+typedef std::vector<Qt3DSDMHandlerParamHandle> THandlerParamHandleList;
+
+class Qt3DSDMMetaDataPropertyHandle : public CDataModelHandle
+{
+public:
+ Qt3DSDMMetaDataPropertyHandle(int inHandle = 0)
+ : CDataModelHandle(inHandle)
+ {
+ }
+
+ Qt3DSDMMetaDataPropertyHandle(const CDataModelHandle &inOther)
+ : CDataModelHandle(inOther)
+ {
+ }
+
+ Qt3DSDMMetaDataPropertyHandle(const Qt3DSDMMetaDataPropertyHandle &inOther)
+ : CDataModelHandle(inOther)
+ {
+ }
+
+ Qt3DSDMMetaDataPropertyHandle &operator=(const Qt3DSDMMetaDataPropertyHandle &inOther)
+ {
+ return static_cast<Qt3DSDMMetaDataPropertyHandle &>(CDataModelHandle::operator=(inOther));
+ }
+};
+
+typedef std::vector<Qt3DSDMMetaDataPropertyHandle> TMetaDataPropertyHandleList;
+
+class Qt3DSDMCategoryHandle : public CDataModelHandle
+{
+public:
+ Qt3DSDMCategoryHandle(int inHandle = 0)
+ : CDataModelHandle(inHandle)
+ {
+ }
+
+ Qt3DSDMCategoryHandle(const CDataModelHandle &inOther)
+ : CDataModelHandle(inOther)
+ {
+ }
+
+ Qt3DSDMCategoryHandle(const Qt3DSDMCategoryHandle &inOther)
+ : CDataModelHandle(inOther)
+ {
+ }
+ Qt3DSDMCategoryHandle &operator=(const Qt3DSDMCategoryHandle &inOther)
+ {
+ return static_cast<Qt3DSDMCategoryHandle &>(CDataModelHandle::operator=(inOther));
+ }
+};
+
+typedef std::vector<Qt3DSDMCategoryHandle> TCategoryHandleList;
+
+class Qt3DSDMGuideHandle : public CDataModelHandle
+{
+public:
+ Qt3DSDMGuideHandle(int inHandle = 0)
+ : CDataModelHandle(inHandle)
+ {
+ }
+
+ Qt3DSDMGuideHandle(const CDataModelHandle &inOther)
+ : CDataModelHandle(inOther)
+ {
+ }
+
+ Qt3DSDMGuideHandle(const Qt3DSDMCategoryHandle &inOther)
+ : CDataModelHandle(inOther)
+ {
+ }
+ Qt3DSDMGuideHandle &operator=(const Qt3DSDMGuideHandle &inOther)
+ {
+ CDataModelHandle::operator=(inOther);
+ return *this;
+ }
+};
+
+typedef std::vector<Qt3DSDMGuideHandle> TGuideHandleList;
+}
+
+Q_DECLARE_METATYPE(qt3dsdm::Qt3DSDMSlideHandle);
+
+#endif
diff --git a/src/dm/systems/Qt3DSDMMetaData.cpp b/src/dm/systems/Qt3DSDMMetaData.cpp
new file mode 100644
index 0000000..66f56ce
--- /dev/null
+++ b/src/dm/systems/Qt3DSDMMetaData.cpp
@@ -0,0 +1,4170 @@
+/****************************************************************************
+**
+** Copyright (C) 2008 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 : 4103)
+#endif
+#include "Qt3DSDMMetaData.h"
+#include "Qt3DSDMXML.h"
+#include "foundation/Qt3DSAssert.h"
+#include "StandardExtensions.h"
+#include <unordered_map>
+#include <memory>
+#include <unordered_set>
+#include "Qt3DSDMTransactions.h"
+#include "VectorTransactions.h"
+#include "Qt3DSDMSignals.h"
+// Pull in the fancy str-type implementations
+#include "Qt3DSDMWStrOpsImpl.h"
+#include "Qt3DSDMDataCore.h"
+#include "DataCoreProducer.h"
+#include "Qt3DSDMWindowsCompatibility.h"
+#include "Qt3DSRenderEffectSystem.h"
+#include "Qt3DSRenderDynamicObjectSystemCommands.h"
+#include "foundation/StringConversionImpl.h"
+
+#include <QtCore/qdir.h>
+
+using namespace qt3dsdm;
+using std::shared_ptr;
+using std::make_shared;
+using std::static_pointer_cast;
+using std::unordered_map;
+using std::unordered_set;
+using std::function;
+using std::bind;
+using std::ref;
+using std::get;
+using qt3ds::foundation::Empty;
+
+typedef Qt3DSDMInstanceHandle TInstanceHandle;
+typedef Qt3DSDMPropertyHandle TPropertyHandle;
+typedef Qt3DSDMEventHandle TEventHandle;
+typedef Qt3DSDMHandlerHandle THandlerHandle;
+typedef Qt3DSDMHandlerArgHandle THandlerArgHandle;
+typedef Qt3DSDMMetaDataPropertyHandle TMetaDataPropertyHandle;
+typedef Qt3DSDMCategoryHandle TCategoryHandle;
+
+namespace qt3dsdm {
+#define QT3DS_WCHAR_T_None L"None"
+#define QT3DS_WCHAR_T_StringList L"StringList"
+#define QT3DS_WCHAR_T_Range L"Range"
+#define QT3DS_WCHAR_T_Image L"Image"
+#define QT3DS_WCHAR_T_Color L"Color"
+#define QT3DS_WCHAR_T_Rotation L"Rotation"
+#define QT3DS_WCHAR_T_Font L"Font"
+#define QT3DS_WCHAR_T_FontSize L"FontSize"
+#define QT3DS_WCHAR_T_MultiLine L"MultiLine"
+#define QT3DS_WCHAR_T_ObjectRef L"ObjectRef"
+#define QT3DS_WCHAR_T_Mesh L"Mesh"
+#define QT3DS_WCHAR_T_Import L"Import"
+#define QT3DS_WCHAR_T_Texture L"Texture"
+#define QT3DS_WCHAR_T_Image2D L"Image2D"
+#define QT3DS_WCHAR_T_Buffer L"Buffer"
+#define QT3DS_WCHAR_T_Property L"Property"
+#define QT3DS_WCHAR_T_Dependent L"Dependent"
+#define QT3DS_WCHAR_T_Slide L"Slide"
+#define QT3DS_WCHAR_T_Event L"Event"
+#define QT3DS_WCHAR_T_Object L"Object"
+#define QT3DS_WCHAR_T_Signal L"Signal"
+#define QT3DS_WCHAR_T_Renderable L"Renderable"
+#define QT3DS_WCHAR_T_PathBuffer L"PathBuffer"
+#define QT3DS_WCHAR_T_ShadowMapResolution L"ShadowMapResolution"
+#define QT3DS_WCHAR_T_String L"String"
+
+#define ITERATE_ADDITIONAL_META_DATA_TYPES \
+ HANDLE_ADDITIONAL_META_DATA_TYPE(None) \
+ HANDLE_ADDITIONAL_META_DATA_TYPE(StringList) \
+ HANDLE_ADDITIONAL_META_DATA_TYPE(Range) \
+ HANDLE_ADDITIONAL_META_DATA_TYPE(Image) \
+ HANDLE_ADDITIONAL_META_DATA_TYPE(Color) \
+ HANDLE_ADDITIONAL_META_DATA_TYPE(Rotation) \
+ HANDLE_ADDITIONAL_META_DATA_TYPE(Font) \
+ HANDLE_ADDITIONAL_META_DATA_TYPE(FontSize) \
+ HANDLE_ADDITIONAL_META_DATA_TYPE(MultiLine) \
+ HANDLE_ADDITIONAL_META_DATA_TYPE(ObjectRef) \
+ HANDLE_ADDITIONAL_META_DATA_TYPE(Mesh) \
+ HANDLE_ADDITIONAL_META_DATA_TYPE(Import) \
+ HANDLE_ADDITIONAL_META_DATA_TYPE(Texture) \
+ HANDLE_ADDITIONAL_META_DATA_TYPE(Renderable) \
+ HANDLE_ADDITIONAL_META_DATA_TYPE(PathBuffer) \
+ HANDLE_ADDITIONAL_META_DATA_TYPE(ShadowMapResolution) \
+ HANDLE_ADDITIONAL_META_DATA_TYPE(String)
+template <>
+struct WStrOps<AdditionalMetaDataType::Value>
+{
+ QT3DSU32 ToStr(AdditionalMetaDataType::Value item, NVDataRef<wchar_t> buffer)
+ {
+ switch (item) {
+#define HANDLE_ADDITIONAL_META_DATA_TYPE(name) \
+ case AdditionalMetaDataType::name: \
+ wcscpy_s(buffer.begin(), buffer.size(), QT3DS_WCHAR_T_##name); \
+ return 1;
+ ITERATE_ADDITIONAL_META_DATA_TYPES
+ #undef HANDLE_ADDITIONAL_META_DATA_TYPE
+ }
+ return 0;
+ }
+ bool StrTo(const wchar_t *buffer, AdditionalMetaDataType::Value &item)
+ {
+#define HANDLE_ADDITIONAL_META_DATA_TYPE(name) \
+ if (AreEqual(buffer, QT3DS_WCHAR_T_##name)) { \
+ item = AdditionalMetaDataType::name; \
+ return true; \
+ }
+ ITERATE_ADDITIONAL_META_DATA_TYPES
+ #undef HANDLE_ADDITIONAL_META_DATA_TYPE
+ return false;
+ }
+};
+
+#undef ITERATE_ADDITIONAL_META_DATA_TYPES
+
+#define ITERATE_HANDLER_ARG_TYPES \
+ HANDLE_HANDLER_ARG_TYPE(None) \
+ HANDLE_HANDLER_ARG_TYPE(Property) \
+ HANDLE_HANDLER_ARG_TYPE(Dependent) \
+ HANDLE_HANDLER_ARG_TYPE(Slide) \
+ HANDLE_HANDLER_ARG_TYPE(Event) \
+ HANDLE_HANDLER_ARG_TYPE(Object) \
+ HANDLE_HANDLER_ARG_TYPE(Signal)
+
+QT3DSU32 WStrOps<HandlerArgumentType::Value>::ToStr(HandlerArgumentType::Value item, NVDataRef<wchar_t> buffer)
+{
+ switch (item) {
+#define HANDLE_HANDLER_ARG_TYPE(name) \
+ case HandlerArgumentType::name: \
+ wcscpy_s(buffer.begin(), buffer.size(), QT3DS_WCHAR_T_##name); \
+ return 1;
+ ITERATE_HANDLER_ARG_TYPES
+ #undef HANDLE_HANDLER_ARG_TYPE
+ }
+ return 0;
+}
+
+bool WStrOps<HandlerArgumentType::Value>::StrTo(const wchar_t *buffer, HandlerArgumentType::Value &item)
+{
+#define HANDLE_HANDLER_ARG_TYPE(name) \
+ if (AreEqual(buffer, QT3DS_WCHAR_T_##name)) { \
+ item = HandlerArgumentType::name; \
+ return true; \
+}
+ ITERATE_HANDLER_ARG_TYPES
+ #undef HANDLE_HANDLER_ARG_TYPE
+ return false;
+}
+
+#define QT3DS_WCHAR_T_FloatRange L"FloatRange"
+#define QT3DS_WCHAR_T_LongRange L"LongRange"
+#define QT3DS_WCHAR_T_Vector L"Vector"
+#define QT3DS_WCHAR_T_MultiLineString L"MultiLineString"
+#define QT3DS_WCHAR_T_Boolean L"Boolean"
+#define QT3DS_WCHAR_T_Guid L"Guid"
+#define QT3DS_WCHAR_T_StringListOrInt L"StringListOrInt"
+#define QT3DS_WCHAR_T_Scale L"Scale"
+
+#define ITERATE_QT3DSDM_COMPLETE_TYPES \
+ HANDLE_QT3DSDM_COMPLETE_NONE_TYPE \
+ HANDLE_QT3DSDM_COMPLETE_TYPE(StringList, StringList, DataModelDataType::String) \
+ HANDLE_QT3DSDM_COMPLETE_TYPE(FloatRange, Range, DataModelDataType::Float) \
+ HANDLE_QT3DSDM_COMPLETE_TYPE(LongRange, Range, DataModelDataType::Long) \
+ HANDLE_QT3DSDM_COMPLETE_TYPE(Float, None, DataModelDataType::Float) \
+ HANDLE_QT3DSDM_COMPLETE_TYPE(Long, None, DataModelDataType::Long) \
+ HANDLE_QT3DSDM_COMPLETE_TYPE(Float2, None, DataModelDataType::Float2) \
+ HANDLE_QT3DSDM_COMPLETE_TYPE(Vector, None, DataModelDataType::Float3) \
+ HANDLE_QT3DSDM_COMPLETE_TYPE(Scale, None, DataModelDataType::Float3) \
+ HANDLE_QT3DSDM_COMPLETE_TYPE(Rotation, Rotation, DataModelDataType::Float3) \
+ HANDLE_QT3DSDM_COMPLETE_TYPE(Color, Color, DataModelDataType::Float4) \
+ HANDLE_QT3DSDM_COMPLETE_TYPE(Boolean, None, DataModelDataType::Bool) \
+ HANDLE_QT3DSDM_COMPLETE_TYPE(Slide, None, DataModelDataType::String) \
+ HANDLE_QT3DSDM_COMPLETE_TYPE(Font, Font, DataModelDataType::String) \
+ HANDLE_QT3DSDM_COMPLETE_TYPE(FontSize, FontSize, DataModelDataType::Float) \
+ HANDLE_QT3DSDM_COMPLETE_TYPE(String, String, DataModelDataType::String) \
+ HANDLE_QT3DSDM_COMPLETE_TYPE(MultiLineString, MultiLine, DataModelDataType::String) \
+ HANDLE_QT3DSDM_COMPLETE_TYPE(ObjectRef, ObjectRef, DataModelDataType::ObjectRef) \
+ HANDLE_QT3DSDM_COMPLETE_TYPE(Image, Image, DataModelDataType::Long4) \
+ HANDLE_QT3DSDM_COMPLETE_TYPE(Mesh, Mesh, DataModelDataType::String) \
+ HANDLE_QT3DSDM_COMPLETE_TYPE(Import, Import, DataModelDataType::String) \
+ HANDLE_QT3DSDM_COMPLETE_TYPE(Texture, Texture, DataModelDataType::String) \
+ HANDLE_QT3DSDM_COMPLETE_TYPE(Image2D, Texture, DataModelDataType::String) \
+ HANDLE_QT3DSDM_COMPLETE_TYPE(Buffer, Texture, DataModelDataType::String) \
+ HANDLE_QT3DSDM_COMPLETE_TYPE(Guid, None, DataModelDataType::Long4) \
+ HANDLE_QT3DSDM_COMPLETE_TYPE(StringListOrInt, StringList, DataModelDataType::StringOrInt) \
+ HANDLE_QT3DSDM_COMPLETE_TYPE(Renderable, Renderable, DataModelDataType::String) \
+ HANDLE_QT3DSDM_COMPLETE_TYPE(PathBuffer, PathBuffer, DataModelDataType::String) \
+ HANDLE_QT3DSDM_COMPLETE_TYPE(ShadowMapResolution, ShadowMapResolution, DataModelDataType::Long)
+
+DataModelDataType::Value CompleteMetaDataType::ToDataType(CompleteMetaDataType::Enum inCompleteType)
+{
+ switch (inCompleteType) {
+#define HANDLE_QT3DSDM_COMPLETE_NONE_TYPE \
+ case Unknown: \
+ return DataModelDataType::None;
+#define HANDLE_QT3DSDM_COMPLETE_TYPE(name, addtype, dtype) \
+ case name: \
+ return dtype;
+ ITERATE_QT3DSDM_COMPLETE_TYPES
+ #undef HANDLE_QT3DSDM_COMPLETE_NONE_TYPE
+ #undef HANDLE_QT3DSDM_COMPLETE_TYPE
+ }
+ QT3DS_ASSERT(false);
+ return DataModelDataType::None;
+}
+
+AdditionalMetaDataType::Value
+CompleteMetaDataType::ToAdditionalType(CompleteMetaDataType::Enum inCompleteType)
+{
+ switch (inCompleteType) {
+#define HANDLE_QT3DSDM_COMPLETE_NONE_TYPE \
+ case Unknown: \
+ return AdditionalMetaDataType::None;
+#define HANDLE_QT3DSDM_COMPLETE_TYPE(name, addtype, dtype) \
+ case name: \
+ return AdditionalMetaDataType::addtype;
+ ITERATE_QT3DSDM_COMPLETE_TYPES
+ #undef HANDLE_QT3DSDM_COMPLETE_NONE_TYPE
+ #undef HANDLE_QT3DSDM_COMPLETE_TYPE
+ }
+ QT3DS_ASSERT(false);
+ return AdditionalMetaDataType::None;
+}
+
+CompleteMetaDataType::Enum
+CompleteMetaDataType::ToCompleteType(DataModelDataType::Value inDataType,
+ AdditionalMetaDataType::Value inAdditionalType)
+{
+#define HANDLE_QT3DSDM_COMPLETE_NONE_TYPE \
+ if (inDataType == DataModelDataType::None) \
+ return CompleteMetaDataType::Unknown;
+#define HANDLE_QT3DSDM_COMPLETE_TYPE(name, addtype, dtype) \
+ if (inDataType == dtype \
+ && inAdditionalType == AdditionalMetaDataType::addtype) \
+ return CompleteMetaDataType::name;
+
+ ITERATE_QT3DSDM_COMPLETE_TYPES
+ #undef HANDLE_QT3DSDM_COMPLETE_NONE_TYPE
+ #undef HANDLE_QT3DSDM_COMPLETE_TYPE
+ QT3DS_ASSERT(false);
+ return CompleteMetaDataType::Unknown;
+}
+
+QT3DSU32 WStrOps<CompleteMetaDataType::Enum>::ToStr(CompleteMetaDataType::Enum item,
+ NVDataRef<wchar_t> buffer)
+{
+ switch (item) {
+#define HANDLE_QT3DSDM_COMPLETE_NONE_TYPE \
+ case CompleteMetaDataType::Unknown: \
+ wcscpy_s(buffer.begin(), buffer.size(), L"None"); \
+ return 1;
+#define HANDLE_QT3DSDM_COMPLETE_TYPE(name, addtype, dtype) \
+ case CompleteMetaDataType::name: \
+ wcscpy_s(buffer.begin(), buffer.size(), QT3DS_WCHAR_T_##name); \
+ return 1;
+
+ ITERATE_QT3DSDM_COMPLETE_TYPES
+ #undef HANDLE_QT3DSDM_COMPLETE_NONE_TYPE
+ #undef HANDLE_QT3DSDM_COMPLETE_TYPE
+ }
+ QT3DS_ASSERT(false);
+ return 0;
+}
+bool WStrOps<CompleteMetaDataType::Enum>::StrTo(const wchar_t *buffer,
+ CompleteMetaDataType::Enum &item)
+{
+
+#define HANDLE_QT3DSDM_COMPLETE_NONE_TYPE \
+ if (AreEqual(buffer, L"None")) { \
+ item = CompleteMetaDataType::Unknown; \
+ return true; \
+}
+#define HANDLE_QT3DSDM_COMPLETE_TYPE(name, addtype, dtype) \
+ if (AreEqual(buffer, QT3DS_WCHAR_T_##name)) { \
+ item = CompleteMetaDataType::name; \
+ return true; \
+}
+
+ ITERATE_QT3DSDM_COMPLETE_TYPES
+ #undef HANDLE_QT3DSDM_COMPLETE_NONE_TYPE
+ #undef HANDLE_QT3DSDM_COMPLETE_TYPE
+ return false;
+}
+}
+
+namespace {
+
+#ifndef QT3DSDM_META_DATA_NO_SIGNALS
+#define CONNECT(x) std::make_shared<qt3dsdm::QtSignalConnection>(QObject::connect(this, x, inCallback))
+#else
+#define CONNECT(x) std::shared_ptr<qt3dsdm::ISignalConnection>()
+
+struct SNullFunc
+{
+ template <typename TArgType>
+ void operator()(TArgType)
+ {
+ }
+ template <typename TA1, typename TA2>
+ void operator()(TA1, TA2)
+ {
+ }
+};
+
+#endif
+
+typedef TCharStr TStrType;
+using std::hash;
+
+struct InstanceHandleVecHash
+{
+ size_t operator()(const vector<TInstanceHandle> &inInstances) const
+ {
+ size_t retval = 0;
+ for (size_t idx = 0, end = inInstances.size(); idx < end; ++idx)
+ retval = retval ^ hash<int>()(inInstances[idx]);
+ return retval;
+ }
+};
+
+struct SEventAndHandlerBase
+{
+ Qt3DSDMInstanceHandle m_Instance;
+ TStrType m_Name;
+ TStrType m_FormalName;
+ TStrType m_Category;
+ TStrType m_Description;
+ SEventAndHandlerBase() {}
+ SEventAndHandlerBase(Qt3DSDMInstanceHandle hdl)
+ : m_Instance(hdl)
+ {
+ }
+};
+
+struct SEvent : public SEventAndHandlerBase
+{
+ SEvent() {}
+ SEvent(Qt3DSDMInstanceHandle hdl)
+ : SEventAndHandlerBase(hdl)
+ {
+ }
+};
+
+struct SHandler : public SEventAndHandlerBase
+{
+ SHandler() {}
+ SHandler(Qt3DSDMInstanceHandle hdl)
+ : SEventAndHandlerBase(hdl)
+ {
+ }
+ vector<SMetaDataHandlerArgumentInfo> m_Arguments;
+};
+
+// Note that this hash item only works for strings that are in the string table.
+// These have the property that pointer comparison also indicates string equality.
+struct SInstanceStrHash
+{
+ size_t operator()(const pair<TInstanceHandle, TCharPtr> &inPair) const
+ {
+ return hash<int>()(inPair.first) ^ hash<const void *>()(inPair.second);
+ }
+};
+
+template <typename TDataType>
+NVConstDataRef<TDataType> VecToCRef(const eastl::vector<TDataType> &inType)
+{
+ return NVConstDataRef<TDataType>(inType.data(), (QT3DSU32)inType.size());
+}
+
+struct SMetaDataDynamicObjectImpl
+{
+private:
+ SMetaDataDynamicObjectImpl &operator=(const SMetaDataDynamicObjectImpl &inOther);
+
+public:
+ TCharStr m_Name;
+ TCharStr m_SourcePath;
+ eastl::vector<SMetaDataShader> m_Shaders;
+ eastl::vector<qt3ds::render::dynamic::SPropertyDefinition> m_Properties;
+ eastl::vector<eastl::vector<qt3ds::foundation::CRegisteredString> *> m_EnumValueNames;
+ ~SMetaDataDynamicObjectImpl() { ClearEnumValueNames(); }
+
+ void ClearEnumValueNames()
+ {
+ for (QT3DSU32 idx = 0, end = m_EnumValueNames.size(); idx < end; ++idx)
+ delete (m_EnumValueNames[idx]);
+ m_EnumValueNames.clear();
+ }
+};
+
+struct SMetaDataEffectImpl : public SMetaDataDynamicObjectImpl
+{
+private:
+ SMetaDataEffectImpl &operator=(const SMetaDataEffectImpl &inOther);
+
+public:
+ eastl::vector<qt3ds::render::dynamic::SCommand *> m_EffectCommands;
+
+ void ClearEffectCommands()
+ {
+ for (QT3DSU32 idx = 0, end = m_EnumValueNames.size(); idx < end; ++idx)
+ free(m_EffectCommands[idx]);
+ m_EffectCommands.clear();
+ }
+ SMetaDataEffect ToEffect() const
+ {
+ return SMetaDataEffect(m_Name, VecToCRef(m_Shaders), VecToCRef(m_Properties),
+ VecToCRef(m_EffectCommands));
+ }
+};
+
+struct SMetaDataCustomMaterialImpl : public SMetaDataDynamicObjectImpl
+{
+private:
+ SMetaDataCustomMaterialImpl &operator=(const SMetaDataCustomMaterialImpl &);
+
+public:
+ eastl::vector<qt3ds::render::dynamic::SCommand *>
+ m_CustomerMaterialCommands; ///< our command stream used for rendering
+ bool m_HasTransparency; ///< this material is transparent
+ bool m_HasRefraction; ///< this material is refractive (e.g glass)
+ bool m_AlwaysDirty;
+ QT3DSU32 m_ShaderKey; ///< What does this shader contain ( e.g. specular, diffuse, ...)
+ QT3DSU32 m_LayerCount; ///< How much layers does this material have
+
+ void ClearEffectCommands()
+ {
+ for (QT3DSU32 idx = 0, end = m_EnumValueNames.size(); idx < end; ++idx) {
+ free(m_CustomerMaterialCommands[idx]);
+ }
+
+ m_CustomerMaterialCommands.clear();
+ }
+
+ SMetaDataCustomMaterial ToMaterial() const
+ {
+ return SMetaDataCustomMaterial(m_Name, VecToCRef(m_Shaders), VecToCRef(m_Properties),
+ VecToCRef(m_CustomerMaterialCommands), m_HasTransparency,
+ m_HasRefraction, m_AlwaysDirty, m_ShaderKey, m_LayerCount);
+ }
+};
+
+#ifndef QT3DSDM_META_DATA_NO_SIGNALS
+class SNewMetaDataImpl : public QObject, public IMetaData
+{
+ Q_OBJECT
+#else
+class SNewMetaDataImpl : public IMetaData
+{
+#endif
+public:
+ typedef unordered_map<TCharPtr, TInstanceHandle> TStrInstanceMap;
+ typedef unordered_map<TInstanceHandle, TCharPtr, hash<int>> TInstanceStrMap;
+ // Caching the derivation chain lookup so we can quickly lookup the entire list of
+ // derived instances (and have it ordered, somewhat).
+ typedef unordered_map<vector<TInstanceHandle>, vector<TInstanceHandle>, InstanceHandleVecHash>
+ TDerivationMap;
+
+ typedef unordered_map<TCategoryHandle, SCategoryInfo, hash<int>> TCategoryMap;
+ typedef unordered_map<TCharPtr, TCategoryHandle> TNameCategoryMap;
+
+ typedef unordered_map<TMetaDataPropertyHandle, SMetaDataPropertyInfo, hash<int>>
+ TMetaDataPropertyMap;
+ typedef unordered_map<TInstanceHandle, vector<TMetaDataPropertyHandle>, hash<int>>
+ TInstancePropertyMap;
+ typedef unordered_map<pair<TInstanceHandle, TCharPtr>, TMetaDataPropertyHandle,
+ SInstanceStrHash>
+ TInstancePropertyNamePropertyMap;
+ typedef unordered_map<TMetaDataPropertyHandle, eastl::vector<SPropertyFilterInfo>, hash<int>>
+ TMetaDataPropertyFilterMap;
+ typedef unordered_map<TInstanceHandle, vector<TCharPtr>, hash<int>> TInstanceGroupMap;
+
+ typedef unordered_map<TEventHandle, SEvent, hash<int>> TEventMap;
+ typedef unordered_map<TInstanceHandle, vector<TEventHandle>, hash<int>> TInstanceEventMap;
+ typedef unordered_map<pair<TInstanceHandle, TCharPtr>, TEventHandle, SInstanceStrHash>
+ TInstanceEventNameEventMap;
+
+ typedef unordered_map<THandlerHandle, SHandler, hash<int>> THandlerMap;
+ typedef unordered_map<TInstanceHandle, vector<THandlerHandle>, hash<int>> TInstanceHandlerMap;
+ typedef unordered_map<pair<TInstanceHandle, TCharPtr>, THandlerHandle, SInstanceStrHash>
+ TInstanceHandlerNameHandlerMap;
+
+ typedef unordered_map<TInstanceHandle, vector<TCharPtr>, hash<int>> TInstanceStringListMap;
+ typedef unordered_map<TCharPtr, SMetaDataEffectImpl> TEffectMap;
+ typedef unordered_map<TCharPtr, SMetaDataCustomMaterialImpl> TCustomMaterialMap;
+
+ std::shared_ptr<IDataCore> m_DataCore;
+ IStringTable &m_StringTable;
+ TTransactionConsumerPtr m_Consumer;
+
+ int m_NextId;
+
+ // Helper objects to speed up queries
+ TStrInstanceMap m_CanonicalTypeToInstances;
+ TInstanceStrMap m_InstancesToCanonicalType;
+ TDerivationMap m_DerivationMap;
+
+ TCategoryMap m_Categories;
+ TNameCategoryMap m_NameToCategories;
+
+ TMetaDataPropertyMap m_Properties;
+ TInstancePropertyMap m_InstanceToProperties;
+ TInstancePropertyNamePropertyMap m_InstanceNameToProperties;
+ TMetaDataPropertyFilterMap m_PropertyFilters;
+ TInstanceGroupMap m_InstanceGroupMap;
+
+ TEventMap m_Events;
+ TInstanceEventMap m_InstanceToEvents;
+ TInstanceEventNameEventMap m_InstanceNameToEvents;
+
+ THandlerMap m_Handlers;
+ TInstanceHandlerMap m_InstanceToHandlers;
+ TInstanceHandlerNameHandlerMap m_InstanceNameToHandlers;
+
+ TInstanceStringListMap m_InstanceToReferences;
+
+ vector<TInstanceHandle> m_Parents;
+ vector<TInstanceHandle> m_NextParents;
+ vector<TInstanceHandle> m_DerivationChain;
+ unordered_set<int> m_UniqueSet;
+ unordered_set<size_t> m_SizeTSet;
+
+ MemoryBuffer<RawAllocator> m_TempBuffer;
+ MemoryBuffer<RawAllocator> m_ReadBuffer;
+
+ eastl::string m_ConvertStr;
+
+ TCharStr m_ObjectName;
+
+ TEffectMap m_EffectMap;
+ TCustomMaterialMap m_CustomMaterials;
+
+#ifndef QT3DSDM_META_DATA_NO_SIGNALS
+Q_SIGNALS:
+ void internalCategoryDestroyed(Qt3DSDMCategoryHandle);
+ void internalMetaDataPropertyDestroyed(Qt3DSDMMetaDataPropertyHandle);
+ void internalEventDestroyed(Qt3DSDMEventHandle);
+ void internalHandlerDestroyed(Qt3DSDMHandlerHandle);
+ void internalHandlerArgDestroyed(Qt3DSDMHandlerHandle, QT3DSU32);
+#else
+ SNullFunc internalCategoryDestroyed;
+ SNullFunc internalMetaDataPropertyDestroyed;
+ SNullFunc internalEventDestroyed;
+ SNullFunc internalHandlerDestroyed;
+ SNullFunc internalHandlerArgDestroyed;
+#endif
+public:
+ TSignalConnectionPtr m_PropertyDeletedConnection;
+ bool m_IgnorePropertyDeleted;
+ TSignalConnectionPtr m_InstanceDeletedConnection;
+
+ SNewMetaDataImpl(std::shared_ptr<IDataCore> inDataCore)
+ : m_DataCore(inDataCore)
+ , m_StringTable(inDataCore->GetStringTable())
+ , m_NextId(1)
+ , m_IgnorePropertyDeleted(false)
+ {
+#ifndef QT3DSDM_META_DATA_NO_SIGNALS
+ CDataCoreProducer *producer = dynamic_cast<CDataCoreProducer *>(inDataCore.get());
+ if (producer) {
+ m_PropertyDeletedConnection = producer->ConnectPropertyRemoved(
+ bind(&SNewMetaDataImpl::OnPropertyRemoved, this,
+ std::placeholders::_1, std::placeholders::_2));
+ m_InstanceDeletedConnection = producer->ConnectBeforeInstanceDeleted(
+ bind(&SNewMetaDataImpl::OnInstanceRemoved, this,
+ std::placeholders::_1));
+ }
+#endif
+ }
+
+ ////////////////////////////////////////////////////////////////////////////
+ // Helper Functions
+
+ const wchar_t *Intern(TStrType inData) { return m_StringTable.RegisterStr(inData.wide_str()); }
+ const wchar_t *Intern(const char *inData) { return m_StringTable.GetWideStr(inData); }
+
+ inline int GetNextId()
+ {
+ int retval = m_NextId;
+ ++m_NextId;
+ return retval;
+ }
+
+ template <typename TMapType, typename THandleType>
+ static void AddItemToInstanceList(TInstanceHandle inInstance, THandleType inHandle, QT3DSU32 inIdx,
+ TMapType &ioMap)
+ {
+ pair<typename TMapType::iterator, bool> inserter =
+ ioMap.insert(make_pair(inInstance, vector<THandleType>()));
+ inserter.first->second.insert(inserter.first->second.begin() + inIdx, inHandle);
+ }
+
+ template <typename TMapType, typename THandleType>
+ static QT3DSU32 AddItemToInstanceList(TInstanceHandle inInstance, THandleType inHandle,
+ TMapType &ioMap)
+ {
+ pair<typename TMapType::iterator, bool> inserter =
+ ioMap.insert(make_pair(inInstance, vector<THandleType>()));
+ QT3DSU32 offset = (QT3DSU32)inserter.first->second.size();
+ inserter.first->second.push_back(inHandle);
+ return offset;
+ }
+
+ template <typename TItemType>
+ struct VectorEqualPred
+ {
+ TItemType m_Item;
+ VectorEqualPred(const TItemType &inItem)
+ : m_Item(inItem)
+ {
+ }
+
+ bool operator()(const TItemType &inOther) const { return m_Item == inOther; }
+ };
+
+ template <typename THandleType, typename TMapType>
+ static QT3DSU32 DoRemoveItemFromInstanceList(TInstanceHandle inInstance, THandleType inHandle,
+ TMapType &ioMap)
+ {
+ typename TMapType::iterator find = ioMap.find(inInstance);
+ if (find != ioMap.end()) {
+ typename vector<THandleType>::iterator theVecFind =
+ std::find(find->second.begin(), find->second.end(), inHandle);
+ if (theVecFind != find->second.end()) {
+ QT3DSU32 retval = (QT3DSU32)(theVecFind - find->second.begin());
+ find->second.erase(theVecFind);
+ if (find->second.empty())
+ ioMap.erase(find);
+ return retval;
+ }
+ }
+ QT3DS_ASSERT(false);
+ return QT3DS_MAX_U32;
+ }
+
+ template <typename TMapType, typename THandleType>
+ struct InstanceListTransaction : ITransaction
+ {
+ TInstanceHandle m_Instance;
+ THandleType m_Handle;
+ TMapType &m_Map;
+ QT3DSU32 m_Idx;
+ bool m_InsertOnDo;
+
+ InstanceListTransaction(const char *inFile, int inLine, TInstanceHandle inst,
+ THandleType handle, TMapType &map, QT3DSU32 inIdx, bool inInsertOnDo)
+ : ITransaction(inFile, inLine)
+ , m_Instance(inst)
+ , m_Handle(handle)
+ , m_Map(map)
+ , m_Idx(inIdx)
+ , m_InsertOnDo(inInsertOnDo)
+ {
+ }
+
+ void insert()
+ {
+ SNewMetaDataImpl::AddItemToInstanceList(m_Instance, m_Handle, m_Idx, m_Map);
+ }
+ void remove()
+ {
+ SNewMetaDataImpl::DoRemoveItemFromInstanceList(m_Instance, m_Handle, m_Map);
+ }
+
+ void Do() override
+ {
+ if (m_InsertOnDo)
+ insert();
+ else
+ remove();
+ }
+ void Undo() override
+ {
+ if (m_InsertOnDo)
+ remove();
+ else
+ insert();
+ }
+ };
+
+ template <typename THandleType, typename TMapType>
+ void RemoveItemFromInstanceList(const char *inFile, int inLine, TInstanceHandle inInstance,
+ THandleType inHandle, TMapType &ioMap)
+ {
+ typename TMapType::iterator find = ioMap.find(inInstance);
+ if (find != ioMap.end()) {
+ QT3DSU32 idx = DoRemoveItemFromInstanceList(inInstance, inHandle, ioMap);
+ if (m_Consumer != NULL) {
+ m_Consumer->OnTransaction(
+ std::make_shared<InstanceListTransaction<TMapType, THandleType>>(
+ inFile, inLine, inInstance, inHandle, std::ref(ioMap), idx, false));
+ }
+ }
+ }
+
+ template <typename THandleType, typename TValueType, typename TMapType,
+ typename TInstanceListMapType>
+ THandleType CreateItem(const char *inFile, int inLine, Qt3DSDMInstanceHandle inInstance,
+ TMapType &inMap, TInstanceListMapType &inInstanceListMap)
+ {
+ int retval = GetNextId();
+ pair<THandleType, TValueType> thePair(make_pair(retval, TValueType(inInstance)));
+ inMap.insert(thePair);
+ QT3DSU32 idx = AddItemToInstanceList(inInstance, THandleType(retval), inInstanceListMap);
+ if (m_Consumer) {
+ CreateHashMapInsertTransaction(inFile, inLine, m_Consumer, thePair, inMap);
+ m_Consumer->OnTransaction(
+ std::make_shared<InstanceListTransaction<TInstanceListMapType, THandleType>>(
+ inFile, inLine, inInstance, retval, std::ref(inInstanceListMap), idx, true));
+ }
+ return retval;
+ }
+
+ template <typename TKeyType, typename TValueType, typename THashType>
+ TValueType *FindHashItem(TKeyType inHandle,
+ unordered_map<TKeyType, TValueType, THashType> &ioHash)
+ {
+ typename unordered_map<TKeyType, TValueType, THashType>::iterator find =
+ ioHash.find(inHandle);
+ if (find != ioHash.end())
+ return &find->second;
+ return NULL;
+ }
+
+ template <typename THandleType, typename TMapType>
+ static void DoReplaceNamedItem(TInstanceHandle inInst, TCharPtr inOldName, TCharPtr inNewName,
+ THandleType inNewHandle, TMapType &ioMap)
+ {
+ ioMap.erase(make_pair(inInst, inOldName));
+ bool success = ioMap.insert(make_pair(make_pair(inInst, inNewName), inNewHandle)).second;
+ (void)success;
+ QT3DS_ASSERT(success);
+ }
+
+ template <typename TMapType, typename THandleType>
+ struct ReplaceNamedItemTransaction : ITransaction
+ {
+ TInstanceHandle m_Instance;
+ TCharPtr m_OldName;
+ TCharPtr m_NewName;
+ THandleType m_OldHandle;
+ THandleType m_NewHandle;
+ TMapType &m_Map;
+ ReplaceNamedItemTransaction(const char *inFile, int inLine, TInstanceHandle inst,
+ TCharPtr oldNm, TCharPtr newNm, THandleType oldHdl,
+ THandleType newHdl, TMapType &map)
+ : ITransaction(inFile, inLine)
+ , m_Instance(inst)
+ , m_OldName(oldNm)
+ , m_NewName(newNm)
+ , m_OldHandle(oldHdl)
+ , m_NewHandle(newHdl)
+ , m_Map(map)
+ {
+ }
+ void Do() override
+ {
+ SNewMetaDataImpl::DoReplaceNamedItem(m_Instance, m_OldName, m_NewName, m_NewHandle,
+ m_Map);
+ }
+ void Undo() override
+ {
+ SNewMetaDataImpl::DoReplaceNamedItem(m_Instance, m_NewName, m_OldName, m_OldHandle,
+ m_Map);
+ }
+ };
+
+ template <typename THandleType, typename TMapType>
+ void ReplaceNamedItem(const char *inFile, int inLine, TInstanceHandle inInst,
+ TCharPtr inOldName, TCharPtr inNewName, THandleType inNewHandle,
+ TMapType &ioMap)
+ {
+ typename TMapType::iterator find = ioMap.find(std::make_pair(inInst, inOldName));
+ THandleType oldHandle;
+ if (find != ioMap.end())
+ oldHandle = find->second;
+ DoReplaceNamedItem(inInst, inOldName, inNewName, inNewHandle, ioMap);
+ if (m_Consumer) {
+ if (oldHandle.Valid()) {
+ m_Consumer->OnTransaction(
+ std::make_shared<ReplaceNamedItemTransaction<TMapType, THandleType>>(
+ inFile, inLine, inInst, inOldName, inNewName, oldHandle, inNewHandle,
+ std::ref(ioMap)));
+ } else
+ CreateHashMapInsertTransaction(__FILE__, __LINE__, m_Consumer,
+ make_pair(make_pair(inInst, inNewName), inNewHandle),
+ ioMap);
+ }
+ }
+
+ template <typename THandleType, typename TMapType>
+ void DestroyNamedItem(const char *inFile, int inLine, TInstanceHandle inInst, TCharPtr inName,
+ TMapType &ioMap)
+ {
+ typename TMapType::iterator iter = ioMap.find(make_pair(inInst, inName));
+ if (iter != ioMap.end()) {
+ pair<pair<TInstanceHandle, TCharPtr>, THandleType> existing(*iter);
+ ioMap.erase(iter);
+ CreateHashMapEraseTransaction(inFile, inLine, m_Consumer, existing, ioMap);
+ }
+ }
+
+ template <typename THandleType, typename TInfoType, typename TMapType, typename TNamedMapType>
+ void SetItemInfo(const char *inFile, int inLine, THandleType inItem, const TInfoType &oldInfo,
+ const TInfoType &newInfo, TMapType &inMap, TNamedMapType &inNamedMap)
+ {
+ TCharPtr newName = Intern(newInfo.m_Name.wide_str());
+ TCharPtr oldName = Intern(oldInfo.m_Name.wide_str());
+ ReplaceNamedItem(inFile, inLine, newInfo.m_Instance, oldName, newName, inItem, inNamedMap);
+ CreateHashMapSwapTransaction(inFile, inLine, m_Consumer, inItem, oldInfo, newInfo, inMap);
+ }
+
+ bool AddDerivationChainItem(TInstanceHandle inInst)
+ {
+ if (m_UniqueSet.find(inInst) == m_UniqueSet.end()) {
+ m_DerivationChain.push_back(inInst);
+ m_UniqueSet.insert(inInst);
+ return true;
+ }
+ return false;
+ }
+
+ void GetDerivationChain(TInstanceHandle inInst)
+ {
+ m_Parents.clear();
+ m_DerivationChain.clear();
+ m_UniqueSet.clear();
+ m_NextParents.clear();
+ m_DataCore->GetInstanceParents(inInst, m_Parents);
+
+ TDerivationMap::iterator mapIter = m_DerivationMap.find(m_Parents);
+ if (mapIter != m_DerivationMap.end())
+ m_DerivationChain = mapIter->second;
+ else {
+ while (m_Parents.empty() == false) {
+ for (size_t idx = 0, end = m_Parents.size(); idx < end; ++idx) {
+ if (AddDerivationChainItem(m_Parents[idx]))
+ m_DataCore->GetInstanceParents(m_Parents[idx], m_NextParents);
+ }
+ m_Parents = m_NextParents;
+ m_NextParents.clear();
+ }
+ m_NextParents.clear();
+
+ m_DataCore->GetInstanceParents(inInst, m_NextParents);
+ m_DerivationMap.insert(make_pair(m_NextParents, m_DerivationChain));
+ }
+ }
+
+ template <typename THandleType, typename TMapType>
+ THandleType FindItemByName(TInstanceHandle inInst, TCharPtr inName, TMapType &ioMap)
+ {
+ typename TMapType::iterator find(ioMap.find(make_pair(inInst, inName)));
+ if (find != ioMap.end())
+ return find->second;
+
+ GetDerivationChain(inInst);
+ for (size_t idx = 0, end = m_DerivationChain.size(); idx < end; ++idx) {
+ find = ioMap.find(make_pair(m_DerivationChain[idx], inName));
+ if (find != ioMap.end())
+ return find->second;
+ }
+ return 0;
+ }
+
+ template <typename TItemType, typename TVectorType>
+ void AddListMapItems(const std::vector<TItemType> &inMapEntry, TVectorType &outVector)
+ {
+ typedef typename std::vector<TItemType>::const_iterator TIterType;
+ for (TIterType theIter = inMapEntry.begin(), theEnd = inMapEntry.end(); theIter != theEnd;
+ ++theIter)
+ outVector.push_back(*theIter);
+ }
+
+ template <typename TListMapType, typename TSizeTOpType, typename TVectorType>
+ void DoGetHandleList(Qt3DSDMInstanceHandle inInstance, TListMapType &inMap,
+ TVectorType &outHandles, TSizeTOpType inOperator)
+ {
+ typename TListMapType::iterator find;
+ GetDerivationChain(inInstance);
+ for (size_t idx = 0, end = m_DerivationChain.size(); idx < end; ++idx) {
+ // Add base classes to the list first
+ find = inMap.find(m_DerivationChain[end - idx - 1]);
+ if (find != inMap.end())
+ AddListMapItems(find->second, outHandles);
+ }
+ find = inMap.find(inInstance);
+ if (find != inMap.end())
+ AddListMapItems(find->second, outHandles);
+ m_SizeTSet.clear();
+ for (size_t ridx = 0; ridx < outHandles.size(); ++ridx) {
+ size_t idx = outHandles.size() - ridx - 1;
+ // Run through the list backwards, making sure that items further in the list
+ // completely overshadow items earlier in the list.
+
+ // Create unique key from the item that we can check against
+ size_t item = inOperator(outHandles[idx]);
+ if (m_SizeTSet.insert(item).second == false) {
+ outHandles.erase(outHandles.begin() + idx);
+ --ridx;
+ }
+ }
+ }
+
+ template <typename THandleType, typename TMapType>
+ struct NameSizeTOpType
+ {
+ SNewMetaDataImpl &m_Impl;
+ TMapType &m_Map;
+ NameSizeTOpType(SNewMetaDataImpl &inImpl, TMapType &inMap)
+ : m_Impl(inImpl)
+ , m_Map(inMap)
+ {
+ }
+
+ size_t operator()(THandleType inHandle)
+ {
+ return reinterpret_cast<size_t>(m_Impl.Intern(m_Map[inHandle].m_Name));
+ }
+ };
+
+ // Ensure we don't return two items of the same name.
+ template <typename THandleType, typename TListMapType, typename TMapType>
+ void GetHandleList(Qt3DSDMInstanceHandle inInstance, TListMapType &inMap, TMapType &inTypeName,
+ vector<THandleType> &outHandles)
+ {
+ DoGetHandleList(inInstance, inMap, outHandles,
+ NameSizeTOpType<THandleType, TMapType>(*this, inTypeName));
+ }
+
+ template <typename THandleType, typename TMapType, typename TNameMapType,
+ typename TListMapType>
+ bool DestroyItem(const char *inFile, int inLine, THandleType inItem,
+ TMapType &inMap, TNameMapType &inNameMap, TListMapType &inListMap)
+ {
+ typename TMapType::iterator find(inMap.find(inItem));
+ if (find == inMap.end())
+ return false;
+ DestroyNamedItem<THandleType>(inFile, inLine, find->second.m_Instance,
+ Intern(find->second.m_Name.wide_str()), inNameMap);
+ RemoveItemFromInstanceList(inFile, inLine, find->second.m_Instance, inItem, inListMap);
+ CreateHashMapEraseTransaction(inFile, inLine, m_Consumer,
+ make_pair(find->first, find->second), inMap);
+ inMap.erase(find);
+ return true;
+ }
+
+ template <typename THandleType, typename TListMapType>
+ void ForEachItem(Qt3DSDMInstanceHandle inInstance, TListMapType &ioMap,
+ function<void(THandleType)> inOperation)
+ {
+ typename TListMapType::iterator find = ioMap.find(inInstance);
+ if (find != ioMap.end()) {
+ vector<THandleType> itemData(find->second);
+ for (size_t idx = 0, end = itemData.size(); idx < end; ++idx)
+ inOperation(itemData[idx]);
+ }
+ }
+
+ SCategoryInfo *FindCategory(Qt3DSDMCategoryHandle inCategory)
+ {
+ return FindHashItem(inCategory, m_Categories);
+ }
+
+ SMetaDataPropertyInfo *FindProperty(Qt3DSDMMetaDataPropertyHandle inPropertyHandle)
+ {
+ return FindHashItem(inPropertyHandle, m_Properties);
+ }
+
+ SEvent *FindEvent(Qt3DSDMEventHandle inEventHandle)
+ {
+ return FindHashItem(inEventHandle, m_Events);
+ }
+
+ SHandler *FindHandler(Qt3DSDMHandlerHandle inHandle)
+ {
+ return FindHashItem(inHandle, m_Handlers);
+ }
+
+ SMetaDataHandlerArgumentInfo *FindHandlerArg(Qt3DSDMHandlerHandle inHandler, QT3DSU32 inIdx)
+ {
+ SHandler *theHandler(FindHandler(inHandler));
+ if (theHandler && theHandler->m_Arguments.size() > inIdx)
+ return &theHandler->m_Arguments[inIdx];
+ return NULL;
+ }
+
+ void OnPropertyRemoved(Qt3DSDMInstanceHandle inInstance, Qt3DSDMPropertyHandle inProperty)
+ {
+ if (m_IgnorePropertyDeleted)
+ return;
+
+ vector<Qt3DSDMMetaDataPropertyHandle> propertiesToDestroy;
+ for (TMetaDataPropertyMap::iterator iter = m_Properties.begin(), end = m_Properties.end();
+ iter != end; ++iter) {
+ if (iter->second.m_Property == inProperty)
+ propertiesToDestroy.push_back(iter->first);
+ }
+
+ for (size_t idx = 0, end = propertiesToDestroy.size(); idx < end; ++idx)
+ DestroyMetaDataProperty(propertiesToDestroy[idx]);
+ }
+
+ void OnInstanceRemoved(Qt3DSDMInstanceHandle inInstance) { DestroyMetaData(inInstance); }
+ template <typename TEntryType, typename TMapType>
+ void InsertWithTransaction(const char *inFile, int inLine, const TEntryType &inEntry,
+ TMapType &inMap)
+ {
+ inMap.insert(inEntry);
+ CreateHashMapInsertTransaction(inFile, inLine, m_Consumer, inEntry, inMap);
+ }
+
+ template <typename TKeyType, typename TMapType>
+ void EraseWithTransaction(const char *inFile, int inLine, TKeyType inKey, TMapType &inMap)
+ {
+ typename TMapType::iterator find(inMap.find(inKey));
+ if (find != inMap.end()) {
+ CreateHashMapEraseTransaction(inFile, inLine, m_Consumer,
+ std::make_pair(find->first, find->second), inMap);
+ inMap.erase(find);
+ }
+ }
+
+ template <typename TEntryType, typename TMapType>
+ void InsertOrUpdateWithTransaction(const TEntryType &inEntry, TMapType &inMap)
+ {
+ pair<typename TMapType::iterator, bool> inserter = inMap.insert(inEntry);
+ if (inserter.second)
+ CreateHashMapInsertTransaction(__FILE__, __LINE__, m_Consumer, inEntry, inMap);
+ else {
+ typename TMapType::iterator theIter(inserter.first);
+ CreateHashMapSwapTransaction(__FILE__, __LINE__, m_Consumer, theIter->first,
+ theIter->second, inEntry.second, inMap);
+ theIter->second = inEntry.second;
+ }
+ }
+
+ ////////////////////////////////////////////////////////////////////////////////////
+ // API Implementation
+
+ ////////////////////////////////////////////////////////////////////////////////////
+ // Sharing some utility objects
+ IStringTable &GetStringTable() override { return m_DataCore->GetStringTable(); }
+ TStringTablePtr GetStringTablePtr() override { return m_DataCore->GetStringTablePtr(); }
+ TDataCorePtr GetDataCore() override { return m_DataCore; }
+
+ ////////////////////////////////////////////////////////////////////////////////////
+ // Canonical Instances
+ void SetInstanceAsCanonical(Qt3DSDMInstanceHandle inInstance, TStrType inTypename) override
+ {
+ const wchar_t *theTypename(Intern(inTypename));
+ if (g_DataModelDebugLogger)
+ g_DataModelDebugLogger("IMetaData::SetInstanceAsCanonical Enter");
+ if (g_DataModelDebugLogger)
+ g_DataModelDebugLogger(GetStringTable().GetNarrowStr(inTypename.wide_str()));
+ m_CanonicalTypeToInstances.insert(make_pair(theTypename, inInstance));
+ m_InstancesToCanonicalType.insert(make_pair(inInstance, theTypename));
+ CreateHashMapInsertTransaction(__FILE__, __LINE__, m_Consumer,
+ make_pair(theTypename, inInstance),
+ m_CanonicalTypeToInstances);
+ CreateHashMapInsertTransaction(__FILE__, __LINE__, m_Consumer,
+ make_pair(inInstance, theTypename),
+ m_InstancesToCanonicalType);
+ if (g_DataModelDebugLogger)
+ g_DataModelDebugLogger("IMetaData::SetInstanceAsCanonical Leave");
+ }
+
+ Qt3DSDMInstanceHandle GetCanonicalInstanceForType(TStrType inTypename) override
+ {
+ TStrInstanceMap::iterator find = m_CanonicalTypeToInstances.find(Intern(inTypename));
+ if (find != m_CanonicalTypeToInstances.end())
+ return find->second;
+ return 0;
+ }
+
+ Option<TCharStr> GetTypeForCanonicalInstance(Qt3DSDMInstanceHandle inInstance) override
+ {
+ TInstanceStrMap::iterator find = m_InstancesToCanonicalType.find(inInstance);
+ if (find != m_InstancesToCanonicalType.end())
+ return TCharStr(find->second);
+ return Empty();
+ }
+
+ Option<TCharStr> GetTypeForInstance(Qt3DSDMInstanceHandle inInstance) override
+ {
+ Option<TCharStr> theType = GetTypeForCanonicalInstance(inInstance);
+ if (theType.hasValue())
+ return theType;
+ GetDerivationChain(inInstance);
+ for (size_t idx = 0, end = m_DerivationChain.size(); idx < end; ++idx) {
+ theType = GetTypeForCanonicalInstance(m_DerivationChain[idx]);
+ if (theType.hasValue())
+ return theType;
+ }
+ return Empty();
+ }
+
+ QT3DSU32 GetGroupCountForInstance(Qt3DSDMInstanceHandle inInstance) override
+ {
+ std::vector<TCharStr> outNames;
+ QT3DSU32 count = GetGroupNamesForInstance(inInstance, outNames);
+ return (count == 0) ? 1 : count;
+ }
+
+ QT3DSU32 GetGroupNamesForInstance(Qt3DSDMInstanceHandle inInstance,
+ std::vector<TCharStr> &outNames) override
+ {
+ TInstanceStrMap::iterator canonicalFind = m_InstancesToCanonicalType.find(inInstance);
+ if (canonicalFind != m_InstancesToCanonicalType.end()) {
+ TInstanceGroupMap::iterator find = m_InstanceGroupMap.find(inInstance);
+ if (find != m_InstanceGroupMap.end()) {
+ pair<typename TInstanceGroupMap::iterator, bool> inserter =
+ m_InstanceGroupMap.insert(make_pair(inInstance, vector<TCharPtr>()));
+ vector<TCharPtr> &itemList = inserter.first->second;
+ for (size_t i = 0, j = itemList.size(); i < j; ++i) {
+ bool alreadyInList = false;
+ // discard duplicates
+ for (size_t k = 0, l = outNames.size(); k < l; ++k) {
+ TCharStr curListName = itemList[i];
+ if (curListName == outNames[k].wide_str()) {
+ alreadyInList = true;
+ break;
+ }
+ }
+ if (!alreadyInList)
+ outNames.push_back(itemList[i]);
+ }
+ }
+ return (QT3DSU32)outNames.size();
+ }
+
+ GetDerivationChain(inInstance);
+
+ for (int idx = (int)m_DerivationChain.size() - 1, end = 0; idx >= end; --idx) {
+ TInstanceGroupMap::iterator find = m_InstanceGroupMap.find(m_DerivationChain[idx]);
+ if (find != m_InstanceGroupMap.end()) {
+ pair<typename TInstanceGroupMap::iterator, bool> inserter =
+ m_InstanceGroupMap.insert(
+ make_pair(m_DerivationChain[idx], vector<TCharPtr>()));
+ vector<TCharPtr> &itemList = inserter.first->second;
+ for (size_t i = 0, j = itemList.size(); i < j; ++i) {
+ bool alreadyInList = false;
+ // discard duplicates
+ for (size_t k = 0, l = outNames.size(); k < l; ++k) {
+ TCharStr curListName = itemList[i];
+ if (curListName == outNames[k].wide_str()) {
+ alreadyInList = true;
+ break;
+ }
+ }
+ if (!alreadyInList)
+ outNames.push_back(itemList[i]);
+ }
+ }
+ }
+
+ return (QT3DSU32)outNames.size();
+ }
+
+ Option<TCharStr> GetGroupFilterNameForInstance(Qt3DSDMInstanceHandle inInstance,
+ long inIndex) override
+ {
+ std::vector<TCharStr> outNames;
+ QT3DSU32 count = GetGroupNamesForInstance(inInstance, outNames);
+ if (count > (QT3DSU32)inIndex)
+ return outNames[inIndex];
+
+ return Empty();
+ }
+
+ ////////////////////////////////////////////////////////////////////////////////////
+ // Categories
+
+ std::pair<Qt3DSDMCategoryHandle, bool> GetOrCreateCategory(TStrType inName) override
+ {
+ TCharPtr theName(Intern(inName));
+ TNameCategoryMap::iterator find = m_NameToCategories.find(theName);
+ if (find != m_NameToCategories.end())
+ return make_pair(find->second, false);
+
+ TCategoryHandle retval(GetNextId());
+ InsertWithTransaction(__FILE__, __LINE__, make_pair(retval, SCategoryInfo(inName)),
+ m_Categories);
+ InsertWithTransaction(__FILE__, __LINE__, make_pair(theName, retval), m_NameToCategories);
+ return make_pair(retval, true);
+ }
+
+ void SetCategoryInfo(Qt3DSDMCategoryHandle inCategory, TStrType inIcon,
+ TStrType inHighlight, TStrType inDescription) override
+ {
+ SCategoryInfo *infoPtr(FindCategory(inCategory));
+ if (infoPtr == NULL) {
+ QT3DS_ASSERT(false);
+ return;
+ }
+ SCategoryInfo &newInfo(*infoPtr);
+ SCategoryInfo oldInfo(newInfo);
+
+ newInfo.m_Icon = inIcon;
+ newInfo.m_HighlightIcon = inHighlight;
+ newInfo.m_Description = inDescription;
+ CreateHashMapSwapTransaction(__FILE__, __LINE__, m_Consumer, inCategory, oldInfo, newInfo,
+ m_Categories);
+ }
+
+ void DestroyCategory(Qt3DSDMCategoryHandle inCategory) override
+ {
+ SCategoryInfo *infoPtr(FindCategory(inCategory));
+ if (infoPtr == NULL) {
+ QT3DS_ASSERT(false);
+ return;
+ }
+ EraseWithTransaction(__FILE__, __LINE__, Intern(infoPtr->m_Name), m_NameToCategories);
+ EraseWithTransaction(__FILE__, __LINE__, inCategory, m_Categories);
+ }
+ Option<SCategoryInfo> GetCategoryInfo(Qt3DSDMCategoryHandle inCategory) override
+ {
+ SCategoryInfo *infoPtr(FindCategory(inCategory));
+ if (infoPtr)
+ return *infoPtr;
+ return Empty();
+ }
+ Qt3DSDMCategoryHandle FindCategoryByName(TStrType inName) override
+ {
+ TCharPtr theName(Intern(inName));
+ TNameCategoryMap::iterator find = m_NameToCategories.find(theName);
+ if (find != m_NameToCategories.end())
+ return find->second;
+ return 0;
+ }
+
+ void GetCategories(vector<Qt3DSDMCategoryHandle> &outCategories) override
+ {
+ for (TCategoryMap::iterator iter = m_Categories.begin(), end = m_Categories.end();
+ iter != end; ++iter)
+ outCategories.push_back(iter->first);
+ }
+
+ Option<SCategoryInfo> GetEventCategory(TStrType inName) override
+ {
+ return GetCategoryInfo(FindCategoryByName(inName));
+ }
+
+ Option<SCategoryInfo> GetHandlerCategory(TStrType inName) override
+ {
+ return GetCategoryInfo(FindCategoryByName(inName));
+ }
+
+ ////////////////////////////////////////////////////////////////////////////////////
+ // Properties
+
+ Qt3DSDMMetaDataPropertyHandle CreateMetaDataProperty(Qt3DSDMInstanceHandle inInstance) override
+ {
+ return CreateItem<Qt3DSDMMetaDataPropertyHandle, SMetaDataPropertyInfo>(
+ __FILE__, __LINE__, inInstance, m_Properties, m_InstanceToProperties);
+ }
+
+ void EnsureDataCoreProperty(SMetaDataPropertyInfo &newInfo)
+ {
+ m_IgnorePropertyDeleted = true;
+ // If the existing property under the new name doesn't match
+ // the new info, then we also have to delete the property
+ Qt3DSDMPropertyHandle theExistingProperty =
+ m_DataCore->GetAggregateInstancePropertyByName(newInfo.m_Instance, newInfo.m_Name);
+ // Ensure the types match.
+ if (theExistingProperty.Valid()) {
+ Qt3DSDMPropertyDefinition theDefinition(m_DataCore->GetProperty(theExistingProperty));
+ if (theDefinition.m_Name != newInfo.m_Name
+ || theDefinition.m_Type != newInfo.GetDataType()) {
+ m_DataCore->RemoveProperty(theExistingProperty);
+ theExistingProperty = 0;
+ }
+ }
+
+ // Finally, if we don't have a property at this point, create a new property
+ if (theExistingProperty.Valid() == false)
+ theExistingProperty = m_DataCore->AddProperty(
+ newInfo.m_Instance, newInfo.m_Name.wide_str(), newInfo.GetDataType());
+ newInfo.m_Property = theExistingProperty;
+ m_IgnorePropertyDeleted = false;
+ }
+
+ // If the type doesn't match the default, then it has no default.
+ SValue VerifyDefaultPropertyType(DataModelDataType::Value inDataType, const SValue &inValue)
+ {
+ if (inValue.empty() == false) {
+ DataModelDataType::Value theType = GetValueType(inValue);
+ if (theType != inDataType) {
+ return SValue(0.0f);
+ }
+ }
+ return inValue;
+ }
+ // If the datatype doesn't match the value, force the value to match the type.
+ // some types *have* to have values.
+ TMetaDataData VerifyMetaDataDataType(AdditionalMetaDataType::Value inDataType,
+ const TMetaDataData &inValue)
+ {
+ if (inDataType == AdditionalMetaDataType::StringList
+ || inDataType == AdditionalMetaDataType::Range) {
+ if (inValue.empty() == true || inDataType != GetMetaDataValueType(inValue)) {
+ QT3DS_ASSERT(false);
+ if (inDataType == AdditionalMetaDataType::StringList)
+ return TMetaDataStringList();
+ if (inDataType == AdditionalMetaDataType::Range)
+ return SMetaDataRange(0, 1);
+ }
+ }
+ return inValue;
+ }
+
+ void SetPropertyBaseInfo(SMetaPropertyBase &newInfo, TStrType inName, TStrType inFormalName,
+ TStrType inDescription, TStrType inUsage,
+ CompleteMetaDataType::Enum inDataType, const SValue &inDefaultValue,
+ const TMetaDataData &inMetaData)
+ {
+ newInfo.m_Name = inName;
+ newInfo.m_FormalName = inFormalName;
+ newInfo.m_Description = inDescription;
+ newInfo.m_Usage = inUsage;
+ newInfo.m_CompleteType = inDataType;
+ newInfo.m_DefaultValue =
+ VerifyDefaultPropertyType(CompleteMetaDataType::ToDataType(inDataType),
+ inDefaultValue);
+ newInfo.m_MetaDataData =
+ VerifyMetaDataDataType(CompleteMetaDataType::ToAdditionalType(inDataType),
+ inMetaData);
+ }
+
+ // For properties, you set the default values separately
+ // This may delete the underlying data model property rebuild it.
+ void SetMetaDataPropertyInfo(Qt3DSDMMetaDataPropertyHandle inPropertyHandle,
+ TStrType inName, TStrType inFormalName,
+ TStrType inDescription, TStrType inUsage,
+ CompleteMetaDataType::Enum inDataType,
+ const SValue &inDefaultValue,
+ const TMetaDataData &inMetaData, TStrType inGroupName,
+ bool inIsHidden, bool inIsAnimatable,
+ bool inIsControllable) override
+ {
+ SMetaDataPropertyInfo *infoPtr = FindProperty(inPropertyHandle);
+ if (infoPtr == NULL) {
+ QT3DS_ASSERT(false);
+ return;
+ }
+ SMetaDataPropertyInfo &newInfo(*infoPtr);
+ SMetaDataPropertyInfo oldInfo(newInfo);
+
+ SetPropertyBaseInfo(newInfo, inName, inFormalName, inDescription, inUsage, inDataType,
+ inDefaultValue, inMetaData);
+ newInfo.m_IsHidden = inIsHidden;
+ newInfo.m_Animatable = inIsAnimatable;
+ newInfo.m_Controllable = inIsControllable;
+ newInfo.m_GroupName = inGroupName;
+ EnsureDataCoreProperty(newInfo);
+
+ SetItemInfo(__FILE__, __LINE__, inPropertyHandle, oldInfo, newInfo, m_Properties,
+ m_InstanceNameToProperties);
+
+ SetPropertyDefault(newInfo, CompleteMetaDataType::ToDataType(inDataType));
+ }
+
+ void SetPropertyDefault(SMetaDataPropertyInfo &newInfo, DataModelDataType::Value inDataType)
+ {
+ if (newInfo.m_DefaultValue.empty() == false
+ && GetValueType(newInfo.m_DefaultValue) == inDataType) {
+ m_DataCore->SetInstancePropertyValue(newInfo.m_Instance, newInfo.m_Property,
+ newInfo.m_DefaultValue);
+ }
+ }
+
+ // Destroy just this meta data property
+ void DestroyMetaDataProperty(Qt3DSDMMetaDataPropertyHandle inProperty) override
+ {
+ SMetaDataPropertyInfo *infoPtr = FindProperty(inProperty);
+ if (infoPtr == NULL) {
+ QT3DS_ASSERT(false);
+ return;
+ }
+ if (DestroyItem(__FILE__, __LINE__, inProperty,
+ m_Properties, m_InstanceNameToProperties, m_InstanceToProperties)) {
+ Q_EMIT internalMetaDataPropertyDestroyed(inProperty);
+ }
+
+ RemoveMetaDataPropertyFilters(inProperty);
+ }
+
+ Qt3DSDMMetaDataPropertyHandle GetMetaDataProperty(Qt3DSDMInstanceHandle inInstance,
+ TStrType inPropertyName) override
+ {
+ return FindItemByName<Qt3DSDMMetaDataPropertyHandle>(inInstance, Intern(inPropertyName),
+ m_InstanceNameToProperties);
+ }
+ Qt3DSDMMetaDataPropertyHandle GetMetaDataProperty(Qt3DSDMInstanceHandle inInstance,
+ Qt3DSDMPropertyHandle inProperty) override
+ {
+ Qt3DSDMPropertyDefinition propDef(m_DataCore->GetProperty(inProperty));
+ return GetMetaDataProperty(inInstance, propDef.m_Name);
+ }
+ // Sets the value in the data core
+ virtual Option<SMetaDataPropertyInfo>
+ GetMetaDataPropertyInfo(Qt3DSDMMetaDataPropertyHandle inProperty) override
+ {
+ SMetaDataPropertyInfo *infoPtr = FindProperty(inProperty);
+ if (infoPtr == NULL) {
+ return Empty();
+ }
+ return *infoPtr;
+ }
+
+ void GetMetaDataProperties(Qt3DSDMInstanceHandle inInstance,
+ vector<Qt3DSDMMetaDataPropertyHandle> &outProperties) override
+ {
+ return GetHandleList<Qt3DSDMMetaDataPropertyHandle>(inInstance, m_InstanceToProperties,
+ m_Properties, outProperties);
+ }
+ virtual Qt3DSDMMetaDataPropertyHandle
+ GetSpecificMetaDataProperty(Qt3DSDMInstanceHandle inInstance, TStrType inPropertyName)
+ {
+ TInstancePropertyNamePropertyMap::iterator theFind = m_InstanceNameToProperties.find(
+ make_pair(inInstance, m_StringTable.RegisterStr(inPropertyName.wide_str())));
+ if (theFind != m_InstanceNameToProperties.end())
+ return theFind->second;
+ return 0;
+ }
+ virtual Qt3DSDMMetaDataPropertyHandle
+ GetOrCreateSpecificMetaDataProperty(Qt3DSDMInstanceHandle inInstance,
+ TStrType inPropertyName) override
+ {
+ Qt3DSDMMetaDataPropertyHandle theProp(
+ GetSpecificMetaDataProperty(inInstance, inPropertyName));
+ if (theProp.Valid())
+ return theProp;
+ return CreateMetaDataProperty(inInstance);
+ }
+
+ void GetSpecificMetaDataProperties(Qt3DSDMInstanceHandle inInstance,
+ vector<Qt3DSDMMetaDataPropertyHandle> &outProperties) override
+ {
+ TInstancePropertyMap::iterator find = m_InstanceToProperties.find(inInstance);
+ if (find != m_InstanceToProperties.end())
+ outProperties.insert(outProperties.end(), find->second.begin(), find->second.end());
+ }
+
+ TCharStr GetFormalName(Qt3DSDMInstanceHandle inInstance,
+ Qt3DSDMPropertyHandle inProperty) override
+ {
+ Qt3DSDMMetaDataPropertyHandle propHandle(GetMetaDataProperty(inInstance, inProperty));
+ SMetaDataPropertyInfo *infoPtr = FindProperty(propHandle);
+ if (infoPtr)
+ return infoPtr->m_FormalName;
+ return TCharStr();
+ }
+ AdditionalMetaDataType::Value GetAdditionalMetaDataType(
+ Qt3DSDMInstanceHandle inInstance, Qt3DSDMPropertyHandle inProperty) override
+ {
+ Qt3DSDMMetaDataPropertyHandle propHandle(GetMetaDataProperty(inInstance, inProperty));
+ SMetaDataPropertyInfo *infoPtr = FindProperty(propHandle);
+ if (infoPtr)
+ return infoPtr->GetAdditionalType();
+ return AdditionalMetaDataType::None;
+ }
+ TMetaDataData GetAdditionalMetaDataData(Qt3DSDMInstanceHandle inInstance,
+ Qt3DSDMPropertyHandle inProperty) override
+ {
+ Qt3DSDMMetaDataPropertyHandle propHandle(GetMetaDataProperty(inInstance, inProperty));
+ SMetaDataPropertyInfo *infoPtr = FindProperty(propHandle);
+ if (propHandle.Valid())
+ return infoPtr->m_MetaDataData;
+ return TMetaDataData();
+ }
+
+ bool IsCustomInstance(Qt3DSDMInstanceHandle inInstance)
+ {
+ return m_InstancesToCanonicalType.find(inInstance) == m_InstancesToCanonicalType.end();
+ }
+
+ SValue GetDefaultValue(Qt3DSDMInstanceHandle inInstance,
+ Qt3DSDMPropertyHandle inProperty) override
+ {
+ Qt3DSDMMetaDataPropertyHandle theProperty(GetMetaDataProperty(inInstance, inProperty));
+ if (theProperty.Valid() == false) {
+ QT3DS_ASSERT(false);
+ return SValue();
+ }
+ return FindProperty(theProperty)->m_DefaultValue;
+ }
+
+ bool IsCustomProperty(Qt3DSDMInstanceHandle inInstance,
+ Qt3DSDMPropertyHandle inProperty) override
+ {
+ Qt3DSDMMetaDataPropertyHandle propHandle(GetMetaDataProperty(inInstance, inProperty));
+ SMetaDataPropertyInfo *infoPtr = FindProperty(propHandle);
+ if (infoPtr)
+ return IsCustomInstance(infoPtr->m_Instance);
+
+ return false;
+ }
+
+ bool IsFilterValid(Qt3DSDMMetaDataPropertyHandle inProperty,
+ const SPropertyFilterInfo &inFilter)
+ {
+ SMetaDataPropertyInfo *infoPtr = FindProperty(inProperty);
+ if (m_DataCore->IsProperty(inFilter.m_FilterProperty) == false) {
+ QT3DS_ASSERT(false);
+ return false;
+ }
+
+ Qt3DSDMPropertyDefinition theProp(m_DataCore->GetProperty(inFilter.m_FilterProperty));
+ Qt3DSDMPropertyHandle propCheck =
+ m_DataCore->GetAggregateInstancePropertyByName(infoPtr->m_Instance, theProp.m_Name);
+ if (propCheck != inFilter.m_FilterProperty) {
+ QT3DS_ASSERT(false);
+ return false;
+ }
+
+ DataModelDataType::Value theType = GetValueType(inFilter.m_Value);
+ if (theType != theProp.m_Type) {
+ QT3DS_ASSERT(false);
+ return false;
+ }
+
+ return true;
+ }
+
+ void SetMetaDataPropertyFilters(Qt3DSDMMetaDataPropertyHandle inProperty,
+ NVConstDataRef<SPropertyFilterInfo> inFilters) override
+ {
+ SMetaDataPropertyInfo *infoPtr = FindProperty(inProperty);
+ if (infoPtr == NULL) {
+ QT3DS_ASSERT(false);
+ return;
+ }
+
+ eastl::vector<SPropertyFilterInfo> newFilters;
+ for (QT3DSU32 idx = 0, end = inFilters.size(); idx < end; ++idx) {
+ const SPropertyFilterInfo &theFilter(inFilters[idx]);
+ if (IsFilterValid(inProperty, theFilter))
+ newFilters.push_back(theFilter);
+ }
+
+ InsertOrUpdateWithTransaction(std::make_pair(inProperty, newFilters), m_PropertyFilters);
+ }
+
+ virtual NVConstDataRef<SPropertyFilterInfo>
+ GetMetaDataPropertyFilters(Qt3DSDMMetaDataPropertyHandle inProperty) override
+ {
+ TMetaDataPropertyFilterMap::iterator theIter(m_PropertyFilters.find(inProperty));
+ if (theIter != m_PropertyFilters.end())
+ return qt3ds::foundation::toDataRef(theIter->second.data(), theIter->second.size());
+ return NVConstDataRef<SPropertyFilterInfo>();
+ }
+
+ void RemoveMetaDataPropertyFilters(Qt3DSDMMetaDataPropertyHandle inProperty) override
+ {
+ TMetaDataPropertyFilterMap::iterator theIter(m_PropertyFilters.find(inProperty));
+ if (theIter != m_PropertyFilters.end())
+ EraseWithTransaction(__FILE__, __LINE__, inProperty, m_PropertyFilters);
+ }
+
+ ////////////////////////////////////////////////////////////////////////////////////
+ // Properties
+ Qt3DSDMEventHandle CreateMetaDataEvent(TInstanceHandle inInstance) override
+ {
+ return CreateItem<Qt3DSDMEventHandle, SEvent>(__FILE__, __LINE__, inInstance, m_Events,
+ m_InstanceToEvents);
+ }
+
+ void SetEventInfo(Qt3DSDMEventHandle inEventHandle, TStrType inName,
+ TStrType inFormalName, TStrType inCategory, TStrType inDescription) override
+ {
+ SEvent *infoPtr = FindEvent(inEventHandle);
+ if (infoPtr == NULL) {
+ QT3DS_ASSERT(false);
+ return;
+ }
+ SEvent &newInfo(*infoPtr);
+ SEvent oldInfo(newInfo);
+ newInfo.m_Name = inName;
+ newInfo.m_FormalName = inFormalName;
+ newInfo.m_Category = inCategory;
+ newInfo.m_Description = inDescription;
+ SetItemInfo(__FILE__, __LINE__, inEventHandle, oldInfo, newInfo, m_Events,
+ m_InstanceNameToEvents);
+ }
+
+ void DestroyEvent(Qt3DSDMEventHandle inEventHandle) override
+ {
+ if (DestroyItem(__FILE__, __LINE__, inEventHandle, m_Events,
+ m_InstanceNameToEvents, m_InstanceToEvents)) {
+ Q_EMIT internalEventDestroyed(inEventHandle);
+ }
+ }
+
+ void GetEvents(Qt3DSDMInstanceHandle inInstance, TEventHandleList &outEvents) override
+ {
+ return GetHandleList<Qt3DSDMEventHandle>(inInstance, m_InstanceToEvents, m_Events,
+ outEvents);
+ }
+
+ Qt3DSDMEventHandle FindEvent(Qt3DSDMInstanceHandle inInstance, TStrType inName) override
+ {
+ return FindItemByName<Qt3DSDMEventHandle>(inInstance, Intern(inName),
+ m_InstanceNameToEvents);
+ }
+
+ Option<SEventInfo> GetEventInfo(Qt3DSDMEventHandle inEventHandle) override
+ {
+ SEvent *infoPtr = FindEvent(inEventHandle);
+ if (infoPtr == NULL) {
+ return Empty();
+ }
+ SEventInfo retval;
+ retval.m_Name = infoPtr->m_Name;
+ retval.m_FormalName = infoPtr->m_FormalName;
+ retval.m_Description = infoPtr->m_Description;
+ retval.m_Category = infoPtr->m_Category;
+ return retval;
+ }
+
+ bool IsCustomEvent(Qt3DSDMEventHandle inEventHandle) override
+ {
+ SEvent *infoPtr = FindEvent(inEventHandle);
+ if (infoPtr != NULL)
+ return IsCustomInstance(infoPtr->m_Instance);
+ return false;
+ }
+
+ void GetSpecificEvents(Qt3DSDMInstanceHandle inInstance, TEventHandleList &outEvents) override
+ {
+ TInstanceEventMap::iterator theFind(m_InstanceToEvents.find(inInstance));
+ if (theFind != m_InstanceToEvents.end())
+ outEvents.insert(outEvents.end(), theFind->second.begin(), theFind->second.end());
+ }
+
+ Qt3DSDMEventHandle GetOrCreateSpecificEvent(Qt3DSDMInstanceHandle inInstance,
+ TStrType inName) override
+ {
+ TInstanceEventNameEventMap::iterator theFind(
+ m_InstanceNameToEvents.find(make_pair(inInstance, Intern(inName))));
+ if (theFind != m_InstanceNameToEvents.end())
+ return theFind->second;
+ return CreateMetaDataEvent(inInstance);
+ }
+
+ ////////////////////////////////////////////////////////////////////////////////////
+ // Handlers
+
+ Qt3DSDMHandlerHandle CreateHandler(Qt3DSDMInstanceHandle inInstance) override
+ {
+ return CreateItem<Qt3DSDMHandlerHandle, SHandler>(__FILE__, __LINE__, inInstance,
+ m_Handlers, m_InstanceToHandlers);
+ }
+
+ void SetHandlerInfo(Qt3DSDMHandlerHandle inHandle, TStrType inName,
+ TStrType inFormalName, TStrType inCategoryName,
+ TStrType inDescription) override
+ {
+ SHandler *infoPtr = FindHandler(inHandle);
+ if (infoPtr == NULL) {
+ QT3DS_ASSERT(false);
+ return;
+ }
+ SHandler &newInfo(*infoPtr);
+ SHandler oldInfo(newInfo);
+ newInfo.m_Name = inName;
+ newInfo.m_FormalName = inFormalName;
+ newInfo.m_Description = inDescription;
+ newInfo.m_Category = inCategoryName;
+ SetItemInfo(__FILE__, __LINE__, inHandle, oldInfo, newInfo, m_Handlers,
+ m_InstanceNameToHandlers);
+ }
+
+ void DestroyHandler(Qt3DSDMHandlerHandle inHandlerHandle) override
+ {
+ SHandler *infoPtr(FindHandler(inHandlerHandle));
+ if (infoPtr == NULL) {
+ QT3DS_ASSERT(false);
+ return;
+ }
+ while (infoPtr->m_Arguments.empty() == false)
+ DestroyHandlerArgument(inHandlerHandle, (QT3DSU32)infoPtr->m_Arguments.size() - 1);
+ if (DestroyItem(__FILE__, __LINE__, inHandlerHandle, m_Handlers,
+ m_InstanceNameToHandlers, m_InstanceToHandlers)) {
+ Q_EMIT internalHandlerDestroyed(inHandlerHandle);
+ }
+ }
+
+ Qt3DSDMHandlerHandle FindHandlerByName(Qt3DSDMInstanceHandle inInstance,
+ TStrType inName) override
+ {
+ return FindItemByName<Qt3DSDMHandlerHandle>(inInstance, Intern(inName),
+ m_InstanceNameToHandlers);
+ }
+
+ Option<SHandlerInfo> GetHandlerInfo(Qt3DSDMHandlerHandle inHandlerHandle) override
+ {
+ SHandler *infoPtr = FindHandler(inHandlerHandle);
+ if (infoPtr == NULL)
+ return Empty();
+
+ SHandlerInfo retval;
+ retval.m_Name = infoPtr->m_Name;
+ retval.m_FormalName = infoPtr->m_FormalName;
+ retval.m_Category = infoPtr->m_Category;
+ retval.m_Description = infoPtr->m_Description;
+
+ return retval;
+ }
+
+ void GetHandlers(Qt3DSDMInstanceHandle inInstance, THandlerHandleList &outHandlers) override
+ {
+ return GetHandleList<Qt3DSDMHandlerHandle>(inInstance, m_InstanceToHandlers, m_Handlers,
+ outHandlers);
+ }
+
+ bool IsCustomHandler(Qt3DSDMHandlerHandle inHandle) override
+ {
+ SHandler *infoPtr = FindHandler(inHandle);
+ if (infoPtr != NULL)
+ return IsCustomInstance(infoPtr->m_Instance);
+ return false;
+ }
+
+ void GetSpecificHandlers(Qt3DSDMInstanceHandle inInstance,
+ THandlerHandleList &outHandlers) override
+ {
+ TInstanceHandlerMap::iterator theFind = m_InstanceToHandlers.find(inInstance);
+ if (theFind != m_InstanceToHandlers.end())
+ outHandlers.insert(outHandlers.end(), theFind->second.begin(), theFind->second.end());
+ }
+
+ Qt3DSDMHandlerHandle GetOrCreateSpecificHandler(Qt3DSDMInstanceHandle inInstance,
+ TStrType inName) override
+ {
+ TInstanceHandlerNameHandlerMap::iterator theFind =
+ m_InstanceNameToHandlers.find(make_pair(inInstance, Intern(inName)));
+ if (theFind != m_InstanceNameToHandlers.end())
+ return theFind->second;
+ return CreateHandler(inInstance);
+ }
+
+ ////////////////////////////////////////////////////////////////////////////////////
+ // Handler Arguments
+
+ void DoAddHandlerArgument(Qt3DSDMHandlerHandle inHandler,
+ const SMetaDataHandlerArgumentInfo &inArgHandle, QT3DSU32 inIdx)
+ {
+ SHandler *infoPtr = FindHandler(inHandler);
+ if (infoPtr == NULL) {
+ QT3DS_ASSERT(false);
+ return;
+ }
+ infoPtr->m_Arguments.insert(infoPtr->m_Arguments.begin() + inIdx, inArgHandle);
+ }
+
+ struct ArgNameEqual
+ {
+ const TCharStr &m_Name;
+ ArgNameEqual(const TCharStr &nm)
+ : m_Name(nm)
+ {
+ }
+ bool operator()(const SMetaDataHandlerArgumentInfo &info) const
+ {
+ return m_Name == info.m_Name;
+ }
+ };
+
+ void DoRemoveHandlerArgument(Qt3DSDMHandlerHandle inHandler,
+ const SMetaDataHandlerArgumentInfo &inArgHandle)
+ {
+ SHandler *infoPtr = FindHandler(inHandler);
+ if (infoPtr == NULL) {
+ QT3DS_ASSERT(false);
+ return;
+ }
+ erase_if(infoPtr->m_Arguments, ArgNameEqual(inArgHandle.m_Name));
+ }
+
+ struct HandlerArgumentAddRemoveTransaction : public ITransaction
+ {
+ SNewMetaDataImpl &m_Impl;
+ Qt3DSDMHandlerHandle m_Handler;
+ SMetaDataHandlerArgumentInfo m_Arg;
+ QT3DSU32 m_Idx;
+ bool m_AddOnDo;
+
+ HandlerArgumentAddRemoveTransaction(const char *inFile, int inLine, SNewMetaDataImpl &impl,
+ Qt3DSDMHandlerHandle hdl,
+ const SMetaDataHandlerArgumentInfo &arg, QT3DSU32 inIdx,
+ bool inAddOnDo)
+ : ITransaction(inFile, inLine)
+ , m_Impl(impl)
+ , m_Handler(hdl)
+ , m_Arg(arg)
+ , m_Idx(inIdx)
+ , m_AddOnDo(inAddOnDo)
+ {
+ }
+ void insert() { m_Impl.DoAddHandlerArgument(m_Handler, m_Arg, m_Idx); }
+ void remove() { m_Impl.DoRemoveHandlerArgument(m_Handler, m_Arg); }
+ void Do() override
+ {
+ if (m_AddOnDo)
+ insert();
+ else
+ remove();
+ }
+ void Undo() override
+ {
+ if (m_AddOnDo)
+ remove();
+ else
+ insert();
+ }
+ };
+
+ QT3DSU32 AddHandlerArgument(Qt3DSDMHandlerHandle inHandler) override
+ {
+ SHandler *infoPtr = FindHandler(inHandler);
+ if (infoPtr == NULL) {
+ QT3DS_ASSERT(false);
+ return 0;
+ }
+
+ SMetaDataHandlerArgumentInfo theInfo(inHandler);
+ QT3DSU32 idx = (QT3DSU32)infoPtr->m_Arguments.size();
+ DoAddHandlerArgument(inHandler, theInfo, idx);
+ if (m_Consumer)
+ m_Consumer->OnTransaction(make_shared<HandlerArgumentAddRemoveTransaction>(
+ __FILE__, __LINE__, ref(*this), inHandler, theInfo,
+ idx, true));
+
+ return idx;
+ }
+
+ void DoSetHandlerArgument(THandlerHandle inHandler, QT3DSU32 inIdx,
+ const SMetaDataHandlerArgumentInfo &inInfo)
+ {
+ SMetaDataHandlerArgumentInfo *infoPtr(FindHandlerArg(inHandler, inIdx));
+ if (infoPtr == NULL) {
+ QT3DS_ASSERT(false);
+ return;
+ }
+ *infoPtr = inInfo;
+ }
+
+ struct SetHandlerArgumentInfoTrans : public ITransaction
+ {
+ SNewMetaDataImpl &m_Impl;
+ THandlerHandle m_Handler;
+ QT3DSU32 m_Idx;
+ SMetaDataHandlerArgumentInfo m_NewValue;
+ SMetaDataHandlerArgumentInfo m_OldValue;
+ SetHandlerArgumentInfoTrans(const char *inFile, int inLine, SNewMetaDataImpl &impl,
+ THandlerHandle handler, QT3DSU32 inIdx,
+ const SMetaDataHandlerArgumentInfo &inNewVal,
+ const SMetaDataHandlerArgumentInfo &inOldVal)
+ : ITransaction(inFile, inLine)
+ , m_Impl(impl)
+ , m_Handler(handler)
+ , m_Idx(inIdx)
+ , m_NewValue(inNewVal)
+ , m_OldValue(inOldVal)
+ {
+ }
+ void Do() override { m_Impl.DoSetHandlerArgument(m_Handler, m_Idx, m_NewValue); }
+ void Undo() override { m_Impl.DoSetHandlerArgument(m_Handler, m_Idx, m_OldValue); }
+ };
+
+ void SetHandlerArgumentInfo(THandlerHandle inHandler, QT3DSU32 inIdx, TStrType inName,
+ TStrType inFormalName, TStrType inDescription,
+ CompleteMetaDataType::Enum inDataType,
+ const SValue &inDefaultValue,
+ const TMetaDataData &inMetaData,
+ HandlerArgumentType::Value inArgType) override
+ {
+ SMetaDataHandlerArgumentInfo *infoPtr(FindHandlerArg(inHandler, inIdx));
+ if (infoPtr == NULL) {
+ QT3DS_ASSERT(false);
+ return;
+ }
+ SMetaDataHandlerArgumentInfo &newInfo(*infoPtr);
+ SMetaDataHandlerArgumentInfo oldInfo(newInfo);
+ SetPropertyBaseInfo(newInfo, inName, inFormalName, inDescription, L"", inDataType,
+ inDefaultValue, inMetaData);
+ newInfo.m_ArgType = inArgType;
+ if (m_Consumer != NULL)
+ m_Consumer->OnTransaction(make_shared<SetHandlerArgumentInfoTrans>(
+ __FILE__, __LINE__, ref(*this), inHandler, inIdx,
+ newInfo, oldInfo));
+ }
+
+ void DestroyHandlerArgument(THandlerHandle inHandler, QT3DSU32 inIdx) override
+ {
+ SHandler *ownerPtr = FindHandler(inHandler);
+ SMetaDataHandlerArgumentInfo *infoPtr(FindHandlerArg(inHandler, inIdx));
+ if (infoPtr == NULL) {
+ QT3DS_ASSERT(false);
+ return;
+ }
+ if (ownerPtr == NULL) {
+ QT3DS_ASSERT(false);
+ return;
+ }
+
+ Q_EMIT internalHandlerArgDestroyed(inHandler, inIdx);
+
+ if (m_Consumer)
+ m_Consumer->OnTransaction(make_shared<HandlerArgumentAddRemoveTransaction>(
+ __FILE__, __LINE__, ref(*this), infoPtr->m_Handler,
+ *infoPtr, inIdx, false));
+
+ DoRemoveHandlerArgument(infoPtr->m_Handler, *infoPtr);
+ }
+
+ Option<SMetaDataHandlerArgumentInfo> FindHandlerArgumentByName(THandlerHandle inHandler,
+ TStrType inName) override
+ {
+ SHandler *ownerPtr = FindHandler(inHandler);
+ if (ownerPtr == NULL) {
+ return Empty();
+ }
+ for (size_t idx = 0, end = ownerPtr->m_Arguments.size(); idx < end; ++idx) {
+ if (ownerPtr->m_Arguments[idx].m_Name == inName)
+ return ownerPtr->m_Arguments[idx];
+ }
+ return Empty();
+ }
+
+ void GetHandlerArguments(THandlerHandle inHandler,
+ vector<SMetaDataHandlerArgumentInfo> &outArguments) override
+ {
+ SHandler *ownerPtr = FindHandler(inHandler);
+ if (ownerPtr == NULL) {
+ return;
+ }
+ outArguments.insert(outArguments.end(), ownerPtr->m_Arguments.begin(),
+ ownerPtr->m_Arguments.end());
+ }
+
+ virtual Option<SMetaDataHandlerArgumentInfo>
+ GetHandlerArgumentInfo(Qt3DSDMHandlerHandle inHandle, QT3DSU32 inIdx) override
+ {
+ SMetaDataHandlerArgumentInfo *infoPtr(FindHandlerArg(inHandle, inIdx));
+ if (infoPtr == NULL) {
+ return Empty();
+ }
+ return *infoPtr;
+ }
+
+ QT3DSU32 GetNumHandlerArguments(Qt3DSDMHandlerHandle inHandler) override
+ {
+ SHandler *ownerPtr = FindHandler(inHandler);
+ if (ownerPtr == NULL) {
+ return 0;
+ }
+ return (QT3DSU32)ownerPtr->m_Arguments.size();
+ }
+
+ ////////////////////////////////////////////////////////////////////////////////////
+ // References
+ void AddReference(Qt3DSDMInstanceHandle inInstance, TStrType inRefString) override
+ {
+ // trim whitespace from the beginning and the end of the string
+ TCharStr::size_type startPos = inRefString.find_first_not_of(L"\n\r\t ");
+ TCharStr::size_type endPos = inRefString.find_last_not_of(L"\n\r\t ");
+ const wchar_t *theStr = NULL;
+ if (startPos != TCharStr::npos) {
+ TStrType temp = inRefString.substr(startPos, endPos - startPos + 1);
+ theStr = Intern(temp);
+ } else
+ theStr = Intern(inRefString);
+
+ QT3DSU32 idx = AddItemToInstanceList(inInstance, theStr, m_InstanceToReferences);
+ if (m_Consumer) {
+ m_Consumer->OnTransaction(
+ std::make_shared<InstanceListTransaction<TInstanceStringListMap,
+ const wchar_t *>>(
+ __FILE__, __LINE__, inInstance, theStr,
+ std::ref(m_InstanceToReferences), idx,
+ true));
+ }
+ }
+
+ void DestroyReferences(Qt3DSDMInstanceHandle inInstance) override
+ {
+ TInstanceStringListMap::iterator find = m_InstanceToReferences.find(inInstance);
+
+ if (find == m_InstanceToReferences.end())
+ return;
+
+ CreateHashMapEraseTransaction(__FILE__, __LINE__, m_Consumer,
+ make_pair(find->first, find->second), m_InstanceToReferences);
+ m_InstanceToReferences.erase(find);
+ }
+
+ struct InternSizeTOpType
+ {
+ SNewMetaDataImpl &m_Impl;
+ InternSizeTOpType(SNewMetaDataImpl &inImpl)
+ : m_Impl(inImpl)
+ {
+ }
+
+ size_t operator()(const TCharStr &inHandle)
+ {
+ return reinterpret_cast<size_t>(m_Impl.Intern(inHandle));
+ }
+ };
+
+ void GetReferences(Qt3DSDMInstanceHandle inInstance, vector<TCharStr> &outReferences) override
+ {
+ DoGetHandleList(inInstance, m_InstanceToReferences, outReferences,
+ InternSizeTOpType(*this));
+ }
+
+ ////////////////////////////////////////////////////////////////////////////////////
+ // Instance-global functions
+ // Destroy all meta data that relates to this instance.
+ // Calling this on a derived instance does nothing, this only works if this specific
+ // instance was mapped to a type.
+ // This function must be completely undoable.
+ void DestroyMetaData(Qt3DSDMInstanceHandle inInstance) override
+ {
+ ForEachItem<TMetaDataPropertyHandle>(
+ inInstance, m_InstanceToProperties,
+ bind(&SNewMetaDataImpl::DestroyMetaDataProperty, this,
+ std::placeholders::_1));
+ ForEachItem<TEventHandle>(inInstance, m_InstanceToEvents,
+ bind(&SNewMetaDataImpl::DestroyEvent, this,
+ std::placeholders::_1));
+ ForEachItem<THandlerHandle>(inInstance, m_InstanceToHandlers,
+ bind(&SNewMetaDataImpl::DestroyHandler, this,
+ std::placeholders::_1));
+ DestroyReferences(inInstance);
+
+ TInstanceStrMap::iterator find = m_InstancesToCanonicalType.find(inInstance);
+ if (find != m_InstancesToCanonicalType.end()) {
+ TCharPtr theName(find->second);
+ m_CanonicalTypeToInstances.erase(theName);
+ m_InstancesToCanonicalType.erase(inInstance);
+ CreateHashMapEraseTransaction(__FILE__, __LINE__, m_Consumer,
+ make_pair(theName, inInstance),
+ m_CanonicalTypeToInstances);
+ CreateHashMapEraseTransaction(__FILE__, __LINE__, m_Consumer,
+ make_pair(inInstance, theName),
+ m_InstancesToCanonicalType);
+ }
+ }
+
+ ////////////////////////////////////////////////////////////////////////////////////
+ // Serialization
+ // You can either save out in canonical format (and it will only save canonical-instance-related
+ // information *or* you can save out in normal format where we link directly to instance handle
+ // instead of to typename
+ template <typename THashType>
+ void AddInstancesFromHash(THashType &inHash,
+ unordered_set<TInstanceHandle, hash<int>> &outInstances)
+ {
+ for (typename THashType::const_iterator iter = inHash.begin(), end = inHash.end();
+ iter != end; ++iter)
+ outInstances.insert(iter->first);
+ }
+
+ void SerializeMetaDataData(IDOMWriter &inWriter, TMetaDataData &inItem,
+ AdditionalMetaDataType::Value inType)
+ {
+ if (!inItem.empty()) {
+ if (inType == AdditionalMetaDataType::Range) {
+ SMetaDataRange theRange(get<SMetaDataRange>(inItem));
+ inWriter.Att(L"min", theRange.m_min);
+ inWriter.Att(L"max", theRange.m_max);
+ inWriter.Att(L"decimals", theRange.m_decimals);
+ } else if (inType == AdditionalMetaDataType::StringList) {
+ const TMetaDataStringList &theList(get<TMetaDataStringList>(inItem));
+ TCharStr theBuffer;
+ for (uint32_t idx = 0, end = theList.size(); idx < end; ++idx) {
+ if (idx)
+ theBuffer.append(L":");
+ theBuffer.append(theList[idx]);
+ }
+ inWriter.Att(L"list", theBuffer.wide_str());
+ }
+ }
+ }
+
+ void SerializeDataModelValue(IDOMWriter &inWriter, const SValue &inValue,
+ DataModelDataType::Value /*inType*/,
+ const wchar_t *inName = L"default")
+ {
+ if (inValue.empty())
+ return;
+
+ m_TempBuffer.clear();
+ WCharTWriter writer(m_TempBuffer);
+ WStrOps<SValue>().ToBuf(inValue, writer);
+
+ if (m_TempBuffer.size()) {
+ m_TempBuffer.write((QT3DSU16)0);
+ inWriter.Att(inName, (const wchar_t *)m_TempBuffer.begin());
+ }
+ }
+
+ void SerializeDataModelValue(IDOMReader &inReader, SValue &outValue,
+ DataModelDataType::Value inType,
+ const wchar_t *inName = L"default")
+ {
+ const char8_t *theDefaultValue;
+ qt3ds::foundation::ConvertUTF(
+ reinterpret_cast<const qt3ds::foundation::TWCharEASTLConverter::TCharType *>(
+ inName), 0,
+ m_ConvertStr);
+ if (inReader.UnregisteredAtt(m_ConvertStr.c_str(), theDefaultValue)) {
+ m_TempBuffer.clear();
+ // We have to write a temporary value because the parsing of floats,
+ // in order to be efficient, is destructive.
+ if (theDefaultValue && *theDefaultValue)
+ m_TempBuffer.write(theDefaultValue, (QT3DSU32)strlen(theDefaultValue) + 1);
+
+ if (m_TempBuffer.size() == 0) {
+ SetDefault(inType, outValue);
+ return;
+ }
+ m_ReadBuffer.clear();
+
+ char8_t *trashPtr = (char8_t *)m_TempBuffer.begin();
+ WCharTReader theReader(trashPtr, m_ReadBuffer, m_StringTable);
+ outValue = WStrOps<SValue>().BufTo(inType, theReader);
+ } else
+ SetDefault(inType, outValue);
+ }
+
+ void SerializeMetaDataData(IDOMReader &inReader, TMetaDataData &ioItem,
+ CompleteMetaDataType::Enum &ioType)
+ {
+ // Use the meta data extra information to force the type
+ // to something that works correctly.
+ SMetaDataRange theRange;
+ if (inReader.Att("min", theRange.m_min) && inReader.Att("max", theRange.m_max)) {
+ inReader.Att("decimals", theRange.m_decimals);
+ ioItem = theRange;
+ if (ioType == CompleteMetaDataType::Long)
+ ioType = CompleteMetaDataType::LongRange;
+ else
+ ioType = CompleteMetaDataType::FloatRange;
+ } else {
+ TMetaDataStringList theList;
+ TCharStr theItems;
+ if (inReader.Att(L"list", theItems)) {
+ for (TCharStr::size_type theIter = theItems.find_first_of(L":,");
+ theIter != theItems.npos; theIter = theItems.find_first_of(L":,")) {
+ theList.push_back(theItems.substr(0, theIter));
+ theItems = theItems.substr(theIter + 1);
+ }
+ theList.push_back(theItems);
+ ioItem = theList;
+ if (ioType != CompleteMetaDataType::StringListOrInt)
+ ioType = CompleteMetaDataType::StringList;
+ }
+ }
+ }
+ void EnsureCategory(IDOMWriter &, const TCharStr &, const TCharStr &) {}
+ void EnsureCategory(IDOMReader &, TCharStr &inCategory, const TCharStr &inObjectName)
+ {
+ Qt3DSDMCategoryHandle theCategory = FindCategoryByName(inCategory);
+ if (theCategory.Valid() == false) {
+ if (inObjectName.empty()) {
+ QT3DS_ASSERT(false);
+ } else {
+ if (inCategory.empty())
+ inCategory = inObjectName;
+
+ pair<Qt3DSDMCategoryHandle, bool> theGetOrCreateResult(
+ GetOrCreateCategory(inCategory));
+
+ if (theGetOrCreateResult.second == true) {
+ SetCategoryInfo(theGetOrCreateResult.first, L"Objects-Behavior-Normal.png",
+ L"Objects-Behavior-Normal.png", inCategory);
+ }
+ }
+ }
+ }
+
+ void SerializePropertyBase(IDOMWriter &inArchive, SMetaPropertyBase &inItem)
+ {
+ inArchive.Att(L"name", inItem.m_Name);
+ if (inItem.m_FormalName != inItem.m_Name)
+ inArchive.Att(L"formalName", inItem.m_FormalName);
+ if (inItem.m_Description != inItem.m_Name)
+ inArchive.Att(L"description", inItem.m_Description);
+ if (inItem.m_CompleteType != CompleteMetaDataType::Float
+ && inItem.m_CompleteType != CompleteMetaDataType::FloatRange
+ && inItem.m_CompleteType != CompleteMetaDataType::LongRange
+ && inItem.m_CompleteType != CompleteMetaDataType::StringList) {
+ inArchive.Att(L"type", inItem.m_CompleteType);
+ }
+
+ // Ensure that all types work
+ if (inItem.GetAdditionalType() != AdditionalMetaDataType::None)
+ SerializeMetaDataData(inArchive, inItem.m_MetaDataData, inItem.GetAdditionalType());
+
+ if (inItem.GetDataType() != DataModelDataType::None) {
+ SValue theGlobalDefault;
+ SetDefault(inItem.GetDataType(), theGlobalDefault);
+ if (!Equals(theGlobalDefault.toOldSkool(), inItem.m_DefaultValue.toOldSkool()))
+ SerializeDataModelValue(inArchive, inItem.m_DefaultValue, inItem.GetDataType());
+ }
+ }
+
+ void SerializePropertyBase(IDOMReader &inArchive, SMetaPropertyBase &inItem)
+ {
+ inArchive.Att(L"name", inItem.m_Name);
+ inArchive.Att(L"formalName", inItem.m_FormalName);
+ inArchive.Att(L"usage", inItem.m_Usage);
+ inArchive.Att(L"description", inItem.m_Description);
+ inArchive.Att(L"type", inItem.m_CompleteType);
+ // Setup reasonable defaults in the case where the users are specifying little information
+ // in the file format
+ if (inItem.m_FormalName.empty())
+ inItem.m_FormalName = inItem.m_Name;
+ if (inItem.m_Description.empty())
+ inItem.m_Description = inItem.m_FormalName;
+
+ // Ensure that users can use a float type and make minimal decisions
+ SerializeMetaDataData(inArchive, inItem.m_MetaDataData, inItem.m_CompleteType);
+
+ if (inItem.GetDataType() != DataModelDataType::None)
+ SerializeDataModelValue(inArchive, inItem.m_DefaultValue, inItem.GetDataType());
+ }
+
+ void FinalizeCategory(IDOMWriter &, SCategoryInfo &) {}
+
+ void FinalizeCategory(IDOMReader &, SCategoryInfo &inCategory)
+ {
+ if (inCategory.m_Description.empty())
+ inCategory.m_Description = inCategory.m_Name;
+ }
+
+ template <typename TArchiveType>
+ void SerializeItem(TArchiveType &inArchive, SCategoryInfo &inItem)
+ {
+ inArchive.Att(L"name", inItem.m_Name);
+ inArchive.Att(L"description", inItem.m_Description);
+ inArchive.Att(L"icon", inItem.m_Icon);
+ inArchive.Att(L"highlightIcon", inItem.m_HighlightIcon);
+
+ FinalizeCategory(inArchive, inItem);
+ }
+
+ void SerializeItem(IDOMWriter &inArchive, SMetaDataPropertyInfo &inItem,
+ Qt3DSDMMetaDataPropertyHandle inHandle)
+ {
+ SerializePropertyBase(inArchive, inItem);
+ if (inItem.m_IsHidden == true)
+ inArchive.Att("hidden", inItem.m_IsHidden);
+ if (inItem.m_Animatable == false)
+ inArchive.Att("animatable", inItem.m_Animatable);
+ if (inItem.m_Controllable == true)
+ inArchive.Att("controllable", inItem.m_Controllable);
+ NVConstDataRef<SPropertyFilterInfo> theInfos = GetMetaDataPropertyFilters(inHandle);
+ for (QT3DSU32 idx = 0, end = theInfos.size(); idx < end; ++idx) {
+ const SPropertyFilterInfo &theInfo(theInfos[idx]);
+ Qt3DSDMPropertyDefinition thePropertyInfo(
+ m_DataCore->GetProperty(theInfo.m_FilterProperty));
+
+ const wchar_t *theFilterName;
+ if (theInfo.m_FilterType == PropertyFilterTypes::HideIfEqual)
+ theFilterName = L"HideIfEqual";
+ else
+ theFilterName = L"ShowIfEqual";
+
+ IDOMWriter::Scope filterScope(inArchive, theFilterName);
+ inArchive.Att(L"property", thePropertyInfo.m_Name);
+ SerializeDataModelValue(inArchive, theInfo.m_Value, thePropertyInfo.m_Type, L"value");
+ }
+ }
+
+ void SerializeItem(IDOMReader &inArchive, SMetaDataPropertyInfo &inItem,
+ Qt3DSDMMetaDataPropertyHandle inHandle)
+ {
+ QT3DS_ASSERT(inHandle.Valid());
+
+ SerializePropertyBase(inArchive, inItem);
+ inArchive.Att("hidden", inItem.m_IsHidden);
+ inArchive.Att("animatable", inItem.m_Animatable);
+ inArchive.Att("controllable", inItem.m_Controllable);
+ inArchive.Att(L"category", inItem.m_GroupName);
+ }
+
+ void ReadChildren(IDOMReader &inArchive, SMetaDataPropertyInfo &inItem,
+ Qt3DSDMMetaDataPropertyHandle inHandle)
+ {
+ IDOMReader::Scope __readerScope(inArchive);
+ eastl::vector<SPropertyFilterInfo> theFilters;
+ for (bool success = inArchive.MoveToFirstChild(); success;
+ success = inArchive.MoveToNextSibling()) {
+
+ if (AreEqual(inArchive.GetElementName(), L"ShowIfEqual")) {
+ TCharStr theName;
+ inArchive.Att(L"property", theName);
+ Qt3DSDMPropertyHandle theProperty =
+ m_DataCore->GetAggregateInstancePropertyByName(inItem.m_Instance, theName);
+ if (theProperty.Valid() == false) {
+ QT3DS_ASSERT(false);
+ return;
+ }
+ Qt3DSDMPropertyDefinition thePropDef(m_DataCore->GetProperty(theProperty));
+
+ SPropertyFilterInfo theInfo;
+ theInfo.m_FilterType = PropertyFilterTypes::ShowIfEqual;
+ theInfo.m_FilterProperty = theProperty;
+ SerializeDataModelValue(inArchive, theInfo.m_Value, thePropDef.m_Type, L"value");
+ theFilters.push_back(theInfo);
+ } else if (AreEqual(inArchive.GetElementName(), L"HideIfEqual")) {
+ TCharStr theName;
+ inArchive.Att(L"property", theName);
+ Qt3DSDMPropertyHandle theProperty =
+ m_DataCore->GetAggregateInstancePropertyByName(inItem.m_Instance, theName);
+ if (theProperty.Valid() == false) {
+ QT3DS_ASSERT(false);
+ return;
+ }
+ Qt3DSDMPropertyDefinition thePropDef(m_DataCore->GetProperty(theProperty));
+
+ SPropertyFilterInfo theInfo;
+ theInfo.m_FilterType = PropertyFilterTypes::HideIfEqual;
+ theInfo.m_FilterProperty = theProperty;
+ SerializeDataModelValue(inArchive, theInfo.m_Value, thePropDef.m_Type, L"value");
+ theFilters.push_back(theInfo);
+ } else {
+ QT3DS_ASSERT(false);
+ }
+ }
+ if (theFilters.size())
+ SetMetaDataPropertyFilters(
+ inHandle, qt3ds::foundation::toDataRef(theFilters.data(),
+ theFilters.size()));
+ }
+
+ void EnsureEventHandlerBase(IDOMWriter &, SEventAndHandlerBase &) {}
+
+ void EnsureEventHandlerBase(IDOMReader &, SEventAndHandlerBase &inItem)
+ {
+ if (inItem.m_FormalName.empty())
+ inItem.m_FormalName = inItem.m_Name;
+ if (inItem.m_Description.empty())
+ inItem.m_Description = inItem.m_Name;
+ }
+
+ void SerializeItem(IDOMWriter &inArchive, SEvent &inItem, Qt3DSDMEventHandle &)
+ {
+ inArchive.Att(L"name", inItem.m_Name);
+ if (inItem.m_Name != inItem.m_FormalName)
+ inArchive.Att(L"formalName", inItem.m_FormalName);
+ if (inItem.m_Category != L"Default")
+ inArchive.Att(L"category", inItem.m_Category);
+ if (inItem.m_Description != inItem.m_Name)
+ inArchive.Att(L"description", inItem.m_Description);
+
+ EnsureCategory(inArchive, inItem.m_Category, m_ObjectName);
+ EnsureEventHandlerBase(inArchive, inItem);
+ }
+
+ void SerializeItem(IDOMReader &inArchive, SEvent &inItem, Qt3DSDMEventHandle &)
+ {
+ inArchive.Att(L"name", inItem.m_Name);
+ inArchive.Att(L"formalName", inItem.m_FormalName);
+ inArchive.Att(L"category", inItem.m_Category);
+ EnsureCategory(inArchive, inItem.m_Category, m_ObjectName);
+ inArchive.Att(L"description", inItem.m_Description);
+ EnsureEventHandlerBase(inArchive, inItem);
+ }
+
+ void SerializeHandlerArgument(IDOMWriter &inArchive, SMetaDataHandlerArgumentInfo &inArgument)
+ {
+ SerializePropertyBase(inArchive, inArgument);
+ if (inArgument.m_ArgType != HandlerArgumentType::None)
+ inArchive.Att(L"argumentType", inArgument.m_ArgType);
+ }
+
+ void SerializeHandlerArgument(IDOMReader &inArchive, SMetaDataHandlerArgumentInfo &inArgument)
+ {
+ SerializePropertyBase(inArchive, inArgument);
+ inArchive.Att(L"argumentType", inArgument.m_ArgType);
+ }
+
+ void SerializeHandlerArguments(IDOMWriter &inWriter, SHandler &inItem, Qt3DSDMHandlerHandle &)
+ {
+ for (size_t idx = 0, end = inItem.m_Arguments.size(); idx < end; ++idx) {
+ SMetaDataHandlerArgumentInfo &theArg(inItem.m_Arguments[idx]);
+ IDOMWriter::Scope __argScope(inWriter, L"Argument");
+ SerializeHandlerArgument(inWriter, theArg);
+ }
+ }
+
+ void SerializeHandlerArguments(IDOMReader &inReader, SHandler &inItem, THandlerHandle &inHandle)
+ {
+ if (inHandle.GetHandleValue() == 0)
+ inHandle = THandlerHandle(GetNextId());
+
+ IDOMReader::Scope __handlerScope(inReader);
+ for (bool success = inReader.MoveToFirstChild(); success;
+ success = inReader.MoveToNextSibling()) {
+ SMetaDataHandlerArgumentInfo theArg(inHandle);
+ SerializeHandlerArgument(inReader, theArg);
+ inItem.m_Arguments.push_back(theArg);
+ }
+ }
+
+ void SerializeHandlerItem(IDOMWriter &inArchive, SHandler &inItem)
+ {
+ inArchive.Att(L"name", inItem.m_Name);
+ if (inItem.m_FormalName != inItem.m_Name)
+ inArchive.Att(L"formalName", inItem.m_FormalName);
+ if (inItem.m_Category != L"Default")
+ inArchive.Att(L"category", inItem.m_Category);
+ if (inItem.m_Description != inItem.m_Name)
+ inArchive.Att(L"description", inItem.m_Description);
+ EnsureEventHandlerBase(inArchive, inItem);
+ }
+
+ void SerializeHandlerItem(IDOMReader &inArchive, SHandler &inItem)
+ {
+ inArchive.Att(L"name", inItem.m_Name);
+ inArchive.Att(L"formalName", inItem.m_FormalName);
+ inArchive.Att(L"category", inItem.m_Category);
+ EnsureCategory(inArchive, inItem.m_Category, m_ObjectName);
+ inArchive.Att(L"description", inItem.m_Description);
+ EnsureEventHandlerBase(inArchive, inItem);
+ }
+
+ template <typename TArchiveType>
+ void SerializeItem(TArchiveType &inArchive, SHandler &inItem, Qt3DSDMHandlerHandle &inHandle)
+ {
+ SerializeHandlerItem(inArchive, inItem);
+ SerializeHandlerArguments(inArchive, inItem, inHandle);
+ }
+
+ template <typename TInfoType, typename THandleType, typename TListMapType, typename THashType,
+ typename TNameMapType>
+ void SerializeInstanceData(IDOMWriter &inArchive, TInstanceHandle inInstanceHandle,
+ TCharPtr inElementName,
+ unordered_map<THandleType, TInfoType, THashType> &inMap,
+ TListMapType &inListMap, TNameMapType & /*inNameMap*/)
+ {
+ typedef unordered_map<THandleType, TInfoType, THashType> TMapType;
+ typename TListMapType::iterator find = inListMap.find(inInstanceHandle);
+ if (find == inListMap.end())
+ return;
+
+ vector<THandleType> &itemList = find->second;
+ for (size_t idx = 0, end = itemList.size(); idx < end; ++idx) {
+ typename TMapType::iterator iter = inMap.find(itemList[idx]);
+ if (iter == inMap.end()) {
+ QT3DS_ASSERT(false);
+ continue;
+ }
+ TInfoType &theType = iter->second;
+ IDOMWriter::Scope __elemScope(inArchive, inElementName);
+ SerializeItem(inArchive, theType, itemList[idx]);
+ }
+ }
+
+ void CreateInstanceGroupInfo(SMetaDataPropertyInfo &inProperty)
+ {
+ if (!inProperty.m_GroupName.empty()) {
+ const wchar_t *theGroupName = Intern(inProperty.m_GroupName);
+ bool found = false;
+ pair<typename TInstanceGroupMap::iterator, bool> inserter =
+ m_InstanceGroupMap.insert(make_pair(inProperty.m_Instance, vector<TCharPtr>()));
+ vector<TCharPtr> &itemList = inserter.first->second;
+ for (size_t idx = 0, end = itemList.size(); idx < end; ++idx) {
+ TCharStr curListName = itemList[idx];
+ if (curListName == theGroupName) {
+ found = true;
+ break;
+ }
+ }
+ if (!found && !inProperty.m_IsHidden)
+ inserter.first->second.push_back(theGroupName);
+ }
+ }
+ void CreateInstanceGroupInfo(SEvent &) {}
+ void CreateInstanceGroupInfo(SHandler &) {}
+
+ // Make sure the data core
+ void PostLoad(SMetaDataPropertyInfo &inProperty)
+ {
+ EnsureDataCoreProperty(inProperty);
+ SetPropertyDefault(inProperty, inProperty.GetDataType());
+ }
+
+ void ReadChildren(IDOMReader &, SEvent &, Qt3DSDMEventHandle) {}
+ void ReadChildren(IDOMReader &, SHandler &, Qt3DSDMHandlerHandle) {}
+
+ void PostLoad(SEvent &) {}
+ void PostLoad(SHandler &) {}
+ template <typename TInfoType, typename THandleType, typename TListMapType, typename THashType,
+ typename TNameMapType>
+ void SerializeInstanceData(IDOMReader &inArchive, TInstanceHandle inInstanceHandle,
+ TCharPtr inElementName,
+ unordered_map<THandleType, TInfoType, THashType> &inMap,
+ TListMapType &inListMap, TNameMapType &inNameMap)
+ {
+ // Ensure we pop out to where we were.
+ IDOMReader::Scope __readerScope(inArchive);
+ for (bool success = inArchive.MoveToFirstChild(inElementName); success;
+ success = inArchive.MoveToNextSibling(inElementName)) {
+ TInfoType theInfo(inInstanceHandle);
+ THandleType theHandle(GetNextId());
+ SerializeItem(inArchive, theInfo, theHandle);
+ PostLoad(theInfo);
+ CreateInstanceGroupInfo(theInfo);
+ inMap.insert(make_pair(theHandle, theInfo));
+ this->AddItemToInstanceList(inInstanceHandle, theHandle, inListMap);
+ inNameMap.insert(
+ make_pair(make_pair(inInstanceHandle, Intern(theInfo.m_Name)), theHandle));
+ ReadChildren(inArchive, theInfo, theHandle);
+ }
+ }
+
+ void SerializeInstanceData(IDOMWriter &inArchive, TInstanceHandle inInstance,
+ TCharPtr inElementName, TInstanceStringListMap &inMap)
+ {
+ TInstanceStringListMap::iterator iter = inMap.find(inInstance);
+ if (iter == inMap.end())
+ return;
+ const vector<TCharPtr> &theValueList(iter->second);
+ for (size_t idx = 0, end = theValueList.size(); idx < end; ++idx) {
+ IDOMWriter::Scope __elemScope(inArchive, inElementName);
+ inArchive.Value(theValueList[idx]);
+ }
+ }
+
+ void SerializeInstanceData(IDOMReader &inArchive, TInstanceHandle inInstance,
+ TCharPtr inElementName, TInstanceStringListMap &inMap)
+ {
+ IDOMReader::Scope __readerScope(inArchive);
+ for (bool success = inArchive.MoveToFirstChild(inElementName); success;
+ success = inArchive.MoveToNextSibling(inElementName)) {
+ const wchar_t *theValue;
+ if (inArchive.RegisteredValue(theValue))
+ AddItemToInstanceList(inInstance, theValue, inMap);
+ }
+ }
+
+ template <typename TArchiveType>
+ void SerializeInstance(TArchiveType &inArchive, TInstanceHandle inInstance)
+ {
+ SerializeInstanceData(inArchive, inInstance, L"Property", m_Properties,
+ m_InstanceToProperties, m_InstanceNameToProperties);
+ SerializeInstanceData(inArchive, inInstance, L"Event", m_Events, m_InstanceToEvents,
+ m_InstanceNameToEvents);
+ SerializeInstanceData(inArchive, inInstance, L"Handler", m_Handlers, m_InstanceToHandlers,
+ m_InstanceNameToHandlers);
+ SerializeInstanceData(inArchive, inInstance, L"Reference", m_InstanceToReferences);
+ }
+ void SerializeCategories(IDOMWriter &inWriter)
+ {
+ for (TCategoryMap::iterator iter = m_Categories.begin(), end = m_Categories.end();
+ iter != end; ++iter) {
+ IDOMWriter::Scope __writerScope(inWriter, L"Category");
+ SerializeItem(inWriter, iter->second);
+ }
+ }
+ void SerializeCategories(IDOMReader &inReader)
+ {
+ IDOMReader::Scope __readerScope(inReader);
+ for (bool success = inReader.MoveToFirstChild(L"Category"); success;
+ success = inReader.MoveToNextSibling(L"Category")) {
+ SCategoryInfo theInfo;
+ SerializeItem(inReader, theInfo);
+ TCategoryHandle newHandle(GetNextId());
+ theInfo.m_Canonical = true;
+ m_Categories.insert(make_pair(newHandle, theInfo));
+ m_NameToCategories.insert(make_pair(Intern(theInfo.m_Name), newHandle));
+ }
+ }
+
+ struct SInstanceSorter
+ {
+ const TInstanceStrMap &m_Map;
+ SInstanceSorter(const TInstanceStrMap &inMap)
+ : m_Map(inMap)
+ {
+ }
+ bool operator()(TInstanceHandle lhs, TInstanceHandle rhs)
+ {
+ TInstanceStrMap::const_iterator lhsIter(m_Map.find(lhs));
+ TInstanceStrMap::const_iterator rhsIter(m_Map.find(rhs));
+ if (lhsIter == rhsIter)
+ return false;
+ if (lhsIter == m_Map.end())
+ return false;
+ if (rhsIter == m_Map.end())
+ return true;
+ return wcscmp(lhsIter->second, rhsIter->second) < 0;
+ }
+ };
+
+ void Save(IDOMWriter &inWriter) override
+ {
+ SerializeCategories(inWriter);
+ typedef unordered_set<TInstanceHandle, hash<int>> TInstanceListType;
+ TInstanceListType theInstanceList;
+ // Get the list of instances to serialize.
+
+ AddInstancesFromHash(m_InstanceToProperties, theInstanceList);
+ AddInstancesFromHash(m_InstanceToEvents, theInstanceList);
+ AddInstancesFromHash(m_InstanceToHandlers, theInstanceList);
+ AddInstancesFromHash(m_InstanceToReferences, theInstanceList);
+
+ vector<TInstanceHandle> theInstances;
+ theInstances.reserve(theInstanceList.size());
+ theInstances.insert(theInstances.begin(), theInstanceList.begin(), theInstanceList.end());
+ sort(theInstances.begin(), theInstances.end(), SInstanceSorter(m_InstancesToCanonicalType));
+
+ for (vector<TInstanceHandle>::iterator iter = theInstances.begin(),
+ end = theInstances.end();
+ iter != end; ++iter) {
+ TInstanceHandle instHandle = *iter;
+ Option<TCharStr> theType(GetTypeForCanonicalInstance(*iter));
+ if (theType.hasValue()) {
+ IDOMWriter::Scope __instanceElem(inWriter, theType->wide_str());
+ SerializeInstance(inWriter, *iter);
+ }
+ }
+ }
+
+ // Loading expects the canonical instances to be setup already which means that
+ // it will perform lookups based on
+ void Load(IDOMReader &inReader) override
+ {
+ if (!inReader.Att("NextId", m_NextId))
+ m_NextId = 1;
+ m_ObjectName = L"";
+ SerializeCategories(inReader);
+ IDOMReader::Scope __instanceGatherScope(inReader);
+ for (bool success = inReader.MoveToFirstChild(); success;
+ success = inReader.MoveToNextSibling()) {
+ const wchar_t *elemName = inReader.GetElementName();
+ TStrInstanceMap::iterator find = m_CanonicalTypeToInstances.find(elemName);
+ if (find == m_CanonicalTypeToInstances.end()) {
+ continue;
+ }
+
+ SerializeInstance(inReader, find->second);
+ }
+ }
+
+ template <typename THandleType, typename TMapType>
+ void RemoveOldItemsAndSetOrder(
+ Qt3DSDMInstanceHandle inInstance, vector<THandleType> &inNewHandles,
+ void (SNewMetaDataImpl::*inGetSpecificFun)(Qt3DSDMInstanceHandle, vector<THandleType> &),
+ void (SNewMetaDataImpl::*inDestroyFun)(THandleType), TMapType &inListMap)
+ {
+ vector<THandleType> theHandles;
+ (this->*inGetSpecificFun)(inInstance, theHandles);
+ for (size_t idx = 0, end = theHandles.size(); idx < end; ++idx)
+ if (find(inNewHandles.begin(), inNewHandles.end(), theHandles[idx])
+ == inNewHandles.end())
+ (this->*inDestroyFun)(theHandles[idx]);
+
+ InsertOrUpdateWithTransaction(make_pair(inInstance, inNewHandles), inListMap);
+ }
+
+ // Load meta data and apply it to just this instance
+ // This needs to be undoable so we have to do this through a slightly different
+ // system than we did before.
+ void LoadInstance(IDOMReader &inReader, Qt3DSDMInstanceHandle inInstance,
+ const TCharStr &inObjectName,
+ std::vector<SMetaDataLoadWarning> &outWarnings) override
+ {
+ const wchar_t *theAtt;
+ vector<Qt3DSDMMetaDataPropertyHandle> theProperties;
+ vector<Qt3DSDMEventHandle> theEvents;
+ vector<Qt3DSDMHandlerHandle> theHandlers;
+ DestroyReferences(inInstance);
+ m_ObjectName = inObjectName;
+ for (bool success = inReader.MoveToFirstChild(); success;
+ success = inReader.MoveToNextSibling()) {
+ if (AreEqual(inReader.GetElementName(), L"Category")) {
+ SCategoryInfo theInfo;
+ SerializeItem(inReader, theInfo);
+ Qt3DSDMCategoryHandle theCategoryInfo(GetOrCreateCategory(theInfo.m_Name).first);
+ SetCategoryInfo(theCategoryInfo, theInfo.m_Icon, theInfo.m_HighlightIcon,
+ theInfo.m_Description);
+ } else if (AreEqual(inReader.GetElementName(), L"Property")) {
+ SMetaDataPropertyInfo theInfo(inInstance);
+ if (inReader.Att(L"name", theAtt)) {
+ Qt3DSDMMetaDataPropertyHandle theProperty(
+ GetOrCreateSpecificMetaDataProperty(inInstance, theAtt));
+ SerializeItem(inReader, theInfo, theProperty);
+ SetMetaDataPropertyInfo(theProperty, theInfo.m_Name, theInfo.m_FormalName,
+ theInfo.m_Description, theInfo.m_Usage,
+ theInfo.m_CompleteType, theInfo.m_DefaultValue,
+ theInfo.m_MetaDataData, theInfo.m_GroupName,
+ theInfo.m_IsHidden, theInfo.m_Animatable,
+ theInfo.m_Controllable);
+ CreateInstanceGroupInfo(theInfo);
+ theProperties.push_back(theProperty);
+ ReadChildren(inReader, theInfo, theProperty);
+ } else
+ outWarnings.push_back(
+ SMetaDataLoadWarning(MetaDataLoadWarningType::InvalidProperty,
+ MetaDataLoadWarningMessage::MissingName));
+ } else if (AreEqual(inReader.GetElementName(), L"Event")) {
+ SEvent theInfo(inInstance);
+ if (inReader.Att(L"name", theAtt)) {
+ Qt3DSDMEventHandle theEvent(GetOrCreateSpecificEvent(inInstance, theAtt));
+ SerializeItem(inReader, theInfo, theEvent);
+ SetEventInfo(theEvent, theInfo.m_Name, theInfo.m_FormalName, theInfo.m_Category,
+ theInfo.m_Description);
+ theEvents.push_back(theEvent);
+ } else
+ outWarnings.push_back(
+ SMetaDataLoadWarning(MetaDataLoadWarningType::InvalidEvent,
+ MetaDataLoadWarningMessage::MissingName));
+ } else if (AreEqual(inReader.GetElementName(), L"Handler")) {
+ if (inReader.Att(L"name", theAtt)) {
+ Qt3DSDMHandlerHandle theHandler(GetOrCreateSpecificHandler(inInstance, theAtt));
+ SHandler theInfo(inInstance);
+ SerializeHandlerItem(inReader, theInfo);
+ SetHandlerInfo(theHandler, theInfo.m_Name, theInfo.m_FormalName,
+ theInfo.m_Category, theInfo.m_Description);
+ IDOMReader::Scope __argScope(inReader);
+ QT3DSU32 argIdx = 0;
+ for (bool argSuccess = inReader.MoveToFirstChild(); argSuccess;
+ argSuccess = inReader.MoveToNextSibling(), ++argIdx) {
+ SMetaDataHandlerArgumentInfo theArg(theHandler);
+ SerializeHandlerArgument(inReader, theArg);
+ while (argIdx >= GetNumHandlerArguments(theHandler))
+ AddHandlerArgument(theHandler);
+
+ if (argIdx < GetNumHandlerArguments(theHandler)) {
+ SetHandlerArgumentInfo(theHandler, argIdx, theArg.m_Name,
+ theArg.m_FormalName, theArg.m_Description,
+ theArg.m_CompleteType, theArg.m_DefaultValue,
+ theArg.m_MetaDataData, theArg.m_ArgType);
+ }
+ }
+ while (GetNumHandlerArguments(theHandler) > argIdx)
+ DestroyHandlerArgument(theHandler, GetNumHandlerArguments(theHandler) - 1);
+ theHandlers.push_back(theHandler);
+ } else
+ outWarnings.push_back(
+ SMetaDataLoadWarning(MetaDataLoadWarningType::InvalidHandler,
+ MetaDataLoadWarningMessage::MissingName));
+ } else if (AreEqual(inReader.GetElementName(), L"Reference")) {
+ const wchar_t *theValue;
+ if (inReader.Value(theValue))
+ AddReference(inInstance, theValue);
+ } else {
+ QT3DS_ASSERT(false);
+ }
+ }
+ RemoveOldItemsAndSetOrder(
+ inInstance, theProperties, &SNewMetaDataImpl::GetSpecificMetaDataProperties,
+ &SNewMetaDataImpl::DestroyMetaDataProperty, m_InstanceToProperties);
+ RemoveOldItemsAndSetOrder(inInstance, theEvents, &SNewMetaDataImpl::GetSpecificEvents,
+ &SNewMetaDataImpl::DestroyEvent, m_InstanceToEvents);
+ RemoveOldItemsAndSetOrder(inInstance, theHandlers, &SNewMetaDataImpl::GetSpecificHandlers,
+ &SNewMetaDataImpl::DestroyHandler, m_InstanceToHandlers);
+ }
+
+ // Save just this instances meta data out to the writer
+ void SaveInstance(IDOMWriter &inWriter, Qt3DSDMInstanceHandle inInstance) override
+ {
+ SerializeInstance(inWriter, inInstance);
+ }
+
+ // Helper to convert char to wchar_t
+ eastl::basic_string<qt3ds::foundation::TWCharEASTLConverter::TCharType> m_Buf;
+ const wchar_t *ConvertChar(const char *inName)
+ {
+ if (inName && *inName) {
+ qt3ds::foundation::ConvertUTF(inName, 0, m_Buf);
+ return reinterpret_cast<const wchar_t *>(m_Buf.c_str());
+ }
+ return NULL;
+ }
+
+ void LoadEffectInstance(const char *inShaderFile, Qt3DSDMInstanceHandle inInstance,
+ const TCharStr &inObjectName,
+ std::vector<SMetaDataLoadWarning> &outWarnings,
+ qt3ds::foundation::IInStream &inStream) override
+ {
+ QString shaderFile(inShaderFile);
+ if (shaderFile.endsWith(".effect")) {
+ LoadEffectXMLFromSourcePath(inShaderFile, inInstance, inObjectName, outWarnings,
+ inStream);
+ } else {
+ QT3DS_ASSERT(false);
+ }
+ }
+
+ bool IsEffectInstanceRegistered(const char *inName) override
+ {
+ return m_EffectMap.find(Intern(inName)) != m_EffectMap.end();
+ }
+
+ inline qt3ds::render::NVRenderTextureFormats::Enum
+ ConvertTypeAndFormatToTextureFormat(const char8_t *inType, const char8_t *inFormat)
+ {
+ qt3ds::render::NVRenderTextureFormats::Enum retval
+ = qt3ds::render::NVRenderTextureFormats::RGBA8;
+ if (AreEqual(inFormat, "source"))
+ retval = qt3ds::render::NVRenderTextureFormats::Unknown;
+ else if (AreEqual(inFormat, "depth24stencil8"))
+ retval = qt3ds::render::NVRenderTextureFormats::Depth24Stencil8;
+ else {
+ if (AreEqual(inType, "ubyte")) {
+ if (AreEqual(inFormat, "rgb"))
+ retval = qt3ds::render::NVRenderTextureFormats::RGB8;
+ else if (AreEqual(inFormat, "rgba"))
+ retval = qt3ds::render::NVRenderTextureFormats::RGBA8;
+ else if (AreEqual(inFormat, "alpha"))
+ retval = qt3ds::render::NVRenderTextureFormats::Alpha8;
+ else if (AreEqual(inFormat, "lum"))
+ retval = qt3ds::render::NVRenderTextureFormats::Luminance8;
+ else if (AreEqual(inFormat, "lum_alpha"))
+ retval = qt3ds::render::NVRenderTextureFormats::LuminanceAlpha8;
+ else if (AreEqual(inFormat, "rg"))
+ retval = qt3ds::render::NVRenderTextureFormats::RG8;
+ } else if (AreEqual(inType, "ushort")) {
+ if (AreEqual(inFormat, "rgb"))
+ retval = qt3ds::render::NVRenderTextureFormats::RGB565;
+ else if (AreEqual(inFormat, "rgba"))
+ retval = qt3ds::render::NVRenderTextureFormats::RGBA5551;
+ } else if (AreEqual(inType, "fp16")) {
+ if (AreEqual(inFormat, "rgba"))
+ retval = qt3ds::render::NVRenderTextureFormats::RGBA16F;
+ else if (AreEqual(inFormat, "rg"))
+ retval = qt3ds::render::NVRenderTextureFormats::RG16F;
+ } else if (AreEqual(inType, "fp32")) {
+ if (AreEqual(inFormat, "rgba"))
+ retval = qt3ds::render::NVRenderTextureFormats::RGBA32F;
+ else if (AreEqual(inFormat, "rg"))
+ retval = qt3ds::render::NVRenderTextureFormats::RG32F;
+ } else {
+ QT3DS_ASSERT(false);
+ // inFoundation.error( QT3DS_INVALID_PARAMETER, "Unsupported texture type %s,
+ // defaulting to RGBA8", inType );
+ }
+ }
+ return retval;
+ }
+
+ static inline qt3ds::render::NVRenderTextureMagnifyingOp::Enum
+ ConvertFilterToMagOp(const char8_t *inFilter)
+ {
+ if (AreEqual(inFilter, "linear"))
+ return qt3ds::render::NVRenderTextureMagnifyingOp::Linear;
+ if (IsTrivial(inFilter) || AreEqual(inFilter, "nearest"))
+ return qt3ds::render::NVRenderTextureMagnifyingOp::Nearest;
+ else {
+ QT3DS_ASSERT(false);
+ // inFoundation.error( QT3DS_INVALID_PARAMETER, "Unsupported filter type %s, defaulting to
+ // linear", inFilter );
+ return qt3ds::render::NVRenderTextureMagnifyingOp::Linear;
+ }
+ }
+
+ static inline qt3ds::render::NVRenderTextureMinifyingOp::Enum
+ ConvertFilterToMinOp(const char8_t *inFilter)
+ {
+ // we make the decision based on the texture usage
+ if (AreEqual(inFilter, "linear"))
+ return qt3ds::render::NVRenderTextureMinifyingOp::Linear;
+ if (AreEqual(inFilter, "nearest"))
+ return qt3ds::render::NVRenderTextureMinifyingOp::Nearest;
+ if (AreEqual(inFilter, "linearMipmapLinear"))
+ return qt3ds::render::NVRenderTextureMinifyingOp::LinearMipmapLinear;
+ if (AreEqual(inFilter, "nearestMipmapNearest"))
+ return qt3ds::render::NVRenderTextureMinifyingOp::NearestMipmapNearest;
+ if (AreEqual(inFilter, "nearestMipmapLinear"))
+ return qt3ds::render::NVRenderTextureMinifyingOp::NearestMipmapLinear;
+ if (AreEqual(inFilter, "linearMipmapNearest"))
+ return qt3ds::render::NVRenderTextureMinifyingOp::LinearMipmapNearest;
+ else {
+ QT3DS_ASSERT(false);
+ // inFoundation.error( QT3DS_INVALID_PARAMETER, "Unsupported filter type %s, defaulting
+ // to linear", inFilter );
+ return qt3ds::render::NVRenderTextureMinifyingOp::Linear;
+ }
+ }
+
+ static inline qt3ds::render::NVRenderTextureCoordOp::Enum
+ ConvertTextureCoordOp(const char8_t *inWrap)
+ {
+ if (IsTrivial(inWrap) || AreEqual(inWrap, "clamp"))
+ return qt3ds::render::NVRenderTextureCoordOp::ClampToEdge;
+ if (AreEqual(inWrap, "repeat"))
+ return qt3ds::render::NVRenderTextureCoordOp::Repeat;
+ else {
+ QT3DS_ASSERT(false);
+ // inFoundation.error( QT3DS_INVALID_PARAMETER, "Unsupported wrap type %s, defaulting to
+ // clamp", inWrap );
+ return qt3ds::render::NVRenderTextureCoordOp::ClampToEdge;
+ }
+ }
+
+ static inline qt3ds::render::NVRenderTextureTypeValue::Enum
+ ConvertTextureType(const char8_t *inTexType)
+ {
+ // this usually comes from a MDL description file
+ if (IsTrivial(inTexType))
+ return qt3ds::render::NVRenderTextureTypeValue::Unknown;
+ if (AreEqual(inTexType, "environment"))
+ return qt3ds::render::NVRenderTextureTypeValue::Environment;
+ if (AreEqual(inTexType, "diffuse"))
+ return qt3ds::render::NVRenderTextureTypeValue::Diffuse;
+ if (AreEqual(inTexType, "specular"))
+ return qt3ds::render::NVRenderTextureTypeValue::Specular;
+ if (AreEqual(inTexType, "bump"))
+ return qt3ds::render::NVRenderTextureTypeValue::Bump;
+ if (AreEqual(inTexType, "displacement"))
+ return qt3ds::render::NVRenderTextureTypeValue::Displace;
+ if (AreEqual(inTexType, "shadow"))
+ return qt3ds::render::NVRenderTextureTypeValue::LightmapShadow;
+ if (AreEqual(inTexType, "emissive"))
+ return qt3ds::render::NVRenderTextureTypeValue::Emissive;
+ if (AreEqual(inTexType, "emissive_mask"))
+ return qt3ds::render::NVRenderTextureTypeValue::Emissive2;
+ else {
+ return qt3ds::render::NVRenderTextureTypeValue::Unknown;
+ }
+ }
+
+ static inline qt3ds::render::NVRenderSrcBlendFunc::Enum
+ ConvertToSrcBlendFunc(const char8_t *inFilter)
+ {
+ if (AreEqual(inFilter, "SrcAlpha"))
+ return qt3ds::render::NVRenderSrcBlendFunc::SrcAlpha;
+ if (AreEqual(inFilter, "OneMinusSrcAlpha"))
+ return qt3ds::render::NVRenderSrcBlendFunc::OneMinusSrcAlpha;
+ if (AreEqual(inFilter, "One"))
+ return qt3ds::render::NVRenderSrcBlendFunc::One;
+ else {
+ QT3DS_ASSERT(false);
+ // inFoundation.error( QT3DS_INVALID_PARAMETER, "Unsupported filter type %s, defaulting
+ // to linear", inFilter );
+ return qt3ds::render::NVRenderSrcBlendFunc::One;
+ }
+ }
+
+ static inline qt3ds::render::NVRenderDstBlendFunc::Enum
+ ConvertToDstBlendFunc(const char8_t *inFilter)
+ {
+ if (AreEqual(inFilter, "SrcAlpha"))
+ return qt3ds::render::NVRenderDstBlendFunc::SrcAlpha;
+ if (AreEqual(inFilter, "OneMinusSrcAlpha"))
+ return qt3ds::render::NVRenderDstBlendFunc::OneMinusSrcAlpha;
+ if (AreEqual(inFilter, "One"))
+ return qt3ds::render::NVRenderDstBlendFunc::One;
+ else {
+ QT3DS_ASSERT(false);
+ // inFoundation.error( QT3DS_INVALID_PARAMETER, "Unsupported filter type %s, defaulting
+ // to linear", inFilter );
+ return qt3ds::render::NVRenderDstBlendFunc::One;
+ }
+ }
+
+ static inline qt3ds::render::NVRenderState::Enum ConvertRenderState(const char8_t *inState)
+ {
+ if (AreEqual(inState, "Stencil"))
+ return qt3ds::render::NVRenderState::StencilTest;
+ else {
+ QT3DS_ASSERT(false);
+ // inFoundation.error( QT3DS_INVALID_PARAMETER, "Unsupported filter type %s, defaulting
+ // to linear", inFilter );
+ return qt3ds::render::NVRenderState::StencilTest;
+ }
+ }
+
+ static inline qt3ds::render::NVRenderImageAccessType::Enum
+ ConvertToImageAccessType(const char8_t *inAccess)
+ {
+ if (AreEqual(inAccess, "read"))
+ return qt3ds::render::NVRenderImageAccessType::Read;
+ if (AreEqual(inAccess, "write"))
+ return qt3ds::render::NVRenderImageAccessType::Write;
+ if (AreEqual(inAccess, "readwrite"))
+ return qt3ds::render::NVRenderImageAccessType::ReadWrite;
+ else
+ QT3DS_ASSERT(false);
+
+ return qt3ds::render::NVRenderImageAccessType::ReadWrite;
+ }
+
+ static inline size_t GetTypeSize(const char8_t *inType)
+ {
+ if (AreEqual(inType, "uint"))
+ return sizeof(QT3DSU32);
+ else if (AreEqual(inType, "int"))
+ return sizeof(QT3DSI32);
+ else if (AreEqual(inType, "uvec4"))
+ return sizeof(QT3DSU32) * 4;
+ else
+ QT3DS_ASSERT(false);
+
+ return 1;
+ }
+
+ inline qt3ds::render::NVRenderBufferBindValues::Enum
+ ConvertFormatToBufferBindFlags(const char8_t *inFormat)
+ {
+ if (AreEqual(inFormat, "storage"))
+ return qt3ds::render::NVRenderBufferBindValues::Storage;
+ else if (AreEqual(inFormat, "indirect"))
+ return qt3ds::render::NVRenderBufferBindValues::Draw_Indirect;
+ else
+ QT3DS_ASSERT(false);
+
+ return qt3ds::render::NVRenderBufferBindValues::Unknown;
+ }
+
+ static inline void AppendShaderUniform(const char8_t *type, const char8_t *name,
+ eastl::string &shaderPrefix)
+ {
+ shaderPrefix.append("uniform ");
+ shaderPrefix.append(type);
+ shaderPrefix.append(" ");
+ shaderPrefix.append(name);
+ shaderPrefix.append(";\n");
+ }
+ static inline void AppendShaderCode(
+ const char8_t *inCode, Qt3DSDMStr &ioStr,
+ eastl::basic_string<qt3ds::foundation::TWCharEASTLConverter::TCharType>
+ &inConvertBuffer)
+ {
+ qt3ds::foundation::ConvertUTF(inCode, 0, inConvertBuffer);
+ ioStr.append(inConvertBuffer);
+ }
+ void HideEffectProperty(Qt3DSDMInstanceHandle inInstance, const char8_t *inParamName)
+ {
+ Qt3DSDMMetaDataPropertyHandle theProp =
+ GetSpecificMetaDataProperty(inInstance, Intern(inParamName));
+ if (theProp.Valid()) {
+ SMetaDataPropertyInfo theInfo = GetMetaDataPropertyInfo(theProp);
+ SetMetaDataPropertyInfo(theProp, theInfo.m_Name, theInfo.m_FormalName,
+ theInfo.m_Description, theInfo.m_Usage, theInfo.m_CompleteType,
+ theInfo.m_DefaultValue, theInfo.m_MetaDataData,
+ theInfo.m_GroupName, true, theInfo.m_Animatable,
+ theInfo.m_Controllable);
+ }
+ }
+
+ static inline void GetShaderName(const TCharStr &inObjectName,
+ const char8_t *inShaderSpecificName,
+ eastl::string &outShaderName)
+ {
+ outShaderName.clear();
+ qt3ds::foundation::ConvertUTF(inObjectName.c_str(), 0, outShaderName);
+ outShaderName.append(" - ");
+ outShaderName.append(inShaderSpecificName);
+ }
+
+ void LoadDynamicObjectProperties(IDOMReader &inStream, SMetaDataDynamicObjectImpl &ioObject,
+ Qt3DSDMInstanceHandle inInstance, const TCharStr &inObjectName,
+ std::vector<SMetaDataLoadWarning> &outWarnings,
+ eastl::string &shaderPrefix)
+ {
+ eastl::string vertexUniforms;
+ eastl::string fragmentUniforms;
+ vertexUniforms += "#ifdef VERTEX_SHADER\n";
+ fragmentUniforms += "#ifdef FRAGMENT_SHADER\n";
+ using namespace qt3ds::render::dynamic;
+ ioObject.m_Properties.clear();
+ ioObject.ClearEnumValueNames();
+ IDOMReader::Scope __readerScope(inStream);
+ if (inStream.MoveToFirstChild("MetaData")) {
+ {
+ IDOMReader::Scope __readerScope(inStream);
+ LoadInstance(inStream, inInstance, inObjectName, outWarnings);
+ }
+
+ vector<Qt3DSDMMetaDataPropertyHandle> theProperties;
+ GetSpecificMetaDataProperties(inInstance, theProperties);
+ size_t propIdx = 0, propEnd = theProperties.size();
+ for (bool success = inStream.MoveToFirstChild("Property"); success && propIdx < propEnd;
+ success = inStream.MoveToNextSibling("Property"), ++propIdx) {
+ ioObject.m_Properties.push_back();
+ SPropertyDefinition &theNewDefinition = ioObject.m_Properties.back();
+ SMetaDataPropertyInfo theInfo(GetMetaDataPropertyInfo(theProperties[propIdx]));
+ theNewDefinition.m_Name =
+ m_StringTable.GetRenderStringTable().RegisterStr(theInfo.m_Name.c_str());
+ const char8_t *xmlName;
+ inStream.Att("name", xmlName);
+ const char8_t *stage;
+ inStream.Att("stage", stage);
+ eastl::string uniforms;
+ if (AreEqual(xmlName, theNewDefinition.m_Name.c_str())) {
+ switch (theInfo.GetDataType()) {
+ case DataModelDataType::Bool:
+ theNewDefinition.m_DataType =
+ qt3ds::render::NVRenderShaderDataTypes::QT3DSRenderBool;
+ AppendShaderUniform("bool", theNewDefinition.m_Name.c_str(), uniforms);
+ break;
+ case DataModelDataType::Long:
+ theNewDefinition.m_DataType
+ = qt3ds::render::NVRenderShaderDataTypes::QT3DSI32;
+ AppendShaderUniform("int", theNewDefinition.m_Name.c_str(), uniforms);
+ break;
+ case DataModelDataType::Float2:
+ theNewDefinition.m_DataType
+ = qt3ds::render::NVRenderShaderDataTypes::QT3DSVec2;
+ AppendShaderUniform("vec2", theNewDefinition.m_Name.c_str(), uniforms);
+ break;
+ case DataModelDataType::Float3:
+ theNewDefinition.m_DataType
+ = qt3ds::render::NVRenderShaderDataTypes::QT3DSVec3;
+ AppendShaderUniform("vec3", theNewDefinition.m_Name.c_str(), uniforms);
+ break;
+ case DataModelDataType::Float4:
+ theNewDefinition.m_DataType
+ = qt3ds::render::NVRenderShaderDataTypes::QT3DSVec4;
+ AppendShaderUniform("vec4", theNewDefinition.m_Name.c_str(), uniforms);
+ break;
+ case DataModelDataType::String:
+ if (theInfo.m_CompleteType == CompleteMetaDataType::Texture) {
+ theNewDefinition.m_DataType =
+ qt3ds::render::NVRenderShaderDataTypes::NVRenderTexture2DPtr;
+ const char8_t *filter = "linear", *minFilter = "linear",
+ *clamp = "clamp", *usage = "", *path = "";
+ if (inStream.Att("filter", filter))
+ theNewDefinition.m_MagFilterOp = ConvertFilterToMagOp(filter);
+ if (inStream.Att("minfilter", minFilter))
+ theNewDefinition.m_MinFilterOp = ConvertFilterToMinOp(minFilter);
+ if (inStream.Att("clamp", clamp))
+ theNewDefinition.m_CoordOp = ConvertTextureCoordOp(clamp);
+ if (inStream.Att("usage", usage))
+ theNewDefinition.m_TexUsageType = ConvertTextureType(usage);
+ if (inStream.Att("default", path)) {
+ TDataStrPtr theDataStr(
+ theInfo.m_DefaultValue.getData<TDataStrPtr>());
+ theNewDefinition.m_ImagePath =
+ m_StringTable.GetRenderStringTable().RegisterStr(
+ theDataStr->GetData());
+ }
+
+ // Output macro so we can change the set of variables used for this
+ // independent of the
+ // meta data system.
+ uniforms.append("SNAPPER_SAMPLER2D(");
+ uniforms.append(theNewDefinition.m_Name.c_str());
+ uniforms.append(", ");
+ uniforms.append(theNewDefinition.m_Name.c_str());
+ uniforms.append(", ");
+ uniforms.append(filter);
+ uniforms.append(", ");
+ uniforms.append(clamp);
+ uniforms.append(", ");
+ uniforms.append("false )\n");
+ } else if (theInfo.m_CompleteType == CompleteMetaDataType::StringList) {
+ theNewDefinition.m_DataType =
+ qt3ds::render::NVRenderShaderDataTypes::QT3DSI32;
+ const TMetaDataStringList &theList =
+ qt3dsdm::get<TMetaDataStringList>(theInfo.m_MetaDataData);
+ ioObject.m_EnumValueNames.push_back(
+ new eastl::vector<qt3ds::foundation::CRegisteredString>());
+ eastl::vector<qt3ds::foundation::CRegisteredString> &theBack =
+ *ioObject.m_EnumValueNames.back();
+ for (QT3DSU32 idx = 0, end = (QT3DSU32)theList.size(); idx < end; ++idx)
+ theBack.push_back(m_StringTable.GetRenderStringTable().RegisterStr(
+ theList[idx].c_str()));
+ theNewDefinition.m_EnumValueNames = VecToCRef(theBack);
+ theNewDefinition.m_IsEnumProperty = true;
+ AppendShaderUniform("int", theNewDefinition.m_Name.c_str(),
+ uniforms);
+ } else if (theInfo.m_CompleteType == CompleteMetaDataType::Image2D) {
+ theNewDefinition.m_DataType =
+ qt3ds::render::NVRenderShaderDataTypes::NVRenderImage2DPtr;
+ const char8_t *format = "", *binding = "", *access = "readonly";
+ uniforms.append("layout(");
+ inStream.Att("format", format);
+ uniforms.append(format);
+ if (inStream.Att("binding", binding)) {
+ uniforms.append(", binding = ");
+ uniforms.append(binding);
+ }
+ uniforms.append(") ");
+
+ // if we have format layout we cannot set an additional access qualifier
+ if (inStream.Att("access", access) && !AreEqual(format, ""))
+ uniforms.append(access);
+
+ uniforms.append(" uniform image2D ");
+ uniforms.append(theNewDefinition.m_Name.c_str());
+ uniforms.append(";\n");
+ } else if (theInfo.m_CompleteType == CompleteMetaDataType::Buffer) {
+ theNewDefinition.m_DataType =
+ qt3ds::render::NVRenderShaderDataTypes::NVRenderDataBufferPtr;
+ const char8_t *align = "std140", *usage = "storage", *binding = "",
+ *format = "float";
+ uniforms.append("layout(");
+
+ inStream.Att("format", format);
+ inStream.Att("usage", usage);
+ if (AreEqual(usage, "storage")) {
+ inStream.Att("align", align);
+ uniforms.append(align);
+
+ if (inStream.Att("binding", binding)) {
+ uniforms.append(", binding = ");
+ uniforms.append(binding);
+ }
+
+ uniforms.append(") ");
+
+ uniforms.append("buffer ");
+ uniforms.append(theNewDefinition.m_Name.c_str());
+ uniforms.append("\n{ \n");
+ uniforms.append(format);
+ uniforms.append(" ");
+ uniforms.append(theNewDefinition.m_Name.c_str());
+ uniforms.append("_data[]; \n};\n");
+ } else {
+ // currently we only handle storage counters
+ QT3DS_ASSERT(false);
+ }
+ }
+ break;
+ default:
+ QT3DS_ASSERT(false);
+ // Fallthrough intentional
+ case DataModelDataType::Float:
+ theNewDefinition.m_DataType = qt3ds::render::NVRenderShaderDataTypes::QT3DSF32;
+ AppendShaderUniform("float", theNewDefinition.m_Name.c_str(), uniforms);
+ break;
+ }
+ } else {
+ // It is conceivable that we not every property tag gets parsed into a property.
+ QT3DS_ASSERT(false);
+ // So we will bump to the next item and try again.
+ --propIdx;
+ }
+
+ if (AreEqual(stage, "vertex")) {
+ vertexUniforms += uniforms;
+ } else if (AreEqual(stage, "fragment")) {
+ fragmentUniforms += uniforms;
+ } else {
+ vertexUniforms += uniforms;
+ fragmentUniforms += uniforms;
+ }
+ }
+ }
+ vertexUniforms += "#endif\n";
+ fragmentUniforms += "#endif\n";
+ shaderPrefix.append(vertexUniforms);
+ shaderPrefix.append(fragmentUniforms);
+ }
+
+ void LoadDynamicObjectShaders(IDOMReader &inStream, SMetaDataDynamicObjectImpl &ioObject,
+ eastl::string &shaderPrefix, const TCharStr &inObjectName)
+ {
+ eastl::string theShaderNameStr;
+ eastl::string theShaderTypeStr;
+ eastl::string theShaderVersionStr;
+ {
+ IDOMReader::Scope __readerScope(inStream);
+ eastl::basic_string<qt3ds::foundation::TWCharEASTLConverter::TCharType> theConvertBuffer;
+ if (inStream.MoveToFirstChild("Shaders")) {
+ const char8_t *globalShared = "";
+ const char8_t *globalVertexShared = "";
+ const char8_t *globalFragmentShared = "";
+ inStream.ChildValue("Shared", globalShared);
+ inStream.ChildValue("VertexShaderShared", globalVertexShared);
+ inStream.ChildValue("FragmentShaderShared", globalFragmentShared);
+
+ inStream.Att("type", theShaderTypeStr); // can be empty
+ inStream.Att("version", theShaderVersionStr); // can be empty
+
+ for (bool success = inStream.MoveToFirstChild(); success;
+ success = inStream.MoveToNextSibling()) {
+ IDOMReader::Scope __shaderScope(inStream);
+ const char8_t *elemName = inStream.GetNarrowElementName();
+ // If this is neither a compute shader nor a normal shader, go on and ignore
+ // element.
+ if (!(AreEqual(elemName, "Shader") || AreEqual(elemName, "ComputeShader")))
+ continue;
+
+ ioObject.m_Shaders.push_back();
+ SMetaDataShader &theShader = ioObject.m_Shaders.back();
+
+ qt3ds::foundation::ConvertUTF(theShaderTypeStr.c_str(), theShaderTypeStr.size(),
+ theShader.m_Type);
+ qt3ds::foundation::ConvertUTF(theShaderVersionStr.c_str(),
+ theShaderVersionStr.size(), theShader.m_Version);
+ const char8_t *theName = "";
+ char8_t theITOABuffer[64] = { 0 };
+ if (!inStream.Att("name", theName)) {
+ sprintf(theITOABuffer, "%d", (int)ioObject.m_Shaders.size() - 1);
+ theName = theITOABuffer;
+ }
+ GetShaderName(inObjectName, theName, theShaderNameStr);
+ qt3ds::foundation::ConvertUTF(theShaderNameStr.c_str(), theShaderNameStr.size(),
+ theShader.m_Name);
+
+ if (AreEqual(elemName, "Shader")) {
+ const char8_t *shaderShared = "";
+ inStream.ChildValue("Shared", shaderShared);
+ const char8_t *vertexCode = "";
+ inStream.ChildValue("VertexShader", vertexCode);
+ if (IsTrivial(vertexCode))
+ vertexCode = "void vert(){}";
+ const char8_t *fragmentCode = "void frag(){}";
+ inStream.ChildValue("FragmentShader", fragmentCode);
+ if (IsTrivial(fragmentCode))
+ fragmentCode = "void frag(){}";
+ const char8_t *geomCode = "";
+ inStream.ChildValue("GeometryShader", geomCode);
+
+ AppendShaderCode(shaderPrefix.c_str(), theShader.m_Code, theConvertBuffer);
+ AppendShaderCode(globalShared, theShader.m_Code, theConvertBuffer);
+ AppendShaderCode(shaderShared, theShader.m_Code, theConvertBuffer);
+ AppendShaderCode("\n#ifdef VERTEX_SHADER\n", theShader.m_Code,
+ theConvertBuffer);
+ AppendShaderCode(globalVertexShared, theShader.m_Code, theConvertBuffer);
+ AppendShaderCode(vertexCode, theShader.m_Code, theConvertBuffer);
+ AppendShaderCode("\n#endif\n", theShader.m_Code, theConvertBuffer);
+ if (!IsTrivial(geomCode)) {
+ AppendShaderCode("\n#ifdef USER_GEOMETRY_SHADER\n", theShader.m_Code,
+ theConvertBuffer);
+ AppendShaderCode(geomCode, theShader.m_Code, theConvertBuffer);
+ AppendShaderCode("\n#endif\n", theShader.m_Code, theConvertBuffer);
+ theShader.m_HasGeomShader = true;
+ }
+ AppendShaderCode("\n#ifdef FRAGMENT_SHADER\n", theShader.m_Code,
+ theConvertBuffer);
+ AppendShaderCode(globalFragmentShared, theShader.m_Code, theConvertBuffer);
+ AppendShaderCode(fragmentCode, theShader.m_Code, theConvertBuffer);
+ AppendShaderCode("\n#endif\n", theShader.m_Code, theConvertBuffer);
+ } else if (AreEqual(elemName, "ComputeShader")) {
+ const char8_t *shaderCode = "";
+ inStream.Value(shaderCode);
+ theShader.m_IsComputeShader = true;
+ AppendShaderCode(shaderCode, theShader.m_Code, theConvertBuffer);
+ }
+ }
+ }
+ }
+ }
+
+ static size_t Align(size_t inValue)
+ {
+ if (inValue % 4)
+ return inValue + (4 - (inValue % 4));
+ return inValue;
+ }
+
+ static qt3ds::render::dynamic::SDepthStencilFlags ParseDepthStencilFlags(const char8_t *inFlags)
+ {
+ eastl::string parseStr(inFlags);
+ eastl::string tokenStr;
+ qt3ds::render::dynamic::SDepthStencilFlags retval;
+ for (uint32_t pos = parseStr.find('|'); parseStr.empty() == false;
+ pos = parseStr.find('|')) {
+ if (pos != eastl::string::npos) {
+ tokenStr = parseStr.substr(pos);
+ parseStr.erase(parseStr.begin(), parseStr.begin() + pos + 1);
+ } else {
+ tokenStr = parseStr;
+ parseStr.clear();
+ }
+ if (AreEqual(tokenStr.c_str(), "clear-stencil"))
+ retval |= qt3ds::render::dynamic::DepthStencilFlagValues::ClearStencil;
+ if (AreEqual(tokenStr.c_str(), "clear-depth"))
+ retval |= qt3ds::render::dynamic::DepthStencilFlagValues::ClearDepth;
+ }
+ return retval;
+ }
+
+ static qt3ds::render::NVRenderBoolOp::Enum ParseBoolOp(const char8_t *inOp)
+ {
+ if (AreEqual(inOp, "never"))
+ return qt3ds::render::NVRenderBoolOp::Never;
+ if (AreEqual(inOp, "less"))
+ return qt3ds::render::NVRenderBoolOp::Less;
+ if (AreEqual(inOp, "less-than-or-equal"))
+ return qt3ds::render::NVRenderBoolOp::LessThanOrEqual;
+ if (AreEqual(inOp, "equal"))
+ return qt3ds::render::NVRenderBoolOp::Equal;
+ if (AreEqual(inOp, "not-equal"))
+ return qt3ds::render::NVRenderBoolOp::NotEqual;
+ if (AreEqual(inOp, "greater"))
+ return qt3ds::render::NVRenderBoolOp::Greater;
+ if (AreEqual(inOp, "greater-than-or-equal"))
+ return qt3ds::render::NVRenderBoolOp::GreaterThanOrEqual;
+ if (AreEqual(inOp, "always"))
+ return qt3ds::render::NVRenderBoolOp::AlwaysTrue;
+
+ QT3DS_ASSERT(false);
+ return qt3ds::render::NVRenderBoolOp::Unknown;
+ }
+
+ static qt3ds::render::NVRenderStencilOp::Enum ParseStencilOp(const char8_t *inOp)
+ {
+
+ if (AreEqual(inOp, "keep"))
+ return qt3ds::render::NVRenderStencilOp::Keep;
+ if (AreEqual(inOp, "zero"))
+ return qt3ds::render::NVRenderStencilOp::Zero;
+ if (AreEqual(inOp, "replace"))
+ return qt3ds::render::NVRenderStencilOp::Replace;
+ if (AreEqual(inOp, "increment"))
+ return qt3ds::render::NVRenderStencilOp::Increment;
+ if (AreEqual(inOp, "increment-wrap"))
+ return qt3ds::render::NVRenderStencilOp::IncrementWrap;
+ if (AreEqual(inOp, "decrement"))
+ return qt3ds::render::NVRenderStencilOp::Decrement;
+ if (AreEqual(inOp, "decrement-wrap"))
+ return qt3ds::render::NVRenderStencilOp::DecrementWrap;
+ if (AreEqual(inOp, "invert"))
+ return qt3ds::render::NVRenderStencilOp::Invert;
+
+ QT3DS_ASSERT(false);
+ return qt3ds::render::NVRenderStencilOp::Unknown;
+ }
+
+ // Reloads an effect if one is already loaded so we can replace the existing effect definition
+ void LoadEffectXML(IDOMReader &inStream, Qt3DSDMInstanceHandle inInstance,
+ const TCharStr &inObjectName,
+ std::vector<SMetaDataLoadWarning> &outWarnings,
+ const TCharStr &inSourcePath) override
+ {
+ using namespace qt3ds::render::dynamic;
+ std::pair<TEffectMap::iterator, bool> theInserter =
+ m_EffectMap.insert(std::make_pair(Intern(inObjectName), SMetaDataEffectImpl()));
+ /*if ( inStream.MoveToFirstChild( "Effect" ) == false )
+ {
+ outWarnings.push_back( SMetaDataLoadWarning( MetaDataLoadWarningType::Unknown,
+ MetaDataLoadWarningMessage::GeneralError, L"File doesn't appear to be an effect xml file,
+ missing top level Effect tag" ) );
+ return;
+ }*/
+ eastl::string shaderPrefix = "#include \"effect.glsllib\"\n";
+
+ SMetaDataEffectImpl &theEffect = theInserter.first->second;
+ m_ObjectName = inObjectName;
+ theEffect.m_Name = inObjectName;
+ theEffect.m_SourcePath = inSourcePath;
+ theEffect.ClearEffectCommands();
+ LoadDynamicObjectProperties(inStream, theEffect, inInstance, inObjectName, outWarnings,
+ shaderPrefix);
+ theEffect.m_Shaders.clear();
+ LoadDynamicObjectShaders(inStream, theEffect, shaderPrefix, inObjectName);
+ eastl::string theShaderNameStr;
+ {
+ IDOMReader::Scope __readerScope(inStream);
+ if (inStream.MoveToFirstChild("Passes")) {
+ for (bool success = inStream.MoveToFirstChild(); success;
+ success = inStream.MoveToNextSibling()) {
+ IDOMReader::Scope __passScope(inStream);
+ if (AreEqual("Pass", inStream.GetNarrowElementName())) {
+ bool drawIndirect = false;
+ const char8_t *shader = "", *input = "[source]", *output = "[dest]",
+ *outputFormat = "rgba";
+ inStream.Att("shader", shader);
+ inStream.Att("input", input);
+ inStream.Att("output", output);
+ // this is only for the final output of the effect
+ inStream.Att("format", outputFormat);
+ qt3ds::render::NVRenderTextureFormats::Enum theOutputFormat =
+ ConvertTypeAndFormatToTextureFormat("ubyte", outputFormat);
+ if (AreEqual(output, "[dest]") || IsTrivial(output))
+ theEffect.m_EffectCommands.push_back(new SBindTarget(theOutputFormat));
+ else
+ theEffect.m_EffectCommands.push_back(
+ new SBindBuffer(
+ m_StringTable.GetRenderStringTable().RegisterStr(output),
+ false));
+ GetShaderName(inObjectName, shader, theShaderNameStr);
+ theEffect.m_EffectCommands.push_back(
+ new SBindShader(m_StringTable.GetRenderStringTable().RegisterStr(
+ theShaderNameStr.c_str())));
+ theEffect.m_EffectCommands.push_back(new SApplyInstanceValue());
+ if (AreEqual(input, "[source]") || IsTrivial(input))
+ theEffect.m_EffectCommands.push_back(
+ new SApplyBufferValue(
+ m_StringTable.GetRenderStringTable().RegisterStr(""),
+ m_StringTable.GetRenderStringTable().RegisterStr("")));
+ else
+ theEffect.m_EffectCommands.push_back(
+ new SApplyBufferValue(
+ m_StringTable.GetRenderStringTable().RegisterStr(input),
+ m_StringTable.GetRenderStringTable().RegisterStr("")));
+ for (bool bufParam = inStream.MoveToFirstChild(); bufParam;
+ bufParam = inStream.MoveToNextSibling()) {
+ if (AreEqual("BufferInput", inStream.GetNarrowElementName())) {
+ const char8_t *param = "";
+ const char8_t *value = "";
+ inStream.Att("param", param);
+ inStream.Att("value", value);
+ if (AreEqual("[source]", value))
+ value = "";
+ theEffect.m_EffectCommands.push_back(
+ new SApplyBufferValue(
+ m_StringTable.GetRenderStringTable().RegisterStr(
+ value),
+ m_StringTable.GetRenderStringTable().RegisterStr(
+ param)));
+ HideEffectProperty(inInstance, param);
+ } else if (AreEqual("DepthInput", inStream.GetNarrowElementName())) {
+ const char8_t *param = "";
+ inStream.Att("param", param);
+ theEffect.m_EffectCommands.push_back(
+ new SApplyDepthValue(
+ m_StringTable.GetRenderStringTable().RegisterStr(
+ param)));
+ HideEffectProperty(inInstance, param);
+ } else if (AreEqual("ImageInput", inStream.GetNarrowElementName())) {
+ bool useAsTexture = false;
+ bool needSync = false;
+ const char8_t *param = "";
+ const char8_t *value = "";
+ const char8_t *usage = "";
+ const char8_t *sync = "";
+ inStream.Att("param", param);
+ inStream.Att("value", value);
+ if (AreEqual("[source]", value))
+ value = "";
+ inStream.Att("usage", usage);
+ if (AreEqual("texture", usage))
+ useAsTexture = true;
+ inStream.Att("sync", sync);
+ if (AreEqual("true", sync))
+ needSync = true;
+
+ theEffect.m_EffectCommands.push_back(
+ new SApplyImageValue(
+ m_StringTable.GetRenderStringTable().RegisterStr(
+ value),
+ m_StringTable.GetRenderStringTable().RegisterStr(
+ param), useAsTexture, needSync));
+ HideEffectProperty(inInstance, param);
+ } else if (AreEqual("DataBufferInput",
+ inStream.GetNarrowElementName())) {
+ const char8_t *param = "";
+ const char8_t *usage = "";
+ inStream.Att("param", param);
+ inStream.Att("usage", usage);
+ qt3ds::render::NVRenderBufferBindValues::Enum bufType =
+ ConvertFormatToBufferBindFlags(usage);
+
+ // check if we using an indirect buffer for drawing
+ if (bufType == qt3ds::render::NVRenderBufferBindValues::Draw_Indirect)
+ drawIndirect = true;
+
+ theEffect.m_EffectCommands.push_back(
+ new SApplyDataBufferValue(
+ m_StringTable.GetRenderStringTable().RegisterStr(
+ param), bufType));
+ HideEffectProperty(inInstance, param);
+ } else if (AreEqual("SetParam", inStream.GetNarrowElementName())) {
+ const char8_t *name = "";
+ inStream.Att("name", name);
+ const char8_t *value = "";
+ inStream.Att("value", value);
+ // find the param and the type.
+ qt3ds::foundation::CRegisteredString propName =
+ m_StringTable.GetRenderStringTable().RegisterStr(name);
+ qt3ds::render::dynamic::SPropertyDefinition *theDefinition = NULL;
+ for (uint32_t propIdx = 0, propEnd = theEffect.m_Properties.size();
+ propIdx < propEnd && theDefinition == NULL; ++propIdx) {
+ if (theEffect.m_Properties[propIdx].m_Name == propName)
+ theDefinition = &theEffect.m_Properties[propIdx];
+ }
+ if (theDefinition != NULL) {
+ // Hack it for now because the shader datatypes don't have a
+ // built in sizeof operator.
+ QT3DSU32 valueSize = 4;
+ qt3ds::render::NVRenderShaderDataTypes::Enum theDataType =
+ theDefinition->m_DataType;
+ size_t allocSize = sizeof(SApplyValue) + valueSize;
+ QT3DSU8 *theCommandData = (QT3DSU8 *)malloc(allocSize);
+ QT3DSU8 *theValueData = theCommandData + sizeof(SApplyValue);
+ new (theCommandData) SApplyValue(propName, theDataType);
+ SApplyValue *theCommand =
+ reinterpret_cast<SApplyValue *>(theCommandData);
+ switch (theDataType) {
+ case qt3ds::render::NVRenderShaderDataTypes::QT3DSRenderBool: {
+ bool &target = *reinterpret_cast<bool *>(theValueData);
+ qt3ds::foundation::StringConversion<bool>().StrTo(value,
+ target);
+ } break;
+ case qt3ds::render::NVRenderShaderDataTypes::QT3DSI32: {
+ QT3DSI32 &target = *reinterpret_cast<QT3DSI32 *>(
+ theValueData);
+ qt3ds::foundation::StringConversion<QT3DSI32>().StrTo(
+ value, target);
+ } break;
+ default:
+ QT3DS_ASSERT(false);
+ // Fallthrough intentional
+ case qt3ds::render::NVRenderShaderDataTypes::QT3DSF32: {
+ QT3DSF32 &target = *reinterpret_cast<QT3DSF32 *>(
+ theValueData);
+ qt3ds::foundation::StringConversion<QT3DSF32>().StrTo(
+ value, target);
+ } break;
+ }
+ theCommand->m_Value = NVDataRef<QT3DSU8>(theValueData,
+ valueSize);
+ theEffect.m_EffectCommands.push_back(theCommand);
+ }
+ } else if (AreEqual("Blending", inStream.GetNarrowElementName())) {
+ const char8_t *theSrcBlendFuncStr = "", *theDestBlendFuncStr = "";
+ inStream.Att("source", theSrcBlendFuncStr);
+ inStream.Att("dest", theDestBlendFuncStr);
+
+ qt3ds::render::NVRenderSrcBlendFunc::Enum theSrcBlendFunc =
+ ConvertToSrcBlendFunc(theSrcBlendFuncStr);
+ qt3ds::render::NVRenderDstBlendFunc::Enum theDstBlendFuc =
+ ConvertToDstBlendFunc(theDestBlendFuncStr);
+
+ // this will setup blending
+ theEffect.m_EffectCommands.push_back(
+ new SApplyBlending(theSrcBlendFunc, theDstBlendFuc));
+ } else if (AreEqual("RenderState", inStream.GetNarrowElementName())) {
+ const char8_t *name = "";
+ inStream.Att("name", name);
+ const char8_t *value = "";
+ inStream.Att("value", value);
+ // find the param and the type.
+ bool theStateEnable = false;
+ qt3ds::render::NVRenderState::Enum theState
+ = ConvertRenderState(name);
+ if (AreEqual("true", value))
+ theStateEnable = true;
+
+ // this will setup blending
+ theEffect.m_EffectCommands.push_back(
+ new SApplyRenderState(theState, theStateEnable));
+ } else if (AreEqual("DepthStencil", inStream.GetNarrowElementName())) {
+ const char8_t *bufferName = "";
+ inStream.Att("buffer", bufferName);
+ QT3DSU32 stencilvalue = 0;
+ inStream.Att("reference", stencilvalue);
+ const char8_t *flags = "";
+ inStream.Att("flags", flags);
+ QT3DSU32 mask = QT3DS_MAX_U32;
+ inStream.Att("mask", mask);
+ qt3ds::render::NVRenderBoolOp::Enum stencilFunction =
+ qt3ds::render::NVRenderBoolOp::Equal;
+ qt3ds::render::NVRenderStencilOp::Enum stencilFailOperation =
+ qt3ds::render::NVRenderStencilOp::Keep;
+ qt3ds::render::NVRenderStencilOp::Enum depthPass =
+ qt3ds::render::NVRenderStencilOp::Keep;
+ qt3ds::render::NVRenderStencilOp::Enum depthFail =
+ qt3ds::render::NVRenderStencilOp::Keep;
+ const char8_t *temp;
+ if (inStream.Att("stencil-fail", temp))
+ stencilFailOperation = ParseStencilOp(temp);
+ if (inStream.Att("depth-pass", temp))
+ depthPass = ParseStencilOp(temp);
+ if (inStream.Att("depth-fail", temp))
+ depthFail = ParseStencilOp(temp);
+ if (inStream.Att("stencil-function", temp))
+ stencilFunction = ParseBoolOp(temp);
+
+ qt3ds::render::dynamic::SDepthStencilFlags flagValues =
+ ParseDepthStencilFlags(flags);
+ theEffect.m_EffectCommands.push_back(
+ new SDepthStencil(
+ m_StringTable.GetRenderStringTable().RegisterStr(
+ bufferName), flagValues, stencilFailOperation,
+ depthPass, depthFail, stencilFunction, stencilvalue,
+ mask));
+ } else {
+ QT3DS_ASSERT(false);
+ }
+ }
+ theEffect.m_EffectCommands.push_back(new SRender(drawIndirect));
+ } else if (AreEqual("Buffer", inStream.GetNarrowElementName())
+ || AreEqual("Image", inStream.GetNarrowElementName())) {
+ SAllocateBufferFlags theFlags;
+ const char8_t *theLifetimeStr = "", *theType = "", *theFormat = "",
+ *theFilter = "", *theWrap = "", *theName = "";
+ QT3DSF32 theSize = 1.0f;
+ bool isImage = AreEqual("Image", inStream.GetNarrowElementName());
+ inStream.Att("name", theName);
+ inStream.Att("lifetime", theLifetimeStr);
+ inStream.Att("type", theType);
+ inStream.Att("format", theFormat);
+ inStream.Att("filter", theFilter);
+ inStream.Att("wrap", theWrap);
+ inStream.Att("size", theSize);
+ // Clamp the size to valid amounts
+ if (theSize <= 0)
+ theSize = 1.0f;
+ if (theSize > 1.0f)
+ theSize = 1.0f;
+ if (AreEqual(theLifetimeStr, "scene"))
+ theFlags.SetSceneLifetime(true);
+ qt3ds::render::NVRenderTextureFormats::Enum theTexFormat =
+ ConvertTypeAndFormatToTextureFormat(theType, theFormat);
+ qt3ds::render::NVRenderTextureMagnifyingOp::Enum theMagOp =
+ ConvertFilterToMagOp(theFilter);
+ qt3ds::render::NVRenderTextureCoordOp::Enum theCoordOp =
+ ConvertTextureCoordOp(theWrap);
+ if (*theName == 0) {
+ QT3DS_ASSERT(false);
+ // inFoundation.error( QT3DS_INVALID_PARAMETER, "Buffer is missing its
+ // name" );
+ } else if (isImage) {
+ const char8_t *temp;
+ qt3ds::render::NVRenderImageAccessType::Enum theAccess =
+ qt3ds::render::NVRenderImageAccessType::ReadWrite;
+ if (inStream.Att("access", temp))
+ theAccess = ConvertToImageAccessType(temp);
+
+ theEffect.m_EffectCommands.push_back(
+ new SAllocateImage(
+ m_StringTable.GetRenderStringTable().RegisterStr(
+ theName), theTexFormat, theMagOp, theCoordOp,
+ theSize, theFlags, theAccess));
+ } else {
+ theEffect.m_EffectCommands.push_back(
+ new SAllocateBuffer(
+ m_StringTable.GetRenderStringTable().RegisterStr(
+ theName), theTexFormat, theMagOp, theCoordOp,
+ theSize, theFlags));
+ }
+ } else if (AreEqual("DataBuffer", inStream.GetNarrowElementName())) {
+ SAllocateBufferFlags theFlags;
+ const char8_t *theLifetimeStr = "", *theType = "", *theWrapName = "",
+ *theWrapType = "", *theFormat = "", *theName = "";
+ QT3DSF32 theSize = 1.0f;
+ qt3ds::render::NVRenderBufferBindValues::Enum bufType,
+ wrapBufType = qt3ds::render::NVRenderBufferBindValues::Unknown;
+
+ inStream.Att("name", theName);
+ inStream.Att("lifetime", theLifetimeStr);
+ inStream.Att("type", theType);
+ inStream.Att("format", theFormat);
+ inStream.Att("size", theSize);
+ if (AreEqual(theLifetimeStr, "scene"))
+ theFlags.SetSceneLifetime(true);
+ bufType = ConvertFormatToBufferBindFlags(theType);
+
+ if (inStream.Att("wrapType", theWrapType)) {
+ wrapBufType = ConvertFormatToBufferBindFlags(theWrapType);
+ inStream.Att("wrapName", theWrapName);
+ if (*theWrapName == 0)
+ QT3DS_ASSERT(false);
+ }
+
+ theSize *= GetTypeSize(theFormat);
+
+ if (theSize <= 0)
+ theSize = 1.0f;
+
+ if (*theName == 0) {
+ QT3DS_ASSERT(false);
+ } else {
+ theEffect.m_EffectCommands.push_back(
+ new SAllocateDataBuffer(
+ m_StringTable.GetRenderStringTable().RegisterStr(
+ theName), bufType,
+ m_StringTable.GetRenderStringTable().RegisterStr(
+ theWrapName), wrapBufType, theSize, theFlags));
+ }
+ } else {
+ QT3DS_ASSERT(false); // Unrecognized effect passes member.
+ }
+ }
+
+ } else {
+ if (theEffect.m_Shaders.size()) {
+ // Create the minimal set of commands that we could run the first shader with.
+ theEffect.m_EffectCommands.push_back(new SBindTarget());
+ theEffect.m_EffectCommands.push_back(
+ new SBindShader(m_StringTable.GetRenderStringTable().RegisterStr(
+ theEffect.m_Shaders[0].m_Name.c_str())));
+ theEffect.m_EffectCommands.push_back(new SApplyInstanceValue());
+ theEffect.m_EffectCommands.push_back(new SRender(false));
+ }
+ }
+ }
+ }
+
+ bool LoadEffectXMLFromSourcePath(const char *inSourcePath,
+ Qt3DSDMInstanceHandle inInstance,
+ const TCharStr &inObjectName,
+ std::vector<SMetaDataLoadWarning> &outWarnings,
+ qt3ds::foundation::IInStream &inStream) override
+ {
+ std::shared_ptr<IDOMFactory> theFactory(
+ IDOMFactory::CreateDOMFactory(m_DataCore->GetStringTablePtr()));
+ qt3dsdm::SDOMElement *theElem = CDOMSerializer::Read(*theFactory, inStream, NULL);
+ if (theElem != NULL) {
+ std::shared_ptr<IDOMReader> theReader(
+ IDOMReader::CreateDOMReader(*theElem, m_DataCore->GetStringTablePtr(),
+ theFactory));
+ LoadEffectXML(*theReader, inInstance, inObjectName, outWarnings,
+ TCharStr(Intern(inSourcePath)));
+ return true;
+ }
+ return false;
+ }
+
+ Option<SMetaDataEffect> GetEffectBySourcePath(const char *inSourcePath) override
+ {
+ QDir sourcePath = QDir::cleanPath(QString(inSourcePath));
+ for (TEffectMap::iterator iter = m_EffectMap.begin(), end = m_EffectMap.end(); iter != end;
+ ++iter) {
+ QDir effectPath = QDir::cleanPath(QString::fromWCharArray(
+ iter->second.m_SourcePath.wide_str()));
+ if (effectPath == sourcePath)
+ return iter->second.ToEffect();
+ }
+ return Empty();
+ }
+
+ void LoadMaterialInstance(const char *inShaderFile, Qt3DSDMInstanceHandle inInstance,
+ const TCharStr &inName,
+ std::vector<SMetaDataLoadWarning> &outWarnings,
+ qt3ds::foundation::IInStream &inStream) override
+ {
+ QString shaderFile(inShaderFile);
+ if (shaderFile.endsWith(".material") || shaderFile.endsWith(".shader")) {
+ LoadMaterialClassFromSourcePath(inShaderFile, inInstance, inName, outWarnings,
+ inStream);
+ } else {
+ QT3DS_ASSERT(false);
+ }
+ }
+
+ bool IsMaterialClassRegistered(const char *inName) override
+ {
+ return m_CustomMaterials.find(Intern(inName)) != m_CustomMaterials.end();
+ }
+
+ void LoadMaterialClassXML(IDOMReader &inStream, Qt3DSDMInstanceHandle inInstance,
+ const TCharStr &inObjectName,
+ std::vector<SMetaDataLoadWarning> &outWarnings,
+ const TCharStr &inSourcePath) override
+ {
+ using namespace qt3ds::render::dynamic;
+
+ std::pair<TCustomMaterialMap::iterator, bool> theInserter = m_CustomMaterials.insert(
+ std::make_pair(Intern(inObjectName), SMetaDataCustomMaterialImpl()));
+ /*if ( inStream.MoveToFirstChild( "Effect" ) == false )
+ {
+ outWarnings.push_back( SMetaDataLoadWarning( MetaDataLoadWarningType::Unknown,
+ MetaDataLoadWarningMessage::GeneralError, L"File doesn't appear to be an effect xml file,
+ missing top level Effect tag" ) );
+ return;
+ }*/
+ eastl::string shaderPrefix = "#include \"customMaterial.glsllib\"\n";
+
+ SMetaDataCustomMaterialImpl &theMaterial = theInserter.first->second;
+ m_ObjectName = inObjectName;
+ theMaterial.m_Name = inObjectName;
+ theMaterial.m_SourcePath = inSourcePath;
+ theMaterial.m_HasTransparency = false;
+ theMaterial.m_HasRefraction = false;
+ theMaterial.m_AlwaysDirty = false;
+ theMaterial.m_ShaderKey = 0;
+ theMaterial.m_LayerCount = 0;
+ inStream.Att("always-dirty", theMaterial.m_AlwaysDirty);
+ LoadDynamicObjectProperties(inStream, theMaterial, inInstance, inObjectName, outWarnings,
+ shaderPrefix);
+ LoadDynamicObjectShaders(inStream, theMaterial, shaderPrefix, inObjectName);
+
+ // currently single pass shader only
+ if (theMaterial.m_Shaders.size()) {
+ eastl::string theShaderNameStr;
+
+ // in Passes we store additional render commands
+ IDOMReader::Scope __readerScope(inStream);
+ if (inStream.MoveToFirstChild("Passes")) {
+ for (bool success = inStream.MoveToFirstChild(); success;
+ success = inStream.MoveToNextSibling()) {
+ IDOMReader::Scope __passScope(inStream);
+ if (AreEqual("Pass", inStream.GetNarrowElementName())) {
+ const char8_t *typeStr;
+ if (!inStream.UnregisteredAtt("type", typeStr))
+ typeStr = "render";
+ if (AreEqual(typeStr, "render")) {
+ const char8_t *shader = "", *input = "[source]", *output = "[dest]",
+ *outputFormat = "rgba", *clear = "";
+ bool needsClear = false;
+ inStream.Att("shader", shader);
+ inStream.Att("input", input);
+ inStream.Att("output", output);
+ // for multi pass materials
+ inStream.Att("clear", clear);
+ if (AreEqual("true", clear))
+ needsClear = true;
+
+ GetShaderName(inObjectName, shader, theShaderNameStr);
+ // this is only for the final output of the effect
+ inStream.Att("format", outputFormat);
+ qt3ds::render::NVRenderTextureFormats::Enum theOutputFormat =
+ ConvertTypeAndFormatToTextureFormat("ubyte", outputFormat);
+
+ if (AreEqual(output, "[dest]") || IsTrivial(output)) {
+ theMaterial.m_CustomerMaterialCommands.push_back(
+ new SBindTarget(theOutputFormat));
+ } else {
+ theMaterial.m_CustomerMaterialCommands.push_back(
+ new SBindBuffer(
+ m_StringTable.GetRenderStringTable().RegisterStr(
+ output), needsClear));
+ }
+
+ // add shader to command stream
+ qt3ds::render::CRegisteredString theShaderName;
+ if (!IsTrivial(shader)) {
+ for (QT3DSU32 idx = 0, end = theMaterial.m_Shaders.size();
+ idx < end && theShaderName.IsValid() == false; ++idx) {
+ qt3ds::render::CRegisteredString thePossibleNameStr =
+ m_StringTable.GetRenderStringTable().RegisterStr(
+ theMaterial.m_Shaders[idx].m_Name.c_str());
+ if (AreEqual(thePossibleNameStr.c_str(),
+ theShaderNameStr.c_str()))
+ theShaderName = thePossibleNameStr;
+ }
+ }
+ if (theShaderName.IsValid() == false
+ && theMaterial.m_Shaders.empty() == false)
+ theShaderName = m_StringTable.GetRenderStringTable().RegisterStr(
+ theMaterial.m_Shaders[0].m_Name.c_str());
+ if (theShaderName.IsValid()) {
+ theMaterial.m_CustomerMaterialCommands.push_back(
+ new SBindShader(theShaderName));
+ // this is a place holder for our input values to the shader
+ theMaterial.m_CustomerMaterialCommands.push_back(
+ new SApplyInstanceValue());
+
+ for (bool bufParam = inStream.MoveToFirstChild(); bufParam;
+ bufParam = inStream.MoveToNextSibling()) {
+ if (AreEqual("BufferBlit", inStream.GetNarrowElementName())) {
+ const char8_t *value = "";
+ const char8_t *dest = "";
+ const char8_t *source = "";
+ inStream.Att("dest", dest);
+ if (AreEqual("[dest]", dest))
+ value = "";
+ inStream.Att("source", source);
+ if (AreEqual("[source]", source))
+ value = "";
+
+ theMaterial.m_CustomerMaterialCommands.push_back(
+ new SApplyBlitFramebuffer(
+ m_StringTable.GetRenderStringTable().RegisterStr(
+ source),
+ m_StringTable.GetRenderStringTable().RegisterStr(
+ dest)));
+
+ // note need a better way to pass information from MDL to
+ // our input
+ // We use buffer blits to simulate glass refraction
+ theMaterial.m_HasRefraction = true;
+ } else if (AreEqual("BufferInput",
+ inStream.GetNarrowElementName())) {
+ const char8_t *param = "";
+ const char8_t *value = "";
+ inStream.Att("param", param);
+ inStream.Att("value", value);
+ if (AreEqual("[source]", value))
+ value = "";
+ theMaterial.m_CustomerMaterialCommands.push_back(
+ new SApplyBufferValue(
+ m_StringTable.GetRenderStringTable().RegisterStr(
+ value),
+ m_StringTable.GetRenderStringTable().RegisterStr(
+ param)));
+ HideEffectProperty(inInstance, param);
+ } else if (AreEqual("Blending",
+ inStream.GetNarrowElementName())) {
+ const char8_t *theSrcBlendFuncStr = "",
+ *theDestBlendFuncStr = "";
+ inStream.Att("source", theSrcBlendFuncStr);
+ inStream.Att("dest", theDestBlendFuncStr);
+
+ qt3ds::render::NVRenderSrcBlendFunc::Enum theSrcBlendFunc =
+ ConvertToSrcBlendFunc(theSrcBlendFuncStr);
+ qt3ds::render::NVRenderDstBlendFunc::Enum theDstBlendFuc =
+ ConvertToDstBlendFunc(theDestBlendFuncStr);
+
+ // this will setup blending
+ theMaterial.m_CustomerMaterialCommands.push_back(
+ new SApplyBlending(theSrcBlendFunc,
+ theDstBlendFuc));
+ // if we have blending we have transparency
+ theMaterial.m_HasTransparency = true;
+ } else if (AreEqual("RenderState",
+ inStream.GetNarrowElementName())) {
+ // UdoL Todo: add this one
+ }
+ }
+ }
+ // add the render command as last thing in the pass, it is a render
+ // pass.
+ theMaterial.m_CustomerMaterialCommands.push_back(new SRender(false));
+ }
+ } else if (AreEqual("ShaderKey", inStream.GetNarrowElementName())) {
+ QT3DSU32 theValue = 0;
+ inStream.Att("value", theValue);
+ theMaterial.m_ShaderKey = theValue;
+ } else if (AreEqual("LayerKey", inStream.GetNarrowElementName())) {
+ QT3DSU32 theValue = 0;
+ inStream.Att("count", theValue);
+ theMaterial.m_LayerCount = theValue;
+ } else if (AreEqual("Buffer", inStream.GetNarrowElementName())) {
+ SAllocateBufferFlags theFlags;
+ const char8_t *theLifetimeStr = "", *theType = "", *theFormat = "",
+ *theFilter = "", *theWrap = "", *theName = "";
+ QT3DSF32 theSize = 1.0f;
+ inStream.Att("name", theName);
+ inStream.Att("lifetime", theLifetimeStr);
+ inStream.Att("type", theType);
+ inStream.Att("format", theFormat);
+ inStream.Att("filter", theFilter);
+ inStream.Att("wrap", theWrap);
+ inStream.Att("size", theSize);
+ // Clamp the size to valid amounts
+ if (theSize <= 0)
+ theSize = 1.0f;
+ if (theSize > 1.0f)
+ theSize = 1.0f;
+ if (AreEqual(theLifetimeStr, "scene"))
+ theFlags.SetSceneLifetime(true);
+ qt3ds::render::NVRenderTextureFormats::Enum theTexFormat =
+ ConvertTypeAndFormatToTextureFormat(theType, theFormat);
+ qt3ds::render::NVRenderTextureMagnifyingOp::Enum theMagOp =
+ ConvertFilterToMagOp(theFilter);
+ qt3ds::render::NVRenderTextureCoordOp::Enum theCoordOp =
+ ConvertTextureCoordOp(theWrap);
+ if (*theName == 0) {
+ QT3DS_ASSERT(false);
+ // inFoundation.error( QT3DS_INVALID_PARAMETER, "Buffer is missing its
+ // name" );
+ } else {
+ theMaterial.m_CustomerMaterialCommands.push_back(
+ new SAllocateBuffer(
+ m_StringTable.GetRenderStringTable().RegisterStr(
+ theName), theTexFormat, theMagOp, theCoordOp,
+ theSize, theFlags));
+ }
+ }
+ }
+ }
+
+ if (theMaterial.m_CustomerMaterialCommands.size() == 0) {
+ // add minimal set
+ // add shader to command stream
+ theMaterial.m_CustomerMaterialCommands.push_back(
+ new SBindShader(m_StringTable.GetRenderStringTable().RegisterStr(
+ theMaterial.m_Shaders[0].m_Name.c_str())));
+ // this is a place holder for our input values to the shader
+ theMaterial.m_CustomerMaterialCommands.push_back(new SApplyInstanceValue());
+ // add the render command as last thing
+ theMaterial.m_CustomerMaterialCommands.push_back(new SRender(false));
+ }
+ }
+ }
+
+ bool LoadMaterialClassFromSourcePath(const char *inSourcePath,
+ Qt3DSDMInstanceHandle inInstance,
+ const TCharStr &inObjectName,
+ std::vector<SMetaDataLoadWarning> &outWarnings,
+ qt3ds::foundation::IInStream &inStream) override
+ {
+ std::shared_ptr<IDOMFactory> theFactory(
+ IDOMFactory::CreateDOMFactory(m_DataCore->GetStringTablePtr()));
+ qt3dsdm::SDOMElement *theElem = CDOMSerializer::Read(*theFactory, inStream, NULL);
+ if (theElem != NULL) {
+ std::shared_ptr<IDOMReader> theReader(
+ IDOMReader::CreateDOMReader(*theElem, m_DataCore->GetStringTablePtr(),
+ theFactory));
+ LoadMaterialClassXML(*theReader, inInstance, inObjectName, outWarnings,
+ TCharStr(Intern(inSourcePath)));
+ return true;
+ }
+ return false;
+ }
+
+ Option<SMetaDataCustomMaterial> GetMaterialBySourcePath(const char *inSourcePath) override
+ {
+ TCharStr theSourcePath(Intern(inSourcePath));
+ for (TCustomMaterialMap::iterator iter = m_CustomMaterials.begin(),
+ end = m_CustomMaterials.end();
+ iter != end; ++iter) {
+ if (iter->second.m_SourcePath == theSourcePath)
+ return iter->second.ToMaterial();
+ }
+ return Empty();
+ }
+
+ ////////////////////////////////////////////////////////////////////////////////////
+ // Undo/Redo
+ void SetConsumer(TTransactionConsumerPtr inConsumer) override { m_Consumer = inConsumer; }
+
+ ////////////////////////////////////////////////////////////////////////////////////
+ // Signals
+ virtual TSignalConnectionPtr
+ ConnectInternalCategoryDestroyed(function<void(Qt3DSDMCategoryHandle)> inCallback)
+ {
+ return CONNECT(&SNewMetaDataImpl::internalCategoryDestroyed);
+ }
+ virtual TSignalConnectionPtr
+ ConnectInternalPropertyDestroyed(function<void(Qt3DSDMMetaDataPropertyHandle)> inCallback)
+ {
+ return CONNECT(&SNewMetaDataImpl::internalMetaDataPropertyDestroyed);
+ }
+ virtual TSignalConnectionPtr
+ ConnectInternalEventDestroyed(function<void(Qt3DSDMEventHandle)> inCallback)
+ {
+ return CONNECT(&SNewMetaDataImpl::internalEventDestroyed);
+ }
+ virtual TSignalConnectionPtr
+ ConnectInternalHandlerDestroyed(function<void(Qt3DSDMHandlerHandle)> inCallback)
+ {
+ return CONNECT(&SNewMetaDataImpl::internalHandlerDestroyed);
+ }
+ virtual TSignalConnectionPtr
+ ConnectInternalHandlerArgDestroyed(function<void(Qt3DSDMHandlerHandle, QT3DSU32)> inCallback)
+ {
+ return CONNECT(&SNewMetaDataImpl::internalHandlerArgDestroyed);
+ }
+};
+}
+
+std::shared_ptr<IMetaData> IMetaData::CreateNewMetaData(std::shared_ptr<IDataCore> inDataCore)
+{
+ return std::make_shared<SNewMetaDataImpl>(inDataCore);
+}
+#ifndef QT3DSDM_META_DATA_NO_SIGNALS
+#include "Qt3DSDMMetaData.moc"
+#endif
diff --git a/src/dm/systems/Qt3DSDMMetaData.h b/src/dm/systems/Qt3DSDMMetaData.h
new file mode 100644
index 0000000..67a7fb1
--- /dev/null
+++ b/src/dm/systems/Qt3DSDMMetaData.h
@@ -0,0 +1,400 @@
+/****************************************************************************
+**
+** Copyright (C) 2008 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
+
+#include "Qt3DSDMMetaDataTypes.h"
+#include "foundation/Qt3DSOption.h"
+#include <functional>
+#include <memory>
+#include "Qt3DSDMActionInfo.h"
+#include "Qt3DSDMStringTable.h"
+#include "Qt3DSDMValue.h"
+
+struct SShaderParameters;
+namespace qt3ds {
+namespace foundation {
+ class IInStream;
+}
+}
+
+namespace qt3dsdm {
+
+using qt3ds::foundation::Option;
+using qt3ds::QT3DSU32;
+using std::pair;
+using std::vector;
+
+class ISignalConnection;
+class ITransactionConsumer;
+class IDOMWriter;
+class IDOMReader;
+class IDataCore;
+class CDataCoreProducer;
+
+struct MetaDataLoadWarningType
+{
+ enum Enum {
+ Unknown = 0,
+ InvalidProperty,
+ InvalidEvent,
+ InvalidHandler,
+ };
+};
+
+struct MetaDataLoadWarningMessage
+{
+ enum Enum {
+ Unknown = 0,
+ GeneralError,
+ MissingName,
+ InvalidDefault,
+ };
+};
+
+struct SMetaDataLoadWarning
+{
+ MetaDataLoadWarningType::Enum m_Type;
+ MetaDataLoadWarningMessage::Enum m_Message;
+ TCharStr m_ExtraInfo;
+
+ SMetaDataLoadWarning(MetaDataLoadWarningType::Enum inType,
+ MetaDataLoadWarningMessage::Enum inMessage, TCharStr inInfo = TCharStr())
+ : m_Type(inType)
+ , m_Message(inMessage)
+ , m_ExtraInfo(inInfo)
+ {
+ }
+ SMetaDataLoadWarning()
+ : m_Type(MetaDataLoadWarningType::Unknown)
+ , m_Message(MetaDataLoadWarningMessage::Unknown)
+ {
+ }
+};
+
+/**
+ * Meta data class to hold meta data descriptions of the objects used in DataModel.
+ * A user-visible type in DataModel (things in the timeline) has a specific set of metadata,
+ * the type can have properties, events, handlers, and references.
+ *
+ * Properties are exactly what they sound like. Events are messages the object can send,
+ * and handlers are functions that are exported from the object.
+ *
+ * Events are hooked up to handlers using an ActionCore which takes tuples
+ * of instance, event, handler and slide and maintains a specific instance of an action.
+ *
+ * References allow us to track which properties are being accessed. Properties are stripped
+ * from the engine portion of the runtime (although they still appear in the scenegraph)
+ * if they aren't animated nor set in a given slide.
+ */
+class IMetaData
+{
+protected:
+ virtual ~IMetaData() {}
+public:
+ typedef const TCharStr &TStrType;
+
+ ////////////////////////////////////////////////////////////////////////////////////
+ // Sharing some utility objects
+ virtual IStringTable &GetStringTable() = 0;
+ virtual TStringTablePtr GetStringTablePtr() = 0;
+ virtual std::shared_ptr<IDataCore> GetDataCore() = 0;
+
+ ////////////////////////////////////////////////////////////////////////////////////
+ // Canonical Instances
+ // Map an instance to a given type name. The type name is stored, along with the instance
+ // handle in the file if this object is *not* canonical.
+ // If this object is canonical, then we expect this mapping setup before loading the
+ // canonical data, and we will use a type lookup instead of a direct handle lookup
+ // when loading canonical information.
+ virtual void SetInstanceAsCanonical(Qt3DSDMInstanceHandle inInstance, TStrType inTypename) = 0;
+
+ virtual Qt3DSDMInstanceHandle GetCanonicalInstanceForType(TStrType inTypename) = 0;
+ // If this instance wasn't registered as canonical, then we return empty.
+ virtual Option<TCharStr> GetTypeForCanonicalInstance(Qt3DSDMInstanceHandle inInstance) = 0;
+ // Gets the type for this instance via derivation
+ virtual Option<TCharStr> GetTypeForInstance(Qt3DSDMInstanceHandle inInstance) = 0;
+ // Get group count for instance
+ virtual QT3DSU32 GetGroupCountForInstance(Qt3DSDMInstanceHandle inInstance) = 0;
+ // Get all group names
+ virtual QT3DSU32 GetGroupNamesForInstance(Qt3DSDMInstanceHandle inInstance,
+ std::vector<TCharStr> &outNames) = 0;
+ // Get group count for instance
+ virtual Option<TCharStr> GetGroupFilterNameForInstance(Qt3DSDMInstanceHandle inInstance,
+ long inIndex) = 0;
+
+ ////////////////////////////////////////////////////////////////////////////////////
+ // Categories
+ // Categories appear in the UI to divide up large lists of events, actions, and properties.
+ // Returns <handle,true> if a category was created
+ // else returns <handle,false>
+ virtual pair<Qt3DSDMCategoryHandle, bool> GetOrCreateCategory(TStrType inName) = 0;
+
+ virtual void SetCategoryInfo(Qt3DSDMCategoryHandle inCategory, TStrType inIcon,
+ TStrType inHighlight, TStrType inDescription) = 0;
+ virtual void DestroyCategory(Qt3DSDMCategoryHandle inCategory) = 0;
+
+ virtual Option<SCategoryInfo> GetCategoryInfo(Qt3DSDMCategoryHandle inCategory) = 0;
+ virtual Qt3DSDMCategoryHandle FindCategoryByName(TStrType inName) = 0;
+ virtual void GetCategories(vector<Qt3DSDMCategoryHandle> &outCategories) = 0;
+ virtual Option<SCategoryInfo> GetEventCategory(TStrType inName) = 0;
+ virtual Option<SCategoryInfo> GetHandlerCategory(TStrType inName) = 0;
+
+ ////////////////////////////////////////////////////////////////////////////////////
+ // Properties
+ // Will create the property on the instance associated with this type name if it doesn't exist.
+ // Metadata properties can be redifined for child instances and this re-definition will override
+ // the parent definition. We currently use this to give different formal names and description
+ // to the sourcepath property (for models it is mesh, for materials it is image).
+ virtual Qt3DSDMMetaDataPropertyHandle
+ CreateMetaDataProperty(Qt3DSDMInstanceHandle inInstance) = 0;
+
+ // For properties, you set the default values separately
+ // This may delete the underlying data model property rebuild it.
+ virtual void SetMetaDataPropertyInfo(Qt3DSDMMetaDataPropertyHandle inPropertyHandle,
+ TStrType inName, TStrType inFormalName,
+ TStrType inDescription, TStrType inUsage,
+ CompleteMetaDataType::Enum inDataType,
+ const SValue &inDefaultValue,
+ const TMetaDataData &inMetaData, TStrType inGroupName,
+ bool inIsHidden = false, bool inIsAnimatable = false,
+ bool inIsControllable = false) = 0;
+
+ // Destroy just this meta data property
+ // Does not destroy the underlying data core property, so this function isn't a perfect
+ // reverse of the above system. This *just* destroyed the meta data pointed to by
+ // this property.
+ virtual void DestroyMetaDataProperty(Qt3DSDMMetaDataPropertyHandle inProperty) = 0;
+
+ virtual Qt3DSDMMetaDataPropertyHandle GetMetaDataProperty(Qt3DSDMInstanceHandle inInstance,
+ TStrType inPropertyName) = 0;
+ virtual Qt3DSDMMetaDataPropertyHandle GetMetaDataProperty(Qt3DSDMInstanceHandle inInstance,
+ Qt3DSDMPropertyHandle inProperty) = 0;
+ virtual Option<SMetaDataPropertyInfo>
+ GetMetaDataPropertyInfo(Qt3DSDMMetaDataPropertyHandle inProperty) = 0;
+ // Get all of the meta data properties defined on this object or its derivation parents
+ virtual void GetMetaDataProperties(Qt3DSDMInstanceHandle inInstance,
+ vector<Qt3DSDMMetaDataPropertyHandle> &outProperties) = 0;
+
+ // Get the meta data properties defined on *only* this object, don't search parents
+ virtual Qt3DSDMMetaDataPropertyHandle
+ GetOrCreateSpecificMetaDataProperty(Qt3DSDMInstanceHandle inInstance,
+ TStrType inPropertyName) = 0;
+ virtual void
+ GetSpecificMetaDataProperties(Qt3DSDMInstanceHandle inInstance,
+ vector<Qt3DSDMMetaDataPropertyHandle> &outProperties) = 0;
+
+ virtual TCharStr GetFormalName(Qt3DSDMInstanceHandle inInstance,
+ Qt3DSDMPropertyHandle inProperty) = 0;
+ virtual AdditionalMetaDataType::Value GetAdditionalMetaDataType(Qt3DSDMInstanceHandle inInstance,
+ Qt3DSDMPropertyHandle inProperty) = 0;
+ virtual TMetaDataData GetAdditionalMetaDataData(Qt3DSDMInstanceHandle inInstance,
+ Qt3DSDMPropertyHandle inProperty) = 0;
+ virtual bool IsCustomProperty(Qt3DSDMInstanceHandle inInstance,
+ Qt3DSDMPropertyHandle inProperty) = 0;
+ virtual SValue GetDefaultValue(Qt3DSDMInstanceHandle inInstance,
+ Qt3DSDMPropertyHandle inProperty) = 0;
+
+ virtual void
+ SetMetaDataPropertyFilters(Qt3DSDMMetaDataPropertyHandle inProperty,
+ qt3ds::foundation::NVConstDataRef<SPropertyFilterInfo> inFilters) = 0;
+ virtual qt3ds::foundation::NVConstDataRef<SPropertyFilterInfo>
+ GetMetaDataPropertyFilters(Qt3DSDMMetaDataPropertyHandle inProperty) = 0;
+ virtual void RemoveMetaDataPropertyFilters(Qt3DSDMMetaDataPropertyHandle inProperty) = 0;
+
+ ////////////////////////////////////////////////////////////////////////////////////
+ // Events
+ // CreateMetaDataEvent was original named CreateEvent but this collides with
+ // the microsoft macro CreateEvent which expands to CreateEventA or CreateEventW
+ virtual Qt3DSDMEventHandle CreateMetaDataEvent(Qt3DSDMInstanceHandle inInstance) = 0;
+ virtual void SetEventInfo(Qt3DSDMEventHandle inEventHandle, TStrType inName,
+ TStrType inFormalName, TStrType inCategory,
+ TStrType inDescription) = 0;
+
+ virtual void DestroyEvent(Qt3DSDMEventHandle inEventHandle) = 0;
+
+ virtual void GetEvents(Qt3DSDMInstanceHandle inInstance, TEventHandleList &outEvents) = 0;
+ virtual Qt3DSDMEventHandle FindEvent(Qt3DSDMInstanceHandle inInstance, TStrType inName) = 0;
+ virtual Option<SEventInfo> GetEventInfo(Qt3DSDMEventHandle inEventHandle) = 0;
+ virtual bool IsCustomEvent(Qt3DSDMEventHandle inEventHandle) = 0;
+
+ // Get/Find an event that occurs on just this instance, don't search parent instances
+ virtual void GetSpecificEvents(Qt3DSDMInstanceHandle inInstance,
+ TEventHandleList &outEvents) = 0;
+ virtual Qt3DSDMEventHandle GetOrCreateSpecificEvent(Qt3DSDMInstanceHandle inInstance,
+ TStrType inName) = 0;
+
+ ////////////////////////////////////////////////////////////////////////////////////
+ // Handlers
+ virtual Qt3DSDMHandlerHandle CreateHandler(Qt3DSDMInstanceHandle inInstance) = 0;
+ virtual void SetHandlerInfo(Qt3DSDMHandlerHandle inHandle, TStrType inName,
+ TStrType inFormalName, TStrType inCategory,
+ TStrType inDescription) = 0;
+ virtual void DestroyHandler(Qt3DSDMHandlerHandle inHandlerHandle) = 0;
+
+ virtual Qt3DSDMHandlerHandle FindHandlerByName(Qt3DSDMInstanceHandle inInstance,
+ TStrType inName) = 0;
+ virtual Option<SHandlerInfo> GetHandlerInfo(Qt3DSDMHandlerHandle inHandlerHandle) = 0;
+ virtual void GetHandlers(Qt3DSDMInstanceHandle inInstance, THandlerHandleList &outHandlers) = 0;
+ virtual bool IsCustomHandler(Qt3DSDMHandlerHandle inEventHandle) = 0;
+
+ virtual void GetSpecificHandlers(Qt3DSDMInstanceHandle inInstance,
+ THandlerHandleList &outHandlers) = 0;
+ virtual Qt3DSDMHandlerHandle GetOrCreateSpecificHandler(Qt3DSDMInstanceHandle inInstance,
+ TStrType inName) = 0;
+
+ ////////////////////////////////////////////////////////////////////////////////////
+ // Handler Arguments
+ virtual QT3DSU32 AddHandlerArgument(Qt3DSDMHandlerHandle inHandler) = 0;
+ virtual void
+ SetHandlerArgumentInfo(Qt3DSDMHandlerHandle inHandler, QT3DSU32 inArgIndex, TStrType inName,
+ TStrType inFormalName, TStrType inDescription,
+ CompleteMetaDataType::Enum inDataType, const SValue &inDefaultValue,
+ const TMetaDataData &inMetaData, HandlerArgumentType::Value inArgType) = 0;
+
+ virtual void DestroyHandlerArgument(Qt3DSDMHandlerHandle inHandler, QT3DSU32 inArgIndex) = 0;
+
+ virtual Option<SMetaDataHandlerArgumentInfo>
+ FindHandlerArgumentByName(Qt3DSDMHandlerHandle inHandler, TStrType inName) = 0;
+ virtual void GetHandlerArguments(Qt3DSDMHandlerHandle inHandler,
+ vector<SMetaDataHandlerArgumentInfo> &outArguments) = 0;
+ virtual Option<SMetaDataHandlerArgumentInfo>
+ GetHandlerArgumentInfo(Qt3DSDMHandlerHandle inHandle, QT3DSU32 inIndex) = 0;
+ virtual QT3DSU32 GetNumHandlerArguments(Qt3DSDMHandlerHandle inHandler) = 0;
+
+ ////////////////////////////////////////////////////////////////////////////////////
+ // References
+ // Duplicate references are removed from this instance
+ virtual void AddReference(Qt3DSDMInstanceHandle inInstance, TStrType inRefString) = 0;
+ virtual void DestroyReferences(Qt3DSDMInstanceHandle inInstance) = 0;
+
+ // Does the recursive gather from all the parents. Duplicate references are removed from the
+ // final list.
+ virtual void GetReferences(Qt3DSDMInstanceHandle inInstance,
+ std::vector<TCharStr> &outReferences) = 0;
+
+ ////////////////////////////////////////////////////////////////////////////////////
+ // Instance-global functions
+ // Destroy all meta data that relates to this instance.
+ // Calling this on a derived instance does nothing, this only works if this specific
+ // instance was mapped directly to meta data.
+ virtual void DestroyMetaData(Qt3DSDMInstanceHandle inInstance) = 0;
+
+ ////////////////////////////////////////////////////////////////////////////////////
+ // Serialization
+ // You can either save out in canonical format (and it will only save canonical-instance-related
+ // information *or* you can save out in normal format where we link directly to instance handle
+ // instead of to typename
+ virtual void Save(IDOMWriter &inWriter) = 0;
+ // Loading expects the canonical instances to be setup already which means that
+ // it will perform lookups based on
+ // One huge assumption is that the reader is using the same string table
+ // that this object was built with
+ // InIsCanonical tells us whether to mark loaded categories as canonical
+ // or not.
+ virtual void Load(IDOMReader &ioStream) = 0;
+
+ // Load meta data and apply it to just this instance
+ virtual void LoadInstance(IDOMReader &inReader, Qt3DSDMInstanceHandle inInstance,
+ const TCharStr &inName,
+ std::vector<SMetaDataLoadWarning> &outWarnings) = 0;
+
+ // Save just this instances meta data out to the writer
+ virtual void SaveInstance(IDOMWriter &inWriter, Qt3DSDMInstanceHandle inInstance) = 0;
+
+ // Load effect meta data from file and apply it to just this instance
+ virtual void LoadEffectInstance(const char *inShaderFile, Qt3DSDMInstanceHandle inInstance,
+ const TCharStr &inName,
+ std::vector<SMetaDataLoadWarning> &outWarnings,
+ qt3ds::foundation::IInStream &inStream) = 0;
+
+ virtual bool IsEffectInstanceRegistered(const char *inName) = 0;
+ virtual void LoadEffectXML(IDOMReader &inStream, Qt3DSDMInstanceHandle inInstance,
+ const TCharStr &inObjectName,
+ std::vector<SMetaDataLoadWarning> &outWarnings,
+ const TCharStr &inSourcePath) = 0;
+ virtual bool LoadEffectXMLFromSourcePath(const char *inSourcePath,
+ Qt3DSDMInstanceHandle inInstance,
+ const TCharStr &inObjectName,
+ std::vector<SMetaDataLoadWarning> &outWarnings,
+ qt3ds::foundation::IInStream &inStream) = 0;
+ virtual Option<SMetaDataEffect> GetEffectBySourcePath(const char *inName) = 0;
+
+ virtual void LoadMaterialInstance(const char *inShaderFile,
+ Qt3DSDMInstanceHandle inInstance,
+ const TCharStr &inName,
+ std::vector<SMetaDataLoadWarning> &outWarnings,
+ qt3ds::foundation::IInStream &inStream) = 0;
+ virtual bool IsMaterialClassRegistered(const char *inName) = 0;
+ virtual void LoadMaterialClassXML(IDOMReader &inStream, Qt3DSDMInstanceHandle inInstance,
+ const TCharStr &inObjectName,
+ std::vector<SMetaDataLoadWarning> &outWarnings,
+ const TCharStr &inSourcePath) = 0;
+ virtual bool LoadMaterialClassFromSourcePath(const char *inSourcePath,
+ Qt3DSDMInstanceHandle inInstance,
+ const TCharStr &inObjectName,
+ std::vector<SMetaDataLoadWarning> &outWarnings,
+ qt3ds::foundation::IInStream &inStream) = 0;
+ virtual Option<SMetaDataCustomMaterial> GetMaterialBySourcePath(const char *inSourcePath) = 0;
+
+ ////////////////////////////////////////////////////////////////////////////////////
+ // Undo/Redo
+ virtual void SetConsumer(std::shared_ptr<ITransactionConsumer> inConsumer) = 0;
+
+#ifndef QT3DSDM_META_DATA_NO_SIGNALS
+ ////////////////////////////////////////////////////////////////////////////////////
+ // Signals
+ // These events are sent out only once, they aren't set into the transaction consumer
+ // to be sent out upon undo and redo. These events are meant for chaining together side effects
+ // so other systems don't have references to invalid handler arguments and handles.
+ // Also, the objects in these messages are still valid so you can query information about them
+ // at this time. They will be destroyed subsequent to the event.
+ virtual std::shared_ptr<ISignalConnection>
+ ConnectInternalCategoryDestroyed(std::function<void(Qt3DSDMCategoryHandle)> inCallback) = 0;
+ virtual std::shared_ptr<ISignalConnection> ConnectInternalPropertyDestroyed(
+ std::function<void(Qt3DSDMMetaDataPropertyHandle)> inCallback) = 0;
+ virtual std::shared_ptr<ISignalConnection>
+ ConnectInternalEventDestroyed(std::function<void(Qt3DSDMEventHandle)> inCallback) = 0;
+ virtual std::shared_ptr<ISignalConnection>
+ ConnectInternalHandlerDestroyed(std::function<void(Qt3DSDMHandlerHandle)> inCallback) = 0;
+ virtual std::shared_ptr<ISignalConnection> ConnectInternalHandlerArgDestroyed(
+ std::function<void(Qt3DSDMHandlerHandle, QT3DSU32)> inCallback) = 0;
+#endif
+
+ ////////////////////////////////////////////////////////////////////////////////////
+ // Creation/Lifetime Management
+ friend class std::shared_ptr<IMetaData>;
+ // The data core is used to create the properties if they don't exist or
+ // query their underlying type if they do exist. We also subscribe to
+ // the datacore's beforeInstanceDelete function in order to ensure
+ // that we delete our existing meta data for instances that are being deleted.
+ static std::shared_ptr<IMetaData> CreateNewMetaData(std::shared_ptr<IDataCore> inDataCore);
+};
+
+typedef std::shared_ptr<IMetaData> TNewMetaDataPtr;
+}
diff --git a/src/dm/systems/Qt3DSDMMetaDataTypes.h b/src/dm/systems/Qt3DSDMMetaDataTypes.h
new file mode 100644
index 0000000..5532e0a
--- /dev/null
+++ b/src/dm/systems/Qt3DSDMMetaDataTypes.h
@@ -0,0 +1,350 @@
+/****************************************************************************
+**
+** Copyright (C) 2008 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
+#include "Qt3DSDMMetaDataValue.h"
+
+namespace qt3ds {
+namespace render {
+ namespace dynamic {
+ struct SCommand;
+ struct SPropertyDeclaration;
+ struct SPropertyDefinition;
+ }
+}
+}
+
+namespace qt3dsdm {
+
+struct HandlerArgumentType {
+
+ enum Value {
+ None,
+ Property, // Property reference. Load the Properties of the Target Object.
+ Dependent, // Property type depends on another property.
+ Slide, // Slide reference. Load the list of slides of the Target Object if
+ // applicable.
+ Event, // Event reference. Load the applicable Events of the Target Object.
+ Object, // Object reference. Used for dynamic actions with object referenced
+ // property.
+ Signal, // Signal reference. Used for emiting signals fired from the trigger
+ // object.
+ };
+
+ Q_ENUM(Value)
+ Q_GADGET
+};
+
+struct CompleteMetaDataType
+{
+ enum Enum {
+ Unknown = 0,
+ StringList,
+ FloatRange,
+ LongRange,
+ Float,
+ Long,
+ Float2,
+ Vector,
+ Scale,
+ Rotation,
+ Color,
+ Boolean,
+ Slide,
+ Font,
+ FontSize,
+ String,
+ MultiLineString,
+ ObjectRef,
+ Image,
+ Mesh,
+ Import,
+ Texture,
+ Guid,
+ StringListOrInt,
+ Renderable,
+ Image2D,
+ Buffer,
+ PathBuffer,
+ ShadowMapResolution,
+ };
+
+ // Functions defined in UICDMMetaData.cpp
+ static DataModelDataType::Value ToDataType(Enum inCompleteType);
+ static AdditionalMetaDataType::Value ToAdditionalType(Enum inCompleteType);
+ static CompleteMetaDataType::Enum ToCompleteType(DataModelDataType::Value inDataType,
+ AdditionalMetaDataType::Value inAdditionalType);
+ Q_ENUM(Enum)
+ Q_GADGET
+};
+
+typedef std::pair<DataModelDataType::Value, AdditionalMetaDataType::Value> TDataTypePair;
+
+inline bool Equals(const TMetaDataData &lhs, const TMetaDataData &rhs)
+{
+ return rhs == lhs;
+}
+
+inline AdditionalMetaDataType::Value GetMetaDataValueType(const TMetaDataData &inValue)
+{
+ return inValue.getType();
+}
+
+// Base class shared between property info
+// and handler arguments.
+struct SMetaPropertyBase
+{
+ TCharStr m_Name;
+ TCharStr m_FormalName;
+ TCharStr m_Usage;
+ TCharStr m_Description;
+ CompleteMetaDataType::Enum m_CompleteType;
+ TMetaDataData m_MetaDataData;
+ SValue m_DefaultValue;
+
+ SMetaPropertyBase()
+ : m_CompleteType(CompleteMetaDataType::Float)
+ {
+ }
+ bool operator==(const SMetaPropertyBase &inOther) const
+ {
+ return m_Name == inOther.m_Name && m_FormalName == inOther.m_FormalName
+ && m_Usage == inOther.m_Usage && m_Description == inOther.m_Description
+ && m_CompleteType == inOther.m_CompleteType
+ && Equals(m_DefaultValue.toOldSkool(), inOther.m_DefaultValue.toOldSkool())
+ && Equals(m_MetaDataData, inOther.m_MetaDataData);
+ }
+ DataModelDataType::Value GetDataType() const
+ {
+ return CompleteMetaDataType::ToDataType(m_CompleteType);
+ }
+ AdditionalMetaDataType::Value GetAdditionalType() const
+ {
+ return CompleteMetaDataType::ToAdditionalType(m_CompleteType);
+ }
+};
+
+struct SMetaDataPropertyInfo : SMetaPropertyBase
+{
+ Qt3DSDMInstanceHandle m_Instance;
+ Qt3DSDMPropertyHandle m_Property;
+ bool m_Controllable = false; // Can this property be controlled via data input (default no)
+ bool m_IsHidden = false; // Is this property hidden in the inspector (default no)
+ bool m_Animatable = true; // Is this property animatable (default yes)
+ // Note: all animatables are controllable
+
+ TCharStr m_GroupName; // Name of the group this property belongs to or "default"
+
+ SMetaDataPropertyInfo(Qt3DSDMInstanceHandle inInstance)
+ : m_Instance(inInstance)
+ {
+ }
+ SMetaDataPropertyInfo() {}
+
+ bool operator==(const SMetaDataPropertyInfo &inOther) const
+ {
+ return m_Instance == inOther.m_Instance && m_Property == inOther.m_Property
+ && m_IsHidden == inOther.m_IsHidden && m_Animatable == inOther.m_Animatable
+ && m_GroupName == inOther.m_GroupName
+ && m_Controllable == inOther.m_Controllable
+ && SMetaPropertyBase::operator==(inOther);
+ }
+
+ bool operator!=(const SMetaDataPropertyInfo &inOther) const { return !(*this == inOther); }
+};
+
+struct SMetaDataHandlerArgumentInfo : SMetaPropertyBase
+{
+ Qt3DSDMHandlerHandle m_Handler;
+ HandlerArgumentType::Value m_ArgType;
+ SMetaDataHandlerArgumentInfo(Qt3DSDMHandlerHandle inHandler = Qt3DSDMHandlerHandle())
+ : m_Handler(inHandler)
+ , m_ArgType(HandlerArgumentType::None)
+ {
+ }
+};
+
+struct SCategoryInfo
+{
+ TCharStr m_Name;
+ TCharStr m_Description;
+ TCharStr m_Icon;
+ TCharStr m_HighlightIcon;
+ bool m_Canonical;
+
+ SCategoryInfo()
+ : m_Canonical(false)
+ {
+ }
+ SCategoryInfo(TCharStr inName)
+ : m_Name(inName)
+ , m_Canonical(false)
+ {
+ }
+};
+
+struct SEventInfo
+{
+ bool operator!=(const SEventInfo &inEvent) const
+ {
+ return (m_Name != inEvent.m_Name || m_FormalName != inEvent.m_FormalName
+ || m_Category != inEvent.m_Category || m_Description != inEvent.m_Description);
+ }
+
+ TCharStr m_Name;
+ TCharStr m_FormalName;
+ TCharStr m_Category;
+ TCharStr m_Description;
+};
+
+struct SHandlerInfo
+{
+ TCharStr m_Name;
+ TCharStr m_FormalName;
+ TCharStr m_Category;
+ TCharStr m_Description;
+
+ bool operator!=(const SHandlerInfo &inHandler) const
+ {
+ return (m_Name != inHandler.m_Name || m_FormalName != inHandler.m_FormalName
+ || m_Category != inHandler.m_Category || m_Description != inHandler.m_Description);
+ }
+};
+
+struct PropertyFilterTypes
+{
+ enum Enum {
+ Unknown,
+ ShowIfEqual,
+ HideIfEqual,
+ };
+};
+
+struct SPropertyFilterInfo
+{
+ PropertyFilterTypes::Enum m_FilterType;
+ Qt3DSDMPropertyHandle m_FilterProperty;
+ SValue m_Value;
+ SPropertyFilterInfo()
+ : m_FilterType(PropertyFilterTypes::Unknown)
+ {
+ }
+ SPropertyFilterInfo(PropertyFilterTypes::Enum inFilterType, Qt3DSDMPropertyHandle inProp,
+ const SValue &inValue)
+ : m_FilterType(inFilterType)
+ , m_FilterProperty(inProp)
+ , m_Value(inValue)
+ {
+ }
+};
+struct SMetaDataShader
+{
+ TCharStr m_Name;
+ TCharStr m_Type; ///< shader type (GLSL or HLSL)
+ TCharStr m_Version; ///< shader version (e.g. 330 vor GLSL)
+ // Code contains both the vertex and fragment portions separated by #define's.
+ //#define VERTEX_SHADER, #define FRAGMENT_SHADER
+ TCharStr m_Code;
+ bool m_HasGeomShader;
+ bool m_IsComputeShader;
+ SMetaDataShader()
+ : m_HasGeomShader(false)
+ , m_IsComputeShader(false)
+ {
+ }
+ SMetaDataShader(const TCharStr &inName, const TCharStr &inType, const TCharStr &inVersion,
+ const TCharStr &inCode, bool hasGeom, bool isCompute)
+ : m_Name(inName)
+ , m_Type(inType)
+ , m_Version(inVersion)
+ , m_Code(inCode)
+ , m_HasGeomShader(hasGeom)
+ , m_IsComputeShader(isCompute)
+ {
+ }
+};
+
+struct SMetaDataDynamicObject
+{
+ TCharStr m_Name;
+ qt3ds::foundation::NVConstDataRef<SMetaDataShader> m_Shaders;
+ qt3ds::foundation::NVConstDataRef<qt3ds::render::dynamic::SPropertyDefinition> m_Properties;
+ SMetaDataDynamicObject() {}
+ SMetaDataDynamicObject(
+ const TCharStr &inName, qt3ds::foundation::NVConstDataRef<SMetaDataShader> inShaders,
+ qt3ds::foundation::NVConstDataRef<qt3ds::render::dynamic::SPropertyDefinition> inProperties)
+ : m_Name(inName)
+ , m_Shaders(inShaders)
+ , m_Properties(inProperties)
+ {
+ }
+};
+
+struct SMetaDataEffect : public SMetaDataDynamicObject
+{
+ qt3ds::foundation::NVConstDataRef<qt3ds::render::dynamic::SCommand *> m_EffectCommands;
+ SMetaDataEffect() {}
+ SMetaDataEffect(
+ const TCharStr &inName, qt3ds::foundation::NVConstDataRef<SMetaDataShader> inShaders,
+ qt3ds::foundation::NVConstDataRef<qt3ds::render::dynamic::SPropertyDefinition> inProperties,
+ qt3ds::foundation::NVConstDataRef<qt3ds::render::dynamic::SCommand *> inEffectCommands)
+ : SMetaDataDynamicObject(inName, inShaders, inProperties)
+ , m_EffectCommands(inEffectCommands)
+ {
+ }
+};
+
+struct SMetaDataCustomMaterial : public SMetaDataDynamicObject
+{
+ qt3ds::foundation::NVConstDataRef<qt3ds::render::dynamic::SCommand *> m_CustomMaterialCommands;
+ bool m_HasTransparency;
+ bool m_HasRefraction;
+ bool m_AlwaysDirty;
+ unsigned int m_ShaderKey;
+ unsigned int m_LayerCount;
+ SMetaDataCustomMaterial() {}
+ SMetaDataCustomMaterial(
+ const TCharStr &inName, qt3ds::foundation::NVConstDataRef<SMetaDataShader> inShaders,
+ qt3ds::foundation::NVConstDataRef<qt3ds::render::dynamic::SPropertyDefinition> inProperties,
+ qt3ds::foundation::NVConstDataRef<qt3ds::render::dynamic::SCommand *> inCustomMaterialCommands,
+ bool inHasTransparency, bool inHasRefraction, bool inIsAlwaysDirty,
+ unsigned int inShaderKey, unsigned int inLayerCount)
+ : SMetaDataDynamicObject(inName, inShaders, inProperties)
+ , m_CustomMaterialCommands(inCustomMaterialCommands)
+ , m_HasTransparency(inHasTransparency)
+ , m_HasRefraction(inHasRefraction)
+ , m_AlwaysDirty(inIsAlwaysDirty)
+ , m_ShaderKey(inShaderKey)
+ , m_LayerCount(inLayerCount)
+ {
+ }
+};
+}
+
+Q_DECLARE_METATYPE(qt3dsdm::HandlerArgumentType::Value)
+
diff --git a/src/dm/systems/Qt3DSDMMetaDataValue.h b/src/dm/systems/Qt3DSDMMetaDataValue.h
new file mode 100644
index 0000000..b981b95
--- /dev/null
+++ b/src/dm/systems/Qt3DSDMMetaDataValue.h
@@ -0,0 +1,251 @@
+/****************************************************************************
+**
+** Copyright (C) 2008 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
+#include <EASTL/string.h>
+#include <EASTL/vector.h>
+#include "Qt3DSDMHandles.h"
+#include "Qt3DSDMDataTypes.h"
+#include "foundation/Qt3DSDataRef.h"
+#include "Qt3DSDMValue.h"
+
+#include <QStringList>
+
+namespace qt3dsdm {
+
+struct AdditionalMetaDataType {
+
+ enum Value {
+ None,
+ StringList,
+ Range,
+ Image,
+ Color,
+ Rotation,
+ Font,
+ FontSize,
+ MultiLine,
+ ObjectRef,
+ Mesh,
+ Import,
+ Texture,
+ Renderable,
+ PathBuffer,
+ ShadowMapResolution,
+ String,
+ };
+
+
+ Q_ENUM(Value)
+ Q_GADGET
+};
+
+// List type metadata
+typedef eastl::vector<TCharStr> TMetaDataStringList;
+
+// Float type metadata
+struct SMetaDataRange
+{
+ SMetaDataRange() {}
+
+ SMetaDataRange(float min, float max, int decimals = -1)
+ : m_min(min)
+ , m_max(max)
+ , m_decimals(decimals)
+ {
+ }
+
+ bool operator==(const SMetaDataRange &other) const
+ {
+ // no need to check m_decimals for quality as it is not significant to the range value
+ return m_min == other.m_min && m_max == other.m_max;
+ }
+
+ float m_min = 0.0f;
+ float m_max = 0.0f;
+ int m_decimals = -1; // num decimals to show, -1: dynamically calculated
+};
+}
+
+namespace qt3ds {
+namespace foundation {
+
+ template <>
+ struct DestructTraits<qt3dsdm::SMetaDataRange>
+ {
+ void destruct(qt3dsdm::SMetaDataRange &) {}
+ };
+}
+}
+
+namespace qt3dsdm {
+
+template <typename TDataType>
+struct SMetaDataTypeToEnumMap
+{
+};
+template <>
+struct SMetaDataTypeToEnumMap<eastl::vector<TCharStr>>
+{
+ static AdditionalMetaDataType::Value getType() { return AdditionalMetaDataType::StringList; }
+};
+template <>
+struct SMetaDataTypeToEnumMap<SMetaDataRange>
+{
+ static AdditionalMetaDataType::Value getType() { return AdditionalMetaDataType::Range; }
+};
+
+struct SMetaDataValueTraits
+{
+ typedef AdditionalMetaDataType::Value TIdType;
+
+ enum {
+ TBufferSize = sizeof(TMetaDataStringList),
+ };
+
+ static TIdType getNoDataId() { return AdditionalMetaDataType::None; }
+
+ template <typename TDataType>
+ static TIdType getType()
+ {
+ return SMetaDataTypeToEnumMap<TDataType>::getType();
+ }
+
+ template <typename TRetType, typename TVisitorType>
+ static TRetType visit(char *inData, AdditionalMetaDataType::Value inType, TVisitorType inVisitor)
+ {
+ switch (inType) {
+ case AdditionalMetaDataType::StringList:
+ return inVisitor(*reinterpret_cast<TMetaDataStringList *>(inData));
+ case AdditionalMetaDataType::Range:
+ return inVisitor(*reinterpret_cast<SMetaDataRange *>(inData));
+ default:
+ QT3DS_ASSERT(false);
+ case AdditionalMetaDataType::None:
+ return inVisitor();
+ }
+ }
+
+ template <typename TRetType, typename TVisitorType>
+ static TRetType visit(const char *inData, AdditionalMetaDataType::Value inType,
+ TVisitorType inVisitor)
+ {
+ switch (inType) {
+ case AdditionalMetaDataType::StringList:
+ return inVisitor(*reinterpret_cast<const TMetaDataStringList *>(inData));
+ case AdditionalMetaDataType::Range:
+ return inVisitor(*reinterpret_cast<const SMetaDataRange *>(inData));
+ default:
+ QT3DS_ASSERT(false);
+ case AdditionalMetaDataType::None:
+ return inVisitor();
+ }
+ }
+};
+
+struct SMetaDataData
+ : public qt3ds::foundation::
+ DiscriminatedUnion<qt3ds::foundation::
+ DiscriminatedUnionGenericBase<SMetaDataValueTraits,
+ Qt3DSDMDataTypeUnionTraits::
+ TBufferSize>,
+ SMetaDataValueTraits::TBufferSize>
+{
+ typedef qt3ds::foundation::
+ DiscriminatedUnion<qt3ds::foundation::DiscriminatedUnionGenericBase<SMetaDataValueTraits,
+ Qt3DSDMDataTypeUnionTraits::
+ TBufferSize>,
+ SMetaDataValueTraits::TBufferSize>
+ TBase;
+ SMetaDataData() {}
+ SMetaDataData(const SMetaDataData &inOther)
+ : TBase(static_cast<const TBase &>(inOther))
+ {
+ }
+ SMetaDataData &operator=(const SMetaDataData &inOther)
+ {
+ TBase::operator=(static_cast<const TBase &>(inOther));
+ return *this;
+ }
+ SMetaDataData(const TMetaDataStringList &inData)
+ : TBase(inData)
+ {
+ }
+ SMetaDataData(const SMetaDataRange &inData)
+ : TBase(inData)
+ {
+ }
+ SMetaDataData &operator=(const TMetaDataStringList &inData)
+ {
+ TBase::operator=(inData);
+ return *this;
+ }
+ SMetaDataData &operator=(const SMetaDataRange &inData)
+ {
+ TBase::operator=(inData);
+ return *this;
+ }
+ bool empty() const { return getType() == AdditionalMetaDataType::None; }
+};
+
+template <>
+struct Qt3DSDMGetter<SMetaDataData>
+{
+ template <typename TRetType>
+ TRetType doGet(const SMetaDataData &inValue)
+ {
+ return inValue.getData<TRetType>();
+ }
+};
+
+template <>
+struct Qt3DSDMValueTyper<SMetaDataData>
+{
+ AdditionalMetaDataType::Value Get(const SMetaDataData &inValue) { return inValue.getType(); }
+};
+
+typedef SMetaDataData TMetaDataData;
+
+
+template <>
+inline QStringList get<QStringList>(const qt3dsdm::SMetaDataData &inType)
+{
+ QStringList result;
+ if (inType.getType() == qt3dsdm::AdditionalMetaDataType::None)
+ return result;
+
+ auto list = qt3dsdm::get<qt3dsdm::TMetaDataStringList>(inType);
+ std::transform(list.begin(), list.end(), std::back_inserter(result), [](const Qt3DSDMStr &s) {
+ return QString::fromWCharArray(s.wide_str());
+ });
+ return result;
+}
+}
+
+Q_DECLARE_METATYPE(qt3dsdm::AdditionalMetaDataType)
+
diff --git a/src/dm/systems/Qt3DSDMPropertyDefinition.h b/src/dm/systems/Qt3DSDMPropertyDefinition.h
new file mode 100644
index 0000000..d324b53
--- /dev/null
+++ b/src/dm/systems/Qt3DSDMPropertyDefinition.h
@@ -0,0 +1,75 @@
+/****************************************************************************
+**
+** 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 QT3DSDM_PROPERTY_DEFINITION_H
+#define QT3DSDM_PROPERTY_DEFINITION_H
+
+#include "Qt3DSDMDataTypes.h"
+
+namespace qt3dsdm {
+
+struct Qt3DSDMPropertyDefinition
+{
+ TCharStr m_Name;
+ Qt3DSDMInstanceHandle m_Instance;
+ DataModelDataType::Value m_Type;
+
+ Qt3DSDMPropertyDefinition()
+ : m_Type(DataModelDataType::None)
+ {
+ }
+ Qt3DSDMPropertyDefinition(Qt3DSDMInstanceHandle inInstanceHandle, TCharPtr inName,
+ DataModelDataType::Value inType)
+ : m_Name(inName)
+ , m_Instance(inInstanceHandle)
+ , m_Type(inType)
+ {
+ }
+ Qt3DSDMPropertyDefinition(const Qt3DSDMPropertyDefinition &inOther)
+ : m_Name(inOther.m_Name)
+ , m_Instance(inOther.m_Instance)
+ , m_Type(inOther.m_Type)
+ {
+ }
+
+ Qt3DSDMPropertyDefinition &operator=(const Qt3DSDMPropertyDefinition &inOther)
+ {
+ if (this != &inOther) {
+ m_Name = inOther.m_Name;
+ m_Instance = inOther.m_Instance;
+ m_Type = inOther.m_Type;
+ }
+ return *this;
+ }
+};
+
+typedef std::vector<Qt3DSDMPropertyDefinition> TPropertyDefinitionList;
+}
+
+#endif
diff --git a/src/dm/systems/Qt3DSDMSignalStructImpl.h b/src/dm/systems/Qt3DSDMSignalStructImpl.h
new file mode 100644
index 0000000..9664566
--- /dev/null
+++ b/src/dm/systems/Qt3DSDMSignalStructImpl.h
@@ -0,0 +1,305 @@
+/****************************************************************************
+**
+** 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 QT3DSDM_SIGNAL_STRUCT_IMPL_H
+#define QT3DSDM_SIGNAL_STRUCT_IMPL_H
+#include "Qt3DSDMSignalStructs.h"
+
+namespace qt3dsdm {
+
+struct SSignalDataStruct0
+{
+ typedef SSignalDataStruct0 TThisType;
+ typedef std::function<void()> TFunType;
+ static void Send(ISignalSystem &system, void *sender, const char *sigName)
+ {
+ system.Signal(sender, sigName, NULL, 0);
+ }
+
+ static void Unpack(void *inSender, const char *inName, const char *inData, size_t inDataSize,
+ TFunType inHandler)
+ {
+ if (inDataSize == 0)
+ inHandler();
+ else {
+ QT3DS_ASSERT(false);
+ }
+ }
+
+ static TGenericSignalHandlerFunc CreateHandler(std::function<void()> inHandler)
+ {
+ return std::bind(&TThisType::Unpack, std::placeholders::_1, std::placeholders::_2,
+ std::placeholders::_3, std::placeholders::_4, inHandler);
+ }
+
+ static std::shared_ptr<ISignalConnection> AddListener(ISignalSystem &inSystem, void *inSender,
+ const char *inName, TFunType inHandler)
+ {
+ return inSystem.AddListener(inSender, inName, CreateHandler(inHandler));
+ }
+};
+
+#define QT3DSDM_SIGNALS_DEFINE_SPECIFIC_SIGNAL_STRUCT0(name) \
+ std::shared_ptr<ISignalConnection> Sig##name::AddListener( \
+ ISignalSystem &inSystem, void *inSender, std::function<void()> inHandler) \
+ { \
+ typedef SSignalDataStruct0 TBase; \
+ return TBase::AddListener(inSystem, inSender, #name, inHandler); \
+ } \
+ void Sig##name::Send(ISignalSystem &system, void *sender) \
+ { \
+ typedef SSignalDataStruct0 TBase; \
+ TBase::Send(system, sender, #name); \
+ }
+
+template <typename TData1>
+struct SSignalDataStruct1
+{
+ typedef SSignalDataStruct1<TData1> TThisType;
+ TData1 m_Data1;
+ typedef std::function<void(TData1)> TFunType;
+ SSignalDataStruct1(TData1 d1)
+ : m_Data1(d1)
+ {
+ }
+ static void Send(ISignalSystem &system, void *sender, const char *sigName, const TData1 &d1)
+ {
+ TThisType theData(d1);
+ system.Signal(sender, sigName, reinterpret_cast<const char *>(&theData), sizeof(TThisType));
+ }
+
+ static void Unpack(void *inSender, const char *inName, const char *inData, size_t inDataSize,
+ TFunType inHandler)
+ {
+ if (inDataSize == sizeof(TThisType)) {
+ const TThisType *theData = reinterpret_cast<const TThisType *>(inData);
+ inHandler(theData->m_Data1);
+ } else {
+ QT3DS_ASSERT(false);
+ }
+ }
+
+ static TGenericSignalHandlerFunc CreateHandler(TFunType inHandler)
+ {
+ return std::bind(&TThisType::Unpack, std::placeholders::_1, std::placeholders::_2,
+ std::placeholders::_3, std::placeholders::_4, inHandler);
+ }
+
+ static std::shared_ptr<ISignalConnection> AddListener(ISignalSystem &inSystem, void *inSender,
+ const char *inName, TFunType inHandler)
+ {
+ return inSystem.AddListener(inSender, inName, CreateHandler(inHandler));
+ }
+};
+
+#define QT3DSDM_SIGNALS_DEFINE_SPECIFIC_SIGNAL_STRUCT1(name, d1) \
+ std::shared_ptr<ISignalConnection> Sig##name::AddListener( \
+ ISignalSystem &inSystem, void *inSender, std::function<void(d1)> inHandler) \
+ { \
+ typedef SSignalDataStruct1<d1> TBase; \
+ return TBase::AddListener(inSystem, inSender, #name, inHandler); \
+ } \
+ void Sig##name::Send(ISignalSystem &system, void *sender, const d1 &arg) \
+ { \
+ typedef SSignalDataStruct1<d1> TBase; \
+ TBase::Send(system, sender, #name, arg); \
+ }
+
+template <typename TData1, typename TData2>
+struct SSignalDataStruct2
+{
+ typedef SSignalDataStruct2<TData1, TData2> TThisType;
+ typedef std::function<void(TData1, TData2)> TFunType;
+ TData1 m_Data1;
+ TData2 m_Data2;
+ SSignalDataStruct2(TData1 d1, TData2 d2)
+ : m_Data1(d1)
+ , m_Data2(d2)
+ {
+ }
+ static void Send(ISignalSystem &system, void *sender, const char *sigName, const TData1 &d1,
+ const TData2 &d2)
+ {
+ TThisType theData(d1, d2);
+ system.Signal(sender, sigName, reinterpret_cast<const char *>(&theData), sizeof(TThisType));
+ }
+
+ static void Unpack(void *inSender, const char *inName, const char *inData, size_t inDataSize,
+ TFunType inHandler)
+ {
+ if (inDataSize == sizeof(TThisType)) {
+ const TThisType *theData = reinterpret_cast<const TThisType *>(inData);
+ inHandler(theData->m_Data1, theData->m_Data2);
+ } else {
+ QT3DS_ASSERT(false);
+ }
+ }
+
+ static TGenericSignalHandlerFunc CreateHandler(TFunType inHandler)
+ {
+ return std::bind(&TThisType::Unpack, std::placeholders::_1, std::placeholders::_2,
+ std::placeholders::_3, std::placeholders::_4, inHandler);
+ }
+
+ static std::shared_ptr<ISignalConnection> AddListener(ISignalSystem &inSystem, void *inSender,
+ const char *inName, TFunType inHandler)
+ {
+ return inSystem.AddListener(inSender, inName, CreateHandler(inHandler));
+ }
+};
+
+#define QT3DSDM_SIGNALS_DEFINE_SPECIFIC_SIGNAL_STRUCT2(name, d1, d2) \
+ std::shared_ptr<ISignalConnection> Sig##name::AddListener( \
+ ISignalSystem &inSystem, void *inSender, std::function<void(d1, d2)> inHandler) \
+ { \
+ return SSignalDataStruct2<d1, d2>::AddListener(inSystem, inSender, #name, inHandler); \
+ } \
+ void Sig##name::Send(ISignalSystem &system, void *sender, const d1 &arg1, const d2 &arg2) \
+ { \
+ SSignalDataStruct2<d1, d2>::Send(system, sender, #name, arg1, arg2); \
+ }
+
+template <typename TData1, typename TData2, typename TData3>
+struct SSignalDataStruct3
+{
+ typedef SSignalDataStruct3<TData1, TData2, TData3> TThisType;
+ typedef std::function<void(TData1, TData2, TData3)> TFunType;
+ TData1 m_Data1;
+ TData2 m_Data2;
+ TData3 m_Data3;
+ SSignalDataStruct3(const TData1 &d1, const TData2 &d2, const TData3 &d3)
+ : m_Data1(d1)
+ , m_Data2(d2)
+ , m_Data3(d3)
+ {
+ }
+ static void Send(ISignalSystem &system, void *sender, const char *sigName, const TData1 &d1,
+ const TData2 &d2, const TData3 &d3)
+ {
+ TThisType theData(d1, d2, d3);
+ system.Signal(sender, sigName, reinterpret_cast<const char *>(&theData), sizeof(TThisType));
+ }
+
+ static void Unpack(void *inSender, const char *inName, const char *inData, size_t inDataSize,
+ TFunType inHandler)
+ {
+ if (inDataSize == sizeof(TThisType)) {
+ const TThisType *theData = reinterpret_cast<const TThisType *>(inData);
+ inHandler(theData->m_Data1, theData->m_Data2, theData->m_Data2);
+ } else {
+ QT3DS_ASSERT(false);
+ }
+ }
+
+ static TGenericSignalHandlerFunc CreateHandler(TFunType inHandler)
+ {
+ return std::bind(&TThisType::Unpack, std::placeholders::_1, std::placeholders::_2,
+ std::placeholders::_3, std::placeholders::_4, inHandler);
+ }
+
+ static std::shared_ptr<ISignalConnection> AddListener(ISignalSystem &inSystem, void *inSender,
+ const char *inName, TFunType inHandler)
+ {
+ return inSystem.AddListener(inSender, inName, CreateHandler(inHandler));
+ }
+};
+
+#define QT3DSDM_SIGNALS_DEFINE_SPECIFIC_SIGNAL_STRUCT3(name, d1, d2, d3) \
+ std::shared_ptr<ISignalConnection> Sig##name::AddListener( \
+ ISignalSystem &inSystem, void *inSender, std::function<void(d1, d2, d3)> inHandler) \
+ { \
+ return SSignalDataStruct3<d1, d2, d3>::AddListener(inSystem, inSender, #name, inHandler); \
+ } \
+ void Sig##name::Send(ISignalSystem &system, void *sender, const d1 &arg1, const d2 &arg2, \
+ const d3 &arg3) \
+ { \
+ SSignalDataStruct3<d1, d2, d3>::Send(system, sender, #name, arg1, arg2, arg3); \
+ }
+
+template <typename TData1, typename TData2, typename TData3, typename TData4>
+struct SSignalDataStruct4
+{
+ typedef SSignalDataStruct4<TData1, TData2, TData3, TData4> TThisType;
+ typedef std::function<void(TData1, TData2, TData3, TData4)> TFunType;
+ TData1 m_Data1;
+ TData2 m_Data2;
+ TData3 m_Data3;
+ TData4 m_Data4;
+ SSignalDataStruct4(const TData1 &d1, const TData2 &d2, const TData3 &d3, const TData4 &d4)
+ : m_Data1(d1)
+ , m_Data2(d2)
+ , m_Data3(d3)
+ , m_Data4(d4)
+ {
+ }
+ static void Send(ISignalSystem &system, void *sender, const char *sigName, const TData1 &d1,
+ const TData2 &d2, const TData3 &d3, const TData4 &d4)
+ {
+ TThisType theData(d1, d2, d3, d4);
+ system.Signal(sender, sigName, reinterpret_cast<const char *>(&theData), sizeof(TThisType));
+ }
+
+ static void Unpack(void *inSender, const char *inName, const char *inData, size_t inDataSize,
+ TFunType inHandler)
+ {
+ if (inDataSize == sizeof(TThisType)) {
+ const TThisType *theData = reinterpret_cast<const TThisType *>(inData);
+ inHandler(theData->m_Data1, theData->m_Data2, theData->m_Data2, theData->m_Data4);
+ } else {
+ QT3DS_ASSERT(false);
+ }
+ }
+
+ static TGenericSignalHandlerFunc CreateHandler(TFunType inHandler)
+ {
+ return std::bind(&TThisType::Unpack, std::placeholders::_1, std::placeholders::_2,
+ std::placeholders::_3, std::placeholders::_4, inHandler);
+ }
+
+ static std::shared_ptr<ISignalConnection> AddListener(ISignalSystem &inSystem, void *inSender,
+ const char *inName, TFunType inHandler)
+ {
+ return inSystem.AddListener(inSender, inName, CreateHandler(inHandler));
+ }
+};
+
+#define QT3DSDM_SIGNALS_DEFINE_SPECIFIC_SIGNAL_STRUCT4(name, d1, d2, d3, d4) \
+ std::shared_ptr<ISignalConnection> Sig##name::AddListener( \
+ ISignalSystem &inSystem, void *inSender, std::function<void(d1, d2, d3, d4)> inHandler) \
+ { \
+ return SSignalDataStruct4<d1, d2, d3, d4>::AddListener(inSystem, inSender, #name, \
+ inHandler); \
+ } \
+ void Sig##name::Send(ISignalSystem &system, void *sender, const d1 &arg1, const d2 &arg2, \
+ const d3 &arg3, const d4 &arg4) \
+ { \
+ SSignalDataStruct4<d1, d2, d3, d4>::Send(system, sender, #name, arg1, arg2, arg3, arg4); \
+ }
+}
+#endif
diff --git a/src/dm/systems/Qt3DSDMSignalStructs.h b/src/dm/systems/Qt3DSDMSignalStructs.h
new file mode 100644
index 0000000..86c09fd
--- /dev/null
+++ b/src/dm/systems/Qt3DSDMSignalStructs.h
@@ -0,0 +1,89 @@
+/****************************************************************************
+**
+** 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 QT3DSDM_SIGNAL_STRUCTS_H
+#define QT3DSDM_SIGNAL_STRUCTS_H
+#include "Qt3DSDMSignalSystem.h"
+// Helper structs for signals of different arity.
+namespace qt3dsdm {
+// Helper defines to create static tables of signals
+// Macros with the same number of args but with 'declare' replaced by 'define
+// are available in UICDMSignalStructImpl.h. You will need to place these somewhere but
+// they rely on std::bind so I don't place them here.
+#define QT3DSDM_SIGNALS_DECLARE_SPECIFIC_SIGNAL_STRUCT0(name) \
+ struct Sig##name \
+ { \
+ static std::shared_ptr<ISignalConnection> \
+ AddListener(ISignalSystem &inSystem, void *inSender, std::function<void()> inHandler); \
+ static void Send(ISignalSystem &system, void *sender); \
+ };
+
+// Helper defines to create static tables of signals
+#define QT3DSDM_SIGNALS_DECLARE_SPECIFIC_SIGNAL_STRUCT1(name, d1) \
+ struct Sig##name \
+ { \
+ static std::shared_ptr<ISignalConnection> \
+ AddListener(ISignalSystem &inSystem, void *inSender, std::function<void(d1)> inHandler); \
+ static void Send(ISignalSystem &system, void *sender, const d1 &arg); \
+ };
+
+// Helper defines to create static tables of signals
+#define QT3DSDM_SIGNALS_DECLARE_SPECIFIC_SIGNAL_STRUCT2(name, d1, d2) \
+ struct Sig##name \
+ { \
+ static std::shared_ptr<ISignalConnection> \
+ AddListener(ISignalSystem &inSystem, void *inSender, \
+ std::function<void(d1, d2)> inHandler); \
+ static void Send(ISignalSystem &system, void *sender, const d1 &arg1, const d2 &arg2); \
+ };
+
+// Helper defines to create static tables of signals
+#define QT3DSDM_SIGNALS_DECLARE_SPECIFIC_SIGNAL_STRUCT3(name, d1, d2, d3) \
+ struct Sig##name \
+ { \
+ static std::shared_ptr<ISignalConnection> \
+ AddListener(ISignalSystem &inSystem, void *inSender, \
+ std::function<void(d1, d2, d3)> inHandler); \
+ static void Send(ISignalSystem &system, void *sender, const d1 &arg1, const d2 &arg2, \
+ const d3 &arg3); \
+ };
+
+// Helper defines to create static tables of signals
+#define QT3DSDM_SIGNALS_DECLARE_SPECIFIC_SIGNAL_STRUCT4(name, d1, d2, d3, d4) \
+ struct Sig##name \
+ { \
+ static std::shared_ptr<ISignalConnection> \
+ AddListener(ISignalSystem &inSystem, void *inSender, \
+ std::function<void(d1, d2, d3, d4)> inHandler); \
+ static void Send(ISignalSystem &system, void *sender, const d1 &arg1, const d2 &arg2, \
+ const d3 &arg3, const d4 &arg4); \
+ };
+}
+
+#endif
diff --git a/src/dm/systems/Qt3DSDMSignalSystem.cpp b/src/dm/systems/Qt3DSDMSignalSystem.cpp
new file mode 100644
index 0000000..37d0200
--- /dev/null
+++ b/src/dm/systems/Qt3DSDMSignalSystem.cpp
@@ -0,0 +1,184 @@
+/****************************************************************************
+**
+** 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 "Qt3DSDMSignalSystem.h"
+#include "EASTL/hash_map.h"
+
+using namespace qt3dsdm;
+
+namespace {
+
+struct SSignalListener;
+class ISignalSystemImpl
+{
+public:
+ virtual ~ISignalSystemImpl() {}
+ virtual void RemoveListener(SSignalListener &inListener) = 0;
+};
+
+struct SSignalSystemKey
+{
+ void *m_Sender;
+ const char *m_SignalName;
+ SSignalSystemKey(void *inSender, const char *inSigName, IStringTable &inStrTable)
+ : m_Sender(inSender)
+ , m_SignalName(inStrTable.GetNarrowStr(inSigName))
+ {
+ }
+ SSignalSystemKey(const SSignalSystemKey &inOther)
+ : m_Sender(inOther.m_Sender)
+ , m_SignalName(inOther.m_SignalName)
+ {
+ }
+
+ SSignalSystemKey &operator=(const SSignalSystemKey &inOther)
+ {
+ if (this != &inOther) {
+ m_Sender = inOther.m_Sender;
+ m_SignalName = inOther.m_SignalName;
+ }
+ return *this;
+ }
+
+ bool operator==(const SSignalSystemKey &inOther) const
+ {
+ return m_Sender == inOther.m_Sender && m_SignalName == inOther.m_SignalName;
+ }
+};
+
+struct SSignalListener : ISignalConnection
+{
+ shared_ptr<ISignalSystemImpl> m_SignalSystem;
+ TGenericSignalHandlerFunc m_Handler;
+ SSignalSystemKey m_Key;
+ SSignalListener(shared_ptr<ISignalSystemImpl> inSystem, TGenericSignalHandlerFunc inHandler,
+ SSignalSystemKey inKey)
+ : m_SignalSystem(inSystem)
+ , m_Handler(inHandler)
+ , m_Key(inKey)
+ {
+ }
+ ~SSignalListener() { m_SignalSystem->RemoveListener(*this); }
+ void Signal(void *inSender, const char *inName, const char *inData, size_t inDataSize)
+ {
+ m_Handler(inSender, inName, inData, inDataSize);
+ }
+};
+
+typedef eastl::vector<SSignalListener *> TSignalListenerPtrList;
+}
+
+namespace eastl {
+template <>
+struct hash<SSignalSystemKey>
+{
+ size_t operator()(const SSignalSystemKey &inKey) const
+ {
+ return hash<void *>()(inKey.m_Sender) ^ hash<const char *>()(inKey.m_SignalName);
+ }
+};
+}
+
+namespace {
+typedef eastl::hash_map<SSignalSystemKey, TSignalListenerPtrList> TSignalHandlerMap;
+
+struct SSignalSystemImpl : public ISignalSystemImpl
+{
+ TSignalHandlerMap m_SignalHandlers;
+ shared_ptr<IStringTable> m_StringTable;
+ SSignalSystemImpl(shared_ptr<IStringTable> inStrTable)
+ : m_StringTable(inStrTable)
+ {
+ }
+
+ TSignalListenerPtrList *FindListenerList(const SSignalSystemKey &inKey)
+ {
+ TSignalHandlerMap::iterator theIter = m_SignalHandlers.find(inKey);
+ if (theIter != m_SignalHandlers.end())
+ return &theIter->second;
+ return NULL;
+ }
+
+ void Signal(void *inSender, const char *inName, const char *inData, size_t inDataSize)
+ {
+ TSignalListenerPtrList *theSignals =
+ FindListenerList(SSignalSystemKey(inSender, inName, *m_StringTable));
+ if (theSignals) {
+ for (eastl_size_t idx = 0, end = theSignals->size(); idx < end; ++idx) {
+ (*theSignals)[idx]->Signal(inSender, inName, inData, inDataSize);
+ }
+ }
+ }
+
+ void RemoveListener(SSignalListener &inListener) override
+ {
+ TSignalListenerPtrList *theSignals = FindListenerList(inListener.m_Key);
+ if (theSignals) {
+ // If we could allow unordered access then this could potentially be a lot faster.
+ TSignalListenerPtrList::iterator theFind =
+ eastl::find(theSignals->begin(), theSignals->end(), &inListener);
+ if (theFind != theSignals->end())
+ theSignals->erase(theFind);
+ }
+ }
+};
+
+struct SSignalSystem : public ISignalSystem
+{
+ shared_ptr<SSignalSystemImpl> m_System;
+ SSignalSystem(shared_ptr<IStringTable> inStrTable)
+ {
+ m_System = std::make_shared<SSignalSystemImpl>(inStrTable);
+ }
+
+ shared_ptr<ISignalConnection> AddListener(void *inSender, const char *inName,
+ TGenericSignalHandlerFunc inFunc) override
+ {
+ SSignalSystemKey theKey(inSender, inName, *m_System->m_StringTable);
+ TSignalHandlerMap::iterator theIter =
+ m_System->m_SignalHandlers.insert(eastl::make_pair(theKey, TSignalListenerPtrList()))
+ .first;
+ TSignalListenerPtrList &theList(theIter->second);
+ shared_ptr<SSignalListener> theSender =
+ std::make_shared<SSignalListener>(m_System, inFunc, theKey);
+ theList.push_back(theSender.get());
+ return theSender;
+ }
+
+ void Signal(void *inSender, const char *inName, const char *inData, size_t inDataSize) override
+ {
+ m_System->Signal(inSender, inName, inData, inDataSize);
+ }
+};
+}
+
+shared_ptr<ISignalSystem> ISignalSystem::CreateSignalSystem(shared_ptr<IStringTable> inStrTable)
+{
+ return std::make_shared<SSignalSystem>(inStrTable);
+}
diff --git a/src/dm/systems/Qt3DSDMSignalSystem.h b/src/dm/systems/Qt3DSDMSignalSystem.h
new file mode 100644
index 0000000..cd80010
--- /dev/null
+++ b/src/dm/systems/Qt3DSDMSignalSystem.h
@@ -0,0 +1,52 @@
+/****************************************************************************
+**
+** 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 QT3DSDM_SIGNAL_SYSTEM_H
+#define QT3DSDM_SIGNAL_SYSTEM_H
+#include <functional>
+#include "Qt3DSDMSignals.h"
+
+namespace qt3dsdm {
+typedef std::function<void(void *, const char *, const char *, size_t)> TGenericSignalHandlerFunc;
+
+class ISignalSystem
+{
+protected:
+ virtual ~ISignalSystem() {}
+public:
+ virtual shared_ptr<ISignalConnection> AddListener(void *inSender, const char *inName,
+ TGenericSignalHandlerFunc inFunc) = 0;
+ virtual void Signal(void *inSender, const char *inName, const char *inData,
+ size_t inDataSize) = 0;
+
+ static shared_ptr<ISignalSystem> CreateSignalSystem(shared_ptr<IStringTable> inStrTable);
+};
+}
+
+#endif
diff --git a/src/dm/systems/Qt3DSDMSignals.h b/src/dm/systems/Qt3DSDMSignals.h
new file mode 100644
index 0000000..57b9659
--- /dev/null
+++ b/src/dm/systems/Qt3DSDMSignals.h
@@ -0,0 +1,611 @@
+/****************************************************************************
+**
+** 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 QT3DSDM_SIGNALS_H
+#define QT3DSDM_SIGNALS_H
+#include "Qt3DSDMDataTypes.h"
+#include "Qt3DSDMHandles.h"
+#include "Qt3DSDMAnimation.h"
+#include "Qt3DSDMActionInfo.h"
+#include "Qt3DSDMValue.h"
+#include <functional>
+#include <string>
+
+namespace qt3dsdm {
+
+class ISignalConnection
+{
+public:
+ virtual ~ISignalConnection() {}
+};
+
+class ISignalItem
+{
+public:
+ virtual ~ISignalItem() {}
+};
+
+typedef std::shared_ptr<ISignalItem> TSignalItemPtr;
+
+typedef std::shared_ptr<ISignalConnection> TSignalConnectionPtr;
+
+class QtSignalConnection : public ISignalConnection
+{
+ Q_DISABLE_COPY(QtSignalConnection)
+private:
+ QMetaObject::Connection m_connection;
+public:
+ QtSignalConnection(const QMetaObject::Connection &inConnection)
+ : m_connection(inConnection)
+ {
+ }
+ ~QtSignalConnection() override
+ {
+ QObject::disconnect(m_connection);
+ }
+};
+
+
+class IInstancePropertyCoreSignalProvider : public ISignalItem
+{
+public:
+ virtual TSignalConnectionPtr ConnectInstancePropertyValue(
+ const std::function<void(Qt3DSDMInstanceHandle, Qt3DSDMPropertyHandle, const SValue &)>
+ &inCallback) = 0;
+};
+
+class IInstancePropertyCoreSignalSender : public ISignalItem
+{
+public:
+ virtual void SignalInstancePropertyValue(Qt3DSDMInstanceHandle inInstance,
+ Qt3DSDMPropertyHandle inProperty,
+ const SValue &inValue) = 0;
+};
+
+class IDataCoreSignalProvider : public ISignalItem
+{
+public:
+ virtual TSignalConnectionPtr
+ ConnectInstanceCreated(const std::function<void(Qt3DSDMInstanceHandle)> &inCallback) = 0;
+ virtual TSignalConnectionPtr
+ ConnectBeforeInstanceDeleted(const std::function<void(Qt3DSDMInstanceHandle)> &inCallback) = 0;
+ virtual TSignalConnectionPtr
+ ConnectInstanceDeleted(const std::function<void(Qt3DSDMInstanceHandle)> &inCallback) = 0;
+ virtual TSignalConnectionPtr ConnectInstanceDerived(
+ const std::function<void(Qt3DSDMInstanceHandle, Qt3DSDMInstanceHandle)> &inCallback) = 0;
+ virtual TSignalConnectionPtr ConnectInstanceParentRemoved(
+ const std::function<void(Qt3DSDMInstanceHandle, Qt3DSDMInstanceHandle)> &inCallback) = 0;
+ virtual TSignalConnectionPtr
+ ConnectPropertyAdded(const std::function<void(Qt3DSDMInstanceHandle, Qt3DSDMPropertyHandle,
+ TCharPtr, DataModelDataType::Value)> &inCallback) = 0;
+ virtual TSignalConnectionPtr ConnectPropertyRemoved(
+ const std::function<void(Qt3DSDMInstanceHandle, Qt3DSDMPropertyHandle, TCharPtr,
+ DataModelDataType::Value)> &inCallback) = 0;
+};
+
+class IDataCoreSignalSender : public ISignalItem
+{
+public:
+ virtual void SignalInstanceCreated(Qt3DSDMInstanceHandle inInstance) = 0;
+ virtual void SignalBeforeInstanceDeleted(Qt3DSDMInstanceHandle inInstance) = 0;
+ virtual void SignalInstanceDeleted(Qt3DSDMInstanceHandle inInstance) = 0;
+ virtual void SignalInstanceDerived(Qt3DSDMInstanceHandle inInstance,
+ Qt3DSDMInstanceHandle inParent) = 0;
+ virtual void SignalInstanceParentRemoved(Qt3DSDMInstanceHandle inInstance,
+ Qt3DSDMInstanceHandle inParent) = 0;
+ virtual void SignalPropertyAdded(Qt3DSDMInstanceHandle inInstance,
+ Qt3DSDMPropertyHandle inProperty, TCharPtr inName,
+ DataModelDataType::Value inDataType) = 0;
+ virtual void SignalPropertyRemoved(Qt3DSDMInstanceHandle inInstance,
+ Qt3DSDMPropertyHandle inProperty, TCharPtr inName,
+ DataModelDataType::Value inDataType) = 0;
+};
+
+class ISlideCoreSignalProvider : public ISignalItem
+{
+public:
+ virtual TSignalConnectionPtr
+ ConnectSlideCreated(const std::function<void(Qt3DSDMSlideHandle)> &inCallback) = 0;
+ virtual TSignalConnectionPtr
+ ConnectBeforeSlideDeleted(const std::function<void(Qt3DSDMSlideHandle)> &inCallback) = 0;
+ virtual TSignalConnectionPtr
+ ConnectSlideDeleted(const std::function<void(Qt3DSDMSlideHandle)> &inCallback) = 0;
+ virtual TSignalConnectionPtr ConnectSlideDerived(
+ const std::function<void(Qt3DSDMSlideHandle, Qt3DSDMSlideHandle, int)> &inCallback) = 0;
+ virtual TSignalConnectionPtr ConnectInstancePropertyValueSet(
+ const std::function<void(Qt3DSDMSlideHandle, Qt3DSDMInstanceHandle, Qt3DSDMPropertyHandle,
+ const SValue &)> &inCallback) = 0;
+ virtual TSignalConnectionPtr ConnectInstancePropertyValueRemoved(
+ const std::function<void(Qt3DSDMSlideHandle, Qt3DSDMInstanceHandle, Qt3DSDMPropertyHandle,
+ const SValue &)> &inCallback) = 0;
+ virtual TSignalConnectionPtr
+ ConnectSlideTimeChanged(const std::function<void(Qt3DSDMSlideHandle)> &inCallback) = 0;
+};
+
+class ISlideCoreSignalSender : public ISignalItem
+{
+public:
+ virtual void SendSlideCreated(Qt3DSDMSlideHandle inSlide) = 0;
+ virtual void SendBeforeSlideDeleted(Qt3DSDMSlideHandle inSlide) = 0;
+ virtual void SendSlideDeleted(Qt3DSDMSlideHandle inSlide) = 0;
+ virtual void SendSlideDerived(Qt3DSDMSlideHandle inSlide, Qt3DSDMSlideHandle inParent,
+ int inIndex) = 0;
+ virtual void SendPropertyValueSet(Qt3DSDMSlideHandle inSlide, Qt3DSDMInstanceHandle inInstance,
+ Qt3DSDMPropertyHandle inParent, const SValue &inValue) = 0;
+ // This gives clients a chance to override a property value the first time it is set on a slide
+ virtual void SendPropertyValueRemoved(Qt3DSDMSlideHandle inSlide,
+ Qt3DSDMInstanceHandle inInstance,
+ Qt3DSDMPropertyHandle inParent, const SValue &inValue) = 0;
+ virtual void SendSlideTimeChanged(Qt3DSDMSlideHandle inSlide) = 0;
+};
+
+class ISlideGraphCoreSignalProvider : public ISignalItem
+{
+public:
+ virtual TSignalConnectionPtr ConnectGraphCreated(
+ const std::function<void(Qt3DSDMSlideGraphHandle, Qt3DSDMSlideHandle)> &inCallback) = 0;
+ virtual TSignalConnectionPtr ConnectGraphDeleted(
+ const std::function<void(Qt3DSDMSlideGraphHandle, Qt3DSDMSlideHandle)> &inCallback) = 0;
+ virtual TSignalConnectionPtr ConnectInstanceAssociated(
+ const std::function<void(Qt3DSDMSlideGraphHandle, Qt3DSDMSlideHandle, Qt3DSDMInstanceHandle)>
+ &inCallback) = 0;
+ virtual TSignalConnectionPtr ConnectInstanceDissociated(
+ const std::function<void(Qt3DSDMSlideGraphHandle, Qt3DSDMSlideHandle, Qt3DSDMInstanceHandle)>
+ &inCallback) = 0;
+ virtual TSignalConnectionPtr ConnectGraphActiveSlide(
+ const std::function<void(Qt3DSDMSlideGraphHandle, Qt3DSDMSlideHandle)> &inCallback) = 0;
+};
+
+class ISlideGraphCoreSignalSender : public ISignalItem
+{
+public:
+ virtual void SendGraphCreated(Qt3DSDMSlideGraphHandle inGraph, Qt3DSDMSlideHandle inSlide) = 0;
+ virtual void SendGraphDeleted(Qt3DSDMSlideGraphHandle inGraph, Qt3DSDMSlideHandle inSlide) = 0;
+ virtual void SendInstanceAssociated(Qt3DSDMSlideGraphHandle inGraph, Qt3DSDMSlideHandle inSlide,
+ Qt3DSDMInstanceHandle inInstance) = 0;
+ virtual void SendInstanceDissociated(Qt3DSDMSlideGraphHandle inGraph, Qt3DSDMSlideHandle inSlide,
+ Qt3DSDMInstanceHandle inInstance) = 0;
+ virtual void SendGraphActiveSlide(Qt3DSDMSlideGraphHandle inGraph,
+ Qt3DSDMSlideHandle inSlide) = 0;
+};
+
+class IAnimationCoreSignalProvider : public ISignalItem
+{
+public:
+ virtual TSignalConnectionPtr ConnectAnimationCreated(
+ const std::function<void(Qt3DSDMAnimationHandle, Qt3DSDMSlideHandle, Qt3DSDMInstanceHandle,
+ Qt3DSDMPropertyHandle, size_t, EAnimationType)> &inCallback) = 0;
+ virtual TSignalConnectionPtr ConnectBeforeAnimationDeleted(
+ const std::function<void(Qt3DSDMAnimationHandle)> &inCallback) = 0;
+ virtual TSignalConnectionPtr ConnectAnimationDeleted(
+ const std::function<void(Qt3DSDMAnimationHandle, Qt3DSDMSlideHandle, Qt3DSDMInstanceHandle,
+ Qt3DSDMPropertyHandle, size_t, EAnimationType)> &inCallback) = 0;
+ virtual TSignalConnectionPtr ConnectKeyframeInserted(
+ const std::function<void(Qt3DSDMAnimationHandle, Qt3DSDMKeyframeHandle, const TKeyframe &)>
+ &inCallback) = 0;
+ virtual TSignalConnectionPtr
+ ConnectBeforeKeyframeErased(const std::function<void(Qt3DSDMKeyframeHandle)> &inCallback) = 0;
+ virtual TSignalConnectionPtr ConnectKeyframeErased(
+ const std::function<void(Qt3DSDMAnimationHandle, Qt3DSDMKeyframeHandle, const TKeyframe &)>
+ &inCallback) = 0;
+ virtual TSignalConnectionPtr ConnectBeforeAllKeyframesErased(
+ const std::function<void(Qt3DSDMAnimationHandle)> &inCallback) = 0;
+ virtual TSignalConnectionPtr ConnectKeyframeUpdated(
+ const std::function<void(Qt3DSDMKeyframeHandle, const TKeyframe &)> &inCallback) = 0;
+ virtual TSignalConnectionPtr ConnectFirstKeyframeDynamicSet(
+ const std::function<void(Qt3DSDMAnimationHandle, bool)> &inCallback) = 0;
+};
+
+class IAnimationCoreSignalSender : public ISignalItem
+{
+public:
+ virtual void SendAnimationCreated(Qt3DSDMAnimationHandle inAnimation, Qt3DSDMSlideHandle inSlide,
+ Qt3DSDMInstanceHandle inInstance,
+ Qt3DSDMPropertyHandle inProperty, size_t inIndex,
+ EAnimationType inAnimationType) = 0;
+ virtual void SendBeforeAnimationDeleted(Qt3DSDMAnimationHandle inAnimation) = 0;
+ virtual void SendAnimationDeleted(Qt3DSDMAnimationHandle inAnimation, Qt3DSDMSlideHandle inSlide,
+ Qt3DSDMInstanceHandle inInstance,
+ Qt3DSDMPropertyHandle inProperty, size_t inIndex,
+ EAnimationType inAnimationType) = 0;
+ virtual void SendKeyframeInserted(Qt3DSDMAnimationHandle inAnimation,
+ Qt3DSDMKeyframeHandle inKeyframe, const TKeyframe &inData) = 0;
+ virtual void SendBeforeKeyframeErased(Qt3DSDMKeyframeHandle inAnimation) = 0;
+ virtual void SendKeyframeErased(Qt3DSDMAnimationHandle inAnimation,
+ Qt3DSDMKeyframeHandle inKeyframe, const TKeyframe &inData) = 0;
+ virtual void SendBeforeAllKeyframesErased(Qt3DSDMAnimationHandle inAnimation) = 0;
+ virtual void SendKeyframeUpdated(Qt3DSDMKeyframeHandle inKeyframe, const TKeyframe &inData) = 0;
+ virtual void SendFirstKeyframeDynamicSet(Qt3DSDMAnimationHandle inAnimation,
+ bool inKeyframeDynamic) = 0;
+};
+
+class IActionCoreSignalProvider : public ISignalItem
+{
+public:
+ virtual TSignalConnectionPtr ConnectTriggerObjectSet(
+ const std::function<void(Qt3DSDMActionHandle, SObjectRefType &)> &inCallback) = 0;
+ virtual TSignalConnectionPtr ConnectTargetObjectSet(
+ const std::function<void(Qt3DSDMActionHandle, SObjectRefType &)> &inCallback) = 0;
+ virtual TSignalConnectionPtr ConnectEventSet(
+ const std::function<void(Qt3DSDMActionHandle, const wstring &)> &inCallback) = 0;
+ virtual TSignalConnectionPtr ConnectHandlerSet(
+ const std::function<void(Qt3DSDMActionHandle, const wstring &)> &inCallback) = 0;
+
+ virtual TSignalConnectionPtr ConnectHandlerArgumentAdded(
+ const std::function<void(Qt3DSDMActionHandle, Qt3DSDMHandlerArgHandle, const TCharStr &,
+ HandlerArgumentType::Value, DataModelDataType::Value)> &inCallback) = 0;
+ virtual TSignalConnectionPtr ConnectHandlerArgumentRemoved(
+ const std::function<void(Qt3DSDMActionHandle, Qt3DSDMHandlerArgHandle, const TCharStr &,
+ HandlerArgumentType::Value, DataModelDataType::Value)> &inCallback) = 0;
+ virtual TSignalConnectionPtr ConnectHandlerArgumentValueSet(
+ const std::function<void(Qt3DSDMHandlerArgHandle, const SValue &)> &inCallback) = 0;
+};
+
+class IActionCoreSignalSender : public ISignalItem
+{
+public:
+ virtual void SendTriggerObjectSet(Qt3DSDMActionHandle inAction,
+ SObjectRefType &inTriggerObject) = 0;
+ virtual void SendTargetObjectSet(Qt3DSDMActionHandle inAction,
+ SObjectRefType &inTargetObject) = 0;
+ virtual void SendEventSet(Qt3DSDMActionHandle inAction, const wstring &inEventHandle) = 0;
+ virtual void SendHandlerSet(Qt3DSDMActionHandle inAction, const wstring &inActionName) = 0;
+
+ virtual void SendHandlerArgumentAdded(Qt3DSDMActionHandle inAction,
+ Qt3DSDMHandlerArgHandle inHandlerArgument,
+ const TCharStr &inName, HandlerArgumentType::Value inArgType,
+ DataModelDataType::Value inValueType) = 0;
+ virtual void SendHandlerArgumentRemoved(Qt3DSDMActionHandle inAction,
+ Qt3DSDMHandlerArgHandle inHandlerArgument,
+ const TCharStr &inName, HandlerArgumentType::Value inArgType,
+ DataModelDataType::Value inValueType) = 0;
+ virtual void SendHandlerArgumentValueSet(Qt3DSDMHandlerArgHandle inHandlerArgument,
+ const SValue &inValue) = 0;
+};
+
+class IActionSystemSignalProvider : public ISignalItem
+{
+public:
+ virtual TSignalConnectionPtr ConnectActionCreated(
+ const std::function<void(Qt3DSDMActionHandle, Qt3DSDMSlideHandle, Qt3DSDMInstanceHandle)>
+ &inCallback) = 0;
+ virtual TSignalConnectionPtr ConnectActionDeleted(
+ const std::function<void(Qt3DSDMActionHandle, Qt3DSDMSlideHandle, Qt3DSDMInstanceHandle)>
+ &inCallback) = 0;
+};
+
+class IActionSystemSignalSender : public ISignalItem
+{
+public:
+ virtual void SendActionCreated(Qt3DSDMActionHandle inAction, Qt3DSDMSlideHandle inSlide,
+ Qt3DSDMInstanceHandle inOwner) = 0;
+ virtual void SendActionDeleted(Qt3DSDMActionHandle inAction, Qt3DSDMSlideHandle inSlide,
+ Qt3DSDMInstanceHandle inOwner) = 0;
+};
+
+class ICustomPropCoreSignalProvider : public ISignalItem
+{
+public:
+ virtual TSignalConnectionPtr ConnectCustomPropertyCreated(
+ const std::function<void(Qt3DSDMPropertyHandle, Qt3DSDMInstanceHandle)> &inCallback) = 0;
+ virtual TSignalConnectionPtr ConnectCustomPropertyDeleted(
+ const std::function<void(Qt3DSDMPropertyHandle, Qt3DSDMInstanceHandle)> &inCallback) = 0;
+ virtual TSignalConnectionPtr ConnectCustomPropertyModified(
+ const std::function<void(Qt3DSDMPropertyHandle)> &inCallback) = 0;
+
+ virtual TSignalConnectionPtr ConnectCustomEventCreated(
+ const std::function<void(Qt3DSDMEventHandle, Qt3DSDMInstanceHandle)> &inCallback) = 0;
+ virtual TSignalConnectionPtr ConnectCustomEventDeleted(
+ const std::function<void(Qt3DSDMEventHandle, Qt3DSDMInstanceHandle)> &inCallback) = 0;
+ virtual TSignalConnectionPtr
+ ConnectCustomEventModified(const std::function<void(Qt3DSDMEventHandle)> &inCallback) = 0;
+
+ virtual TSignalConnectionPtr ConnectCustomHandlerCreated(
+ const std::function<void(Qt3DSDMHandlerHandle, Qt3DSDMInstanceHandle)> &inCallback) = 0;
+ virtual TSignalConnectionPtr ConnectCustomHandlerDeleted(
+ const std::function<void(Qt3DSDMHandlerHandle, Qt3DSDMInstanceHandle)> &inCallback) = 0;
+ virtual TSignalConnectionPtr
+ ConnectCustomHandlerModified(const std::function<void(Qt3DSDMHandlerHandle)> &inCallback) = 0;
+
+ virtual TSignalConnectionPtr ConnectCustomHandlerParamCreated(
+ const std::function<void(Qt3DSDMHandlerParamHandle, Qt3DSDMHandlerHandle)> &inCallback) = 0;
+ virtual TSignalConnectionPtr ConnectCustomHandlerParamDeleted(
+ const std::function<void(Qt3DSDMHandlerParamHandle, Qt3DSDMHandlerHandle)> &inCallback) = 0;
+ virtual TSignalConnectionPtr ConnectCustomHandlerParamModified(
+ const std::function<void(Qt3DSDMHandlerParamHandle)> &inCallback) = 0;
+
+ virtual TSignalConnectionPtr ConnectCustomReferencesModified(
+ const std::function<void(Qt3DSDMInstanceHandle, const TCharStr &)> &inCallback) = 0;
+};
+
+class ICustomPropCoreSignalSender : public ISignalItem
+{
+public:
+ virtual void SendCustomPropertyCreated(Qt3DSDMPropertyHandle inProp,
+ Qt3DSDMInstanceHandle inOwner) = 0;
+ virtual void SendCustomPropertyDeleted(Qt3DSDMPropertyHandle inProp,
+ Qt3DSDMInstanceHandle inOwner) = 0;
+ virtual void SendCustomPropertyModified(Qt3DSDMPropertyHandle inProp) = 0;
+
+ virtual void SendCustomEventCreated(Qt3DSDMEventHandle inEvent,
+ Qt3DSDMInstanceHandle inOwner) = 0;
+ virtual void SendCustomEventDeleted(Qt3DSDMEventHandle inEvent,
+ Qt3DSDMInstanceHandle inOwner) = 0;
+ virtual void SendCustomEventModified(Qt3DSDMEventHandle inEvent) = 0;
+
+ virtual void SendCustomHandlerCreated(Qt3DSDMHandlerHandle inHandler,
+ Qt3DSDMInstanceHandle inOwner) = 0;
+ virtual void SendCustomHandlerDeleted(Qt3DSDMHandlerHandle inHandler,
+ Qt3DSDMInstanceHandle inOwner) = 0;
+ virtual void SendCustomHandlerModified(Qt3DSDMHandlerHandle inHandler) = 0;
+
+ virtual void SendCustomHandlerParamCreated(Qt3DSDMHandlerParamHandle inParameter,
+ Qt3DSDMHandlerHandle inHandler) = 0;
+ virtual void SendCustomHandlerParamDeleted(Qt3DSDMHandlerParamHandle inParameter,
+ Qt3DSDMHandlerHandle inHandler) = 0;
+ virtual void SendCustomHandlerParamModified(Qt3DSDMHandlerParamHandle inParameter) = 0;
+
+ virtual void SendCustomReferencesModified(Qt3DSDMInstanceHandle inOwner,
+ const TCharStr &inString) = 0;
+};
+
+class ISlideSystemSignalProvider : public ISignalItem
+{
+public:
+ virtual TSignalConnectionPtr
+ ConnectMasterCreated(const std::function<void(Qt3DSDMSlideHandle)> &inCallback) = 0;
+ virtual TSignalConnectionPtr
+ ConnectMasterDeleted(const std::function<void(Qt3DSDMSlideHandle)> &inCallback) = 0;
+ virtual TSignalConnectionPtr ConnectSlideCreated(
+ const std::function<void(Qt3DSDMSlideHandle, int, Qt3DSDMSlideHandle)> &inCallback) = 0;
+ virtual TSignalConnectionPtr ConnectSlideDeleted(
+ const std::function<void(Qt3DSDMSlideHandle, int, Qt3DSDMSlideHandle)> &inCallback) = 0;
+ virtual TSignalConnectionPtr ConnectSlideRearranged(
+ const std::function<void(Qt3DSDMSlideHandle, int, int)> &inCallback) = 0;
+ virtual TSignalConnectionPtr ConnectInstanceAssociated(
+ const std::function<void(Qt3DSDMSlideHandle, Qt3DSDMInstanceHandle)> &inCallback) = 0;
+ virtual TSignalConnectionPtr ConnectInstanceDissociated(
+ const std::function<void(Qt3DSDMSlideHandle, Qt3DSDMInstanceHandle)> &inCallback) = 0;
+ virtual TSignalConnectionPtr ConnectPropertyLinked(
+ const std::function<void(Qt3DSDMSlideHandle, Qt3DSDMInstanceHandle, Qt3DSDMPropertyHandle)>
+ &inCallback) = 0;
+ virtual TSignalConnectionPtr ConnectPropertyUnlinked(
+ const std::function<void(Qt3DSDMSlideHandle, Qt3DSDMInstanceHandle, Qt3DSDMPropertyHandle)>
+ &inCallback) = 0;
+ virtual TSignalConnectionPtr ConnectActiveSlide(
+ const std::function<void(Qt3DSDMSlideHandle, int, Qt3DSDMSlideHandle, Qt3DSDMSlideHandle)>
+ &inCallback) = 0;
+};
+
+class ISlideSystemSignalSender : public ISignalItem
+{
+public:
+ virtual void SendMasterCreated(Qt3DSDMSlideHandle inMaster) = 0;
+ virtual void SendMasterDeleted(Qt3DSDMSlideHandle inMaster) = 0;
+ virtual void SendSlideCreated(Qt3DSDMSlideHandle inMaster, int inIndex,
+ Qt3DSDMSlideHandle inSlide) = 0;
+ virtual void SendSlideDeleted(Qt3DSDMSlideHandle inMaster, int inIndex,
+ Qt3DSDMSlideHandle inSlide) = 0;
+ virtual void SendSlideRearranged(Qt3DSDMSlideHandle inMaster, int inOldIndex,
+ int inNewIndex) = 0;
+ virtual void SendInstanceAssociated(Qt3DSDMSlideHandle inMaster,
+ Qt3DSDMInstanceHandle inInstance) = 0;
+ virtual void SendInstanceDissociated(Qt3DSDMSlideHandle inMaster,
+ Qt3DSDMInstanceHandle inInstance) = 0;
+ virtual void SendPropertyLinked(Qt3DSDMSlideHandle inMaster, Qt3DSDMInstanceHandle inInstance,
+ Qt3DSDMPropertyHandle inProperty) = 0;
+ virtual void SendPropertyUnlinked(Qt3DSDMSlideHandle inMaster, Qt3DSDMInstanceHandle inInstance,
+ Qt3DSDMPropertyHandle inProperty) = 0;
+ virtual void SendActiveSlide(Qt3DSDMSlideHandle inMaster, int inIndex,
+ Qt3DSDMSlideHandle inOldSlide, Qt3DSDMSlideHandle inNewSlide) = 0;
+};
+
+class IStudioFullSystemSignalProvider : public ISignalItem
+{
+public:
+ virtual TSignalConnectionPtr
+ ConnectSlideCreated(const std::function<void(Qt3DSDMSlideHandle)> &inCallback) = 0;
+ virtual TSignalConnectionPtr
+ ConnectSlideDeleted(const std::function<void(Qt3DSDMSlideHandle)> &inCallback) = 0;
+ virtual TSignalConnectionPtr ConnectSlideRearranged(
+ const std::function<void(Qt3DSDMSlideHandle, int, int)> &inCallback) = 0;
+ virtual TSignalConnectionPtr
+ ConnectBeginComponentSeconds(const std::function<void(Qt3DSDMSlideHandle)> &inCallback) = 0;
+ virtual TSignalConnectionPtr
+ ConnectComponentSeconds(const std::function<void(Qt3DSDMSlideHandle)> &inCallback) = 0;
+ virtual TSignalConnectionPtr ConnectPropertyLinked(
+ const std::function<void(Qt3DSDMSlideHandle, Qt3DSDMInstanceHandle, Qt3DSDMPropertyHandle)>
+ &inCallback) = 0;
+ virtual TSignalConnectionPtr ConnectPropertyUnlinked(
+ const std::function<void(Qt3DSDMSlideHandle, Qt3DSDMInstanceHandle, Qt3DSDMPropertyHandle)>
+ &inCallback) = 0;
+ virtual TSignalConnectionPtr ConnectActiveSlide(
+ const std::function<void(Qt3DSDMSlideHandle, int, Qt3DSDMSlideHandle)> &inCallback) = 0;
+
+ virtual TSignalConnectionPtr
+ ConnectInstanceCreated(const std::function<void(Qt3DSDMInstanceHandle)> &inCallback) = 0;
+ virtual TSignalConnectionPtr
+ ConnectInstanceDeleted(const std::function<void(Qt3DSDMInstanceHandle)> &inCallback) = 0;
+
+ virtual TSignalConnectionPtr
+ ConnectAnimationCreated(const std::function<void(Qt3DSDMAnimationHandle, Qt3DSDMInstanceHandle,
+ Qt3DSDMPropertyHandle)> &inCallback) = 0;
+ virtual TSignalConnectionPtr
+ ConnectAnimationDeleted(const std::function<void(Qt3DSDMAnimationHandle, Qt3DSDMInstanceHandle,
+ Qt3DSDMPropertyHandle)> &inCallback) = 0;
+ virtual TSignalConnectionPtr ConnectKeyframeInserted(
+ const std::function<void(Qt3DSDMAnimationHandle, Qt3DSDMKeyframeHandle)> &inCallback) = 0;
+ virtual TSignalConnectionPtr ConnectKeyframeErased(
+ const std::function<void(Qt3DSDMAnimationHandle, Qt3DSDMKeyframeHandle)> &inCallback) = 0;
+ virtual TSignalConnectionPtr
+ ConnectKeyframeUpdated(const std::function<void(Qt3DSDMKeyframeHandle)> &inCallback) = 0;
+ virtual TSignalConnectionPtr ConnectFirstKeyframeDynamicSet(
+ const std::function<void(Qt3DSDMAnimationHandle, bool)> &inCallback) = 0;
+
+ virtual TSignalConnectionPtr ConnectInstancePropertyValue(
+ const std::function<void(Qt3DSDMInstanceHandle, Qt3DSDMPropertyHandle)> &inCallback) = 0;
+
+ virtual TSignalConnectionPtr ConnectActionCreated(
+ const std::function<void(Qt3DSDMActionHandle, Qt3DSDMSlideHandle, Qt3DSDMInstanceHandle)>
+ &inCallback) = 0;
+ virtual TSignalConnectionPtr ConnectActionDeleted(
+ const std::function<void(Qt3DSDMActionHandle, Qt3DSDMSlideHandle, Qt3DSDMInstanceHandle)>
+ &inCallback) = 0;
+ virtual TSignalConnectionPtr
+ ConnectTriggerObjectSet(const std::function<void(Qt3DSDMActionHandle)> &inCallback) = 0;
+ virtual TSignalConnectionPtr
+ ConnectTargetObjectSet(const std::function<void(Qt3DSDMActionHandle)> &inCallback) = 0;
+ virtual TSignalConnectionPtr
+ ConnectEventSet(const std::function<void(Qt3DSDMActionHandle)> &inCallback) = 0;
+ virtual TSignalConnectionPtr
+ ConnectHandlerSet(const std::function<void(Qt3DSDMActionHandle)> &inCallback) = 0;
+ virtual TSignalConnectionPtr ConnectHandlerArgumentValueSet(
+ const std::function<void(Qt3DSDMHandlerArgHandle)> &inCallback) = 0;
+
+ virtual TSignalConnectionPtr ConnectCustomPropertyCreated(
+ const std::function<void(Qt3DSDMPropertyHandle, Qt3DSDMInstanceHandle)> &inCallback) = 0;
+ virtual TSignalConnectionPtr ConnectCustomPropertyDeleted(
+ const std::function<void(Qt3DSDMPropertyHandle, Qt3DSDMInstanceHandle)> &inCallback) = 0;
+ virtual TSignalConnectionPtr ConnectCustomPropertyModified(
+ const std::function<void(Qt3DSDMPropertyHandle)> &inCallback) = 0;
+ virtual TSignalConnectionPtr ConnectCustomEventCreated(
+ const std::function<void(Qt3DSDMEventHandle, Qt3DSDMInstanceHandle)> &inCallback) = 0;
+ virtual TSignalConnectionPtr ConnectCustomEventDeleted(
+ const std::function<void(Qt3DSDMEventHandle, Qt3DSDMInstanceHandle)> &inCallback) = 0;
+ virtual TSignalConnectionPtr
+ ConnectCustomEventModified(const std::function<void(Qt3DSDMEventHandle)> &inCallback) = 0;
+ virtual TSignalConnectionPtr ConnectCustomHandlerCreated(
+ const std::function<void(Qt3DSDMHandlerHandle, Qt3DSDMInstanceHandle)> &inCallback) = 0;
+ virtual TSignalConnectionPtr ConnectCustomHandlerDeleted(
+ const std::function<void(Qt3DSDMHandlerHandle, Qt3DSDMInstanceHandle)> &inCallback) = 0;
+ virtual TSignalConnectionPtr
+ ConnectCustomHandlerModified(const std::function<void(Qt3DSDMHandlerHandle)> &inCallback) = 0;
+ virtual TSignalConnectionPtr ConnectCustomHandlerParamCreated(
+ const std::function<void(Qt3DSDMHandlerParamHandle, Qt3DSDMHandlerHandle)> &inCallback) = 0;
+ virtual TSignalConnectionPtr ConnectCustomHandlerParamDeleted(
+ const std::function<void(Qt3DSDMHandlerParamHandle, Qt3DSDMHandlerHandle)> &inCallback) = 0;
+ virtual TSignalConnectionPtr ConnectCustomHandlerParamModified(
+ const std::function<void(Qt3DSDMHandlerParamHandle)> &inCallback) = 0;
+ virtual TSignalConnectionPtr ConnectCustomReferencesModified(
+ const std::function<void(Qt3DSDMInstanceHandle, const TCharStr &)> &inCallback) = 0;
+ virtual TSignalConnectionPtr ConnectControlledToggled(
+ const std::function<void(Qt3DSDMInstanceHandle, Qt3DSDMPropertyHandle)> &inCallback) = 0;
+};
+
+class IStudioFullSystemSignalSender : public ISignalItem
+{
+public:
+ virtual void SendSlideCreated(Qt3DSDMSlideHandle inSlide) = 0;
+ virtual void SendSlideDeleted(Qt3DSDMSlideHandle inSlide) = 0;
+ virtual void SendSlideRearranged(Qt3DSDMSlideHandle inMaster, int inOldIndex,
+ int inNewIndex) = 0;
+ virtual void SendComponentSeconds(Qt3DSDMSlideHandle inMaster) = 0;
+ virtual void SendBeginComponentSeconds(Qt3DSDMSlideHandle inMaster) = 0;
+ virtual void SendPropertyLinked(Qt3DSDMSlideHandle inMaster, Qt3DSDMInstanceHandle inInstance,
+ Qt3DSDMPropertyHandle inProperty) = 0;
+ virtual void SendPropertyUnlinked(Qt3DSDMSlideHandle inMaster, Qt3DSDMInstanceHandle inInstance,
+ Qt3DSDMPropertyHandle inProperty) = 0;
+ virtual void SendActiveSlide(Qt3DSDMSlideHandle inMaster, int inIndex,
+ Qt3DSDMSlideHandle inSlide) = 0;
+
+ virtual void SendInstanceCreated(Qt3DSDMInstanceHandle inInstance) = 0;
+ virtual void SendInstanceDeleted(Qt3DSDMInstanceHandle inInstance) = 0;
+
+ virtual void SendAnimationCreated(Qt3DSDMAnimationHandle inAnimation,
+ Qt3DSDMInstanceHandle inInstance,
+ Qt3DSDMPropertyHandle inProperty) = 0;
+ virtual void SendAnimationDeleted(Qt3DSDMAnimationHandle inAnimation,
+ Qt3DSDMInstanceHandle inInstance,
+ Qt3DSDMPropertyHandle inProperty) = 0;
+ virtual void SendKeyframeInserted(Qt3DSDMAnimationHandle inAnimation,
+ Qt3DSDMKeyframeHandle inKeyframe) = 0;
+ virtual void SendKeyframeErased(Qt3DSDMAnimationHandle inAnimation,
+ Qt3DSDMKeyframeHandle inKeyframe) = 0;
+ virtual void SendKeyframeUpdated(Qt3DSDMKeyframeHandle inKeyframe) = 0;
+ virtual void SendConnectFirstKeyframeDynamicSet(Qt3DSDMAnimationHandle inAnimation,
+ bool inDynamic) = 0;
+
+ virtual void SendInstancePropertyValue(Qt3DSDMInstanceHandle inInstance,
+ Qt3DSDMPropertyHandle inProperty) = 0;
+
+ virtual void SendActionCreated(Qt3DSDMActionHandle inAction, Qt3DSDMSlideHandle inSlide,
+ Qt3DSDMInstanceHandle inOwner) = 0;
+ virtual void SendActionDeleted(Qt3DSDMActionHandle inAction, Qt3DSDMSlideHandle inSlide,
+ Qt3DSDMInstanceHandle inOwner) = 0;
+ virtual void SendTriggerObjectSet(Qt3DSDMActionHandle inAction) = 0;
+ virtual void SendTargetObjectSet(Qt3DSDMActionHandle inAction) = 0;
+ virtual void SendEventSet(Qt3DSDMActionHandle inAction) = 0;
+ virtual void SendHandlerSet(Qt3DSDMActionHandle inAction) = 0;
+ virtual void SendHandlerArgumentValueSet(Qt3DSDMHandlerArgHandle inHandlerArgument) = 0;
+
+ virtual void SendCustomPropertyCreated(Qt3DSDMPropertyHandle inProp,
+ Qt3DSDMInstanceHandle inOwner) = 0;
+ virtual void SendCustomPropertyDeleted(Qt3DSDMPropertyHandle inProp,
+ Qt3DSDMInstanceHandle inOwner) = 0;
+ virtual void SendCustomPropertyModified(Qt3DSDMPropertyHandle inProp) = 0;
+ virtual void SendCustomEventCreated(Qt3DSDMEventHandle inEvent,
+ Qt3DSDMInstanceHandle inOwner) = 0;
+ virtual void SendCustomEventDeleted(Qt3DSDMEventHandle inEvent,
+ Qt3DSDMInstanceHandle inOwner) = 0;
+ virtual void SendCustomEventModified(Qt3DSDMEventHandle inEvent) = 0;
+ virtual void SendCustomHandlerCreated(Qt3DSDMHandlerHandle inHandler,
+ Qt3DSDMInstanceHandle inOwner) = 0;
+ virtual void SendCustomHandlerDeleted(Qt3DSDMHandlerHandle inHandler,
+ Qt3DSDMInstanceHandle inOwner) = 0;
+ virtual void SendCustomHandlerModified(Qt3DSDMHandlerHandle inHandler) = 0;
+ virtual void SendCustomHandlerParamCreated(Qt3DSDMHandlerParamHandle inParameter,
+ Qt3DSDMHandlerHandle inHandler) = 0;
+ virtual void SendCustomHandlerParamDeleted(Qt3DSDMHandlerParamHandle inParameter,
+ Qt3DSDMHandlerHandle inHandler) = 0;
+ virtual void SendCustomHandlerParamModified(Qt3DSDMHandlerParamHandle inParameter) = 0;
+ virtual void SendCustomReferencesModified(Qt3DSDMInstanceHandle inOwner,
+ const TCharStr &inString) = 0;
+ virtual void SendControlledToggled(Qt3DSDMInstanceHandle inInstance,
+ Qt3DSDMPropertyHandle inProperty) = 0;
+};
+
+// Use this if you want to register for only a specific instance or specific property
+template <typename TTransaction>
+inline void MaybackCallbackInstancePropertyValue(Qt3DSDMInstanceHandle inInstance,
+ Qt3DSDMPropertyHandle inProperty,
+ Qt3DSDMInstanceHandle inDesiredInstance,
+ Qt3DSDMPropertyHandle inDesiredProperty,
+ TTransaction inCallback)
+{
+ if ((!inDesiredInstance.Valid() || (inDesiredInstance == inInstance))
+ && (!inDesiredProperty.Valid() || (inDesiredProperty == inProperty)))
+ inCallback(inInstance, inProperty);
+}
+
+void SetDataModelSignalsEnabled(bool inEnabled);
+// Defaults to true
+bool AreDataModelSignalsEnabled();
+}
+
+#endif
diff --git a/src/dm/systems/Qt3DSDMSlideCore.h b/src/dm/systems/Qt3DSDMSlideCore.h
new file mode 100644
index 0000000..8216b01
--- /dev/null
+++ b/src/dm/systems/Qt3DSDMSlideCore.h
@@ -0,0 +1,239 @@
+/****************************************************************************
+**
+** 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 QT3DSDM_SLIDE_CORE_H
+#define QT3DSDM_SLIDE_CORE_H
+#include "Qt3DSDMHandles.h"
+#include "Qt3DSDMDataTypes.h"
+#include "HandleSystemBase.h"
+#include "Qt3DSDMStringTable.h"
+#include "Qt3DSDMDataCore.h"
+
+namespace qt3dsdm {
+typedef std::pair<Qt3DSDMInstanceHandle, Qt3DSDMPropertyHandle> TInstancePropertyPair;
+typedef std::vector<TInstancePropertyPair> TInstancePropertyPairList;
+
+// instance,property,value
+typedef std::tuple<Qt3DSDMInstanceHandle, Qt3DSDMPropertyHandle, SValue> TSlideEntry;
+typedef std::vector<TSlideEntry> TSlideEntryList;
+
+class ISlideCore : public IHandleBase
+{
+public:
+ virtual ~ISlideCore() {}
+ virtual TStringTablePtr GetStringTablePtr() const = 0;
+ virtual IStringTable &GetStringTable() const = 0;
+ //===============================================================
+ // Slide lifetime management
+ //===============================================================
+ /**
+ * Create a new slide. Slides must have an instance allocated for them.
+ */
+ virtual Qt3DSDMSlideHandle CreateSlide(Qt3DSDMInstanceHandle inInstance) = 0;
+ /**
+ * Return the instance that was allocated for this slide.
+ */
+ virtual Qt3DSDMInstanceHandle GetSlideInstance(Qt3DSDMSlideHandle inSlide) const = 0;
+ /**
+ * Reverse lookup into the slide system so you can match slides to instances.
+ */
+ virtual Qt3DSDMSlideHandle GetSlideByInstance(Qt3DSDMInstanceHandle inSlide) const = 0;
+ /**
+ * Delete a given slide. This recursively deletes all children. All associated instances
+ * are returned in the outInstances list so the caller can further delete them.
+ * The deleted object is removed from the parent's list of children. Child objects are
+ * also deleted.
+ */
+ virtual void DeleteSlide(Qt3DSDMSlideHandle inSlide, TInstanceHandleList &outInstances) = 0;
+ /**
+ * Return all of the slides in the core.
+ */
+ virtual void GetSlides(TSlideHandleList &outSlides) const = 0;
+
+ virtual float GetSlideTime(Qt3DSDMSlideHandle inSlide) const = 0;
+
+ virtual void SetSlideTime(Qt3DSDMSlideHandle inSlide, float inNewTime) = 0;
+
+ //===============================================================
+ // Slide derivation
+ //===============================================================
+ /**
+ * Derive a slide from another slide. This simply provides an alternate path for property
+ *lookup
+ * if it isn't found on this slide. OK for parent to be an invalid handle. It is also fine
+ * for the slide to have a valid parent; all involved parties are notified and updated.
+ */
+ virtual void DeriveSlide(Qt3DSDMSlideHandle inSlide, Qt3DSDMSlideHandle inParent,
+ int inIndex = -1) = 0;
+ /**
+ * Return the parent slide for this slide. Invalid handle if no parent.
+ */
+ virtual Qt3DSDMSlideHandle GetParentSlide(Qt3DSDMSlideHandle inSlide) const = 0;
+ /**
+ * Return a list of derived slides for this slide.
+ */
+ virtual void GetChildSlides(Qt3DSDMSlideHandle inSlide, TSlideHandleList &outChildren) const = 0;
+
+ /**
+ * Return the index of this child. Exception if child isn't found
+ */
+ virtual int GetChildIndex(Qt3DSDMSlideHandle inParent, Qt3DSDMSlideHandle inChild) const = 0;
+ //===============================================================
+
+ //===============================================================
+ // Instance Property Access
+ //===============================================================
+ /**
+ * Get this property from this instance in this slide. Includes lookup into any parent slides.
+ */
+ virtual bool GetInstancePropertyValue(Qt3DSDMSlideHandle inSlide,
+ Qt3DSDMInstanceHandle inInstance,
+ Qt3DSDMPropertyHandle inProperty,
+ SValue &outValue) const = 0;
+
+ /**
+ * Set this property. If this slide doesn't already contain an entry
+ *(PushPropertyValueToChildren)
+ * then this will attempt to set it on the parent slide. If it does not have a parent slide or
+ *if
+ * it already has a property entry then it sets the value locally.
+ */
+ virtual void SetInstancePropertyValue(Qt3DSDMSlideHandle inSlide,
+ Qt3DSDMInstanceHandle inInstance,
+ Qt3DSDMPropertyHandle inProperty,
+ const SValue &inValue) = 0;
+
+ /**
+ * Set this property on this slide; do not try to set on parent slide under any circumstances.
+ *Always adds entry to this slide.
+ */
+ virtual void ForceSetInstancePropertyValue(Qt3DSDMSlideHandle inSlide,
+ Qt3DSDMInstanceHandle inInstance,
+ Qt3DSDMPropertyHandle inProperty,
+ const SValue &inValue) = 0;
+
+ /**
+ * Set a property value on an instance on all slides.
+ */
+ virtual void forceSetInstancePropertyValueOnAllSlides(Qt3DSDMInstanceHandle inInstance,
+ Qt3DSDMPropertyHandle inProperty,
+ const SValue &inValue) = 0;
+
+ /**
+ * Return the value for this property if it exists on this slide.
+ */
+ virtual bool GetSpecificInstancePropertyValue(Qt3DSDMSlideHandle inSlide,
+ Qt3DSDMInstanceHandle inInstance,
+ Qt3DSDMPropertyHandle inProperty,
+ SValue &outValue) const = 0;
+
+ /**
+ * Return all of the properties for this instance stored on this slide.
+ */
+ virtual void GetSpecificInstancePropertyValues(Qt3DSDMSlideHandle inSlide,
+ Qt3DSDMInstanceHandle inInstance,
+ TPropertyHandleValuePairList &outValues) = 0;
+
+ /**
+ * Get all of the property entries for the slide.
+ */
+ virtual void GetSlidePropertyEntries(Qt3DSDMSlideHandle inSlide,
+ TSlideEntryList &outEntries) const = 0;
+
+ /**
+ * Set this property value on all my child slides.
+ */
+ virtual void PushPropertyValueToChildren(Qt3DSDMSlideHandle inParent,
+ Qt3DSDMInstanceHandle inInstance,
+ Qt3DSDMPropertyHandle inProperty,
+ const SValue &inValue) = 0;
+
+ /**
+ * If any property entries in slide1 intersect (have matching instance and property handles)
+ *with slide 2,
+ * add said property entry from slide1 to outEntries;
+ */
+ virtual void GetIntersectingProperties(Qt3DSDMSlideHandle inSlide1, Qt3DSDMSlideHandle inSlide2,
+ TSlideEntryList &outEntries) const = 0;
+
+ /**
+ * Take the intersection of the properties of slide1 and slide2 and push values from slide1 to
+ *destination.
+ * Used for new slide operations.
+ */
+ virtual void PushIntersectingProperties(Qt3DSDMSlideHandle inSlide1, Qt3DSDMSlideHandle inSlide2,
+ Qt3DSDMSlideHandle inDestination) = 0;
+
+ /**
+ * Ensure the children of this parent item do not contain entries for a given property.
+ */
+ virtual void ClearChildrenPropertyValues(Qt3DSDMSlideHandle inParent,
+ Qt3DSDMInstanceHandle inHandle,
+ Qt3DSDMPropertyHandle inProperty) = 0;
+
+ /**
+ * Delete all property entries related to this instance.
+ */
+ virtual void DeleteAllInstanceEntries(Qt3DSDMInstanceHandle inHandle) = 0;
+
+ /**
+ * Delete all of the property entries related to this property
+ */
+ virtual void DeleteAllPropertyEntries(Qt3DSDMPropertyHandle inHandle) = 0;
+
+ /**
+ * Delete all property entries that have an instance in the instances list *and*
+ * a property in the properties list.
+ */
+ virtual void DeleteAllInstancePropertyEntries(const TInstanceHandleList &inInstances,
+ const TPropertyHandleList &inProperties) = 0;
+
+ /**
+ * Does this slide contain this property?
+ */
+ virtual bool ContainsProperty(Qt3DSDMSlideHandle inSlide, Qt3DSDMInstanceHandle inHandle,
+ Qt3DSDMPropertyHandle inProperty) const = 0;
+
+ /**
+ * Copy the properties from the source slide and source instance to the destination slide and
+ *destination
+ * instance.
+ */
+ virtual void CopyProperties(Qt3DSDMSlideHandle inSourceSlide,
+ Qt3DSDMInstanceHandle inSourceInstance,
+ Qt3DSDMSlideHandle inDestSlide,
+ Qt3DSDMInstanceHandle inDestInstance) = 0;
+
+ virtual bool IsSlide(Qt3DSDMSlideHandle inSlide) const = 0;
+};
+
+typedef std::shared_ptr<ISlideCore> TSlideCorePtr;
+}
+
+#endif
diff --git a/src/dm/systems/Qt3DSDMSlideGraphCore.h b/src/dm/systems/Qt3DSDMSlideGraphCore.h
new file mode 100644
index 0000000..34c04e1
--- /dev/null
+++ b/src/dm/systems/Qt3DSDMSlideGraphCore.h
@@ -0,0 +1,89 @@
+/****************************************************************************
+**
+** 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 QT3DSDM_SLIDE_GRAPH_CORE_H
+#define QT3DSDM_SLIDE_GRAPH_CORE_H
+
+#include "Qt3DSDMHandles.h"
+#include "HandleSystemBase.h"
+
+namespace qt3dsdm {
+
+typedef std::pair<Qt3DSDMSlideHandle, Qt3DSDMInstanceHandle> TSlideInstancePair;
+typedef std::vector<TSlideInstancePair> TSlideInstancePairList;
+typedef std::pair<Qt3DSDMSlideGraphHandle, Qt3DSDMSlideHandle> TGraphSlidePair;
+
+/**
+ * Binding instances to slide graphs.
+ */
+class ISlideGraphCore : public IHandleBase
+{
+public:
+ virtual ~ISlideGraphCore() {}
+
+ /**
+ * 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.
+ */
+ virtual Qt3DSDMSlideGraphHandle CreateSlideGraph(Qt3DSDMSlideHandle inRoot) = 0;
+ virtual Qt3DSDMSlideHandle GetGraphRoot(Qt3DSDMSlideGraphHandle inGraph) const = 0;
+ virtual Qt3DSDMSlideGraphHandle GetSlideGraph(Qt3DSDMSlideHandle inSlide) const = 0;
+ virtual void GetSlideGraphs(TSlideGraphHandleList &outGraphs) const = 0;
+ virtual void DeleteSlideGraph(Qt3DSDMSlideGraphHandle inHandle) = 0;
+
+ /**
+ * 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.
+ */
+ virtual void AssociateInstance(Qt3DSDMSlideGraphHandle inSlideGraph, Qt3DSDMSlideHandle inSlide,
+ Qt3DSDMInstanceHandle inInstance) = 0;
+ virtual void GetAssociatedInstances(Qt3DSDMSlideGraphHandle inSlideGraph,
+ TSlideInstancePairList &outAssociations) const = 0;
+ virtual TGraphSlidePair GetAssociatedGraph(Qt3DSDMInstanceHandle inInstance) const = 0;
+ virtual void DissociateInstance(Qt3DSDMInstanceHandle inInstance) = 0;
+
+ /**
+ * All graphs always have an active slide. This is assumed to be the root right off the bat.
+ */
+ virtual void SetGraphActiveSlide(Qt3DSDMSlideGraphHandle inGraph, Qt3DSDMSlideHandle inSlide) = 0;
+ virtual Qt3DSDMSlideHandle GetGraphActiveSlide(Qt3DSDMSlideGraphHandle inGraph) const = 0;
+};
+
+typedef std::shared_ptr<ISlideGraphCore> TSlideGraphCorePtr;
+}
+
+#endif \ No newline at end of file
diff --git a/src/dm/systems/Qt3DSDMSlides.h b/src/dm/systems/Qt3DSDMSlides.h
new file mode 100644
index 0000000..aa7c27c
--- /dev/null
+++ b/src/dm/systems/Qt3DSDMSlides.h
@@ -0,0 +1,202 @@
+/****************************************************************************
+**
+** 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 QT3DSDM_SLIDES_H
+#define QT3DSDM_SLIDES_H
+#include "Qt3DSDMHandles.h"
+#include "Qt3DSDMSlideCore.h"
+
+namespace qt3dsdm {
+/**
+ * Some properties point to instances which act like extended properties.
+ * An example of this would be the images on materials. If a material has an
+ * image in one of its slots, that image should be duplicated upon property unlink
+ * and deleted upon property link. It (and its animations) should be duplicated upon
+ * create slide and deleted upon slide destruction such that the concept that the image
+ * is really a property on the material stays sound.
+ */
+class IPropertyInstanceInfo
+{
+public:
+ virtual ~IPropertyInstanceInfo() {}
+
+ /**
+ * Return the instance that relates to this property
+ */
+ virtual Qt3DSDMInstanceHandle GetInstanceForProperty(const SValue &inValue) = 0;
+
+ /**
+ * Duplicate this instance and whichever properties and animations you desire,
+ * returning a new data model value that will be set on the newly created property.
+ * Don't forget to associate the instance with a the dest slide. I doubt things
+ * will work correctly if you do not.
+ */
+ virtual SValue CreateInstanceForProperty(Qt3DSDMSlideHandle inSourceSlide,
+ Qt3DSDMSlideHandle inDestSlide,
+ Qt3DSDMInstanceHandle inInstance) = 0;
+};
+
+typedef std::shared_ptr<IPropertyInstanceInfo> TPropertyInstanceInfoPtr;
+
+struct SInstanceSlideInformation
+{
+ // The slide associated with the instance
+ Qt3DSDMSlideHandle m_AssociatedSlide;
+ // The master slide of the component.
+ Qt3DSDMSlideHandle m_MasterSlide;
+ // The active slide of the component.
+ Qt3DSDMSlideHandle m_ActiveSlide;
+ // The current milliseconds of the active slide on the component.
+ long m_ComponentMilliseconds;
+
+ SInstanceSlideInformation()
+ : m_ComponentMilliseconds(0)
+ {
+ }
+ SInstanceSlideInformation(Qt3DSDMSlideHandle inAssoc, Qt3DSDMSlideHandle inMaster,
+ Qt3DSDMSlideHandle inActive, long inMilliseconds)
+ : m_AssociatedSlide(inAssoc)
+ , m_MasterSlide(inMaster)
+ , m_ActiveSlide(inActive)
+ , m_ComponentMilliseconds(inMilliseconds)
+ {
+ }
+};
+
+class ISlideSystem
+{
+public:
+ virtual ~ISlideSystem() {}
+ virtual Qt3DSDMSlideHandle CreateMasterSlide() = 0;
+ virtual Qt3DSDMSlideHandle CreateSlide(Qt3DSDMSlideHandle inMaster, int inIndex = -1) = 0;
+ // Duplicate this slide and put it into the master's child lists at index.
+ virtual Qt3DSDMSlideHandle DuplicateSlide(Qt3DSDMSlideHandle inSourceSlide, int inDestIndex) = 0;
+ virtual Qt3DSDMSlideHandle GetMasterSlide(Qt3DSDMSlideHandle inSlide) const = 0;
+ virtual bool IsMasterSlide(Qt3DSDMSlideHandle inSlide) const = 0;
+ virtual Qt3DSDMSlideHandle GetMasterSlideByComponentGuid(SLong4 inGuid) const = 0;
+ // Indexes are 1 based. Index 0 refers to the master slide; you can't delete this.
+ virtual void DeleteSlideByIndex(Qt3DSDMSlideHandle inMaster, size_t inIndex) = 0;
+ virtual void GetSlideReferencedInstances(Qt3DSDMSlideHandle inMaster, size_t inIndex,
+ TInstanceHandleList &outReferencedInstances) = 0;
+ virtual Qt3DSDMSlideHandle GetSlideByIndex(Qt3DSDMSlideHandle inMaster, size_t inIndex) const = 0;
+ virtual void SetActiveSlide(Qt3DSDMSlideHandle inMaster, size_t inIndex) = 0;
+ virtual void RearrangeSlide(Qt3DSDMSlideHandle inMaster, size_t inOldIndex,
+ size_t inNewIndex) = 0;
+ /**
+ * Set the current component time. This object will figure out the component from the slide.
+ */
+ virtual void SetComponentSeconds(Qt3DSDMSlideHandle inSlide, float inSeconds) = 0;
+ /**
+ * Return the current time of the component
+ */
+ virtual float GetComponentSeconds(Qt3DSDMSlideHandle inSlide) const = 0;
+ virtual long GetComponentSecondsLong(Qt3DSDMSlideHandle inSlide) const = 0;
+ virtual long GetComponentSecondsLong(Qt3DSDMInstanceHandle inInstance) const = 0;
+
+ // The fastest way possible, get all of the slide information for this instance.
+ virtual SInstanceSlideInformation
+ GetInstanceSlideInformation(Qt3DSDMInstanceHandle inInstance) const = 0;
+ /**
+ * Slide count includes the master slide;
+ */
+ virtual size_t GetSlideCount(Qt3DSDMSlideHandle inMaster) const = 0;
+ /**
+ * Use the instance for storing information such as name, or the GUID of the object
+ * this slide links to.
+ */
+ virtual Qt3DSDMInstanceHandle GetSlideInstance(Qt3DSDMSlideHandle inSlide) const = 0;
+ /**
+ * Reverse lookup into the slide system so you can match slides to instances.
+ */
+ virtual Qt3DSDMSlideHandle GetSlideByInstance(Qt3DSDMInstanceHandle inInstance) const = 0;
+ /**
+ * Slide may be either a master slide
+ */
+ virtual void AssociateInstanceWithSlide(Qt3DSDMSlideHandle inSlide,
+ Qt3DSDMInstanceHandle inInstance) = 0;
+ virtual Qt3DSDMSlideHandle GetAssociatedSlide(Qt3DSDMInstanceHandle inInstance) const = 0;
+ virtual void GetAssociatedInstances(
+ Qt3DSDMSlideHandle inMaster,
+ std::vector<std::pair<Qt3DSDMSlideHandle, Qt3DSDMInstanceHandle>> &outAssociations) const = 0;
+ virtual void GetAssociatedInstances(Qt3DSDMSlideHandle inSlide,
+ TInstanceHandleList &outAssociations) const = 0;
+ virtual void LinkProperty(Qt3DSDMInstanceHandle inInstance, Qt3DSDMPropertyHandle inProperty) = 0;
+ virtual void UnlinkProperty(Qt3DSDMInstanceHandle inInstance,
+ Qt3DSDMPropertyHandle inProperty) = 0;
+ virtual bool IsPropertyLinked(Qt3DSDMInstanceHandle inInstance,
+ Qt3DSDMPropertyHandle inProperty) const = 0;
+ virtual bool CanPropertyBeLinked(Qt3DSDMInstanceHandle inInstance,
+ Qt3DSDMPropertyHandle inProperty) const = 0;
+ virtual void GetUnionOfProperties(Qt3DSDMSlideHandle inSlide1, Qt3DSDMSlideHandle inSlide,
+ TInstancePropertyPairList &outProperties) const = 0;
+
+ virtual bool GetSlidePropertyValue(size_t inSlide, Qt3DSDMInstanceHandle inInstance,
+ Qt3DSDMPropertyHandle inProperty, SValue &outValue) = 0;
+
+ virtual void SetActiveSlide(Qt3DSDMSlideHandle inSlide) = 0;
+ virtual Qt3DSDMSlideHandle GetAssociatedSlide(Qt3DSDMInstanceHandle inInstance,
+ Qt3DSDMPropertyHandle inProperty) const = 0;
+
+ virtual bool SlideValid(Qt3DSDMSlideHandle inSlide) const = 0;
+ virtual int GetSlideIndex(Qt3DSDMSlideHandle inSlide) const = 0;
+ virtual int GetActiveSlideIndex(Qt3DSDMSlideHandle inMaster) const = 0;
+ virtual Qt3DSDMSlideHandle GetActiveSlide(Qt3DSDMSlideHandle inMaster) const = 0;
+ virtual Qt3DSDMInstanceHandle GetSlideSelectedInstance(Qt3DSDMSlideHandle inSlide) const = 0;
+ virtual void SetSlideSelectedInstance(Qt3DSDMSlideHandle inSlide,
+ Qt3DSDMInstanceHandle inInstance) = 0;
+
+ virtual Qt3DSDMSlideHandle GetApplicableSlide(Qt3DSDMInstanceHandle inHandle) = 0;
+ virtual Qt3DSDMSlideHandle GetApplicableSlide(Qt3DSDMInstanceHandle inHandle,
+ Qt3DSDMPropertyHandle inProperty) = 0;
+
+ virtual bool GetInstancePropertyValue(Qt3DSDMSlideHandle inSlide,
+ Qt3DSDMInstanceHandle inInstance,
+ Qt3DSDMPropertyHandle inProperty,
+ SValue &outValue) const = 0;
+ virtual bool GetCanonicalInstancePropertyValue(Qt3DSDMInstanceHandle inInstance,
+ Qt3DSDMPropertyHandle inProperty,
+ SValue &outValue) const = 0;
+ virtual void ForceSetInstancePropertyValue(Qt3DSDMSlideHandle inSlide,
+ Qt3DSDMInstanceHandle inInstance,
+ Qt3DSDMPropertyHandle inProperty,
+ const SValue &inValue) = 0;
+
+ /**
+ * Let this object know that this property will sometimes reference another property
+ * and give an outside entity the chance to create new objects and properties when
+ * the property is unlinked and linked.
+ */
+ virtual void RegisterPropertyInstance(Qt3DSDMPropertyHandle inPropertyHandle,
+ TPropertyInstanceInfoPtr inPropertyInfo) = 0;
+};
+
+typedef std::shared_ptr<ISlideSystem> TSlideSystemPtr;
+}
+
+#endif
diff --git a/src/dm/systems/Qt3DSDMStringTable.cpp b/src/dm/systems/Qt3DSDMStringTable.cpp
new file mode 100644
index 0000000..58db71c
--- /dev/null
+++ b/src/dm/systems/Qt3DSDMStringTable.cpp
@@ -0,0 +1,85 @@
+/****************************************************************************
+**
+** 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 "Qt3DSDMStringTable.h"
+#include "foundation/StringTable.h"
+#include "foundation/TrackingAllocator.h"
+
+using namespace qt3dsdm;
+using namespace eastl;
+using namespace qt3ds;
+
+namespace {
+
+struct StringTableImpl : public IStringTable
+{
+ qt3ds::foundation::MallocAllocator m_MallocAllocator;
+ qt3ds::foundation::IStringTable &m_StringTable;
+ StringTableImpl()
+ : m_StringTable(qt3ds::foundation::IStringTable::CreateStringTable(m_MallocAllocator))
+ {
+ m_StringTable.addRef();
+ }
+ StringTableImpl(qt3ds::foundation::IStringTable &inStrTable)
+ : m_StringTable(inStrTable)
+ {
+ m_StringTable.addRef();
+ }
+
+ virtual ~StringTableImpl() { m_StringTable.release(); }
+ const wchar_t *RegisterStr(const wchar_t *inStr) override
+ {
+ return m_StringTable.GetWideStr(inStr);
+ }
+ const char8_t *RegisterStr(const char8_t *inStr) override
+ {
+ return m_StringTable.GetNarrowStr(inStr);
+ }
+ // Get the utf-8 or utf-(sizeof wchar_t) converted strings
+ const wchar_t *GetWideStr(const char8_t *inStr) override
+ {
+ return m_StringTable.GetWideStr(inStr);
+ }
+ const char8_t *GetNarrowStr(const wchar_t *inStr) override
+ {
+ return m_StringTable.GetNarrowStr(inStr);
+ }
+ qt3ds::foundation::IStringTable &GetRenderStringTable() override { return m_StringTable; }
+};
+}
+
+TStringTablePtr IStringTable::CreateStringTable()
+{
+ return std::make_shared<StringTableImpl>();
+}
+
+TStringTablePtr IStringTable::CreateStringTable(qt3ds::foundation::IStringTable &inStrTable)
+{
+ return std::make_shared<StringTableImpl>(std::ref(inStrTable));
+}
diff --git a/src/dm/systems/Qt3DSDMStringTable.h b/src/dm/systems/Qt3DSDMStringTable.h
new file mode 100644
index 0000000..7f1e945
--- /dev/null
+++ b/src/dm/systems/Qt3DSDMStringTable.h
@@ -0,0 +1,71 @@
+/****************************************************************************
+**
+** 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 QT3DS_IMPORT_STRINGTABLE_H
+#define QT3DS_IMPORT_STRINGTABLE_H
+
+#include <string>
+#include <EABase/eabase.h>
+#include "foundation/Qt3DSPreprocessor.h"
+
+namespace qt3ds {
+namespace foundation {
+ class IStringTable;
+}
+}
+
+namespace qt3dsdm {
+
+class QT3DS_AUTOTEST_EXPORT IStringTable
+{
+public:
+ virtual ~IStringTable() {}
+
+ virtual const wchar_t *RegisterStr(const wchar_t *inStr) = 0;
+ virtual const char8_t *RegisterStr(const char8_t *inStr) = 0;
+ // Get the utf-8 or utf-(sizeof wchar_t) converted strings
+ virtual const wchar_t *GetWideStr(const char8_t *inStr) = 0;
+ virtual const char8_t *GetNarrowStr(const wchar_t *inStr) = 0;
+
+ const wchar_t *GetWideStr(const wchar_t *inStr) { return RegisterStr(inStr); }
+ const char8_t *GetNarrowStr(const char8_t *inStr) { return RegisterStr(inStr); }
+
+ const wchar_t *RegisterStr(const std::wstring &inStr) { return RegisterStr(inStr.c_str()); }
+ const char8_t *RegisterStr(const std::string &inStr) { return RegisterStr(inStr.c_str()); }
+
+ virtual qt3ds::foundation::IStringTable &GetRenderStringTable() = 0;
+
+ static std::shared_ptr<IStringTable> CreateStringTable();
+ static std::shared_ptr<IStringTable>
+ CreateStringTable(qt3ds::foundation::IStringTable &inStrTable);
+};
+typedef std::shared_ptr<IStringTable> TStringTablePtr;
+};
+
+#endif
diff --git a/src/dm/systems/Qt3DSDMTestOps.h b/src/dm/systems/Qt3DSDMTestOps.h
new file mode 100644
index 0000000..ac43eaf
--- /dev/null
+++ b/src/dm/systems/Qt3DSDMTestOps.h
@@ -0,0 +1,61 @@
+/****************************************************************************
+**
+** 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 QT3DSDM_OPS_H
+#define QT3DSDM_OPS_H
+
+namespace qt3dsdm {
+inline const TCharStr &GetPropertyName(const IDataCore &inModel, Qt3DSDMPropertyHandle inProperty)
+{
+ return inModel.GetProperty(inProperty).m_Name;
+}
+
+inline bool PropertyNameMatches(const IDataCore &inModel, const TCharStr &inName,
+ Qt3DSDMPropertyHandle inProperty)
+{
+ return inName == GetPropertyName(inModel, inProperty);
+}
+
+inline const Qt3DSDMPropertyHandle
+GetPropertyByName(const IDataCore &inModel, Qt3DSDMInstanceHandle inInstance, const TCharStr &inName)
+{
+ using namespace std;
+ TPropertyHandleList properties;
+ inModel.GetAggregateInstanceProperties(inInstance, properties);
+ TPropertyHandleList::iterator theProp =
+ std::find_if(properties.begin(), properties.end(),
+ std::bind(PropertyNameMatches, std::ref(inModel), inName,
+ std::placeholders::_1));
+ if (theProp != properties.end())
+ return *theProp;
+ return 0;
+}
+}
+
+#endif
diff --git a/src/dm/systems/Qt3DSDMTransactions.h b/src/dm/systems/Qt3DSDMTransactions.h
new file mode 100644
index 0000000..f6ed3da
--- /dev/null
+++ b/src/dm/systems/Qt3DSDMTransactions.h
@@ -0,0 +1,244 @@
+/****************************************************************************
+**
+** 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 QT3DSDM_TRANSACTIONS_H
+#define QT3DSDM_TRANSACTIONS_H
+#include "Qt3DSDMDataTypes.h"
+#include "StandardExtensions.h"
+#include <functional>
+
+namespace qt3dsdm {
+
+/**
+ * Transaction is some small entity that changes data. A transaction consumer is expected to
+ *execute
+ * a list of these either forward on a "redo" command or backwards on an "undo" command.
+ *
+ * Transactions merely change data. There are two other lists on consumers for "do"
+ *notifications
+ * and "undo" notifications. These lists control the events sent out to the UI about what
+ *actually
+ * changed in the model. Note that undo/do notifications may be more clever than simple
+ *send-signal
+ * commands in that they may check if an object is alive or not before sending a notification
+ *and may
+ * decline to send a notification if the target object is not currently alive.
+ *
+ * Currently the undo/redo system first executes all of the transactions and then sends the
+ *appropriate
+ * notifications. This means that when the UI receives any notification, the model is in its
+ *most-updated
+ * state.
+ */
+class ITransaction
+{
+public:
+ const char *m_File;
+ int m_Line;
+
+ ITransaction(const char *inFile, int inLine)
+ : m_File(inFile)
+ , m_Line(inLine)
+ {
+ }
+ virtual ~ITransaction() {}
+ virtual void Do() = 0;
+ virtual void Undo() = 0;
+};
+
+/**
+ * Merging allows us to efficient handle situations where the users are continuously
+ * modifying an object (or set of objects). These are referred to as live-update
+ * scenarios. Dragging an object in the 3d view or dragging keyframes in the timeline
+ * would be an example of live-update scenarios.
+ */
+template <typename TValueType>
+class IMergeableTransaction
+{
+public:
+ virtual ~IMergeableTransaction() {}
+ // Called when a new value has arrived and we would rather update
+ // an existing representation rather than create a new one.
+ virtual void Update(const TValueType &inValue) = 0;
+};
+
+/**
+ * A consumer is an object that records the transaction. This interface keeps the
+ * base producer objects from binding to how the transaction or the notifications
+ * are stored.
+ */
+class ITransactionConsumer
+{
+public:
+ virtual ~ITransactionConsumer() {}
+ virtual void OnTransaction(std::shared_ptr<ITransaction> inTransaction) = 0;
+ // Notifications to be sent for undo/redo These are used to
+ // notify clients that something is different.
+ virtual void OnDoNotification(std::function<void()> inNotification) = 0;
+ virtual void OnUndoNotification(std::function<void()> inNotification) = 0;
+};
+
+///////////////////////////////////////////////////////////////////////////////
+// Implementation of helper objects and functions.
+///////////////////////////////////////////////////////////////////////////////
+
+typedef std::vector<std::function<void()>> TVoidFunctionList;
+
+typedef std::shared_ptr<ITransactionConsumer> TTransactionConsumerPtr;
+
+class ITransactionProducer
+{
+public:
+ virtual ~ITransactionProducer() {}
+ virtual void SetConsumer(TTransactionConsumerPtr inConsumer) = 0;
+};
+
+template <typename TDoTransaction, typename TUndoTransaction>
+class CGenericTransaction : public ITransaction
+{
+ Q_DISABLE_COPY(CGenericTransaction)
+
+ TUndoTransaction m_UndoTransaction;
+ TDoTransaction m_DoTransaction;
+
+public:
+ CGenericTransaction(const char *inFile, int inLine, TDoTransaction inDo,
+ TUndoTransaction inUndo)
+ : ITransaction(inFile, inLine)
+ , m_UndoTransaction(inUndo)
+ , m_DoTransaction(inDo)
+ {
+ }
+ void Do() override { m_DoTransaction(); }
+ void Undo() override { m_UndoTransaction(); }
+};
+
+template <typename TDoTransaction, typename TUndoTransaction>
+ITransaction *DoCreateGenericTransaction(const char *inFile, int inLine, TDoTransaction inDo,
+ TUndoTransaction inUndo)
+{
+ return static_cast<ITransaction *>(
+ new CGenericTransaction<TDoTransaction, TUndoTransaction>(inFile, inLine, inDo, inUndo));
+}
+
+#define CREATE_GENERIC_TRANSACTION(inDo, inUndo) \
+ DoCreateGenericTransaction(__FILE__, __LINE__, inDo, inUndo)
+
+typedef std::shared_ptr<ITransaction> TTransactionPtr;
+typedef std::vector<TTransactionPtr> TTransactionPtrList;
+
+struct CTransactionConsumer : public ITransactionConsumer
+{
+ TTransactionPtrList m_TransactionList;
+ TVoidFunctionList m_DoNotifications;
+ TVoidFunctionList m_UndoNotifications;
+ void OnTransaction(TTransactionPtr inTransaction) override
+ {
+ m_TransactionList.push_back(inTransaction);
+ }
+ void OnDoNotification(std::function<void()> inNotification) override
+ {
+ m_DoNotifications.push_back(inNotification);
+ }
+ void OnUndoNotification(std::function<void()> inNotification) override
+ {
+ m_UndoNotifications.push_back(inNotification);
+ }
+
+ // Merge with another CTransactionConsumer
+ virtual void Merge(const ITransactionConsumer *inConsumer)
+ {
+ const CTransactionConsumer *theConsumer =
+ static_cast<const CTransactionConsumer *>(inConsumer);
+ m_TransactionList.insert(m_TransactionList.begin(), theConsumer->m_TransactionList.begin(),
+ theConsumer->m_TransactionList.end());
+ }
+ void Reset()
+ {
+ m_TransactionList.clear();
+ m_DoNotifications.clear();
+ m_UndoNotifications.clear();
+ }
+};
+
+template <typename TTransactionType>
+inline void RunWithConsumer(TTransactionConsumerPtr inConsumer, TTransactionType inTransaction)
+{
+ if (inConsumer)
+ inTransaction(inConsumer);
+}
+
+template <typename TDoTransaction, typename TUndoTransaction>
+inline void CreateGenericTransactionWithConsumer(const char *inFile, int inLine,
+ TTransactionConsumerPtr inConsumer,
+ TDoTransaction inDoTransaction,
+ TUndoTransaction inUndoTransaction)
+{
+ if (inConsumer)
+ inConsumer->OnTransaction(TTransactionPtr(
+ DoCreateGenericTransaction(inFile, inLine, inDoTransaction, inUndoTransaction)));
+}
+
+template <typename TItemType>
+inline void DoSetConsumer(TTransactionConsumerPtr inConsumer,
+ std::shared_ptr<TItemType> inTypePtr)
+{
+ ITransactionProducer *theProducer = dynamic_cast<ITransactionProducer *>(inTypePtr.get());
+ if (theProducer)
+ theProducer->SetConsumer(inConsumer);
+}
+
+template <typename TContainer>
+inline void Undo(TContainer &inTransactions)
+{
+ std::for_each(inTransactions.rbegin(), inTransactions.rend(), std::bind(&ITransaction::Undo,
+ std::placeholders::_1));
+}
+
+template <typename TContainer>
+inline void Redo(TContainer &inTransactions)
+{
+ do_all(inTransactions, std::bind(&ITransaction::Do, std::placeholders::_1));
+}
+
+template <typename TItemType>
+void Notify(std::vector<TItemType> &inNotifications)
+{
+ do_all(inNotifications, std::bind(&TItemType::operator(), std::placeholders::_1));
+}
+
+template <typename TItemType>
+void NotifyReverse(std::vector<TItemType> &inNotifications)
+{
+ std::for_each(inNotifications.rbegin(), inNotifications.rend(),
+ std::bind(&TItemType::operator(), std::placeholders::_1));
+}
+}
+
+#endif
diff --git a/src/dm/systems/Qt3DSDMValue.cpp b/src/dm/systems/Qt3DSDMValue.cpp
new file mode 100644
index 0000000..94c5a59
--- /dev/null
+++ b/src/dm/systems/Qt3DSDMValue.cpp
@@ -0,0 +1,178 @@
+/****************************************************************************
+**
+** 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 "Qt3DSDMValue.h"
+
+#include <QColor>
+#include <QDebug>
+#include <QVariant>
+
+using namespace qt3dsdm;
+
+SValue::SValue(const QVariant &inData)
+{
+ switch (inData.type()) {
+ case QVariant::Bool:
+ {
+ *this = inData.toBool();
+ break;
+ }
+ case QVariant::Color:
+ {
+ const QColor c = inData.value<QColor>();
+ *this = qt3dsdm::SFloat4(c.redF(), c.greenF(), c.blueF(), c.alphaF());
+ break;
+ }
+ case QVariant::String:
+ {
+ const QString q = inData.toString();
+ const int count = q.size() + 1;
+#ifdef __INTEGRITY
+ wchar_t* tempBuf = reinterpret_cast<wchar_t*>(malloc(count * sizeof(wchar_t)));
+#else
+ wchar_t* tempBuf = reinterpret_cast<wchar_t*>(alloca(count * sizeof(wchar_t)));
+#endif
+ tempBuf[count - 1] = 0;
+ q.toWCharArray(tempBuf);
+ *this = std::make_shared<qt3dsdm::CDataStr>(tempBuf);
+#ifdef __INTEGRITY
+ free(tempBuf);
+#endif
+ break;
+ }
+ case QVariant::Int: {
+ *this = inData.toInt();
+ break;
+ }
+ case QVariant::Double: {
+ *this = inData.toFloat();
+ break;
+ }
+
+ case QVariant::Vector2D: {
+ const auto v = inData.value<QVector2D>();
+ *this = qt3dsdm::SFloat2(v.x(), v.y());
+ break;
+ }
+
+ case QVariant::Vector3D: {
+ const auto v = inData.value<QVector3D>();
+ *this = qt3dsdm::SFloat3(v.x(), v.y(), v.z());
+ break;
+ }
+
+ default:
+ qDebug() << "Add a handler for QVariant::type" << inData.type();
+ throw std::runtime_error("Cannot transform this QVariant into SValue");
+ }
+}
+
+QVariant SValue::toQVariant() const
+{
+ switch (getType()) {
+ case DataModelDataType::String:
+ case DataModelDataType::StringRef:
+ {
+ return get<QString>(*this);
+ }
+ case DataModelDataType::Float: {
+ return get<float>(*this);
+ }
+ case DataModelDataType::Float2: {
+ return QVariant::fromValue(get<QVector2D>(*this));
+ }
+ case DataModelDataType::Float3: {
+ return QVariant::fromValue(get<QVector3D>(*this));
+ }
+ case DataModelDataType::Float4: {
+ return QVariant::fromValue(get<QVector<float> >(*this));
+ }
+ case DataModelDataType::Long: {
+ return QVariant::fromValue(get<qt3ds::QT3DSI32>(*this));
+ }
+ case DataModelDataType::Bool: {
+ return get<bool>(*this);
+ }
+ case DataModelDataType::FloatList: {
+ //KDAB_TODO
+ qDebug() << "Add a handler for type DataModelDataType::FloatList";
+ return {};
+ }
+ case DataModelDataType::Long4: {
+ return QVariant::fromValue(get<QVector<qt3ds::QT3DSU32> >(*this));
+ }
+ case DataModelDataType::ObjectRef: {
+ const SObjectRefType &theRef(get<SObjectRefType>(*this));
+ switch (theRef.GetReferenceType()) {
+ case ObjectReferenceType::Absolute:
+ return SValue(get<SLong4>(theRef.m_Value)).toQVariant();
+ break;
+ case ObjectReferenceType::Relative:
+ return SValue(get<TDataStrPtr>(theRef.m_Value)).toQVariant();
+ break;
+ case ObjectReferenceType::Unknown:
+ return QVariant::fromValue(QVector<qt3ds::QT3DSU32>());
+ break;
+ }
+ }
+ case DataModelDataType::StringOrInt: {
+ const SStringOrInt &theData(get<SStringOrInt>(*this));
+ if (theData.GetType() == SStringOrIntTypes::Int) {
+ return QVariant::fromValue(get<qt3ds::QT3DSI32>(theData.m_Value));
+ } else if (theData.GetType() == SStringOrIntTypes::String) {
+ auto wideStr = get<TDataStrPtr>(theData.m_Value)->GetData();
+ return QString::fromWCharArray(wideStr);
+ } else {
+ return {};
+ }
+
+ }
+ case DataModelDataType::None:
+ return {};
+ default:
+ break;
+ }
+ return {};
+}
+
+SInternValue::SInternValue(const SValue &inValue, IStringTable &inStringTable)
+{
+ if (GetValueType(inValue) == DataModelDataType::StringRef) {
+ const SStringRef &current = get<SStringRef>(inValue);
+ SStringRef newId = inStringTable.RegisterStr(current.m_Id);
+ m_Value = SValue(newId);
+ } else {
+ m_Value = inValue;
+ }
+}
+
+SInternValue::SInternValue(const SInternValue &inOther)
+ : m_Value(inOther.m_Value)
+{
+}
diff --git a/src/dm/systems/Qt3DSDMValue.h b/src/dm/systems/Qt3DSDMValue.h
new file mode 100644
index 0000000..9e00632
--- /dev/null
+++ b/src/dm/systems/Qt3DSDMValue.h
@@ -0,0 +1,341 @@
+/****************************************************************************
+**
+** 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 QT3DSDM_VALUE_H
+#define QT3DSDM_VALUE_H
+#include "Qt3DSDMDataTypes.h"
+
+#include <QColor>
+#include <QMetaType>
+#include <QVariant>
+#include <QVector>
+#include <QVector2D>
+#include <QVector3D>
+
+namespace qt3dsdm {
+
+template <typename TDataType>
+struct SDataTypeToEnumMap
+{
+};
+
+template <DataModelDataType::Value TEnumVal>
+struct SEnumToDataTypeMap
+{
+};
+
+#define DEFINE_QT3DSDM_DATA_TYPE_MAP(dtype, enumName) \
+ template <> \
+ struct SDataTypeToEnumMap<dtype> \
+ { \
+ static DataModelDataType::Value getType() { return enumName; } \
+ }; \
+ template <> \
+ struct SEnumToDataTypeMap<enumName> \
+ { \
+ typedef dtype TDataType; \
+ };
+
+#define ITERATE_QT3DSDM_DATA_TYPES \
+ HANDLE_QT3DSDM_DATA_TYPE(float, DataModelDataType::Float); \
+ HANDLE_QT3DSDM_DATA_TYPE(SFloat2, DataModelDataType::Float2); \
+ HANDLE_QT3DSDM_DATA_TYPE(SFloat3, DataModelDataType::Float3); \
+ HANDLE_QT3DSDM_DATA_TYPE(SFloat4, DataModelDataType::Float4); \
+ HANDLE_QT3DSDM_DATA_TYPE(qt3ds::QT3DSI32, DataModelDataType::Long); \
+ HANDLE_QT3DSDM_DATA_TYPE(TDataStrPtr, DataModelDataType::String); \
+ HANDLE_QT3DSDM_DATA_TYPE(bool, DataModelDataType::Bool); \
+ HANDLE_QT3DSDM_DATA_TYPE(SLong4, DataModelDataType::Long4); \
+ HANDLE_QT3DSDM_DATA_TYPE(SStringRef, DataModelDataType::StringRef); \
+ HANDLE_QT3DSDM_DATA_TYPE(SObjectRefType, DataModelDataType::ObjectRef); \
+ HANDLE_QT3DSDM_DATA_TYPE(SStringOrInt, DataModelDataType::StringOrInt); \
+ HANDLE_QT3DSDM_DATA_TYPE(TFloatList, DataModelDataType::FloatList);
+
+#define HANDLE_QT3DSDM_DATA_TYPE(a, b) DEFINE_QT3DSDM_DATA_TYPE_MAP(a, b)
+ITERATE_QT3DSDM_DATA_TYPES
+#undef HANDLE_QT3DSDM_DATA_TYPE
+
+struct Qt3DSDMDataTypeUnionTraits
+{
+ typedef DataModelDataType::Value TIdType;
+
+ enum {
+ TBufferSize = sizeof(SObjectRefType),
+ };
+
+ static TIdType getNoDataId() { return DataModelDataType::None; }
+
+ template <typename TDataType>
+ static TIdType getType()
+ {
+ return SDataTypeToEnumMap<TDataType>::getType();
+ }
+
+ template <typename TRetType, typename TVisitorType>
+ static TRetType visit(char *inData, DataModelDataType::Value inType, TVisitorType inVisitor)
+ {
+ switch (inType) {
+#define HANDLE_QT3DSDM_DATA_TYPE(dtype, enumType) \
+ case enumType: \
+ return inVisitor(*NVUnionCast<dtype *>(inData));
+ ITERATE_QT3DSDM_DATA_TYPES
+#undef HANDLE_QT3DSDM_DATA_TYPE
+
+ default:
+ QT3DS_ASSERT(false);
+ case DataModelDataType::None:
+ return inVisitor();
+ }
+ }
+
+ template <typename TRetType, typename TVisitorType>
+ static TRetType visit(const char *inData, DataModelDataType::Value inType, TVisitorType inVisitor)
+ {
+ switch (inType) {
+#define HANDLE_QT3DSDM_DATA_TYPE(dtype, enumType) \
+ case enumType: \
+ return inVisitor(*NVUnionCast<const dtype *>(inData));
+ ITERATE_QT3DSDM_DATA_TYPES
+#undef HANDLE_QT3DSDM_DATA_TYPE
+
+ default:
+ QT3DS_ASSERT(false);
+ case DataModelDataType::None:
+ return inVisitor();
+ }
+ }
+};
+
+typedef qt3ds::foundation::
+ DiscriminatedUnion<qt3ds::foundation::
+ DiscriminatedUnionGenericBase<Qt3DSDMDataTypeUnionTraits,
+ Qt3DSDMDataTypeUnionTraits::TBufferSize>,
+ Qt3DSDMDataTypeUnionTraits::TBufferSize>
+ TValue;
+
+struct SValue : public TValue
+{
+ SValue() {}
+ SValue(const SValue &inOther)
+ : TValue(static_cast<const TValue &>(inOther))
+ {
+ }
+ SValue(const QVariant &inData);
+
+ template <typename TDataType>
+ SValue(const TDataType &inData)
+ : TValue(inData)
+ {
+ }
+ SValue &operator=(const SValue &inOther)
+ {
+ TValue::operator=(inOther);
+ return *this;
+ }
+ bool operator==(const SValue &inOther) const { return TValue::operator==(inOther); }
+ bool operator!=(const SValue &inOther) const { return TValue::operator!=(inOther); }
+ bool empty() const { return getType() == DataModelDataType::None; }
+
+ // Conversion from this data type into a data model value
+ const SValue &toOldSkool() const { return *this; }
+
+ QVariant toQVariant() const;
+};
+
+typedef std::shared_ptr<SValue> SValuePtr;
+
+template <>
+struct Qt3DSDMGetter<SValue>
+{
+ template <typename TRetType>
+ TRetType doGet(const SValue &inValue)
+ {
+ return inValue.getData<TRetType>();
+ }
+};
+
+template <>
+struct Qt3DSDMValueTyper<SValue>
+{
+ DataModelDataType::Value Get(const SValue &inValue) { return inValue.getType(); }
+};
+
+inline bool CheckValueType(DataModelDataType::Value inType, const SValue &inValue)
+{
+ bool retval = inType == inValue.getType();
+ if (!retval)
+ throw ValueTypeError(L"");
+ return retval;
+}
+
+inline bool Equals(const SValue &lhs, const SValue &rhs)
+{
+ return lhs == rhs;
+}
+
+class SInternValue
+{
+ SValue m_Value;
+
+public:
+ SInternValue(const SValue &inValue, IStringTable &inTable);
+ SInternValue() {}
+ SInternValue(const SInternValue &inOther);
+ SInternValue &operator=(const SInternValue &inOther)
+ {
+ m_Value = inOther.m_Value;
+ return *this;
+ }
+
+ static SInternValue ISwearThisHasAlreadyBeenInternalized(const SValue &inValue)
+ {
+ SInternValue retval;
+ retval.m_Value = inValue;
+ return retval;
+ }
+
+ const SValue &GetValue() const { return m_Value; }
+ operator const SValue &() const { return m_Value; }
+};
+
+template <>
+struct SDefaulter<SValue>
+{
+ inline bool SetDefault(DataModelDataType::Value inDataType, SValue &outValue)
+ {
+ switch (inDataType) {
+ case DataModelDataType::Float:
+ outValue = SValue(0.f);
+ break;
+ case DataModelDataType::Float2:
+ outValue = SValue(SFloat2());
+ break;
+ case DataModelDataType::Float3:
+ outValue = SValue(SFloat3());
+ break;
+ case DataModelDataType::Float4:
+ outValue = SValue(SFloat4());
+ break;
+ case DataModelDataType::Long:
+ outValue = SValue(0);
+ break;
+ case DataModelDataType::String:
+ outValue = SValue(TDataStrPtr(new CDataStr(L"")));
+ break;
+ case DataModelDataType::Bool:
+ outValue = SValue(false);
+ break;
+ case DataModelDataType::Long4:
+ outValue = SValue(SLong4());
+ break;
+ case DataModelDataType::StringRef:
+ outValue = SValue(SStringRef());
+ break;
+ case DataModelDataType::ObjectRef:
+ outValue = SValue(SObjectRefType());
+ break;
+ case DataModelDataType::FloatList:
+ outValue = SValue(TFloatList());
+ break;
+ case DataModelDataType::StringOrInt:
+ default:
+ outValue = SValue(SStringOrInt());
+ return false;
+ }
+ return true;
+ }
+};
+
+inline SObjectRefType ConvertToObjectRef(const SValue &inValue)
+{
+ using namespace std;
+ switch (GetValueType(inValue)) {
+ case DataModelDataType::StringRef:
+ return SObjectRefType(make_shared<CDataStr>(get<SStringRef>(inValue).m_Id));
+ case DataModelDataType::String:
+ return SObjectRefType(get<TDataStrPtr>(inValue));
+ case DataModelDataType::Long4:
+ return SObjectRefType(get<SLong4>(inValue));
+ case DataModelDataType::ObjectRef:
+ return get<SObjectRefType>(inValue);
+ default:
+ break;
+ }
+ return SObjectRefType();
+}
+
+
+template <>
+inline QColor get<QColor>(const SValue &inType)
+{
+ auto f = get<qt3dsdm::SFloat4>(inType);
+ qreal r = qBound<qreal>(0.0, f.m_Floats[0], 1.0);
+ qreal g = qBound<qreal>(0.0, f.m_Floats[1], 1.0);
+ qreal b = qBound<qreal>(0.0, f.m_Floats[2], 1.0);
+ qreal a = qBound<qreal>(0.0, f.m_Floats[3], 1.0);
+ return QColor::fromRgbF(r, g, b, a);
+}
+
+template <>
+inline QString get<QString>(const qt3dsdm::SValue &inType)
+{
+ return QString::fromWCharArray(qt3dsdm::get<qt3dsdm::TDataStrPtr>(inType)->GetData());
+}
+
+template <>
+inline QVector2D get<QVector2D>(const qt3dsdm::SValue &inType)
+{
+ auto f = get<qt3dsdm::SFloat2>(inType);
+ return QVector2D(f.m_Floats[0], f.m_Floats[1]);
+}
+
+template <>
+inline QVector3D get<QVector3D>(const qt3dsdm::SValue &inType)
+{
+ auto f = get<qt3dsdm::SFloat3>(inType);
+ return QVector3D(f.m_Floats[0], f.m_Floats[1], f.m_Floats[2]);
+}
+
+template <>
+inline QVector<float> get<QVector<float> >(const qt3dsdm::SValue &inType)
+{
+ auto f = get<qt3dsdm::SFloat4>(inType);
+ return {f.m_Floats[0], f.m_Floats[1], f.m_Floats[2], f.m_Floats[3]};
+}
+
+// KDAB_TODO Shortcut to not define our own 4 member long structure
+template <>
+inline QVector<qt3ds::QT3DSU32> get<QVector<qt3ds::QT3DSU32> >(const qt3dsdm::SValue &inType)
+{
+ auto f = get<qt3dsdm::SLong4>(inType);
+ return {f.m_Longs[0], f.m_Longs[1], f.m_Longs[2], f.m_Longs[3]};
+}
+
+}
+Q_DECLARE_METATYPE(qt3dsdm::DataModelDataType)
+#endif
diff --git a/src/dm/systems/Qt3DSDMWStrOps.h b/src/dm/systems/Qt3DSDMWStrOps.h
new file mode 100644
index 0000000..b1e1fb0
--- /dev/null
+++ b/src/dm/systems/Qt3DSDMWStrOps.h
@@ -0,0 +1,40 @@
+/****************************************************************************
+**
+** 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 QT3DSDM_WSTR_OPS_H
+#define QT3DSDM_WSTR_OPS_H
+namespace qt3dsdm {
+// Template base class so that we can convert items to and from wide string
+template <typename TDataType>
+struct WStrOps
+{
+ bool force_compile_error;
+};
+}
+#endif \ No newline at end of file
diff --git a/src/dm/systems/Qt3DSDMWStrOpsImpl.h b/src/dm/systems/Qt3DSDMWStrOpsImpl.h
new file mode 100644
index 0000000..d65ac13
--- /dev/null
+++ b/src/dm/systems/Qt3DSDMWStrOpsImpl.h
@@ -0,0 +1,761 @@
+/****************************************************************************
+**
+** 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 QT3DS_IMPORT_WSTR_OPS_IMPL_H
+#define QT3DS_IMPORT_WSTR_OPS_IMPL_H
+#include "Qt3DSDMDataTypes.h"
+#include "Qt3DSDMWStrOps.h"
+#include "foundation/Qt3DSMemoryBuffer.h"
+#include "foundation/Qt3DSMemoryBuffer.h"
+#include "Qt3DSDMHandles.h"
+#include "Qt3DSDMAnimation.h"
+#include "Qt3DSDMMetaDataTypes.h"
+#include "Qt3DSDMXML.h"
+#include "EABase/eabase.h"
+#include "Qt3DSDMStringTable.h"
+
+namespace qt3dsdm {
+using qt3ds::QT3DSI8;
+using qt3ds::QT3DSU8;
+using qt3ds::QT3DSI16;
+using qt3ds::QT3DSU16;
+using qt3ds::QT3DSU32;
+using qt3ds::QT3DSI32;
+using qt3ds::QT3DSU64;
+using qt3ds::QT3DSI64;
+using qt3ds::QT3DSF32;
+using qt3ds::QT3DSF64;
+template <>
+struct WStrOps<bool>
+{
+ QT3DSU32 ToStr(bool item, NVDataRef<wchar_t> buffer)
+ {
+ return static_cast<QT3DSU32>(
+ swprintf(buffer.begin(), buffer.size(), L"%s", item ? L"True" : L"False"));
+ }
+ bool StrTo(const wchar_t *buffer, bool &item)
+ {
+ if (AreEqual(buffer, L"True"))
+ item = true;
+ else
+ item = false;
+ return true;
+ }
+ QT3DSU32 ToStr(bool item, NVDataRef<char8_t> buffer)
+ {
+ return static_cast<QT3DSU32>(
+ _snprintf(buffer.begin(), buffer.size(), "%s", item ? "True" : "False"));
+ }
+ bool StrTo(const char8_t *buffer, bool &item)
+ {
+ if (AreEqualCaseless(buffer, "True"))
+ item = true;
+ else
+ item = false;
+ return true;
+ }
+};
+template <>
+struct WStrOps<QT3DSU8>
+{
+ QT3DSU32 ToStr(QT3DSU8 item, NVDataRef<wchar_t> buffer)
+ {
+ return static_cast<QT3DSU32>(
+ swprintf(buffer.begin(), buffer.size(), L"%hu", static_cast<QT3DSU16>(item)));
+ }
+ bool StrTo(const char8_t *buffer, QT3DSU8 &item)
+ {
+ item = static_cast<QT3DSU8>(strtoul(buffer, NULL, 10));
+ return true;
+ }
+};
+template <>
+struct WStrOps<QT3DSI8>
+{
+ QT3DSU32 ToStr(QT3DSI8 item, NVDataRef<wchar_t> buffer)
+ {
+ return static_cast<QT3DSU32>(
+ swprintf(buffer.begin(), buffer.size(), L"%hd", static_cast<QT3DSI16>(item)));
+ }
+ bool StrTo(const char8_t *buffer, QT3DSI8 &item)
+ {
+ item = static_cast<QT3DSI8>(strtol(buffer, NULL, 10));
+ return true;
+ }
+};
+template <>
+struct WStrOps<QT3DSU16>
+{
+ QT3DSU32 ToStr(QT3DSU16 item, NVDataRef<wchar_t> buffer)
+ {
+ return static_cast<QT3DSU32>(swprintf(buffer.begin(), buffer.size(), L"%hu", item));
+ }
+ bool StrTo(const char8_t *buffer, QT3DSU16 &item)
+ {
+ item = static_cast<QT3DSU16>(strtoul(buffer, NULL, 10));
+ return true;
+ }
+};
+template <>
+struct WStrOps<QT3DSI16>
+{
+ QT3DSU32 ToStr(QT3DSI16 item, NVDataRef<wchar_t> buffer)
+ {
+ return static_cast<QT3DSU32>(swprintf(buffer.begin(), buffer.size(), L"%hd", item));
+ }
+ QT3DSU32 ToStr(QT3DSI16 item, NVDataRef<char8_t> buffer)
+ {
+ return static_cast<QT3DSU32>(sprintf(buffer.begin(), "%hd", item));
+ }
+ bool StrTo(const char8_t *buffer, QT3DSI16 &item)
+ {
+ item = static_cast<QT3DSI16>(strtol(buffer, NULL, 10));
+ return true;
+ }
+};
+
+template <>
+struct WStrOps<QT3DSU32>
+{
+ QT3DSU32 ToStr(QT3DSU32 item, NVDataRef<wchar_t> buffer)
+ {
+ return static_cast<QT3DSU32>(swprintf(buffer.begin(), buffer.size(), L"%lu", item));
+ }
+ QT3DSU32 ToStr(QT3DSU32 item, NVDataRef<char8_t> buffer)
+ {
+ // hope the buffer is big enough...
+ return static_cast<QT3DSU32>(sprintf(buffer.begin(), "%u", item));
+ }
+ bool StrTo(const char8_t *buffer, QT3DSU32 &item)
+ {
+ item = strtoul(buffer, NULL, 10);
+ return true;
+ }
+};
+
+template <>
+struct WStrOps<QT3DSI32>
+{
+ QT3DSU32 ToStr(QT3DSI32 item, NVDataRef<wchar_t> buffer)
+ {
+ return static_cast<QT3DSU32>(swprintf(buffer.begin(), buffer.size(), L"%ld", item));
+ }
+ bool StrTo(const char8_t *buffer, QT3DSI32 &item)
+ {
+ item = strtol(buffer, NULL, 10);
+ return true;
+ }
+};
+template <>
+struct WStrOps<QT3DSF32>
+{
+ QT3DSU32 ToStr(QT3DSF32 item, NVDataRef<wchar_t> buffer)
+ {
+ QString s = QLocale::c().toString(item);
+ wcsncpy(buffer.begin(), s.toStdWString().c_str(), buffer.size());
+ return s.length();
+ }
+ QT3DSU32 ToStr(QT3DSF32 item, NVDataRef<char8_t> buffer)
+ {
+ QString s = QLocale::c().toString(item);
+ strncpy(buffer.begin(), s.toStdString().c_str(), buffer.size());
+ return s.length();
+ }
+ bool StrTo(const char8_t *buffer, QT3DSF32 &item)
+ {
+ bool ok;
+ item = QLocale::c().toFloat(buffer, &ok);
+ return ok;
+ }
+};
+
+template <>
+struct WStrOps<QT3DSF64>
+{
+ QT3DSU32 ToStr(QT3DSF64 item, NVDataRef<wchar_t> buffer)
+ {
+ QString s = QLocale::c().toString(item);
+ wcsncpy(buffer.begin(), s.toStdWString().c_str(), buffer.size());
+ return s.length();
+ }
+ bool StrTo(const char8_t *buffer, QT3DSF64 &item)
+ {
+ bool ok;
+ item = QLocale::c().toDouble(buffer, &ok);
+ return ok;
+ }
+};
+#define QT3DS_WCHAR_T_None L"None"
+#define QT3DS_WCHAR_T_Float L"Float"
+#define QT3DS_WCHAR_T_Float2 L"Float2"
+#define QT3DS_WCHAR_T_Float3 L"Float3"
+#define QT3DS_WCHAR_T_Float4 L"Float4"
+#define QT3DS_WCHAR_T_Long L"Long"
+#define QT3DS_WCHAR_T_String L"String"
+#define QT3DS_WCHAR_T_Bool L"Bool"
+#define QT3DS_WCHAR_T_Long4 L"Long4"
+#define QT3DS_WCHAR_T_StringRef L"StringRef"
+#define QT3DS_WCHAR_T_ObjectRef L"ObjectRef"
+#define QT3DS_WCHAR_T_StringOrInt L"StringOrInt"
+#define QT3DS_WCHAR_T_FloatList L"FloatList"
+
+#define QT3DS_IMPORT_ITERATE_DMTYPE \
+ QT3DS_IMPORT_HANDLE_DMTYPE(DataModelDataType::None, None, QT3DSF32) \
+ QT3DS_IMPORT_HANDLE_DMTYPE(DataModelDataType::Float, Float, QT3DSF32) \
+ QT3DS_IMPORT_HANDLE_DMTYPE(DataModelDataType::Float2, Float2, SFloat2) \
+ QT3DS_IMPORT_HANDLE_DMTYPE(DataModelDataType::Float3, Float3, SFloat3) \
+ QT3DS_IMPORT_HANDLE_DMTYPE(DataModelDataType::Float4, Float4, SFloat4) \
+ QT3DS_IMPORT_HANDLE_DMTYPE(DataModelDataType::Long, Long, QT3DSI32) \
+ QT3DS_IMPORT_HANDLE_DMTYPE(DataModelDataType::String, String, TDataStrPtr) \
+ QT3DS_IMPORT_HANDLE_DMTYPE(DataModelDataType::Bool, Bool, bool) \
+ QT3DS_IMPORT_HANDLE_DMTYPE(DataModelDataType::Long4, Long4, SLong4) \
+ QT3DS_IMPORT_HANDLE_DMTYPE(DataModelDataType::StringRef, StringRef, SStringRef) \
+ QT3DS_IMPORT_HANDLE_DMTYPE(DataModelDataType::ObjectRef, ObjectRef, SObjectRefType) \
+ QT3DS_IMPORT_HANDLE_DMTYPE(DataModelDataType::StringOrInt, StringOrInt, SStringOrInt) \
+ QT3DS_IMPORT_HANDLE_DMTYPE(DataModelDataType::FloatList, FloatList, TFloatList)
+
+template <>
+struct WStrOps<DataModelDataType::Value>
+{
+ QT3DSU32 ToStr(DataModelDataType::Value item, NVDataRef<wchar_t> buffer)
+ {
+ const wchar_t *data = NULL;
+ switch (item) {
+#define QT3DS_IMPORT_HANDLE_DMTYPE(x, y, z) \
+ case x: \
+ data = QT3DS_WCHAR_T_##y; \
+ break;
+ QT3DS_IMPORT_ITERATE_DMTYPE
+#undef QT3DS_IMPORT_HANDLE_DMTYPE
+ default:
+ break;
+ }
+ if (data == NULL) {
+ QT3DS_ASSERT(false);
+ data = L"Unknown";
+ }
+ return (QT3DSU32)swprintf(buffer.begin(), buffer.size(), L"%ls", data);
+ }
+ bool StrTo(const wchar_t *buffer, DataModelDataType::Value &item)
+ {
+#define QT3DS_IMPORT_HANDLE_DMTYPE(x, y, z) \
+ if (AreEqual(buffer, QT3DS_WCHAR_T_##y)) { \
+ item = x; \
+ return true; \
+ }
+ QT3DS_IMPORT_ITERATE_DMTYPE
+#undef QT3DS_IMPORT_HANDLE_DMTYPE
+ item = DataModelDataType::None;
+ return false;
+ }
+};
+template <typename TBufferType>
+struct WStrOpsDMWriter
+{
+ TBufferType &buf;
+ WStrOpsDMWriter(TBufferType &_buf)
+ : buf(_buf)
+ {
+ }
+
+ void operator()(float val) { buf.Write(val); }
+ void operator()(const SFloat2 &val) { buf.Write(NVConstDataRef<QT3DSF32>(&val[0], 2)); }
+ void operator()(const SFloat3 &val) { buf.Write(NVConstDataRef<QT3DSF32>(&val[0], 3)); }
+ void operator()(const SFloat4 &val) { buf.Write(NVConstDataRef<QT3DSF32>(&val[0], 4)); }
+ void operator()(QT3DSI32 val) { buf.Write(val); }
+ void operator()(bool val) { buf.Write(val); }
+ void operator()(const TDataStrPtr &val)
+ {
+ if (val != NULL)
+ buf.Write(NVConstDataRef<wchar_t>(val->GetData(), (QT3DSU32)val->GetLength()));
+ }
+ void operator()(const SLong4 &val)
+ {
+ buf.Write(NVConstDataRef<QT3DSU32>(&val.m_Longs[0], 4), 4);
+ }
+ void operator()(const SStringRef &val) { buf.Write(val.m_Id, (QT3DSU32)wcslen(val.m_Id) + 1); }
+ void operator()(const SObjectRefType &val) { val.m_Value.visit<void>(*this); }
+ void operator()(const SStringOrInt &val) { val.m_Value.visit<void>(*this); }
+ void operator()(const TFloatList &val)
+ {
+ buf.Write(NVConstDataRef<float>(val.data(), (QT3DSU32)val.size()));
+ }
+ void operator()() { QT3DS_ASSERT(false); }
+};
+
+template <>
+struct WStrOps<SValue>
+{
+ template <typename TBufferType>
+ void ToBuf(const SValue &item, TBufferType &outBuffer)
+ {
+ WStrOpsDMWriter<TBufferType> writer(outBuffer);
+ item.visit<void>(writer);
+ }
+ template <typename TBufferType>
+ SValue BufTo(DataModelDataType::Value type, TBufferType &inReader)
+ {
+ switch (type) {
+#define QT3DS_IMPORT_HANDLE_DMTYPE(x, y, z) \
+ case x: { \
+ z retval; \
+ Read(inReader, retval); \
+ return retval; \
+ }
+ QT3DS_IMPORT_ITERATE_DMTYPE
+#undef QT3DS_IMPORT_HANDLE_DMTYPE
+ default:
+ break;
+ }
+ QT3DS_ASSERT(false);
+ return SValue();
+ }
+ template <typename TBufferType>
+ void Read(TBufferType &reader, float &val)
+ {
+ reader.Read(val);
+ }
+ template <typename TBufferType>
+ void Read(TBufferType &reader, SFloat2 &val)
+ {
+ reader.ReadRef(NVDataRef<QT3DSF32>(&val[0], 2));
+ }
+ template <typename TBufferType>
+ void Read(TBufferType &reader, SFloat3 &val)
+ {
+ reader.ReadRef(NVDataRef<QT3DSF32>(&val[0], 3));
+ }
+ template <typename TBufferType>
+ void Read(TBufferType &reader, SFloat4 &val)
+ {
+ reader.ReadRef(NVDataRef<QT3DSF32>(&val[0], 4));
+ }
+ template <typename TBufferType>
+ void Read(TBufferType &reader, QT3DSI32 &val)
+ {
+ reader.Read(val);
+ }
+ template <typename TBufferType>
+ void Read(TBufferType &reader, bool &val)
+ {
+ reader.Read(val);
+ }
+ template <typename TBufferType>
+ void Read(TBufferType &reader, TDataStrPtr &val)
+ {
+ NVConstDataRef<wchar_t> buffer;
+ reader.ReadBuffer(buffer);
+ val = std::make_shared<CDataStr>(buffer.begin(), buffer.size());
+ }
+ template <typename TBufferType>
+ void Read(TBufferType &reader, SLong4 &val)
+ {
+ reader.ReadRef(NVDataRef<QT3DSU32>(&val.m_Longs[0], 4));
+ }
+ template <typename TBufferType>
+ void Read(TBufferType &reader, SStringRef &val)
+ {
+ NVConstDataRef<wchar_t> buffer;
+ reader.ReadBuffer(buffer);
+ val = SStringRef(buffer.begin());
+ }
+ template <typename TBufferType>
+ void Read(TBufferType &reader, TFloatList &val)
+ {
+ NVConstDataRef<QT3DSF32> buffer;
+ reader.ReadBuffer(buffer);
+ val.assign(buffer.begin(), buffer.end());
+ }
+ template <typename TBufferType>
+ void Read(TBufferType &reader, SObjectRefType &val)
+ {
+ // Force the read to be as string; callers can always convert to a different
+ // format later if required.
+ TDataStrPtr theValue;
+ Read(reader, theValue);
+ val.m_Value = theValue;
+ }
+ template <typename TBufferType>
+ void Read(TBufferType &reader, SStringOrInt &val)
+ {
+ NVConstDataRef<char8_t> buffer;
+ reader.ReadBuffer(buffer);
+ if (buffer.size() == 0)
+ return;
+
+ if ((buffer[0] >= '0' && buffer[0] <= '9') || buffer[0] == '-') {
+ QT3DSI32 theVal;
+ WStrOps<QT3DSI32>().StrTo(buffer.begin(), theVal);
+ val = SStringOrInt(theVal);
+ } else {
+ NVConstDataRef<wchar_t> wideBuffer;
+ reader.ReadBuffer(wideBuffer);
+ val = SStringOrInt(std::make_shared<CDataStr>(wideBuffer.begin()));
+ }
+ }
+};
+
+// Write the wchar_t but exlude the null terminator
+// Meant to write data model values.
+// Memory buffer contains a non-null-terminated
+// wchar_t string
+struct WCharTWriter
+{
+ MemoryBuffer<RawAllocator> &m_Buffer;
+ WCharTWriter(MemoryBuffer<RawAllocator> &buf)
+ : m_Buffer(buf)
+ {
+ }
+ void Write(const wchar_t *value, QT3DSU32 len = 0)
+ {
+ if (IsTrivial(value))
+ return;
+ if (len == 0)
+ len = (QT3DSU32)wcslen(value);
+ m_Buffer.write(value, len);
+ }
+ void Write(wchar_t value) { m_Buffer.write(value); }
+ void Write(bool value) { Write(value ? L"True" : L"False"); }
+
+ // Takes care of long and float
+ template <typename TDataType>
+ void Write(TDataType value)
+ {
+ wchar_t buf[256];
+ QT3DSU32 numWritten = WStrOps<TDataType>().ToStr(value, NVDataRef<wchar_t>(buf, 256));
+ if (numWritten)
+ Write((const wchar_t *)buf);
+ else {
+ QT3DS_ASSERT(false);
+ }
+ }
+ template <typename TDataType>
+ void Write(NVConstDataRef<TDataType> values, QT3DSU32 grouping = 6, QT3DSU32 tabCount = 0)
+ {
+ for (QT3DSU32 idx = 0; idx < values.size(); ++idx) {
+ if (idx) {
+ if ((idx % grouping) == 0) {
+ Write((wchar_t)'\n');
+ for (QT3DSU32 tabIdx = 0; tabIdx < tabCount; ++tabIdx)
+ Write((wchar_t)'\t');
+ } else
+ Write((wchar_t)' ');
+ }
+ Write(values[idx]);
+ }
+ }
+
+ void Write(NVConstDataRef<wchar_t> values, QT3DSU32 ignored = 6)
+ {
+ (void)ignored;
+ if (values.size() && values[0] != 0) {
+ QT3DSU32 lastItem = values.size() - 1;
+ if (values[lastItem] == 0)
+ --lastItem;
+ Write(values.begin(), lastItem + 1);
+ }
+ }
+};
+
+inline bool IsWhite(wchar_t value)
+{
+ return value == '\n' || value == '\r' || value == ' ' || value == '\t';
+}
+
+// skip until we find whitespace.
+inline wchar_t *FindNextWhitespace(wchar_t *input)
+{
+ if (input == NULL)
+ return input;
+ wchar_t *marker = input;
+ // Empty loop intentional
+ for (; *marker && !IsWhite(*marker); ++marker)
+ ;
+ return marker;
+}
+
+// skip until we find whitespace.
+inline char8_t *FindNextWhitespace(char8_t *input)
+{
+ if (input == NULL)
+ return input;
+ char8_t *marker = input;
+ // Empty loop intentional
+ for (; *marker && !IsWhite(*marker); ++marker)
+ ;
+ return marker;
+}
+
+// skip until we find something that isn't whitespace.
+inline wchar_t *FindNextNonWhitespace(wchar_t *input)
+{
+ if (input == NULL)
+ return input;
+ wchar_t *marker = input;
+ // Empty loop intentional
+ for (; *marker && IsWhite(*marker); ++marker)
+ ;
+ return marker;
+}
+
+inline char8_t *FindNextNonWhitespace(char8_t *input)
+{
+ if (input == NULL)
+ return input;
+ char8_t *marker = input;
+ // Empty loop intentional
+ for (; *marker && IsWhite(*marker); ++marker)
+ ;
+ return marker;
+}
+
+// Reading is destructive in the case of floating point lists, so we may
+// destroy the incoming string.
+// We are assuming the string is null-terminated at end ptr.
+struct WCharTReader
+{
+ char8_t *m_StartPtr;
+ // Buffer used for temp storage
+ MemoryBuffer<RawAllocator> &m_Buffer;
+ IStringTable &m_StringTable;
+ WCharTReader(char8_t *sp, MemoryBuffer<RawAllocator> &buf, IStringTable &inStringTable)
+ : m_StartPtr(sp)
+ , m_Buffer(buf)
+ , m_StringTable(inStringTable)
+ {
+ }
+ void Read(const char8_t *&outPtr) { outPtr = m_StartPtr; }
+ void Read(const wchar_t *&outPtr) { outPtr = m_StringTable.GetWideStr(m_StartPtr); }
+ template <typename TDataType>
+ void Read(TDataType &data)
+ {
+ bool success = WStrOps<TDataType>().StrTo(m_StartPtr, data);
+ QT3DS_ASSERT(success);
+ (void)success;
+ }
+ // Destructive operation because we can't trust
+ // strtod to do the right thing. On windows, for long strings,
+ // it calls strlen every operation thus leading to basically N^2
+ // behavior
+ template <typename TDataType>
+ void ReadRef(NVDataRef<TDataType> data)
+ {
+ QT3DSU32 idx = 0;
+ m_StartPtr = FindNextNonWhitespace(m_StartPtr);
+ for (; idx < data.size() && m_StartPtr && *m_StartPtr; ++idx) {
+ char8_t *nextPtr = FindNextWhitespace(m_StartPtr);
+ if (nextPtr && *nextPtr)
+ *nextPtr = 0;
+ else
+ nextPtr = NULL;
+ WStrOps<TDataType>().StrTo(m_StartPtr, data[idx]);
+ m_StartPtr = nextPtr;
+ if (m_StartPtr)
+ m_StartPtr = FindNextNonWhitespace(m_StartPtr + 1);
+ }
+ }
+
+ void ReadBuffer(NVConstDataRef<char8_t> &outBuffer)
+ {
+ if (m_StartPtr && *m_StartPtr) {
+ QT3DSU32 len = (QT3DSU32)strlen(m_StartPtr);
+ outBuffer = NVConstDataRef<char8_t>(m_StartPtr, len + 1);
+ }
+ }
+ void ReadBuffer(NVConstDataRef<wchar_t> &outBuffer)
+ {
+ if (m_StartPtr && *m_StartPtr) {
+ QT3DSU32 len = (QT3DSU32)strlen(m_StartPtr);
+ outBuffer = NVConstDataRef<wchar_t>(m_StringTable.GetWideStr(m_StartPtr), len + 1);
+ }
+ }
+
+ // Destructive operation because we can't trust
+ // strtod to do the right thing. On windows, for long strings,
+ // it calls strlen every operation thus leading to basically N^2
+ // behavior
+ template <typename TDataType>
+ void ReadBuffer(NVConstDataRef<TDataType> &outBuffer)
+ {
+ m_Buffer.clear();
+ m_StartPtr = FindNextNonWhitespace(m_StartPtr);
+ while (m_StartPtr && *m_StartPtr) {
+ char8_t *nextPtr = FindNextWhitespace(m_StartPtr);
+ if (nextPtr && *nextPtr)
+ *nextPtr = 0;
+ else
+ nextPtr = NULL;
+ TDataType temp;
+ WStrOps<TDataType>().StrTo(m_StartPtr, temp);
+ m_Buffer.write(temp);
+ m_StartPtr = nextPtr;
+ if (m_StartPtr)
+ m_StartPtr = FindNextNonWhitespace(m_StartPtr + 1);
+ }
+ QT3DSU32 numItems = m_Buffer.size() / sizeof(TDataType);
+ if (numItems)
+ outBuffer = NVConstDataRef<TDataType>((TDataType *)m_Buffer.begin(), numItems);
+ else
+ outBuffer = NVConstDataRef<TDataType>();
+ }
+};
+
+template <>
+struct WStrOps<CDataModelHandle>
+{
+ template <typename THandleType>
+ QT3DSU32 ToStr(THandleType item, NVDataRef<wchar_t> buffer)
+ {
+ int theValue(item);
+ return WStrOps<int>().ToStr(theValue, buffer);
+ }
+ template <typename THandleType>
+ bool StrTo(const char8_t *buffer, THandleType &item)
+ {
+ int theValue;
+ bool retval = WStrOps<int>().StrTo(buffer, theValue);
+ item = theValue;
+ return retval;
+ }
+};
+
+#define IMPLEMENT_HANDLE_WSTROPS(HandleType) \
+ template <> \
+ struct WStrOps<HandleType> : public WStrOps<CDataModelHandle> \
+ { \
+ };
+IMPLEMENT_HANDLE_WSTROPS(Qt3DSDMInstanceHandle);
+IMPLEMENT_HANDLE_WSTROPS(Qt3DSDMPropertyHandle);
+IMPLEMENT_HANDLE_WSTROPS(Qt3DSDMSlideHandle);
+IMPLEMENT_HANDLE_WSTROPS(Qt3DSDMSlideGraphHandle);
+IMPLEMENT_HANDLE_WSTROPS(Qt3DSDMAnimationHandle);
+IMPLEMENT_HANDLE_WSTROPS(Qt3DSDMKeyframeHandle);
+IMPLEMENT_HANDLE_WSTROPS(Qt3DSDMActionHandle);
+IMPLEMENT_HANDLE_WSTROPS(Qt3DSDMHandlerArgHandle);
+IMPLEMENT_HANDLE_WSTROPS(Qt3DSDMEventHandle);
+IMPLEMENT_HANDLE_WSTROPS(Qt3DSDMHandlerHandle);
+IMPLEMENT_HANDLE_WSTROPS(Qt3DSDMHandlerParamHandle);
+IMPLEMENT_HANDLE_WSTROPS(Qt3DSDMMetaDataPropertyHandle);
+IMPLEMENT_HANDLE_WSTROPS(Qt3DSDMCategoryHandle);
+#undef IMPLEMENT_HANDLE_WSTROPS
+
+template <>
+struct WStrOps<EAnimationType>
+{
+ QT3DSU32 ToStr(EAnimationType value, NVDataRef<wchar_t> buffer)
+ {
+ const wchar_t *animType = NULL;
+ switch (value) {
+ case EAnimationTypeLinear:
+ animType = L"Linear";
+ break;
+ case EAnimationTypeBezier:
+ animType = L"Bezier";
+ break;
+ case EAnimationTypeEaseInOut:
+ animType = L"EaseInOut";
+ break;
+ default:
+ QT3DS_ASSERT(false);
+ break;
+ }
+ if (animType != NULL)
+ return swprintf(buffer.begin(), buffer.size(), L"%ls", animType);
+ else {
+ QT3DS_ASSERT(false);
+ return 0;
+ }
+ }
+ bool StrTo(const wchar_t *buffer, EAnimationType &item)
+ {
+ if (AreEqual(L"Linear", buffer)) {
+ item = EAnimationTypeLinear;
+ return true;
+ }
+ if (AreEqual(L"Bezier", buffer)) {
+ item = EAnimationTypeBezier;
+ return true;
+ }
+ if (AreEqual(L"EaseInOut", buffer)) {
+ item = EAnimationTypeEaseInOut;
+ return true;
+ }
+ return false;
+ }
+};
+
+// Implemented in UICDMMetaData.h
+template <>
+struct WStrOps<CompleteMetaDataType::Enum>
+{
+ QT3DSU32 ToStr(CompleteMetaDataType::Enum item, NVDataRef<wchar_t> buffer);
+ bool StrTo(const wchar_t *buffer, CompleteMetaDataType::Enum &item);
+};
+
+template <>
+struct WStrOps<HandlerArgumentType::Value>
+{
+ QT3DSU32 ToStr(HandlerArgumentType::Value item, NVDataRef<wchar_t> buffer);
+ bool StrTo(const wchar_t *buffer, HandlerArgumentType::Value &item);
+};
+
+#ifndef __clang__
+#ifndef __INTEGRITY
+// IDOMReader implementations
+template <typename TDataType>
+bool IDOMReader::ValueList(NVDataRef<TDataType> data)
+{
+ const wchar_t *value;
+ if (Value(value)) {
+ WCharTReader reader(const_cast<wchar_t *>(value), m_TempBuf);
+ reader.ReadRef(data);
+ }
+ return true;
+}
+
+// Destructive operation because we can't trust
+// strtod to do the right thing. On windows, for long strings,
+// it calls strlen every operation thus leading to basically N^2
+// behavior
+template <typename TDataType>
+NVConstDataRef<TDataType> IDOMReader::ChildValueList(TWideXMLCharPtr listName)
+{
+ NVConstDataRef<TDataType> retval;
+ TWideXMLCharPtr childValue = NULL;
+ if (ChildValue(listName, childValue)) {
+ WCharTReader reader(const_cast<wchar_t *>(childValue), m_TempBuf);
+ reader.ReadBuffer(retval);
+ }
+ return retval;
+}
+#endif
+#endif
+}
+
+#endif
diff --git a/src/dm/systems/Qt3DSDMWindowsCompatibility.h b/src/dm/systems/Qt3DSDMWindowsCompatibility.h
new file mode 100644
index 0000000..0a53c71
--- /dev/null
+++ b/src/dm/systems/Qt3DSDMWindowsCompatibility.h
@@ -0,0 +1,182 @@
+/****************************************************************************
+**
+** 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 QT3DSDM_WINDOWS_COMPATIBILITY_H
+#define QT3DSDM_WINDOWS_COMPATIBILITY_H
+#include "EABase/config/eaplatform.h"
+#include "EABase/eabase.h"
+#include <string>
+#ifndef __INTEGRITY
+#include <memory.h>
+#endif
+#include <string.h>
+#include <stdio.h>
+
+#if defined QT3DS_PLATFORM_NEEDS_WCHAR_T
+
+inline size_t wcslen(const wchar_t *inStr)
+{
+ size_t retval = 0;
+ while (inStr && *inStr) {
+ ++retval;
+ ++inStr;
+ }
+ return retval;
+}
+
+inline int wmemcmp(const wchar_t *lhs, const wchar_t *rhs, size_t count)
+{
+ return memcmp(lhs, rhs, count * sizeof(wchar_t));
+}
+
+inline wchar_t *wmemcpy(wchar_t *dest, const wchar_t *src, size_t count)
+{
+ memcpy(dest, src, count * sizeof(wchar_t));
+ return dest;
+}
+
+inline const wchar_t *wmemchr(const wchar_t *inFirst, size_t count, const wchar_t val)
+{
+ size_t idx;
+ // empty loop intentional
+ for (idx = 0; idx < count && inFirst[idx] != val; ++idx) {
+ }
+ if (idx < count)
+ return inFirst + idx;
+ return NULL;
+}
+
+inline wchar_t *wmemmove(wchar_t *dest, const wchar_t *src, size_t count)
+{
+ memmove(dest, src, count * sizeof(wchar_t));
+ return dest;
+}
+
+inline wchar_t *wmemset(wchar_t *dest, size_t count, wchar_t val)
+{
+ for (size_t idx = 0; idx < count; ++idx)
+ dest[idx] = val;
+ return dest;
+}
+
+#endif
+
+inline size_t WideToNarrow(char *inDest, size_t inDestLen, const wchar_t *inWideStr);
+template <unsigned int N>
+inline size_t WideToNarrow(char (&inDest)[N], const wchar_t *inWideStr);
+
+#if !defined EA_PLATFORM_WINDOWS
+
+inline void wcscpy_s(wchar_t *inDest, size_t destLen, const wchar_t *inMessage)
+{
+ if (destLen) {
+ size_t idx = 0;
+ while (inMessage && *inMessage && idx < destLen) {
+ inDest[idx] = *inMessage;
+ ++inMessage;
+ ++idx;
+ }
+
+ idx = idx < destLen ? idx : destLen - 1;
+ inDest[idx] = 0;
+ }
+}
+
+template <unsigned int N>
+inline void wcscpy_s(wchar_t (&inDest)[N], const wchar_t *inMessage)
+{
+ wcscpy_s(inDest, N, inMessage);
+}
+
+inline FILE *_wfopen(const wchar_t *inFname, const wchar_t *inFlags)
+{
+ char name[1024] = { 0 };
+ WideToNarrow(name, inFname);
+ char flags[24] = { 0 };
+ WideToNarrow(flags, inFlags);
+ return fopen(name, flags);
+}
+
+inline int _fseeki64(FILE *inFile, int64_t pos, int seekFlags)
+{
+ return fseek(inFile, (int32_t)pos, seekFlags);
+}
+
+inline int64_t _ftelli64(FILE *inFile)
+{
+ return ftell(inFile);
+}
+
+#define _snprintf snprintf
+
+#endif
+
+template <typename TLHS, typename TRHS>
+inline size_t ConvertStr(TLHS *inDest, size_t inDestLen, const TRHS *inWideStr)
+{
+ if (inDestLen == 0)
+ return 0;
+
+ size_t nameLen = 0;
+
+ // empty loop intentional.
+ for (const TRHS *tempPtr = inWideStr; tempPtr && *tempPtr; ++tempPtr, ++nameLen) {
+ }
+
+ if (nameLen > inDestLen - 1)
+ nameLen = inDestLen - 1;
+ for (size_t idx = 0; idx < nameLen; ++idx)
+ inDest[idx] = (char)inWideStr[idx];
+ inDest[nameLen] = 0;
+ return nameLen;
+}
+
+inline size_t WideToNarrow(char *inDest, size_t inDestLen, const wchar_t *inWideStr)
+{
+ return ConvertStr(inDest, inDestLen, inWideStr);
+}
+
+template <unsigned int N>
+inline size_t WideToNarrow(char (&inDest)[N], const wchar_t *inWideStr)
+{
+ return WideToNarrow(inDest, N, inWideStr);
+}
+
+inline size_t WideToNarrow(char *inDest, size_t inDestLen, const char16_t *inWideStr)
+{
+ return ConvertStr(inDest, inDestLen, inWideStr);
+}
+
+template <unsigned int N>
+inline size_t WideToNarrow(char (&inDest)[N], const char16_t *inWideStr)
+{
+ return WideToNarrow(inDest, N, inWideStr);
+}
+
+#endif \ No newline at end of file
diff --git a/src/dm/systems/Qt3DSDMXML.cpp b/src/dm/systems/Qt3DSDMXML.cpp
new file mode 100644
index 0000000..2055adf
--- /dev/null
+++ b/src/dm/systems/Qt3DSDMXML.cpp
@@ -0,0 +1,1253 @@
+/****************************************************************************
+**
+** 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 "Qt3DSDMXML.h"
+#include "foundation/Qt3DSPool.h"
+#include "foundation/Qt3DSAtomic.h"
+#include "foundation/Qt3DSRefCounted.h"
+#include "Qt3DSDMStringTable.h"
+#include "Qt3DSDMWStrOpsImpl.h"
+#include <memory>
+#include "foundation/StrConvertUTF.h"
+#include "foundation/StringTable.h"
+#ifdef QT3DS_VC
+#include <winsock2.h>
+#include <windows.h> //output debug string
+#endif
+
+#include <QtCore/qxmlstream.h>
+
+typedef char XML_Char;
+typedef char XML_LChar;
+
+using namespace qt3dsdm;
+using std::shared_ptr;
+using namespace qt3ds::foundation;
+using qt3ds::foundation::Pool;
+
+#define QT3DSXML_FOREACH(idxnm, val) \
+ for (QT3DSU32 idxnm = 0, __numItems = (QT3DSU32)val; idxnm < __numItems; ++idxnm)
+
+namespace qt3dsdm {
+
+// All names are string table values so we can do straight
+// pointer comparisons on them, we don't have the compare their
+// values.
+struct SDOMAttribute
+{
+ TXMLCharPtr m_Name;
+ TXMLCharPtr m_Value;
+ SDOMAttribute *m_NextAttribute;
+
+ SDOMAttribute(TXMLCharPtr nm, TXMLCharPtr val)
+ : m_Name(nm)
+ , m_Value(val)
+ , m_NextAttribute(NULL)
+ {
+ }
+};
+
+struct SDOMElement
+{
+ TXMLCharPtr m_Name;
+ SDOMAttribute *m_FirstAttribute;
+ SDOMAttribute *m_LastAttribute;
+ SDOMElement *m_Parent;
+ SDOMElement *m_FirstChild;
+ SDOMElement *m_LastChild;
+ SDOMElement *m_NextSibling;
+ TXMLCharPtr m_Value;
+
+ SDOMElement(TXMLCharPtr nm)
+ : m_Name(nm)
+ , m_FirstAttribute(NULL)
+ , m_LastAttribute(NULL)
+ , m_Parent(NULL)
+ , m_FirstChild(NULL)
+ , m_LastChild(NULL)
+ , m_NextSibling(NULL)
+ , m_Value("")
+ {
+ }
+
+ void AddAttribute(SDOMAttribute &att)
+ {
+ if (m_LastAttribute) {
+ m_LastAttribute->m_NextAttribute = &att;
+ m_LastAttribute = &att;
+ } else {
+ QT3DS_ASSERT(m_FirstAttribute == NULL);
+ m_FirstAttribute = m_LastAttribute = &att;
+ }
+ }
+ // Used to ensure duplicate attributes can't happen
+ void SetAttributeValue(TXMLCharPtr inName, TXMLCharPtr inValue, IDOMFactory &inFactory,
+ const SDOMFlags &inFlags)
+ {
+ inName = inFactory.GetStringTable()->RegisterStr(inName);
+ SDOMAttribute *att = FindAttribute(inName, inFlags);
+ if (att) {
+ att->m_Value = inFactory.RegisterValue(inValue);
+ } else {
+ AddAttribute(*inFactory.NextAttribute(inName, inValue));
+ }
+ }
+ void SetAttributeValue(TWideXMLCharPtr inName, TWideXMLCharPtr inValue, IDOMFactory &inFactory,
+ const SDOMFlags &inFlags)
+ {
+ TXMLCharPtr theName = inFactory.GetStringTable()->GetNarrowStr(inName);
+ SDOMAttribute *att = FindAttribute(theName, inFlags);
+ if (att) {
+ att->m_Value = inFactory.RegisterValue(inValue);
+ } else {
+ AddAttribute(
+ *inFactory.NextAttribute(inFactory.GetStringTable()->GetWideStr(inName), inValue));
+ }
+ }
+ const SDOMAttribute *FindAttribute(TXMLCharPtr nm, const SDOMFlags &inFlags) const
+ {
+ return const_cast<SDOMElement *>(this)->FindAttribute(nm, inFlags);
+ }
+ SDOMAttribute *FindAttribute(TXMLCharPtr nm, const SDOMFlags &inFlags)
+ {
+ for (SDOMAttribute *att = m_FirstAttribute; att != NULL; att = att->m_NextAttribute) {
+ if (att->m_Name == nm)
+ return att;
+ else if (inFlags.CaselessAttributes() && AreEqualCaseless(nm, att->m_Name))
+ return att;
+ }
+ return NULL;
+ }
+ void RemoveAttribute(TXMLCharPtr nm, const SDOMFlags &inFlags)
+ {
+ SDOMAttribute *preatt = m_FirstAttribute;
+ for (SDOMAttribute *att = m_FirstAttribute; att != NULL;
+ preatt = att, att = att->m_NextAttribute) {
+ if (att->m_Name == nm
+ || (inFlags.CaselessAttributes() && AreEqualCaseless(nm, att->m_Name))) {
+ if (att == m_FirstAttribute) {
+ m_FirstAttribute = att->m_NextAttribute;
+ } else {
+ preatt->m_NextAttribute = att->m_NextAttribute;
+ if (att == m_LastAttribute)
+ m_LastAttribute = preatt;
+ }
+
+ att->m_NextAttribute = NULL;
+ }
+ }
+ }
+ TXMLCharPtr GetAttributeValue(TXMLCharPtr nm, SDOMFlags &inFlags) const
+ {
+ const SDOMAttribute *att = FindAttribute(nm, inFlags);
+ if (att)
+ return att->m_Value;
+ return NULL;
+ }
+ void AddChild(SDOMElement &elem)
+ {
+ elem.m_Parent = this;
+ if (m_LastChild) {
+ m_LastChild->m_NextSibling = &elem;
+ m_LastChild = &elem;
+ } else {
+ QT3DS_ASSERT(m_FirstChild == NULL);
+ m_FirstChild = m_LastChild = &elem;
+ }
+ }
+ SDOMElement *FindPreviousChild(SDOMElement &elem)
+ {
+ if (&elem == m_FirstChild)
+ return NULL;
+ // Find the previous sibling.
+ SDOMElement *theChild = m_FirstChild;
+ // Empty loop intentional
+ for (; theChild && theChild->m_NextSibling != &elem; theChild = theChild->m_NextSibling) {
+ }
+
+ return theChild;
+ }
+ void RemoveChild(SDOMElement &elem)
+ {
+ if (elem.m_Parent != this) {
+ QT3DS_ASSERT(false);
+ return;
+ }
+ elem.m_Parent = NULL;
+ if (&elem == m_FirstChild) {
+ m_FirstChild = elem.m_NextSibling;
+ } else {
+ SDOMElement *theChild(FindPreviousChild(elem));
+ QT3DS_ASSERT(theChild);
+ if (theChild) {
+ theChild->m_NextSibling = elem.m_NextSibling;
+ if (&elem == m_LastChild)
+ m_LastChild = theChild;
+ }
+ }
+ elem.m_NextSibling = NULL;
+ }
+
+ void ReplaceChild(SDOMElement &inChild, SDOMElement &inReplacement)
+ {
+ inChild.m_Parent = NULL;
+ if (&inChild == m_FirstChild)
+ m_FirstChild = &inReplacement;
+ else {
+ SDOMElement *theChild(FindPreviousChild(inChild));
+ QT3DS_ASSERT(theChild);
+ if (theChild) {
+ theChild->m_NextSibling = &inReplacement;
+ if (&inChild == m_LastChild)
+ m_LastChild = &inReplacement;
+ }
+ }
+ inReplacement.m_NextSibling = inChild.m_NextSibling;
+ inReplacement.m_Parent = this;
+ inChild.m_NextSibling = NULL;
+ }
+
+ void InsertChildBefore(SDOMElement &elem, SDOMElement &theSibling)
+ {
+ // Ensure elem isn't in the graph.
+ QT3DS_ASSERT(elem.m_Parent == NULL);
+ QT3DS_ASSERT(elem.m_NextSibling == NULL);
+ elem.m_Parent = this;
+ if (&theSibling == m_FirstChild)
+ m_FirstChild = &elem;
+ else {
+ SDOMElement *thePrevious = FindPreviousChild(theSibling);
+ QT3DS_ASSERT(thePrevious);
+ if (thePrevious)
+ thePrevious->m_NextSibling = &elem;
+ }
+
+ elem.m_NextSibling = &theSibling;
+ }
+ QT3DSU32 GetNumChildren(TXMLCharPtr inChildName, const SDOMFlags &inFlags) const
+ {
+ QT3DSU32 idx = 0;
+ for (SDOMElement *elem = m_FirstChild; elem != NULL; elem = elem->m_NextSibling) {
+ if (elem->m_Name == inChildName)
+ ++idx;
+ else if (inFlags.CaselessElements() && AreEqualCaseless(inChildName, elem->m_Name))
+ ++idx;
+ }
+ return idx;
+ }
+ QT3DSU32 GetNumChildren() const
+ {
+ QT3DSU32 idx = 0;
+ for (SDOMElement *elem = m_FirstChild; elem != NULL; elem = elem->m_NextSibling)
+ ++idx;
+ return idx;
+ }
+ SDOMElement *FindChildByName(TXMLCharPtr nm, const SDOMFlags &inFlags) const
+ {
+ for (SDOMElement *elem = m_FirstChild; elem != NULL; elem = elem->m_NextSibling) {
+ if (elem->m_Name == nm)
+ return elem;
+ else if (inFlags.CaselessElements() && AreEqualCaseless(nm, elem->m_Name))
+ return elem;
+ }
+ return NULL;
+ }
+ SDOMElement *FindNextSiblingByName(TXMLCharPtr nm, const SDOMFlags &inFlags) const
+ {
+ for (SDOMElement *elem = m_NextSibling; elem != NULL; elem = elem->m_NextSibling) {
+ if (elem->m_Name == nm)
+ return elem;
+ else if (inFlags.CaselessElements() && AreEqualCaseless(nm, elem->m_Name))
+ return elem;
+ }
+ return NULL;
+ }
+};
+}
+
+namespace {
+
+const QT3DSU16 g_BOMMarker = (QT3DSU16)0xFEFF;
+
+struct SElemPointer : eastl::pair<SDOMElement *, SDOMAttribute *>
+{
+ SElemPointer(SDOMElement *elem = NULL)
+ : eastl::pair<SDOMElement *, SDOMAttribute *>(elem, NULL)
+ {
+ }
+ SElemPointer &operator=(SDOMElement *elem)
+ {
+ first = elem;
+ second = NULL;
+ return *this;
+ }
+ SElemPointer &operator=(SDOMAttribute *att)
+ {
+ second = att;
+ return *this;
+ }
+ SElemPointer &operator=(const eastl::pair<SDOMElement *, SDOMAttribute *> &other)
+ {
+ eastl::pair<SDOMElement *, SDOMAttribute *>::operator=(other);
+ return *this;
+ }
+ operator SDOMElement *() const { return first; }
+ SDOMElement *operator->() const { return first; }
+};
+
+// Some DOM parsing operations are destructive. If you need
+// them to not be destructive, then we need to modify
+// the reader. Specifically parsing lists of floats, due
+// to a bug in strtod, is destructive.
+struct SDOMReader : public IDOMReader
+{
+ SElemPointer m_TopElement;
+ eastl::vector<eastl::pair<SDOMElement *, SDOMAttribute *>> m_ScopeStack;
+ std::shared_ptr<IDOMFactory> m_Factory;
+ SDOMFlags m_Flags;
+ eastl::basic_string<TWCharEASTLConverter::TCharType> m_TempBuffer;
+
+ SDOMReader(SDOMElement &te, std::shared_ptr<qt3dsdm::IStringTable> s,
+ std::shared_ptr<IDOMFactory> inFactory = std::shared_ptr<IDOMFactory>())
+ : IDOMReader(s)
+ , m_TopElement(&te)
+ , m_Factory(inFactory)
+ {
+ }
+
+ SDOMElement *Current() const { return m_TopElement.first; }
+ void SetDOMFlags(SDOMFlags inFlags) override { m_Flags = inFlags; }
+ SDOMFlags GetDOMFlags() const override { return m_Flags; }
+
+ void PushScope() override { m_ScopeStack.push_back(m_TopElement); }
+ void PopScope() override
+ {
+ if (m_ScopeStack.size()) {
+ m_TopElement = m_ScopeStack.back();
+ m_ScopeStack.pop_back();
+ } else
+ m_TopElement = eastl::pair<SDOMElement *, SDOMAttribute *>(NULL, NULL);
+ }
+
+ void *GetScope() override { return m_TopElement.first; }
+
+ void SetScope(void *inScope) override
+ {
+ m_TopElement =
+ eastl::make_pair(reinterpret_cast<SDOMElement *>(inScope), (SDOMAttribute *)NULL);
+ }
+
+ TWideXMLCharPtr GetElementName() const override
+ {
+ return m_StringTable->GetWideStr(GetNarrowElementName());
+ }
+
+ TXMLCharPtr GetNarrowElementName() const override
+ {
+ if (!Current()) {
+ QT3DS_ASSERT(false);
+ return NULL;
+ }
+ return Current()->m_Name;
+ }
+
+ bool UnregisteredAtt(TWideXMLCharPtr name, TWideXMLCharPtr &outValue) override
+ {
+ outValue = L"";
+ SDOMElement *current(Current());
+ if (current) {
+ TXMLCharPtr theValue =
+ current->GetAttributeValue(m_StringTable->GetNarrowStr(name), m_Flags);
+ if (theValue && *theValue) {
+ qt3ds::foundation::ConvertUTF(theValue, 0, m_TempBuffer);
+ outValue = reinterpret_cast<const wchar_t *>(m_TempBuffer.c_str());
+ return true;
+ }
+ } else {
+ QT3DS_ASSERT(false);
+ }
+ return false;
+ }
+
+ bool UnregisteredAtt(TXMLCharPtr name, TXMLCharPtr &outValue) override
+ {
+ outValue = "";
+ SDOMElement *current(Current());
+ if (current) {
+ outValue = current->GetAttributeValue(m_StringTable->GetNarrowStr(name), m_Flags);
+ if (outValue)
+ return true;
+ } else {
+ QT3DS_ASSERT(false);
+ }
+ return false;
+ }
+
+ bool Att(TWideXMLCharPtr name, TWideXMLCharPtr &outValue) override
+ {
+ if (UnregisteredAtt(name, outValue)) {
+ outValue = m_StringTable->RegisterStr(outValue);
+ return true;
+ }
+ return false;
+ }
+ bool Att(TXMLCharPtr name, TXMLCharPtr &outValue) override
+ {
+ if (UnregisteredAtt(name, outValue)) {
+ outValue = m_StringTable->RegisterStr(outValue);
+ return true;
+ }
+ return false;
+ }
+
+ QT3DSU32 CountChildren() override
+ {
+ SDOMElement *elem = Current();
+ if (elem == NULL) {
+ QT3DS_ASSERT(false);
+ return 0;
+ }
+ return elem->GetNumChildren();
+ }
+
+ QT3DSU32 CountChildren(TWideXMLCharPtr childName) override
+ {
+ return CountChildren(m_StringTable->GetNarrowStr(childName));
+ }
+
+ QT3DSU32 CountChildren(TXMLCharPtr childName) override
+ {
+ SDOMElement *elem = Current();
+ if (elem == NULL) {
+ QT3DS_ASSERT(false);
+ return 0;
+ }
+ return elem->GetNumChildren(m_StringTable->GetNarrowStr(childName), m_Flags);
+ }
+
+ eastl::pair<TWideXMLCharPtr, TWideXMLCharPtr>
+ ToWide(const eastl::pair<TXMLCharPtr, TXMLCharPtr> &att)
+ {
+ return eastl::make_pair(m_StringTable->GetWideStr(att.first),
+ m_StringTable->GetWideStr(att.second));
+ }
+ eastl::pair<TWideXMLCharPtr, TWideXMLCharPtr> CurrentAtt()
+ {
+ return ToWide(CurrentAttNarrow());
+ }
+
+ eastl::pair<TXMLCharPtr, TXMLCharPtr> CurrentAttNarrow()
+ {
+ if (m_TopElement.second)
+ return eastl::make_pair(m_TopElement.second->m_Name, m_TopElement.second->m_Value);
+ return eastl::make_pair("", "");
+ }
+ eastl::pair<TXMLCharPtr, TXMLCharPtr> GetNarrowFirstAttribute() override
+ {
+ if (m_TopElement.first == NULL) {
+ QT3DS_ASSERT(false);
+ eastl::make_pair("", "");
+ }
+ m_TopElement.second = m_TopElement.first->m_FirstAttribute;
+ return CurrentAttNarrow();
+ }
+
+ eastl::pair<TWideXMLCharPtr, TWideXMLCharPtr> GetFirstAttribute() override
+ {
+ return ToWide(GetNarrowFirstAttribute());
+ }
+ eastl::pair<TXMLCharPtr, TXMLCharPtr> GetNarrowNextAttribute() override
+ {
+ if (m_TopElement.second)
+ m_TopElement.second = m_TopElement.second->m_NextAttribute;
+ return CurrentAttNarrow();
+ }
+
+ eastl::pair<TWideXMLCharPtr, TWideXMLCharPtr> GetNextAttribute() override
+ {
+ return ToWide(GetNarrowNextAttribute());
+ }
+
+ bool MoveToFirstChild() override
+ {
+ SDOMElement *elem = Current();
+ if (elem == NULL) {
+ QT3DS_ASSERT(false);
+ return false;
+ }
+ if (elem->m_FirstChild) {
+ m_TopElement = elem->m_FirstChild;
+ return true;
+ }
+ return false;
+ }
+ bool MoveToFirstChild(TXMLCharPtr childName) override
+ {
+ SDOMElement *elem = Current();
+ if (elem == NULL) {
+ QT3DS_ASSERT(false);
+ return false;
+ }
+ SDOMElement *child = elem->FindChildByName(m_StringTable->RegisterStr(childName), m_Flags);
+ if (child != NULL) {
+ m_TopElement = child;
+ return true;
+ }
+ return false;
+ }
+
+ bool MoveToFirstChild(TWideXMLCharPtr childName) override
+ {
+ return MoveToFirstChild(m_StringTable->GetNarrowStr(childName));
+ }
+
+ bool MoveToNextSibling() override
+ {
+ SDOMElement *elem = Current();
+ if (elem == NULL) {
+ QT3DS_ASSERT(false);
+ return false;
+ }
+ if (elem->m_NextSibling) {
+ m_TopElement = elem->m_NextSibling;
+ return true;
+ }
+ return false;
+ }
+ bool MoveToNextSibling(TXMLCharPtr childName) override
+ {
+ SDOMElement *elem = Current();
+ if (elem == NULL) {
+ QT3DS_ASSERT(false);
+ return false;
+ }
+ SDOMElement *nextSibling =
+ elem->FindNextSiblingByName(m_StringTable->RegisterStr(childName), m_Flags);
+ if (nextSibling) {
+ m_TopElement = nextSibling;
+ return true;
+ }
+ return false;
+ }
+ bool MoveToNextSibling(TWideXMLCharPtr childName) override
+ {
+ return MoveToNextSibling(m_StringTable->GetNarrowStr(childName));
+ }
+ // Leave element means go to its parent.
+ void Leave() override
+ {
+ if (m_TopElement)
+ m_TopElement = m_TopElement->m_Parent;
+
+ QT3DS_ASSERT(m_TopElement);
+ }
+ bool Value(TXMLCharPtr &outValue) override
+ {
+ SDOMElement *current(Current());
+ if (!current) {
+ QT3DS_ASSERT(false);
+ return false;
+ }
+ outValue = current->m_Value;
+ return true;
+ }
+
+ bool Value(TWideXMLCharPtr &outValue) override
+ {
+ outValue = L"";
+ TXMLCharPtr theValue;
+ if (Value(theValue)) {
+ qt3ds::foundation::ConvertUTF(theValue, 0, m_TempBuffer);
+ outValue = reinterpret_cast<const wchar_t *>(m_TempBuffer.c_str());
+ return true;
+ }
+ return false;
+ }
+
+ SDOMElement *GetTopElement() override
+ {
+ SDOMElement *current(Current());
+ while (current && current->m_Parent)
+ current = current->m_Parent;
+ return current;
+ }
+
+ virtual std::shared_ptr<IDOMFactory> GetFactory() { return m_Factory; }
+};
+
+struct SDOMWriter : public IDOMWriter, public SDOMReader
+{
+ std::shared_ptr<IDOMFactory> m_FactoryPtr;
+ IDOMFactory &m_Factory;
+
+ SDOMWriter(std::shared_ptr<IDOMFactory> inDOMFactory,
+ std::shared_ptr<qt3dsdm::IStringTable> inStringTable, SDOMElement &inTopElem)
+ : m_FactoryPtr(inDOMFactory)
+ , m_Factory(*inDOMFactory)
+ , SDOMReader(inTopElem, inStringTable)
+ {
+ }
+ void SetDOMFlags(SDOMFlags inFlags) override { m_Flags = inFlags; }
+ SDOMFlags GetDOMFlags() const override { return m_Flags; }
+
+ void Begin(TXMLCharPtr inElemName) override
+ {
+ if (!m_TopElement) {
+ QT3DS_ASSERT(false);
+ return;
+ }
+ SDOMElement *current(Current());
+ SDOMElement *newElement(m_Factory.NextElement(inElemName));
+ current->AddChild(*newElement);
+ m_TopElement = newElement;
+ }
+
+ void Begin(TWideXMLCharPtr inElemName) override
+ {
+ Begin(m_FactoryPtr->GetStringTable()->GetNarrowStr(inElemName));
+ }
+
+ void Att(TXMLCharPtr name, TXMLCharPtr value) override
+ {
+ if (!m_TopElement) {
+ QT3DS_ASSERT(false);
+ return;
+ }
+ m_TopElement->SetAttributeValue(name, value, m_Factory, m_Flags);
+ }
+ // Attributes. They may be sorted just before write
+ void Att(TWideXMLCharPtr name, TWideXMLCharPtr value) override
+ {
+ if (!m_TopElement) {
+ QT3DS_ASSERT(false);
+ return;
+ }
+ m_TopElement->SetAttributeValue(name, value, m_Factory, m_Flags);
+ }
+
+ void Value(TWideXMLCharPtr value) override
+ {
+ if (!m_TopElement) {
+ QT3DS_ASSERT(false);
+ return;
+ }
+ if (value == NULL)
+ value = L"";
+ size_t len = wcslen(value);
+ m_Factory.AppendStrBuf(value, (QT3DSU32)len);
+ m_TopElement->m_Value = m_Factory.FinalizeStrBuf();
+ }
+ void Value(TXMLCharPtr value) override
+ {
+ if (!m_TopElement) {
+ QT3DS_ASSERT(false);
+ return;
+ }
+ if (value == NULL)
+ value = "";
+ size_t len = strlen(value);
+ m_Factory.AppendStrBuf(value, (QT3DSU32)len);
+ m_TopElement->m_Value = m_Factory.FinalizeStrBuf();
+ }
+
+ void End() override
+ {
+ if (!m_TopElement) {
+ QT3DS_ASSERT(false);
+ return;
+ }
+ Leave();
+ }
+ void RemoveCurrent() override
+ {
+ SDOMElement *current(Current());
+ if (!current) {
+ QT3DS_ASSERT(false);
+ return;
+ }
+ if (current->m_Parent) {
+ m_TopElement = current->m_Parent;
+ m_TopElement->RemoveChild(*current);
+ }
+ }
+ void ReplaceCurrent(SDOMElement &inElement) override
+ {
+ SDOMElement *current(Current());
+ if (!current) {
+ QT3DS_ASSERT(false);
+ return;
+ }
+ if (current->m_Parent) {
+ current->m_Parent->ReplaceChild(*current, inElement);
+ m_TopElement = &inElement;
+ } else {
+ m_TopElement = &inElement;
+ inElement.m_Parent = NULL;
+ inElement.m_NextSibling = NULL;
+ }
+ }
+ void AppendChildren(SDOMElement &inElement) override
+ {
+ SDOMElement *current(Current());
+ if (!current) {
+ QT3DS_ASSERT(false);
+ return;
+ }
+ SDOMElement *theChild = inElement.m_FirstChild;
+ inElement.m_FirstChild = inElement.m_LastChild = NULL;
+ while (theChild) {
+ SDOMElement *theCurrentChild = theChild;
+ theChild = theChild->m_NextSibling;
+
+ theCurrentChild->m_Parent = NULL;
+ theCurrentChild->m_NextSibling = NULL;
+ current->AddChild(*theCurrentChild);
+ }
+ }
+ void RemoveAttribute(TXMLCharPtr inItem) override
+ {
+ SDOMElement *current(Current());
+ if (!current) {
+ QT3DS_ASSERT(false);
+ return;
+ }
+ current->RemoveAttribute(m_StringTable->RegisterStr(inItem), m_Flags);
+ }
+ void RemoveAttribute(TWideXMLCharPtr inItem) override
+ {
+ RemoveAttribute(m_StringTable->GetNarrowStr(inItem));
+ }
+
+ void MoveBefore(TXMLCharPtr inItem, TXMLCharPtr inSibling) override
+ {
+ SDOMElement *current(Current());
+ if (!current) {
+ QT3DS_ASSERT(false);
+ return;
+ }
+
+ SDOMElement *theItem =
+ current->FindChildByName(m_StringTable->RegisterStr(inItem), m_Flags);
+ SDOMElement *theSibling =
+ current->FindChildByName(m_StringTable->RegisterStr(inSibling), m_Flags);
+ QT3DS_ASSERT(theItem && theSibling);
+ if (theItem && theSibling) {
+ current->RemoveChild(*theItem);
+ current->InsertChildBefore(*theItem, *theSibling);
+ }
+ }
+
+ void MoveBefore(TWideXMLCharPtr inItem, TWideXMLCharPtr inSibling) override
+ {
+ MoveBefore(m_StringTable->GetNarrowStr(inItem), m_StringTable->GetNarrowStr(inSibling));
+ }
+
+ // If current has no parent, then we are at the top
+ // of the tree and we should return 0. Or if there is no
+ // current.
+ // If there is one parent, we should return 1.
+ QT3DSU32 GetTabs() override
+ {
+ QT3DSU32 retval = 0;
+ SDOMElement *current(Current());
+ do {
+ if (current)
+ current = current->m_Parent;
+ if (current)
+ ++retval;
+ } while (current);
+ return retval;
+ }
+
+ SDOMElement *GetTopElement() override { return SDOMReader::GetTopElement(); }
+
+ std::shared_ptr<IDOMFactory> GetFactory() override { return m_FactoryPtr; }
+};
+
+struct SimpleXmlWriter
+{
+ IOutStream &m_Stream;
+ eastl::vector<eastl::pair<TXMLCharPtr, bool>> m_OpenElements;
+ bool m_ElementOpen;
+ wchar_t m_PrintBuf[256];
+ QT3DSU32 m_Tabs;
+ eastl::basic_string<char8_t> m_ConvertBuf;
+ eastl::basic_string<TWCharEASTLConverter::TCharType> m_WideBuffer;
+
+ SimpleXmlWriter(IOutStream &stream, QT3DSU32 inTabs = 0)
+ : m_Stream(stream)
+ , m_ElementOpen(false)
+ , m_Tabs(inTabs)
+ {
+ }
+ void Write(TWideXMLCharPtr data)
+ {
+ if (!IsTrivial(data)) {
+ qt3ds::foundation::ConvertUTF(
+ reinterpret_cast<const TWCharEASTLConverter::TCharType *>(data), 0,
+ m_ConvertBuf);
+ m_Stream.Write(m_ConvertBuf.begin(), m_ConvertBuf.size());
+ }
+ }
+ void Write(const char8_t *data)
+ {
+ if (!IsTrivial(data)) {
+ m_Stream.Write(data, (QT3DSU32)strlen(data));
+ }
+ }
+ void BeginWideWrite() { m_WideBuffer.clear(); }
+ void WriteTemp(wchar_t data) { m_WideBuffer.append(1, data); }
+ void WriteTemp(const wchar_t *data)
+ {
+ m_WideBuffer.append(reinterpret_cast<const TWCharEASTLConverter::TCharType *>(data));
+ }
+ void EndWideWrite() { Write(reinterpret_cast<const wchar_t *>(m_WideBuffer.c_str())); }
+ void Write(char8_t data) { m_Stream.Write(data); }
+ void Tabs()
+ {
+ QT3DSXML_FOREACH(idx, (m_OpenElements.size() + m_Tabs))
+ Write('\t');
+ }
+ void Close(bool newline)
+ {
+ if (m_ElementOpen) {
+ Write(L" >");
+ if (newline)
+ Write('\n');
+ }
+ m_ElementOpen = false;
+ }
+ void Begin(TXMLCharPtr name)
+ {
+ Close(true);
+ Tabs();
+ Write('<');
+ Write(name);
+ m_OpenElements.push_back(eastl::pair<TXMLCharPtr, bool>(name, false));
+ m_ElementOpen = true;
+ }
+ TWideXMLCharPtr ToStr(char8_t val)
+ {
+ m_PrintBuf[0] = val;
+ m_PrintBuf[1] = 0;
+ return m_PrintBuf;
+ }
+ template <typename TDataType>
+ TWideXMLCharPtr ToStr(TDataType val)
+ {
+ WStrOps<TDataType>().ToStr(val, NVDataRef<wchar_t>(m_PrintBuf, 256));
+ return m_PrintBuf;
+ }
+ void Att(TXMLCharPtr name, TXMLCharPtr value)
+ {
+ QT3DS_ASSERT(m_ElementOpen);
+ Write(' ');
+ Write(name);
+ Write("=\"");
+ QString str = QString::fromUtf8(nonNull(value)).toHtmlEscaped();
+ Write(str.toUtf8().constData());
+ Write("\"");
+ }
+ template <typename TData>
+ void Att(TXMLCharPtr name, TData value)
+ {
+ Att(name, ToStr(value));
+ }
+
+ void Value(TXMLCharPtr value)
+ {
+ if (!IsTrivial(value)) {
+ Close(false);
+ QString str = QString::fromUtf8(nonNull(value)).toHtmlEscaped();
+ Write(str.toUtf8().constData());
+ m_OpenElements.back().second = true;
+ }
+ }
+ void ChildValue(TXMLCharPtr name, TXMLCharPtr value)
+ {
+ Begin(name);
+ Value(value);
+ End();
+ }
+ void End(bool newlineAfterClose = true)
+ {
+ QT3DS_ASSERT(m_OpenElements.size());
+ eastl::pair<TXMLCharPtr, bool> topElem = m_OpenElements.back();
+ m_OpenElements.pop_back();
+ if (m_ElementOpen)
+ Write(" />");
+ else {
+ if (topElem.second == false)
+ Tabs();
+ Write("</");
+ Write(topElem.first);
+ Write(">");
+ }
+ m_ElementOpen = false;
+ if (newlineAfterClose == true)
+ Write('\n');
+ }
+};
+
+struct DOMParser
+{
+ typedef eastl::basic_string<TWCharEASTLConverter::TCharType> TStrType;
+ IDOMFactory &m_Factory;
+ SDOMElement *m_TopElement;
+ SDOMElement *m_FirstElement;
+
+ DOMParser(IDOMFactory &factory)
+ : m_Factory(factory)
+ , m_FirstElement(NULL)
+ {
+ }
+
+ template <QT3DSU32 THeaderLen>
+ struct SHeaderInStream : public IInStream
+ {
+ QT3DSU8 m_Header[THeaderLen];
+ QT3DSU32 m_BytesRead;
+ IInStream &m_InStream;
+ SHeaderInStream(IInStream &inStream)
+ : m_InStream(inStream)
+ , m_BytesRead(0)
+ {
+ }
+ bool readHeader()
+ {
+ QT3DSU32 amountRead = m_InStream.Read(NVDataRef<QT3DSU8>(m_Header, THeaderLen));
+ return amountRead == THeaderLen;
+ }
+ QT3DSU32 Read(NVDataRef<QT3DSU8> data) override
+ {
+ if (data.size() == 0)
+ return 0;
+ QT3DSU8 *writePtr(data.begin());
+ QT3DSU32 amountToRead(data.size());
+ QT3DSU32 amountRead = 0;
+ if (m_BytesRead < THeaderLen) {
+ QT3DSU32 headerLeft = qMin(THeaderLen - m_BytesRead, amountToRead);
+ memCopy(writePtr, m_Header + m_BytesRead, headerLeft);
+ writePtr += headerLeft;
+ amountToRead -= headerLeft;
+ amountRead += headerLeft;
+ }
+ if (amountToRead)
+ amountRead += m_InStream.Read(NVDataRef<QT3DSU8>(writePtr, amountToRead));
+ m_BytesRead += amountRead;
+ return amountRead;
+ }
+ };
+
+ static SDOMElement *ParseXMLFile(IDOMFactory &factory, IInStream &inStream,
+ CXmlErrorHandler *handler = NULL)
+ {
+ QXmlStreamReader sreader;
+
+ DOMParser domParser(factory);
+ QT3DSU8 dataBuf[2048];
+ QT3DSU32 amountRead = 0;
+ do {
+ amountRead = inStream.Read(toDataRef(dataBuf, 2048));
+ if (amountRead) {
+ QByteArray tmp = QByteArray::fromRawData((char*)dataBuf,amountRead);
+ sreader.addData(tmp);
+ }
+ } while (amountRead > 0);
+
+ while (!sreader.atEnd()) {
+ QXmlStreamReader::TokenType token = sreader.readNext();
+
+ if (token == QXmlStreamReader::StartElement) {
+ domParser.m_Factory.IgnoreStrBuf();
+ SDOMElement *newElem = domParser.m_Factory.NextElement(
+ (TXMLCharPtr)sreader.name().toUtf8().data());
+ if (domParser.m_FirstElement == NULL) {
+ domParser.m_FirstElement = newElem;
+ domParser.m_TopElement = newElem;
+ } else {
+ domParser.m_TopElement->AddChild(*newElem);
+ domParser.m_TopElement = newElem;
+ }
+ const QXmlStreamAttributes& attributes = sreader.attributes();
+ for (auto attrib : attributes) {
+ SDOMAttribute *att = domParser.m_Factory.NextAttribute(
+ (TXMLCharPtr)attrib.name().toUtf8().data(),
+ (TXMLCharPtr)attrib.value().toUtf8().data());
+ newElem->AddAttribute(*att);
+ }
+ } else if (token == QXmlStreamReader::Characters) {
+ QByteArray text = sreader.text().toUtf8();
+ domParser.m_Factory.AppendStrBuf(text.data(),text.length());
+ } else if (token == QXmlStreamReader::EndElement) {
+ domParser.m_TopElement->m_Value = domParser.m_Factory.FinalizeStrBuf();
+ domParser.m_TopElement = domParser.m_TopElement->m_Parent;
+ }
+ if (sreader.hasError()) {
+ if (handler) {
+ handler->OnXmlError(sreader.errorString(), sreader.lineNumber(),
+ sreader.columnNumber());
+ } else {
+ qWarning() << "XML parse error:" << sreader.errorString()
+ << "line:" << sreader.lineNumber()
+ << "column:" << sreader.columnNumber();
+ }
+ return nullptr;
+ }
+ }
+ return domParser.m_FirstElement;
+ }
+};
+
+class SimpleDomFactory : public IDOMFactory
+{
+ typedef eastl::basic_string<char8_t> TNarrowStr;
+ Pool<SDOMElement> m_ElementPool;
+ Pool<SDOMAttribute> m_AttributePool;
+ eastl::vector<char8_t *> m_BigStrings;
+ eastl::vector<char8_t> m_StringBuilder;
+ TNarrowStr m_ConvertBuffer;
+ std::shared_ptr<qt3dsdm::IStringTable> m_StringTable;
+
+public:
+ SimpleDomFactory(std::shared_ptr<qt3dsdm::IStringTable> strt)
+ : m_StringTable(strt)
+ {
+ }
+ ~SimpleDomFactory()
+ {
+ QT3DSXML_FOREACH(idx, m_BigStrings.size())
+ free(m_BigStrings[idx]);
+ }
+
+ TWideXMLCharPtr RegisterStr(TWideXMLCharPtr str)
+ {
+ if (str == NULL || *str == 0)
+ return L"";
+ return m_StringTable->RegisterStr(str);
+ }
+
+ TXMLCharPtr RegisterStr(TXMLCharPtr str)
+ {
+ if (str == NULL || *str == 0)
+ return "";
+ return m_StringTable->RegisterStr(str);
+ }
+
+ void Release() override { delete this; }
+ void AppendStrBuf(TXMLCharPtr str, QT3DSU32 len) override
+ {
+ if (len && *str) {
+ QT3DSU32 offset = m_StringBuilder.size();
+ m_StringBuilder.resize(offset + len);
+ memCopy(&m_StringBuilder[0] + offset, str, len * sizeof(char8_t));
+ }
+ }
+ // Str does not need to be null terminated.
+ void AppendStrBuf(TWideXMLCharPtr str, QT3DSU32 len) override
+ {
+ if (len && *str) {
+ const TWCharEASTLConverter::TCharType *bufPtr =
+ reinterpret_cast<const TWCharEASTLConverter::TCharType *>(str);
+ qt3ds::foundation::ConvertUTF(bufPtr, len, m_ConvertBuffer);
+ AppendStrBuf(m_ConvertBuffer.data(), m_ConvertBuffer.size());
+ }
+ }
+
+ // Null terminate what is there and return the buffer.
+ // This pointer needs to be persistent.
+ TXMLCharPtr FinalizeStrBuf() override
+ {
+ if (m_StringBuilder.size() == 0)
+ return "";
+ m_StringBuilder.push_back(0);
+ QT3DSU32 len = m_StringBuilder.size();
+ QT3DSU32 numBytes = len * sizeof(char8_t);
+ char8_t *newMem = (char8_t *)malloc(numBytes);
+ memCopy(newMem, &m_StringBuilder[0], numBytes);
+ m_BigStrings.push_back(newMem);
+ m_StringBuilder.clear();
+ return newMem;
+ }
+ void IgnoreStrBuf() override { m_StringBuilder.clear(); }
+
+ SDOMAttribute *NextAttribute(TXMLCharPtr name, TXMLCharPtr val) override
+ {
+ TXMLCharPtr n(m_StringTable->GetNarrowStr(name));
+ TXMLCharPtr v(RegisterValue(val));
+ return m_AttributePool.construct(n, v, __FILE__, __LINE__);
+ }
+
+ SDOMAttribute *NextAttribute(TWideXMLCharPtr name, TWideXMLCharPtr val) override
+ {
+ TXMLCharPtr n(m_StringTable->GetNarrowStr(name));
+ TXMLCharPtr v(RegisterValue(val));
+ return m_AttributePool.construct(n, v, __FILE__, __LINE__);
+ }
+
+ SDOMElement *NextElement(TXMLCharPtr name) override
+ {
+ IgnoreStrBuf();
+ TXMLCharPtr n(m_StringTable->GetNarrowStr(name));
+ return m_ElementPool.construct(n, __FILE__, __LINE__);
+ }
+ SDOMElement *NextElement(TWideXMLCharPtr name) override
+ {
+ IgnoreStrBuf();
+ TXMLCharPtr n(m_StringTable->GetNarrowStr(name));
+ return m_ElementPool.construct(n, __FILE__, __LINE__);
+ }
+
+ std::shared_ptr<qt3dsdm::IStringTable> GetStringTable() override { return m_StringTable; }
+};
+}
+
+bool IDOMReader::Value(DataModelDataType::Value type, SValue &outValue)
+{
+ TXMLCharPtr value;
+ if (Value(value)) {
+ WCharTReader reader(const_cast<char8_t *>(value), m_TempBuf, *GetStringTable());
+ outValue = WStrOps<SValue>().BufTo(type, reader);
+ return true;
+ }
+ return false;
+}
+
+std::shared_ptr<IDOMReader>
+IDOMReader::CreateDOMReader(SDOMElement &inRootElement,
+ std::shared_ptr<qt3dsdm::IStringTable> inStringTable,
+ std::shared_ptr<IDOMFactory> inFactory)
+{
+ return std::make_shared<SDOMReader>(std::ref(inRootElement), std::ref(inStringTable),
+ inFactory);
+}
+
+eastl::pair<std::shared_ptr<IDOMWriter>, std::shared_ptr<IDOMReader>>
+IDOMWriter::CreateDOMWriter(std::shared_ptr<IDOMFactory> inFactory, SDOMElement &inRootElement,
+ std::shared_ptr<qt3dsdm::IStringTable> inStringTable)
+{
+ std::shared_ptr<SDOMWriter> writer(std::make_shared<SDOMWriter>(
+ inFactory, std::ref(inStringTable), std::ref(inRootElement)));
+ return eastl::make_pair(writer, writer);
+}
+
+TXMLCharPtr IDOMFactory::RegisterValue(TWideXMLCharPtr inValue)
+{
+ if (IsTrivial(inValue))
+ return "";
+ IgnoreStrBuf();
+ AppendStrBuf(inValue, (QT3DSU32)wcslen(inValue));
+ return FinalizeStrBuf();
+}
+
+TXMLCharPtr IDOMFactory::RegisterValue(TXMLCharPtr inValue)
+{
+ if (IsTrivial(inValue))
+ return "";
+ IgnoreStrBuf();
+ AppendStrBuf(inValue, (QT3DSU32)strlen(inValue));
+ return FinalizeStrBuf();
+}
+
+std::shared_ptr<IDOMFactory>
+IDOMFactory::CreateDOMFactory(std::shared_ptr<qt3dsdm::IStringTable> inStrTable)
+{
+ return std::make_shared<SimpleDomFactory>(std::ref(inStrTable));
+}
+
+void CDOMSerializer::WriteXMLHeader(IOutStream &inStream)
+{
+ SimpleXmlWriter writer(inStream);
+ writer.Write("<?xml version=\"1.0\" encoding=\"UTF-8\" ?>\n");
+}
+
+// Lexigraphically sort the attributes.
+struct SAttributeComparator
+{
+ bool operator()(const SDOMAttribute *lhs, const SDOMAttribute *rhs)
+ {
+ return strcmp(lhs->m_Name, rhs->m_Name) < 0;
+ }
+};
+
+// Write an element with attributes sorted by name so a file diff is effective.
+void WriteElement(SDOMElement &inElement, SimpleXmlWriter &inWriter,
+ std::vector<SDOMAttribute *> &inAttSorter)
+{
+ inAttSorter.clear();
+ for (SDOMAttribute *att = inElement.m_FirstAttribute; att; att = att->m_NextAttribute)
+ inAttSorter.push_back(att);
+ // We decided that we don't want attribute sorting; the code that adds attributes needs
+ // to be consistent.
+ // std::sort( inAttSorter.begin(), inAttSorter.end(), SAttributeComparator() );
+ // This element doesn't add anything to the system in this case.
+ if (inElement.m_FirstAttribute == NULL && inElement.m_FirstChild == NULL
+ && IsTrivial(inElement.m_Value))
+ return;
+
+ inWriter.Begin(inElement.m_Name);
+
+ const char8_t *theLastAttName = 0;
+ for (size_t idx = 0, end = inAttSorter.size(); idx < end; ++idx) {
+ SDOMAttribute *theAtt(inAttSorter[idx]);
+ if (theAtt->m_Name != theLastAttName)
+ inWriter.Att(theAtt->m_Name, theAtt->m_Value);
+ else {
+ QT3DS_ASSERT(false);
+ }
+ theLastAttName = theAtt->m_Name;
+ }
+ // Elements can either have children or values but not both at this point.
+ if (inElement.m_FirstChild) {
+ for (SDOMElement *theChild = inElement.m_FirstChild; theChild;
+ theChild = theChild->m_NextSibling)
+ WriteElement(*theChild, inWriter, inAttSorter);
+ inWriter.End();
+ } else {
+ if (!IsTrivial(inElement.m_Value))
+ inWriter.Value(inElement.m_Value);
+
+ inWriter.End();
+ }
+}
+
+void CDOMSerializer::Write(SDOMElement &inElement, IOutStream &inStream, QT3DSU32 inTabs)
+{
+ // TODO: QXmlStreamWriter here?
+ std::vector<SDOMAttribute *> theAttributes;
+ SimpleXmlWriter writer(inStream, inTabs);
+ std::vector<SDOMAttribute *> theAttSorter;
+ WriteElement(inElement, writer, theAttSorter);
+}
+
+SDOMElement *CDOMSerializer::Read(IDOMFactory &inFactory, IInStream &inStream,
+ CXmlErrorHandler *inErrorHandler)
+{
+ return DOMParser::ParseXMLFile(inFactory, inStream, inErrorHandler);
+}
diff --git a/src/dm/systems/Qt3DSDMXML.h b/src/dm/systems/Qt3DSDMXML.h
new file mode 100644
index 0000000..5fe722f
--- /dev/null
+++ b/src/dm/systems/Qt3DSDMXML.h
@@ -0,0 +1,506 @@
+/****************************************************************************
+**
+** 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 QT3DS_IMPORT_XML_H
+#define QT3DS_IMPORT_XML_H
+#include "foundation/Qt3DS.h"
+#include "foundation/Qt3DSMemoryBuffer.h"
+#include "Qt3DSDMDataTypes.h"
+#include <string>
+#include "Qt3DSDMWStrOps.h" //Conversion between string and various datatypes.
+#include "foundation/Qt3DSFlags.h"
+#include "EASTL/algorithm.h"
+#include "foundation/Qt3DSSimpleTypes.h"
+#include "foundation/IOStreams.h"
+#include "Qt3DSDMValue.h"
+#include <memory>
+
+namespace qt3dsdm {
+using qt3ds::foundation::MemoryBuffer;
+using qt3ds::foundation::RawAllocator;
+class IStringTable;
+
+class IDOMFactory;
+struct SDOMAttribute;
+struct SDOMElement;
+
+typedef const char8_t *TXMLCharPtr;
+typedef const wchar_t *TWideXMLCharPtr;
+
+typedef TCharStr TXMLWideStr;
+typedef eastl::basic_string<char8_t> TXMLStr;
+
+using qt3ds::QT3DSU32;
+using qt3ds::NVFlags;
+using qt3ds::foundation::NVDataRef;
+using qt3ds::foundation::NVConstDataRef;
+using qt3ds::foundation::IOutStream;
+
+class IDOMFactory
+{
+protected:
+ virtual ~IDOMFactory() {}
+public:
+ friend class std::shared_ptr<IDOMFactory>;
+
+ virtual void Release() = 0;
+ // Str does not need to be null terminated.
+ virtual void AppendStrBuf(TXMLCharPtr str, QT3DSU32 len) = 0;
+ virtual void AppendStrBuf(TWideXMLCharPtr str, QT3DSU32 len) = 0;
+ // Null terminate what is there and return the buffer.
+ // This pointer needs to be persistent.
+ virtual TXMLCharPtr FinalizeStrBuf() = 0;
+ virtual void IgnoreStrBuf() = 0;
+
+ virtual std::shared_ptr<IStringTable> GetStringTable() = 0;
+
+ virtual SDOMAttribute *NextAttribute(TWideXMLCharPtr name, TWideXMLCharPtr val) = 0;
+ virtual SDOMElement *NextElement(TWideXMLCharPtr name) = 0;
+
+ virtual SDOMAttribute *NextAttribute(TXMLCharPtr name, TXMLCharPtr val) = 0;
+ virtual SDOMElement *NextElement(TXMLCharPtr name) = 0;
+
+ TXMLCharPtr RegisterValue(TXMLCharPtr inValue);
+ TXMLCharPtr RegisterValue(TWideXMLCharPtr inValue);
+
+ static std::shared_ptr<IDOMFactory>
+ CreateDOMFactory(std::shared_ptr<IStringTable> inStrTable);
+};
+
+struct DOMFlagValues
+{
+ enum Enum {
+ CaselessElementNames = 1 << 0,
+ CaselessAttributeNames = 1 << 1,
+ };
+};
+
+struct SDOMFlags : NVFlags<DOMFlagValues::Enum, int>
+{
+ SDOMFlags()
+ : NVFlags<DOMFlagValues::Enum, int>(DOMFlagValues::CaselessElementNames
+ | DOMFlagValues::CaselessAttributeNames)
+ {
+ }
+ bool CaselessAttributes() const { return *this & DOMFlagValues::CaselessAttributeNames; }
+ bool CaselessElements() const { return *this & DOMFlagValues::CaselessElementNames; }
+};
+
+class IDOMReader
+{
+protected:
+ virtual ~IDOMReader() {}
+public:
+ friend class std::shared_ptr<IDOMReader>;
+
+ // Stack object to save the reader's state.
+ struct Scope
+ {
+ IDOMReader &m_Reader;
+ Scope(IDOMReader &reader)
+ : m_Reader(reader)
+ {
+ m_Reader.PushScope();
+ }
+ ~Scope() { m_Reader.PopScope(); }
+ };
+
+ // Parse buffer
+ MemoryBuffer<RawAllocator> m_TempBuf;
+ std::shared_ptr<IStringTable> m_StringTable;
+
+ IDOMReader(std::shared_ptr<IStringTable> inStringTable)
+ : m_StringTable(inStringTable)
+ {
+ }
+
+ std::shared_ptr<IStringTable> GetStringTable() { return m_StringTable; }
+
+ // DOM reader flags change the nature of the DOM reader.
+ // see DOMFlagValues
+ // Defaults to caseless comparisons for attributes and for
+ // element names.
+ virtual void SetDOMFlags(SDOMFlags inFlags) = 0;
+ virtual SDOMFlags GetDOMFlags() const = 0;
+
+ // Pushing scope saves your state so no matter where you are when
+ // you next pop scope, you come back to the same state.
+ virtual void PushScope() = 0;
+ virtual void PopScope() = 0;
+
+ // Sometimes pushing and popping scope isn't enough and you need
+ // somewhat random access to scope.
+ // This scope does not remember the current attribute.
+ virtual void *GetScope() = 0;
+ virtual void SetScope(void *inScope) = 0;
+ // Return an attribute whose value is *not* registered with the string table.
+ // You can't hold onto this value for any length of time, but when you need to
+ // immediately convert to a different value this is the most efficient way.
+ virtual bool UnregisteredAtt(TWideXMLCharPtr name, TWideXMLCharPtr &outValue) = 0;
+ virtual bool UnregisteredAtt(TXMLCharPtr name, TXMLCharPtr &outValue) = 0;
+ // Return an attribute whose value *is* registered with the string table.
+ virtual bool Att(TWideXMLCharPtr name, TWideXMLCharPtr &outValue) = 0;
+ virtual bool Att(TXMLCharPtr name, TXMLCharPtr &outValue) = 0;
+ virtual eastl::pair<TWideXMLCharPtr, TWideXMLCharPtr> GetFirstAttribute() = 0;
+ virtual eastl::pair<TWideXMLCharPtr, TWideXMLCharPtr> GetNextAttribute() = 0;
+ virtual eastl::pair<TXMLCharPtr, TXMLCharPtr> GetNarrowFirstAttribute() = 0;
+ virtual eastl::pair<TXMLCharPtr, TXMLCharPtr> GetNarrowNextAttribute() = 0;
+ virtual QT3DSU32 CountChildren() = 0;
+ virtual QT3DSU32 CountChildren(TWideXMLCharPtr childName) = 0;
+ virtual QT3DSU32 CountChildren(TXMLCharPtr childName) = 0;
+ virtual bool MoveToFirstChild(TWideXMLCharPtr childName) = 0;
+ virtual bool MoveToFirstChild(TXMLCharPtr childName) = 0;
+ virtual bool MoveToFirstChild() = 0;
+ virtual bool MoveToNextSibling(TWideXMLCharPtr siblingName) = 0;
+ virtual bool MoveToNextSibling(TXMLCharPtr siblingName) = 0;
+ virtual bool MoveToNextSibling() = 0;
+ // Leave element means go to its parent.
+ virtual void Leave() = 0;
+ virtual TWideXMLCharPtr GetElementName() const = 0;
+ virtual TXMLCharPtr GetNarrowElementName() const = 0;
+
+ // Value is the concatentated text node values inside the element
+ virtual bool Value(TWideXMLCharPtr &outValue) = 0;
+ virtual bool Value(TXMLCharPtr &outValue) = 0;
+
+ // Get the element this reader was created with
+ virtual SDOMElement *GetTopElement() = 0;
+
+ bool Att(TWideXMLCharPtr name, TXMLWideStr &outValue)
+ {
+ TWideXMLCharPtr temp;
+ if (UnregisteredAtt(name, temp)) {
+ outValue.assign(temp);
+ return true;
+ }
+ return false;
+ }
+
+ bool Att(TXMLCharPtr name, TXMLStr &outValue)
+ {
+ TXMLCharPtr temp;
+ if (UnregisteredAtt(name, temp)) {
+ outValue.assign(temp);
+ return true;
+ }
+ return false;
+ }
+
+ // Helpers to help make the parsing a bit easier.
+ template <typename TDataType>
+ bool Att(TWideXMLCharPtr name, TDataType &outValue)
+ {
+ TWideXMLCharPtr temp;
+ if (UnregisteredAtt(name, temp)) {
+ WStrOps<TDataType>().StrTo(temp, outValue);
+ return true;
+ } else {
+ return false;
+ }
+ }
+ template <typename TDataType>
+ bool Att(TXMLCharPtr name, TDataType &outValue)
+ {
+ TXMLCharPtr temp;
+ if (UnregisteredAtt(name, temp)) {
+ WStrOps<TDataType>().StrTo(temp, outValue);
+ return true;
+ } else {
+ return false;
+ }
+ }
+
+ bool ChildValue(TXMLCharPtr name, TXMLCharPtr &value)
+ {
+ if (MoveToFirstChild(name)) {
+ Value(value);
+ Leave();
+ return true;
+ }
+ return false;
+ }
+
+ bool ChildValue(TWideXMLCharPtr name, TWideXMLCharPtr &value)
+ {
+ if (MoveToFirstChild(name)) {
+ Value(value);
+ Leave();
+ return true;
+ }
+ return false;
+ }
+
+ bool RegisteredChildValue(TWideXMLCharPtr name, TWideXMLCharPtr &value)
+ {
+ if (MoveToFirstChild(name)) {
+ RegisteredValue(value);
+ Leave();
+ return true;
+ }
+ return false;
+ }
+ bool RegisteredChildValue(TXMLCharPtr name, TXMLCharPtr &value)
+ {
+ if (MoveToFirstChild(name)) {
+ RegisteredValue(value);
+ Leave();
+ return true;
+ }
+ return false;
+ }
+ bool RegisteredValue(TWideXMLCharPtr &outValue)
+ {
+ bool retval = Value(outValue);
+ if (retval)
+ outValue = m_StringTable->RegisterStr(outValue);
+ return retval;
+ }
+ bool RegisteredValue(TXMLCharPtr &outValue)
+ {
+ bool retval = Value(outValue);
+ if (retval)
+ outValue = m_StringTable->RegisterStr(outValue);
+ return retval;
+ }
+ bool Value(DataModelDataType::Value type, SValue &outValue);
+
+ template <typename TDataType>
+ bool Value(TDataType &outValue)
+ {
+ TXMLCharPtr value;
+ if (Value(value)) {
+ WStrOps<TDataType>().StrTo(value, outValue);
+ return true;
+ }
+ return false;
+ }
+
+ // Functions below implemented in WStrOpsImpl
+ // to avoid circular dependencies
+ // Returns the number of items read
+ // Destructive parsing
+ template <typename TDataType>
+ bool ValueList(NVDataRef<TDataType> data);
+
+ // Destructive operation because we can't trust
+ // strtod to do the right thing. On windows, for long strings,
+ // it calls strlen every operation thus leading to basically N^2
+ // behavior
+ template <typename TDataType>
+ NVConstDataRef<TDataType> ChildValueList(TWideXMLCharPtr listName);
+
+ template <typename TDataType>
+ NVConstDataRef<TDataType> ChildValueList(TXMLCharPtr listName);
+
+ template <typename TSerializer>
+ void Serialize(const wchar_t *elemName, TSerializer &serializer)
+ {
+ IDOMReader::Scope __theScope(*this);
+ if (MoveToFirstChild(elemName)) {
+ serializer.Serialize(*this);
+ }
+ }
+ // Optionally hold on to the factory to keep our elements in memory as long as we are.
+ static std::shared_ptr<IDOMReader>
+ CreateDOMReader(SDOMElement &inRootElement, std::shared_ptr<IStringTable> inStringTable,
+ std::shared_ptr<IDOMFactory> inFactory = std::shared_ptr<IDOMFactory>());
+};
+
+// Write out data in an xml-like fasion without specifying exactly
+// where that data is being written.
+class IDOMWriter
+{
+protected:
+ virtual ~IDOMWriter() {}
+public:
+ friend class std::shared_ptr<IDOMWriter>;
+
+ // Control the element scope.
+ struct Scope
+ {
+ IDOMWriter &m_Writer;
+ Scope(IDOMWriter &writer, TWideXMLCharPtr inElemName)
+ : m_Writer(writer)
+ {
+ m_Writer.Begin(inElemName);
+ }
+ Scope(IDOMWriter &writer, TXMLCharPtr inElemName)
+ : m_Writer(writer)
+ {
+ m_Writer.Begin(inElemName);
+ }
+ ~Scope() { m_Writer.End(); }
+ };
+
+ wchar_t m_PrintBuf[256];
+ char8_t m_NarrowBuf[256];
+
+ virtual void SetDOMFlags(SDOMFlags inFlags) = 0;
+ virtual SDOMFlags GetDOMFlags() const = 0;
+ // There tend to be two types of elements.
+ // Containers (<a>\n\t<b/><b/>\n</a>)
+ // and Values <b>onetwothree</b>
+ virtual void Begin(TWideXMLCharPtr inElemName) = 0;
+ virtual void Begin(TXMLCharPtr inElemName) = 0;
+ // Attributes. They may be sorted just before write
+ virtual void Att(TWideXMLCharPtr name, TWideXMLCharPtr value) = 0;
+ virtual void Att(TXMLCharPtr name, TXMLCharPtr value) = 0;
+ virtual void Value(TWideXMLCharPtr value) = 0;
+ virtual void Value(TXMLCharPtr value) = 0;
+ virtual void End() = 0;
+ virtual void RemoveCurrent() = 0;
+ virtual void ReplaceCurrent(SDOMElement &inElement) = 0;
+ // Append all the children of inElement to the child list of the current items.
+ virtual void AppendChildren(SDOMElement &inElement) = 0;
+ virtual void RemoveAttribute(TWideXMLCharPtr inItem) = 0;
+ virtual void RemoveAttribute(TXMLCharPtr inItem) = 0;
+ // Get the number of tabs required to line up the next line
+ // with the opening of the previous line
+ virtual QT3DSU32 GetTabs() = 0;
+ virtual SDOMElement *GetTopElement() = 0;
+ virtual std::shared_ptr<IDOMFactory> GetFactory() = 0;
+ // Move this item before this sibling. Function does not rearrange the
+ // tree in any major way and will not work if inItem and inSibling aren't
+ // siblings.
+ virtual void MoveBefore(TWideXMLCharPtr inItem, TWideXMLCharPtr inSibling) = 0;
+ virtual void MoveBefore(TXMLCharPtr inItem, TXMLCharPtr inSibling) = 0;
+
+ virtual void ChildValue(TWideXMLCharPtr name, TWideXMLCharPtr value)
+ {
+ Begin(name);
+ Value(value);
+ End();
+ }
+
+ virtual void ChildValue(TXMLCharPtr name, TXMLCharPtr value)
+ {
+ Begin(name);
+ Value(value);
+ End();
+ }
+
+ TWideXMLCharPtr ToStr(wchar_t val)
+ {
+ m_PrintBuf[0] = val;
+ m_PrintBuf[1] = 0;
+ return m_PrintBuf;
+ }
+ TXMLCharPtr ToStr(char8_t val)
+ {
+ m_NarrowBuf[0] = val;
+ m_NarrowBuf[1] = 0;
+ return m_NarrowBuf;
+ }
+ template <typename TDataType>
+ TWideXMLCharPtr ToStr(TDataType val)
+ {
+ WStrOps<TDataType>().ToStr(val, NVDataRef<wchar_t>(m_PrintBuf, 256));
+ return m_PrintBuf;
+ }
+
+ template <typename TDataType>
+ TXMLCharPtr ToNarrowStr(TDataType val)
+ {
+ WStrOps<TDataType>().ToStr(val, NVDataRef<char8_t>(m_NarrowBuf, 256));
+ return m_NarrowBuf;
+ }
+
+ void Att(TWideXMLCharPtr name, const TXMLWideStr &inValue)
+ {
+ return Att(name, inValue.wide_str());
+ }
+
+ void Att(TXMLCharPtr name, const TXMLStr &inValue) { return Att(name, inValue.c_str()); }
+
+ template <typename TData>
+ void Att(TWideXMLCharPtr name, TData value)
+ {
+ Att(name, ToStr(value));
+ }
+
+ template <typename TData>
+ void Att(TXMLCharPtr name, TData value)
+ {
+ Att(name, ToNarrowStr(value));
+ }
+
+ template <typename TSerializer>
+ void Serialize(const wchar_t *elemName, TSerializer &serializer)
+ {
+ IDOMWriter::Scope __theScope(*this, elemName);
+ serializer.Serialize(*this);
+ }
+
+ template <typename TSerializer>
+ void Serialize(const char8_t *elemName, TSerializer &serializer)
+ {
+ IDOMWriter::Scope __theScope(*this, elemName);
+ serializer.Serialize(*this);
+ }
+
+ std::shared_ptr<IDOMReader> CreateDOMReader()
+ {
+ std::shared_ptr<IDOMFactory> theFactory(GetFactory());
+ return IDOMReader::CreateDOMReader(*GetTopElement(), theFactory->GetStringTable(),
+ theFactory);
+ }
+
+ // Note that the default method of creating a writer also creates a reader; they can
+ // both manipulation the DOM hierarch.
+ static eastl::pair<std::shared_ptr<IDOMWriter>, std::shared_ptr<IDOMReader>>
+ CreateDOMWriter(std::shared_ptr<IDOMFactory> inFactory, SDOMElement &inRootElement,
+ std::shared_ptr<IStringTable> inStringTable);
+
+ static eastl::pair<std::shared_ptr<IDOMWriter>, std::shared_ptr<IDOMReader>>
+ CreateDOMWriter(const wchar_t *inTopElemName, std::shared_ptr<IStringTable> inStringTable)
+ {
+ std::shared_ptr<IDOMFactory> theFactory(IDOMFactory::CreateDOMFactory(inStringTable));
+ SDOMElement *theRoot = theFactory->NextElement(inTopElemName);
+ return CreateDOMWriter(theFactory, *theRoot, inStringTable);
+ }
+};
+
+class CXmlErrorHandler
+{
+protected:
+ virtual ~CXmlErrorHandler() {}
+public:
+ virtual void OnXmlError(const QString &errorName, int line, int column) = 0;
+};
+
+class CDOMSerializer
+{
+public:
+ static void WriteXMLHeader(IOutStream &inStream);
+ static void Write(SDOMElement &inElement, IOutStream &inStream, QT3DSU32 inTabs = 0);
+ static SDOMElement *Read(IDOMFactory &inFactory, qt3ds::foundation::IInStream &inStream,
+ CXmlErrorHandler *inErrorHandler = NULL);
+};
+}
+#endif
diff --git a/src/dm/systems/SignalsImpl.cpp b/src/dm/systems/SignalsImpl.cpp
new file mode 100644
index 0000000..6f42516
--- /dev/null
+++ b/src/dm/systems/SignalsImpl.cpp
@@ -0,0 +1,1565 @@
+/****************************************************************************
+**
+** 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 : 4103 4512 4503)
+#endif
+#include "SignalsImpl.h"
+
+using namespace std;
+
+namespace {
+bool g_DataModelSignalsEnabled = true;
+
+#define CHECK_SIGNALS_ENABLED() \
+ { \
+ if (g_DataModelSignalsEnabled == false) \
+ return; \
+ }
+}
+
+namespace qt3dsdm {
+void SetDataModelSignalsEnabled(bool inEnabled)
+{
+ g_DataModelSignalsEnabled = inEnabled;
+}
+// Defaults to true
+bool AreDataModelSignalsEnabled()
+{
+ return g_DataModelSignalsEnabled;
+}
+
+#define CONNECT_QT(x) TSignalConnectionPtr(new QtSignalConnection(x))
+#define CONNECT_SIGNAL_QT(x) CONNECT_QT(QObject::connect(this, x, inCallback))
+
+class CPropertyCoreSignaller : public QObject, public IInstancePropertyCoreSignalProvider,
+ public IInstancePropertyCoreSignalSender
+{
+ Q_OBJECT
+Q_SIGNALS:
+ void propertySignal(Qt3DSDMInstanceHandle, Qt3DSDMPropertyHandle, const SValue);
+public:
+ TSignalConnectionPtr ConnectInstancePropertyValue(
+ const std::function<void(Qt3DSDMInstanceHandle, Qt3DSDMPropertyHandle, const SValue &)>
+ &inCallback) override
+ {
+ return CONNECT_QT(QObject::connect(this, &CPropertyCoreSignaller::propertySignal,
+ inCallback));
+ }
+ void SignalInstancePropertyValue(Qt3DSDMInstanceHandle inInstance,
+ Qt3DSDMPropertyHandle inProperty, const SValue &inValue) override
+ {
+ CHECK_SIGNALS_ENABLED();
+ Q_EMIT propertySignal(inInstance, inProperty, inValue);
+ }
+};
+
+TSignalItemPtr CreatePropertyCoreSignaller()
+{
+ return TSignalItemPtr(
+ static_cast<IInstancePropertyCoreSignalProvider *>(new CPropertyCoreSignaller()));
+}
+
+class CDataCoreSignaller : public QObject, public IDataCoreSignalProvider,
+ public IDataCoreSignalSender
+{
+ Q_OBJECT
+Q_SIGNALS:
+ void instanceCreated(Qt3DSDMInstanceHandle handle);
+ void beforeInstanceDeleted(Qt3DSDMInstanceHandle handle);
+ void instanceDeleted(Qt3DSDMInstanceHandle handle);
+ void instanceDerived(Qt3DSDMInstanceHandle handle, Qt3DSDMInstanceHandle handle2);
+ void instanceParentRemoved(Qt3DSDMInstanceHandle handle, Qt3DSDMInstanceHandle handle2);
+ void propertyAdded(Qt3DSDMInstanceHandle, Qt3DSDMPropertyHandle, TCharPtr,
+ DataModelDataType::Value);
+ void propertyRemoved(Qt3DSDMInstanceHandle, Qt3DSDMPropertyHandle, TCharPtr,
+ DataModelDataType::Value);
+
+public:
+ virtual TSignalConnectionPtr
+ ConnectInstanceCreated(const std::function<void(Qt3DSDMInstanceHandle)> &inCallback) override
+ {
+ return CONNECT_QT(QObject::connect(this, &CDataCoreSignaller::instanceCreated,
+ inCallback));
+ }
+ virtual TSignalConnectionPtr
+ ConnectBeforeInstanceDeleted(const std::function<void(Qt3DSDMInstanceHandle)> &inCallback) override
+ {
+ return CONNECT_QT(QObject::connect(this, &CDataCoreSignaller::beforeInstanceDeleted,
+ inCallback));
+ }
+ virtual TSignalConnectionPtr
+ ConnectInstanceDeleted(const std::function<void(Qt3DSDMInstanceHandle)> &inCallback) override
+ {
+ return CONNECT_QT(QObject::connect(this, &CDataCoreSignaller::instanceDeleted,
+ inCallback));
+ }
+ TSignalConnectionPtr ConnectInstanceDerived(
+ const std::function<void(Qt3DSDMInstanceHandle, Qt3DSDMInstanceHandle)> &inCallback) override
+ {
+ return CONNECT_QT(QObject::connect(this, &CDataCoreSignaller::instanceDerived,
+ inCallback));
+ }
+ TSignalConnectionPtr ConnectInstanceParentRemoved(
+ const std::function<void(Qt3DSDMInstanceHandle, Qt3DSDMInstanceHandle)> &inCallback) override
+ {
+ return CONNECT_QT(QObject::connect(this, &CDataCoreSignaller::instanceParentRemoved,
+ inCallback));
+ }
+ virtual TSignalConnectionPtr
+ ConnectPropertyAdded(const std::function<void(Qt3DSDMInstanceHandle, Qt3DSDMPropertyHandle,
+ TCharPtr, DataModelDataType::Value)> &inCallback) override
+ {
+ return CONNECT_QT(QObject::connect(this, &CDataCoreSignaller::propertyAdded, inCallback));
+ }
+ virtual TSignalConnectionPtr
+ ConnectPropertyRemoved(const std::function<void(Qt3DSDMInstanceHandle, Qt3DSDMPropertyHandle,
+ TCharPtr, DataModelDataType::Value)> &inCallback) override
+ {
+ return CONNECT_QT(QObject::connect(this, &CDataCoreSignaller::propertyRemoved,
+ inCallback));
+ }
+
+ void SignalInstanceCreated(Qt3DSDMInstanceHandle inInstance) override
+ {
+ CHECK_SIGNALS_ENABLED();
+ Q_EMIT instanceCreated(inInstance);
+ }
+ void SignalBeforeInstanceDeleted(Qt3DSDMInstanceHandle inInstance) override
+ {
+ CHECK_SIGNALS_ENABLED();
+ Q_EMIT beforeInstanceDeleted(inInstance);
+ }
+ void SignalInstanceDeleted(Qt3DSDMInstanceHandle inInstance) override
+ {
+ CHECK_SIGNALS_ENABLED();
+ Q_EMIT instanceDeleted(inInstance);
+ }
+ void SignalInstanceDerived(Qt3DSDMInstanceHandle inInstance,
+ Qt3DSDMInstanceHandle inParent) override
+ {
+ CHECK_SIGNALS_ENABLED();
+ Q_EMIT instanceDerived(inInstance, inParent);
+ }
+ void SignalInstanceParentRemoved(Qt3DSDMInstanceHandle inInstance,
+ Qt3DSDMInstanceHandle inParent) override
+ {
+ CHECK_SIGNALS_ENABLED();
+ Q_EMIT instanceParentRemoved(inInstance, inParent);
+ }
+ void SignalPropertyAdded(Qt3DSDMInstanceHandle inInstance,
+ Qt3DSDMPropertyHandle inProperty, TCharPtr inName,
+ DataModelDataType::Value inDataType) override
+ {
+ CHECK_SIGNALS_ENABLED();
+ Q_EMIT propertyAdded(inInstance, inProperty, inName, inDataType);
+ }
+ void SignalPropertyRemoved(Qt3DSDMInstanceHandle inInstance,
+ Qt3DSDMPropertyHandle inProperty, TCharPtr inName,
+ DataModelDataType::Value inDataType) override
+ {
+ CHECK_SIGNALS_ENABLED();
+ Q_EMIT propertyRemoved(inInstance, inProperty, inName, inDataType);
+ }
+};
+
+TSignalItemPtr CreateDataCoreSignaller()
+{
+ return TSignalItemPtr(static_cast<IDataCoreSignalProvider *>(new CDataCoreSignaller()));
+}
+
+class CSlideCoreSignaller : public QObject, public ISlideCoreSignalProvider,
+ public ISlideCoreSignalSender
+{
+ Q_OBJECT
+Q_SIGNALS:
+
+ void slideCreated(Qt3DSDMSlideHandle);
+ void beforeSlideDeleted(Qt3DSDMSlideHandle);
+ void slideDeleted(Qt3DSDMSlideHandle);
+ void slideDerived(Qt3DSDMSlideHandle, Qt3DSDMSlideHandle, int);
+ void instancePropertyValueSet(Qt3DSDMSlideHandle, Qt3DSDMInstanceHandle, Qt3DSDMPropertyHandle,
+ const SValue &);
+ qt3dsdm::SValue instancePropertyValueAdded(Qt3DSDMSlideHandle, Qt3DSDMSlideHandle,
+ Qt3DSDMInstanceHandle, Qt3DSDMPropertyHandle,
+ const SValue &);
+ void instancePropertyValueRemoved(Qt3DSDMSlideHandle, Qt3DSDMInstanceHandle,
+ Qt3DSDMPropertyHandle, const SValue &);
+ void slideTimeChanged(Qt3DSDMSlideHandle);
+
+public:
+ virtual TSignalConnectionPtr
+ ConnectSlideCreated(const std::function<void(Qt3DSDMSlideHandle)> &inCallback) override
+ {
+ return CONNECT_SIGNAL_QT(&CSlideCoreSignaller::slideCreated);
+ }
+ virtual TSignalConnectionPtr
+ ConnectBeforeSlideDeleted(const std::function<void(Qt3DSDMSlideHandle)> &inCallback) override
+ {
+ return CONNECT_SIGNAL_QT(&CSlideCoreSignaller::beforeSlideDeleted);
+ }
+ virtual TSignalConnectionPtr
+ ConnectSlideDeleted(const std::function<void(Qt3DSDMSlideHandle)> &inCallback) override
+ {
+ return CONNECT_SIGNAL_QT(&CSlideCoreSignaller::slideDeleted);
+ }
+ TSignalConnectionPtr ConnectSlideDerived(
+ const std::function<void(Qt3DSDMSlideHandle, Qt3DSDMSlideHandle, int)> &inCallback) override
+ {
+ return CONNECT_SIGNAL_QT(&CSlideCoreSignaller::slideDerived);
+ }
+ TSignalConnectionPtr ConnectInstancePropertyValueSet(
+ const std::function<void(Qt3DSDMSlideHandle, Qt3DSDMInstanceHandle, Qt3DSDMPropertyHandle,
+ const SValue &)> &inCallback) override
+ {
+ return CONNECT_SIGNAL_QT(&CSlideCoreSignaller::instancePropertyValueSet);
+ }
+ virtual TSignalConnectionPtr ConnectInstancePropertyValueAdded(
+ const std::function<void(Qt3DSDMSlideHandle, Qt3DSDMSlideHandle, Qt3DSDMInstanceHandle,
+ Qt3DSDMPropertyHandle, const SValue &)> &inCallback)
+ {
+ return CONNECT_SIGNAL_QT(&CSlideCoreSignaller::instancePropertyValueAdded);
+ }
+ TSignalConnectionPtr ConnectInstancePropertyValueRemoved(
+ const std::function<void(Qt3DSDMSlideHandle, Qt3DSDMInstanceHandle, Qt3DSDMPropertyHandle,
+ const SValue &)> &inCallback) override
+ {
+ return CONNECT_SIGNAL_QT(&CSlideCoreSignaller::instancePropertyValueRemoved);
+ }
+ virtual TSignalConnectionPtr
+ ConnectSlideTimeChanged(const std::function<void(Qt3DSDMSlideHandle)> &inCallback) override
+ {
+ return CONNECT_SIGNAL_QT(&CSlideCoreSignaller::slideTimeChanged);
+ }
+
+ void SendSlideCreated(Qt3DSDMSlideHandle inSlide) override
+ {
+ CHECK_SIGNALS_ENABLED();
+ Q_EMIT slideCreated(inSlide);
+ }
+ void SendBeforeSlideDeleted(Qt3DSDMSlideHandle inSlide) override
+ {
+ CHECK_SIGNALS_ENABLED();
+ Q_EMIT beforeSlideDeleted(inSlide);
+ }
+ void SendSlideDeleted(Qt3DSDMSlideHandle inSlide) override
+ {
+ CHECK_SIGNALS_ENABLED();
+ Q_EMIT slideDeleted(inSlide);
+ }
+ void SendSlideDerived(Qt3DSDMSlideHandle inSlide, Qt3DSDMSlideHandle inParent,
+ int inIndex) override
+ {
+ CHECK_SIGNALS_ENABLED();
+ Q_EMIT slideDerived(inSlide, inParent, inIndex);
+ }
+ void SendPropertyValueSet(Qt3DSDMSlideHandle inSlide, Qt3DSDMInstanceHandle inInstance,
+ Qt3DSDMPropertyHandle inProperty, const SValue &inValue) override
+ {
+ CHECK_SIGNALS_ENABLED();
+ Q_EMIT instancePropertyValueSet(inSlide, inInstance, inProperty, inValue);
+ }
+ virtual SValue SendPropertyValueAdded(Qt3DSDMSlideHandle inSource, Qt3DSDMSlideHandle inDest,
+ Qt3DSDMInstanceHandle inInstance,
+ Qt3DSDMPropertyHandle inProperty, const SValue &inValue)
+ {
+ if (!g_DataModelSignalsEnabled) return SValue();
+
+ // check that we have one and only one slot connected to
+ // instancePropertyValueAdded signal as it returns a value.
+ Q_ASSERT(
+ receivers(
+ SIGNAL(
+ instancePropertyValueAdded(
+ Qt3DSDMSlideHandle, Qt3DSDMSlideHandle,
+ Qt3DSDMInstanceHandle, Qt3DSDMPropertyHandle,const SValue &))) == 1);
+ // emit instancePropertyValueAdded
+ return instancePropertyValueAdded(inSource, inDest, inInstance, inProperty, inValue);
+ }
+ void SendPropertyValueRemoved(Qt3DSDMSlideHandle inSlide,
+ Qt3DSDMInstanceHandle inInstance,
+ Qt3DSDMPropertyHandle inProperty, const SValue &inValue) override
+ {
+ CHECK_SIGNALS_ENABLED();
+ Q_EMIT instancePropertyValueRemoved(inSlide, inInstance, inProperty, inValue);
+ }
+ void SendSlideTimeChanged(Qt3DSDMSlideHandle inSlide) override
+ {
+ CHECK_SIGNALS_ENABLED();
+ Q_EMIT slideTimeChanged(inSlide);
+ }
+};
+
+TSignalItemPtr CreateSlideCoreSignaller()
+{
+ return TSignalItemPtr(static_cast<ISlideCoreSignalProvider *>(new CSlideCoreSignaller()));
+}
+
+class CSlideGraphCoreSignaller : public QObject, public ISlideGraphCoreSignalProvider,
+ public ISlideGraphCoreSignalSender
+{
+ Q_OBJECT
+Q_SIGNALS:
+ void graphCreated(Qt3DSDMSlideGraphHandle, Qt3DSDMSlideHandle);
+ void graphDeleted(Qt3DSDMSlideGraphHandle, Qt3DSDMSlideHandle);
+ void instanceAssociated(Qt3DSDMSlideGraphHandle, Qt3DSDMSlideHandle, Qt3DSDMInstanceHandle);
+ void instanceDissociated(Qt3DSDMSlideGraphHandle, Qt3DSDMSlideHandle, Qt3DSDMInstanceHandle);
+ void graphActiveSlide(Qt3DSDMSlideGraphHandle, Qt3DSDMSlideHandle);
+ void graphSeconds(Qt3DSDMSlideGraphHandle, float);
+
+public:
+ TSignalConnectionPtr ConnectGraphCreated(
+ const std::function<void(Qt3DSDMSlideGraphHandle, Qt3DSDMSlideHandle)> &inCallback) override
+ {
+ return CONNECT_SIGNAL_QT(&CSlideGraphCoreSignaller::graphCreated);
+ }
+ TSignalConnectionPtr ConnectGraphDeleted(
+ const std::function<void(Qt3DSDMSlideGraphHandle, Qt3DSDMSlideHandle)> &inCallback) override
+ {
+ return CONNECT_SIGNAL_QT(&CSlideGraphCoreSignaller::graphDeleted);
+ }
+ TSignalConnectionPtr ConnectInstanceAssociated(
+ const std::function<void(Qt3DSDMSlideGraphHandle, Qt3DSDMSlideHandle, Qt3DSDMInstanceHandle)>
+ &inCallback) override
+ {
+ return CONNECT_SIGNAL_QT(&CSlideGraphCoreSignaller::instanceAssociated);
+ }
+ TSignalConnectionPtr ConnectInstanceDissociated(
+ const std::function<void(Qt3DSDMSlideGraphHandle, Qt3DSDMSlideHandle, Qt3DSDMInstanceHandle)>
+ &inCallback) override
+ {
+ return CONNECT_SIGNAL_QT(&CSlideGraphCoreSignaller::instanceDissociated);
+ }
+ TSignalConnectionPtr ConnectGraphActiveSlide(
+ const std::function<void(Qt3DSDMSlideGraphHandle, Qt3DSDMSlideHandle)> &inCallback) override
+ {
+ return CONNECT_SIGNAL_QT(&CSlideGraphCoreSignaller::graphActiveSlide);
+ }
+ virtual TSignalConnectionPtr
+ ConnectGraphSeconds(const std::function<void(Qt3DSDMSlideGraphHandle, float)> &inCallback)
+ {
+ return CONNECT_SIGNAL_QT(&CSlideGraphCoreSignaller::graphSeconds);
+ }
+
+ void SendGraphCreated(Qt3DSDMSlideGraphHandle inGraph, Qt3DSDMSlideHandle inSlide) override
+ {
+ CHECK_SIGNALS_ENABLED();
+ Q_EMIT graphCreated(inGraph, inSlide);
+ }
+ void SendGraphDeleted(Qt3DSDMSlideGraphHandle inGraph, Qt3DSDMSlideHandle inSlide) override
+ {
+ CHECK_SIGNALS_ENABLED();
+ Q_EMIT graphDeleted(inGraph, inSlide);
+ }
+ void SendInstanceAssociated(Qt3DSDMSlideGraphHandle inGraph, Qt3DSDMSlideHandle inSlide,
+ Qt3DSDMInstanceHandle inInstance) override
+ {
+ CHECK_SIGNALS_ENABLED();
+ Q_EMIT instanceAssociated(inGraph, inSlide, inInstance);
+ }
+ void SendInstanceDissociated(Qt3DSDMSlideGraphHandle inGraph, Qt3DSDMSlideHandle inSlide,
+ Qt3DSDMInstanceHandle inInstance) override
+ {
+ CHECK_SIGNALS_ENABLED();
+ Q_EMIT instanceDissociated(inGraph, inSlide, inInstance);
+ }
+ void SendGraphActiveSlide(Qt3DSDMSlideGraphHandle inGraph, Qt3DSDMSlideHandle inSlide) override
+ {
+ CHECK_SIGNALS_ENABLED();
+ Q_EMIT graphActiveSlide(inGraph, inSlide);
+ }
+ virtual void SendGraphSeconds(Qt3DSDMSlideGraphHandle inGraph, float inSeconds)
+ {
+ CHECK_SIGNALS_ENABLED();
+ Q_EMIT graphSeconds(inGraph, inSeconds);
+ }
+};
+
+TSignalItemPtr CreateSlideGraphCoreSignaller()
+{
+ return TSignalItemPtr(
+ static_cast<ISlideGraphCoreSignalProvider *>(new CSlideGraphCoreSignaller()));
+}
+
+class CAnimationCoreSignaller : public QObject, public IAnimationCoreSignalProvider,
+ public IAnimationCoreSignalSender
+{
+ Q_OBJECT
+Q_SIGNALS:
+ void animationCreated(Qt3DSDMAnimationHandle, Qt3DSDMSlideHandle, Qt3DSDMInstanceHandle,
+ Qt3DSDMPropertyHandle, size_t, EAnimationType);
+ void beforeAnimationDeleted(Qt3DSDMAnimationHandle);
+ void animationDeleted(Qt3DSDMAnimationHandle, Qt3DSDMSlideHandle, Qt3DSDMInstanceHandle,
+ Qt3DSDMPropertyHandle, size_t, EAnimationType);
+ void keyframeInserted(Qt3DSDMAnimationHandle, Qt3DSDMKeyframeHandle, const TKeyframe &);
+ void beforeKeyframeErased(Qt3DSDMKeyframeHandle);
+ void keyframeErased(Qt3DSDMAnimationHandle, Qt3DSDMKeyframeHandle, const TKeyframe &);
+ void beforeAllKeyframesErased(Qt3DSDMAnimationHandle);
+ void keyframeUpdated(Qt3DSDMKeyframeHandle, const TKeyframe &);
+ void firstKeyframeDynamic(Qt3DSDMAnimationHandle, bool);
+
+public:
+ TSignalConnectionPtr ConnectAnimationCreated(
+ const std::function<void(Qt3DSDMAnimationHandle, Qt3DSDMSlideHandle, Qt3DSDMInstanceHandle,
+ Qt3DSDMPropertyHandle, size_t, EAnimationType)> &inCallback) override
+ {
+ return CONNECT_SIGNAL_QT(&CAnimationCoreSignaller::animationCreated);
+ }
+ virtual TSignalConnectionPtr
+ ConnectBeforeAnimationDeleted(const std::function<void(Qt3DSDMAnimationHandle)> &inCallback) override
+ {
+ return CONNECT_SIGNAL_QT(&CAnimationCoreSignaller::beforeAnimationDeleted);
+ }
+ TSignalConnectionPtr ConnectAnimationDeleted(
+ const std::function<void(Qt3DSDMAnimationHandle, Qt3DSDMSlideHandle, Qt3DSDMInstanceHandle,
+ Qt3DSDMPropertyHandle, size_t, EAnimationType)> &inCallback) override
+ {
+ return CONNECT_SIGNAL_QT(&CAnimationCoreSignaller::animationDeleted);
+ }
+ TSignalConnectionPtr ConnectKeyframeInserted(
+ const std::function<void(Qt3DSDMAnimationHandle, Qt3DSDMKeyframeHandle, const TKeyframe &)>
+ &inCallback) override
+ {
+ return CONNECT_SIGNAL_QT(&CAnimationCoreSignaller::keyframeInserted);
+ }
+ virtual TSignalConnectionPtr
+ ConnectBeforeKeyframeErased(const std::function<void(Qt3DSDMKeyframeHandle)> &inCallback) override
+ {
+ return CONNECT_SIGNAL_QT(&CAnimationCoreSignaller::beforeKeyframeErased);
+ }
+ TSignalConnectionPtr ConnectKeyframeErased(
+ const std::function<void(Qt3DSDMAnimationHandle, Qt3DSDMKeyframeHandle, const TKeyframe &)>
+ &inCallback) override
+ {
+ return CONNECT_SIGNAL_QT(&CAnimationCoreSignaller::keyframeErased);
+ }
+ virtual TSignalConnectionPtr
+ ConnectBeforeAllKeyframesErased(const std::function<void(Qt3DSDMAnimationHandle)> &inCallback) override
+ {
+ return CONNECT_SIGNAL_QT(&CAnimationCoreSignaller::beforeAllKeyframesErased);
+ }
+ TSignalConnectionPtr ConnectKeyframeUpdated(
+ const std::function<void(Qt3DSDMKeyframeHandle, const TKeyframe &)> &inCallback) override
+ {
+ return CONNECT_SIGNAL_QT(&CAnimationCoreSignaller::keyframeUpdated);
+ }
+ TSignalConnectionPtr ConnectFirstKeyframeDynamicSet(
+ const std::function<void(Qt3DSDMAnimationHandle, bool)> &inCallback) override
+ {
+ return CONNECT_SIGNAL_QT(&CAnimationCoreSignaller::firstKeyframeDynamic);
+ }
+
+ void SendAnimationCreated(Qt3DSDMAnimationHandle inAnimation, Qt3DSDMSlideHandle inSlide,
+ Qt3DSDMInstanceHandle inInstance,
+ Qt3DSDMPropertyHandle inProperty, size_t inIndex,
+ EAnimationType inAnimationType) override
+ {
+ CHECK_SIGNALS_ENABLED();
+ Q_EMIT animationCreated(inAnimation, inSlide, inInstance, inProperty, inIndex,
+ inAnimationType);
+ }
+ void SendBeforeAnimationDeleted(Qt3DSDMAnimationHandle inAnimation) override
+ {
+ CHECK_SIGNALS_ENABLED();
+ Q_EMIT beforeAnimationDeleted(inAnimation);
+ }
+ void SendAnimationDeleted(Qt3DSDMAnimationHandle inAnimation, Qt3DSDMSlideHandle inSlide,
+ Qt3DSDMInstanceHandle inInstance,
+ Qt3DSDMPropertyHandle inProperty, size_t inIndex,
+ EAnimationType inAnimationType) override
+ {
+ CHECK_SIGNALS_ENABLED();
+ Q_EMIT animationDeleted(inAnimation, inSlide, inInstance, inProperty, inIndex,
+ inAnimationType);
+ }
+ void SendKeyframeInserted(Qt3DSDMAnimationHandle inAnimation,
+ Qt3DSDMKeyframeHandle inKeyframe, const TKeyframe &inData) override
+ {
+ CHECK_SIGNALS_ENABLED();
+ Q_EMIT keyframeInserted(inAnimation, inKeyframe, inData);
+ }
+ void SendBeforeKeyframeErased(Qt3DSDMKeyframeHandle inKeyframe) override
+ {
+ CHECK_SIGNALS_ENABLED();
+ Q_EMIT beforeKeyframeErased(inKeyframe);
+ }
+ void SendKeyframeErased(Qt3DSDMAnimationHandle inAnimation,
+ Qt3DSDMKeyframeHandle inKeyframe, const TKeyframe &inData) override
+ {
+ CHECK_SIGNALS_ENABLED();
+ Q_EMIT keyframeErased(inAnimation, inKeyframe, inData);
+ }
+ void SendBeforeAllKeyframesErased(Qt3DSDMAnimationHandle inAnimation) override
+ {
+ CHECK_SIGNALS_ENABLED();
+ Q_EMIT beforeAllKeyframesErased(inAnimation);
+ }
+ void SendKeyframeUpdated(Qt3DSDMKeyframeHandle inKeyframe, const TKeyframe &inData) override
+ {
+ CHECK_SIGNALS_ENABLED();
+ Q_EMIT keyframeUpdated(inKeyframe, inData);
+ }
+ void SendFirstKeyframeDynamicSet(Qt3DSDMAnimationHandle inAnimation,
+ bool inKeyframeDynamic) override
+ {
+ CHECK_SIGNALS_ENABLED();
+ Q_EMIT firstKeyframeDynamic(inAnimation, inKeyframeDynamic);
+ }
+};
+
+TSignalItemPtr CreateAnimationCoreSignaller()
+{
+ return TSignalItemPtr(
+ static_cast<IAnimationCoreSignalProvider *>(new CAnimationCoreSignaller()));
+}
+
+class CActionCoreSignaller : public QObject, public IActionCoreSignalProvider,
+ public IActionCoreSignalSender
+{
+ Q_OBJECT
+Q_SIGNALS:
+ void triggerObjectSet(Qt3DSDMActionHandle, SObjectRefType &);
+ void targetObjectSet(Qt3DSDMActionHandle, SObjectRefType &);
+ void eventHandleSet(Qt3DSDMActionHandle, const wstring &);
+ void handlerHandleSet(Qt3DSDMActionHandle, const wstring &);
+
+ void handlerArgumentAdded(Qt3DSDMActionHandle, Qt3DSDMHandlerArgHandle, const TCharStr &,
+ HandlerArgumentType::Value, DataModelDataType::Value);
+ void handlerArgumentRemoved(Qt3DSDMActionHandle, Qt3DSDMHandlerArgHandle, const TCharStr &,
+ HandlerArgumentType::Value, DataModelDataType::Value);
+ void handlerArgumentValueSet(Qt3DSDMHandlerArgHandle, const SValue &);
+
+public:
+ TSignalConnectionPtr ConnectTriggerObjectSet(
+ const std::function<void(Qt3DSDMActionHandle, SObjectRefType &)> &inCallback) override
+ {
+ return CONNECT_SIGNAL_QT(&CActionCoreSignaller::triggerObjectSet);
+ }
+ TSignalConnectionPtr ConnectTargetObjectSet(
+ const std::function<void(Qt3DSDMActionHandle, SObjectRefType &)> &inCallback) override
+ {
+ return CONNECT_SIGNAL_QT(&CActionCoreSignaller::targetObjectSet);
+ }
+ virtual TSignalConnectionPtr
+ ConnectEventSet(const std::function<void(Qt3DSDMActionHandle, const wstring &)> &inCallback) override
+ {
+ return CONNECT_SIGNAL_QT(&CActionCoreSignaller::eventHandleSet);
+ }
+ virtual TSignalConnectionPtr
+ ConnectHandlerSet(const std::function<void(Qt3DSDMActionHandle, const wstring &)> &inCallback) override
+ {
+ return CONNECT_SIGNAL_QT(&CActionCoreSignaller::handlerHandleSet);
+ }
+
+ TSignalConnectionPtr ConnectHandlerArgumentAdded(
+ const std::function<void(Qt3DSDMActionHandle, Qt3DSDMHandlerArgHandle, const TCharStr &,
+ HandlerArgumentType::Value, DataModelDataType::Value)> &inCallback) override
+ {
+ return CONNECT_SIGNAL_QT(&CActionCoreSignaller::handlerArgumentAdded);
+ }
+ TSignalConnectionPtr ConnectHandlerArgumentRemoved(
+ const std::function<void(Qt3DSDMActionHandle, Qt3DSDMHandlerArgHandle, const TCharStr &,
+ HandlerArgumentType::Value, DataModelDataType::Value)> &inCallback) override
+ {
+ return CONNECT_SIGNAL_QT(&CActionCoreSignaller::handlerArgumentRemoved);
+ }
+ TSignalConnectionPtr ConnectHandlerArgumentValueSet(
+ const std::function<void(Qt3DSDMHandlerArgHandle, const SValue &)> &inCallback) override
+ {
+ return CONNECT_SIGNAL_QT(&CActionCoreSignaller::handlerArgumentValueSet);
+ }
+
+ void SendTriggerObjectSet(Qt3DSDMActionHandle inAction, SObjectRefType &inTriggerObject) override
+ {
+ CHECK_SIGNALS_ENABLED();
+ Q_EMIT triggerObjectSet(inAction, inTriggerObject);
+ }
+ void SendTargetObjectSet(Qt3DSDMActionHandle inAction, SObjectRefType &inTargetObject) override
+ {
+ CHECK_SIGNALS_ENABLED();
+ Q_EMIT targetObjectSet(inAction, inTargetObject);
+ }
+ void SendEventSet(Qt3DSDMActionHandle inAction, const wstring &inEventHandle) override
+ {
+ CHECK_SIGNALS_ENABLED();
+ Q_EMIT eventHandleSet(inAction, inEventHandle);
+ }
+ void SendHandlerSet(Qt3DSDMActionHandle inAction, const wstring &inHandlerHandle) override
+ {
+ CHECK_SIGNALS_ENABLED();
+ Q_EMIT handlerHandleSet(inAction, inHandlerHandle);
+ }
+
+ void SendHandlerArgumentAdded(Qt3DSDMActionHandle inAction,
+ Qt3DSDMHandlerArgHandle inHandlerArgument,
+ const TCharStr &inName, HandlerArgumentType::Value inArgType,
+ DataModelDataType::Value inValueType) override
+ {
+ CHECK_SIGNALS_ENABLED();
+ Q_EMIT handlerArgumentAdded(inAction, inHandlerArgument, inName, inArgType, inValueType);
+ }
+ void SendHandlerArgumentRemoved(Qt3DSDMActionHandle inAction,
+ Qt3DSDMHandlerArgHandle inHandlerArgument,
+ const TCharStr &inName, HandlerArgumentType::Value inArgType,
+ DataModelDataType::Value inValueType) override
+ {
+ CHECK_SIGNALS_ENABLED();
+ Q_EMIT handlerArgumentRemoved(inAction, inHandlerArgument, inName, inArgType, inValueType);
+ }
+ void SendHandlerArgumentValueSet(Qt3DSDMHandlerArgHandle inHandlerArgument,
+ const SValue &inValue) override
+ {
+ CHECK_SIGNALS_ENABLED();
+ Q_EMIT handlerArgumentValueSet(inHandlerArgument, inValue);
+ }
+};
+
+TSignalItemPtr CreateActionCoreSignaller()
+{
+ return TSignalItemPtr(static_cast<IActionCoreSignalProvider *>(new CActionCoreSignaller()));
+}
+
+class CActionSystemSignaller : public QObject, public IActionSystemSignalProvider,
+ public IActionSystemSignalSender
+{
+ Q_OBJECT
+Q_SIGNALS:
+ void actionCreated(Qt3DSDMActionHandle, Qt3DSDMSlideHandle, Qt3DSDMInstanceHandle);
+ void actionDeleted(Qt3DSDMActionHandle, Qt3DSDMSlideHandle, Qt3DSDMInstanceHandle);
+
+public:
+ TSignalConnectionPtr ConnectActionCreated(
+ const std::function<void(Qt3DSDMActionHandle, Qt3DSDMSlideHandle, Qt3DSDMInstanceHandle)>
+ &inCallback) override
+ {
+ return CONNECT_SIGNAL_QT(&CActionSystemSignaller::actionCreated);
+ }
+ TSignalConnectionPtr ConnectActionDeleted(
+ const std::function<void(Qt3DSDMActionHandle, Qt3DSDMSlideHandle, Qt3DSDMInstanceHandle)>
+ &inCallback) override
+ {
+ return CONNECT_SIGNAL_QT(&CActionSystemSignaller::actionDeleted);
+ }
+
+ void SendActionCreated(Qt3DSDMActionHandle inAction, Qt3DSDMSlideHandle inSlide,
+ Qt3DSDMInstanceHandle inOwner) override
+ {
+ CHECK_SIGNALS_ENABLED();
+ Q_EMIT actionCreated(inAction, inSlide, inOwner);
+ }
+ void SendActionDeleted(Qt3DSDMActionHandle inAction, Qt3DSDMSlideHandle inSlide,
+ Qt3DSDMInstanceHandle inOwner) override
+ {
+ CHECK_SIGNALS_ENABLED();
+ Q_EMIT actionDeleted(inAction, inSlide, inOwner);
+ }
+};
+
+TSignalItemPtr CreateActionSystemSignaller()
+{
+ return TSignalItemPtr(static_cast<IActionSystemSignalProvider *>(new CActionSystemSignaller()));
+}
+
+class CSlideSystemSignaller : public QObject, public ISlideSystemSignalProvider,
+ public ISlideSystemSignalSender
+{
+ Q_OBJECT
+Q_SIGNALS:
+ void masterCreated(Qt3DSDMSlideHandle);
+ void masterDeleted(Qt3DSDMSlideHandle);
+ void slideCreated(Qt3DSDMSlideHandle, int, Qt3DSDMSlideHandle);
+ void slideDeleted(Qt3DSDMSlideHandle, int, Qt3DSDMSlideHandle);
+ void slideRearranged(Qt3DSDMSlideHandle, int, int);
+ void componentSeconds(Qt3DSDMSlideHandle, float);
+ void instanceAssociated(Qt3DSDMSlideHandle, Qt3DSDMInstanceHandle);
+ void instanceDissociated(Qt3DSDMSlideHandle, Qt3DSDMInstanceHandle);
+ void propertyLinked(Qt3DSDMSlideHandle, Qt3DSDMInstanceHandle, Qt3DSDMPropertyHandle);
+ void propertyUnlinked(Qt3DSDMSlideHandle, Qt3DSDMInstanceHandle, Qt3DSDMPropertyHandle);
+ void activeSlide(Qt3DSDMSlideHandle, int, Qt3DSDMSlideHandle, Qt3DSDMSlideHandle);
+
+ qt3dsdm::SValue valueCreated(Qt3DSDMSlideHandle, Qt3DSDMInstanceHandle, Qt3DSDMPropertyHandle,
+ const SValue);
+ void valueDestroyed(Qt3DSDMSlideHandle, Qt3DSDMInstanceHandle, Qt3DSDMPropertyHandle,
+ const SValue);
+
+public:
+ virtual TSignalConnectionPtr
+ ConnectMasterCreated(const std::function<void(Qt3DSDMSlideHandle)> &inCallback) override
+ {
+ return CONNECT_SIGNAL_QT(&CSlideSystemSignaller::masterCreated);
+ }
+ virtual TSignalConnectionPtr
+ ConnectMasterDeleted(const std::function<void(Qt3DSDMSlideHandle)> &inCallback) override
+ {
+ return CONNECT_SIGNAL_QT(&CSlideSystemSignaller::masterDeleted);
+ }
+ TSignalConnectionPtr ConnectSlideCreated(
+ const std::function<void(Qt3DSDMSlideHandle, int, Qt3DSDMSlideHandle)> &inCallback) override
+ {
+ return CONNECT_SIGNAL_QT(&CSlideSystemSignaller::slideCreated);
+ }
+ TSignalConnectionPtr ConnectSlideDeleted(
+ const std::function<void(Qt3DSDMSlideHandle, int, Qt3DSDMSlideHandle)> &inCallback) override
+ {
+ return CONNECT_SIGNAL_QT(&CSlideSystemSignaller::slideDeleted);
+ }
+ virtual TSignalConnectionPtr
+ ConnectSlideRearranged(const std::function<void(Qt3DSDMSlideHandle, int, int)> &inCallback) override
+ {
+ return CONNECT_SIGNAL_QT(&CSlideSystemSignaller::slideRearranged);
+ }
+ virtual TSignalConnectionPtr
+ ConnectComponentSeconds(const std::function<void(Qt3DSDMSlideHandle, float)> &inCallback)
+ {
+ return CONNECT_SIGNAL_QT(&CSlideSystemSignaller::componentSeconds);
+ }
+ TSignalConnectionPtr ConnectInstanceAssociated(
+ const std::function<void(Qt3DSDMSlideHandle, Qt3DSDMInstanceHandle)> &inCallback) override
+ {
+ return CONNECT_SIGNAL_QT(&CSlideSystemSignaller::instanceAssociated);
+ }
+ TSignalConnectionPtr ConnectInstanceDissociated(
+ const std::function<void(Qt3DSDMSlideHandle, Qt3DSDMInstanceHandle)> &inCallback) override
+ {
+ return CONNECT_SIGNAL_QT(&CSlideSystemSignaller::instanceDissociated);
+ }
+ TSignalConnectionPtr ConnectPropertyLinked(
+ const std::function<void(Qt3DSDMSlideHandle, Qt3DSDMInstanceHandle, Qt3DSDMPropertyHandle)>
+ &inCallback) override
+ {
+ return CONNECT_SIGNAL_QT(&CSlideSystemSignaller::propertyLinked);
+ }
+ TSignalConnectionPtr ConnectPropertyUnlinked(
+ const std::function<void(Qt3DSDMSlideHandle, Qt3DSDMInstanceHandle, Qt3DSDMPropertyHandle)>
+ &inCallback) override
+ {
+ return CONNECT_SIGNAL_QT(&CSlideSystemSignaller::propertyUnlinked);
+ }
+ TSignalConnectionPtr ConnectActiveSlide(
+ const std::function<void(Qt3DSDMSlideHandle, int, Qt3DSDMSlideHandle, Qt3DSDMSlideHandle)>
+ &inCallback) override
+ {
+ return CONNECT_SIGNAL_QT(&CSlideSystemSignaller::activeSlide);
+ }
+ virtual TSignalConnectionPtr ConnectPropertyValueCreated(
+ const std::function<SValue(Qt3DSDMSlideHandle, Qt3DSDMInstanceHandle, Qt3DSDMPropertyHandle,
+ const SValue &)> &inCallback)
+ {
+ return CONNECT_SIGNAL_QT(&CSlideSystemSignaller::valueCreated);
+ }
+ virtual TSignalConnectionPtr ConnectPropertyValueDestroyed(
+ const std::function<void(Qt3DSDMSlideHandle, Qt3DSDMInstanceHandle, Qt3DSDMPropertyHandle,
+ const SValue &)> &inCallback)
+ {
+ return CONNECT_SIGNAL_QT(&CSlideSystemSignaller::valueDestroyed);
+ }
+
+ void SendMasterCreated(Qt3DSDMSlideHandle inMaster) override
+ {
+ CHECK_SIGNALS_ENABLED();
+ Q_EMIT masterCreated(inMaster);
+ }
+ void SendMasterDeleted(Qt3DSDMSlideHandle inMaster) override
+ {
+ CHECK_SIGNALS_ENABLED();
+ Q_EMIT masterDeleted(inMaster);
+ }
+ void SendSlideCreated(Qt3DSDMSlideHandle inMaster, int inIndex,
+ Qt3DSDMSlideHandle inSlide) override
+ {
+ CHECK_SIGNALS_ENABLED();
+ Q_EMIT slideCreated(inMaster, inIndex, inSlide);
+ }
+ void SendSlideDeleted(Qt3DSDMSlideHandle inMaster, int inIndex,
+ Qt3DSDMSlideHandle inSlide) override
+ {
+ CHECK_SIGNALS_ENABLED();
+ Q_EMIT slideDeleted(inMaster, inIndex, inSlide);
+ }
+ void SendSlideRearranged(Qt3DSDMSlideHandle inMaster, int inOldIndex, int inNewIndex) override
+ {
+ CHECK_SIGNALS_ENABLED();
+ Q_EMIT slideRearranged(inMaster, inOldIndex, inNewIndex);
+ }
+ virtual void SendComponentSeconds(Qt3DSDMSlideHandle inMaster, float inSeconds)
+ {
+ CHECK_SIGNALS_ENABLED();
+ Q_EMIT componentSeconds(inMaster, inSeconds);
+ }
+ void SendInstanceAssociated(Qt3DSDMSlideHandle inMaster, Qt3DSDMInstanceHandle inInstance) override
+ {
+ CHECK_SIGNALS_ENABLED();
+ Q_EMIT instanceAssociated(inMaster, inInstance);
+ }
+ void SendInstanceDissociated(Qt3DSDMSlideHandle inMaster,
+ Qt3DSDMInstanceHandle inInstance) override
+ {
+ CHECK_SIGNALS_ENABLED();
+ Q_EMIT instanceDissociated(inMaster, inInstance);
+ }
+ void SendPropertyLinked(Qt3DSDMSlideHandle inMaster, Qt3DSDMInstanceHandle inInstance,
+ Qt3DSDMPropertyHandle inProperty) override
+ {
+ CHECK_SIGNALS_ENABLED();
+ Q_EMIT propertyLinked(inMaster, inInstance, inProperty);
+ }
+ void SendPropertyUnlinked(Qt3DSDMSlideHandle inMaster, Qt3DSDMInstanceHandle inInstance,
+ Qt3DSDMPropertyHandle inProperty) override
+ {
+ CHECK_SIGNALS_ENABLED();
+ Q_EMIT propertyUnlinked(inMaster, inInstance, inProperty);
+ }
+ void SendActiveSlide(Qt3DSDMSlideHandle inMaster, int inIndex,
+ Qt3DSDMSlideHandle inOldSlide, Qt3DSDMSlideHandle inNewSlide) override
+ {
+ CHECK_SIGNALS_ENABLED();
+ Q_EMIT activeSlide(inMaster, inIndex, inOldSlide, inNewSlide);
+ }
+
+ virtual SValue SendPropertyValueCreated(Qt3DSDMSlideHandle inSlide,
+ Qt3DSDMInstanceHandle inInstance,
+ Qt3DSDMPropertyHandle inProperty, const SValue &inValue)
+ {
+ if (!g_DataModelSignalsEnabled) return SValue();
+
+ // check that we have one and only one slot connected to
+ // valueCreated signal as it returns a value.
+ Q_ASSERT(
+ receivers(
+ SIGNAL(
+ valueCreated(Qt3DSDMSlideHandle, Qt3DSDMInstanceHandle,
+ Qt3DSDMPropertyHandle, const SValue &))) == 1);
+ // emit valueCreated
+ return valueCreated(inSlide, inInstance, inProperty, inValue);
+ }
+ virtual void SendPropertyValueDestroyed(Qt3DSDMSlideHandle inSlide,
+ Qt3DSDMInstanceHandle inInstance,
+ Qt3DSDMPropertyHandle inProperty, const SValue &inValue)
+ {
+ CHECK_SIGNALS_ENABLED();
+ Q_EMIT valueDestroyed(inSlide, inInstance, inProperty, inValue);
+ }
+};
+
+TSignalItemPtr CreateSlideSystemSignaller()
+{
+ return TSignalItemPtr(static_cast<ISlideSystemSignalProvider *>(new CSlideSystemSignaller()));
+}
+
+class CCustomPropCoreSignaller : public QObject, public ICustomPropCoreSignalProvider,
+ public ICustomPropCoreSignalSender
+{
+ Q_OBJECT
+Q_SIGNALS:
+ void customPropertyCreated(Qt3DSDMPropertyHandle, Qt3DSDMInstanceHandle);
+ void customPropertyDeleted(Qt3DSDMPropertyHandle, Qt3DSDMInstanceHandle);
+ void customPropertyModified(Qt3DSDMPropertyHandle);
+ void customEventCreated(Qt3DSDMEventHandle, Qt3DSDMInstanceHandle);
+ void customEventDeleted(Qt3DSDMEventHandle, Qt3DSDMInstanceHandle);
+ void customEventModified(Qt3DSDMEventHandle);
+ void customHandlerCreated(Qt3DSDMHandlerHandle, Qt3DSDMInstanceHandle);
+ void customHandlerDeleted(Qt3DSDMHandlerHandle, Qt3DSDMInstanceHandle);
+ void customHandlerModified(Qt3DSDMHandlerHandle);
+ void customHandlerParamCreated(Qt3DSDMHandlerParamHandle, Qt3DSDMHandlerHandle);
+ void customHandlerParamDeleted(Qt3DSDMHandlerParamHandle, Qt3DSDMHandlerHandle);
+ void customHandlerParamModified(Qt3DSDMHandlerParamHandle);
+ void customReferencesModified(Qt3DSDMInstanceHandle, const TCharStr &);
+
+public:
+ TSignalConnectionPtr ConnectCustomPropertyCreated(
+ const std::function<void(Qt3DSDMPropertyHandle, Qt3DSDMInstanceHandle)> &inCallback) override
+ {
+ return CONNECT_SIGNAL_QT(&CCustomPropCoreSignaller::customPropertyCreated);
+ }
+ TSignalConnectionPtr ConnectCustomPropertyDeleted(
+ const std::function<void(Qt3DSDMPropertyHandle, Qt3DSDMInstanceHandle)> &inCallback) override
+ {
+ return CONNECT_SIGNAL_QT(&CCustomPropCoreSignaller::customPropertyDeleted);
+ }
+ virtual TSignalConnectionPtr
+ ConnectCustomPropertyModified(const std::function<void(Qt3DSDMPropertyHandle)> &inCallback) override
+ {
+ return CONNECT_SIGNAL_QT(&CCustomPropCoreSignaller::customPropertyModified);
+ }
+ TSignalConnectionPtr ConnectCustomEventCreated(
+ const std::function<void(Qt3DSDMEventHandle, Qt3DSDMInstanceHandle)> &inCallback) override
+ {
+ return CONNECT_SIGNAL_QT(&CCustomPropCoreSignaller::customEventCreated);
+ }
+ TSignalConnectionPtr ConnectCustomEventDeleted(
+ const std::function<void(Qt3DSDMEventHandle, Qt3DSDMInstanceHandle)> &inCallback) override
+ {
+ return CONNECT_SIGNAL_QT(&CCustomPropCoreSignaller::customEventDeleted);
+ }
+ virtual TSignalConnectionPtr
+ ConnectCustomEventModified(const std::function<void(Qt3DSDMEventHandle)> &inCallback) override
+ {
+ return CONNECT_SIGNAL_QT(&CCustomPropCoreSignaller::customEventModified);
+ }
+ TSignalConnectionPtr ConnectCustomHandlerCreated(
+ const std::function<void(Qt3DSDMHandlerHandle, Qt3DSDMInstanceHandle)> &inCallback) override
+ {
+ return CONNECT_SIGNAL_QT(&CCustomPropCoreSignaller::customHandlerCreated);
+ }
+ TSignalConnectionPtr ConnectCustomHandlerDeleted(
+ const std::function<void(Qt3DSDMHandlerHandle, Qt3DSDMInstanceHandle)> &inCallback) override
+ {
+ return CONNECT_SIGNAL_QT(&CCustomPropCoreSignaller::customHandlerDeleted);
+ }
+ virtual TSignalConnectionPtr
+ ConnectCustomHandlerModified(const std::function<void(Qt3DSDMHandlerHandle)> &inCallback) override
+ {
+ return CONNECT_SIGNAL_QT(&CCustomPropCoreSignaller::customHandlerModified);
+ }
+ TSignalConnectionPtr ConnectCustomHandlerParamCreated(
+ const std::function<void(Qt3DSDMHandlerParamHandle, Qt3DSDMHandlerHandle)> &inCallback) override
+ {
+ return CONNECT_SIGNAL_QT(&CCustomPropCoreSignaller::customHandlerParamCreated);
+ }
+ TSignalConnectionPtr ConnectCustomHandlerParamDeleted(
+ const std::function<void(Qt3DSDMHandlerParamHandle, Qt3DSDMHandlerHandle)> &inCallback) override
+ {
+ return CONNECT_SIGNAL_QT(&CCustomPropCoreSignaller::customHandlerParamDeleted);
+ }
+ TSignalConnectionPtr ConnectCustomHandlerParamModified(
+ const std::function<void(Qt3DSDMHandlerParamHandle)> &inCallback) override
+ {
+ return CONNECT_SIGNAL_QT(&CCustomPropCoreSignaller::customHandlerParamModified);
+ }
+ TSignalConnectionPtr ConnectCustomReferencesModified(
+ const std::function<void(Qt3DSDMInstanceHandle, const TCharStr &)> &inCallback) override
+ {
+ return CONNECT_SIGNAL_QT(&CCustomPropCoreSignaller::customReferencesModified);
+ }
+
+ void SendCustomPropertyCreated(Qt3DSDMPropertyHandle inProp,
+ Qt3DSDMInstanceHandle inOwner) override
+ {
+ CHECK_SIGNALS_ENABLED();
+ Q_EMIT customPropertyCreated(inProp, inOwner);
+ }
+ void SendCustomPropertyDeleted(Qt3DSDMPropertyHandle inProp,
+ Qt3DSDMInstanceHandle inOwner) override
+ {
+ CHECK_SIGNALS_ENABLED();
+ Q_EMIT customPropertyDeleted(inProp, inOwner);
+ }
+ void SendCustomPropertyModified(Qt3DSDMPropertyHandle inProp) override
+ {
+ CHECK_SIGNALS_ENABLED();
+ Q_EMIT customPropertyModified(inProp);
+ }
+ void SendCustomEventCreated(Qt3DSDMEventHandle inEvent, Qt3DSDMInstanceHandle inOwner) override
+ {
+ CHECK_SIGNALS_ENABLED();
+ Q_EMIT customEventCreated(inEvent, inOwner);
+ }
+ void SendCustomEventDeleted(Qt3DSDMEventHandle inEvent, Qt3DSDMInstanceHandle inOwner) override
+ {
+ CHECK_SIGNALS_ENABLED();
+ Q_EMIT customEventDeleted(inEvent, inOwner);
+ }
+ void SendCustomEventModified(Qt3DSDMEventHandle inEvent) override
+ {
+ CHECK_SIGNALS_ENABLED();
+ Q_EMIT customEventModified(inEvent);
+ }
+ void SendCustomHandlerCreated(Qt3DSDMHandlerHandle inHandler,
+ Qt3DSDMInstanceHandle inOwner) override
+ {
+ CHECK_SIGNALS_ENABLED();
+ Q_EMIT customHandlerCreated(inHandler, inOwner);
+ }
+ void SendCustomHandlerDeleted(Qt3DSDMHandlerHandle inHandler,
+ Qt3DSDMInstanceHandle inOwner) override
+ {
+ CHECK_SIGNALS_ENABLED();
+ Q_EMIT customHandlerDeleted(inHandler, inOwner);
+ }
+ void SendCustomHandlerModified(Qt3DSDMHandlerHandle inHandler) override
+ {
+ CHECK_SIGNALS_ENABLED();
+ Q_EMIT customHandlerModified(inHandler);
+ }
+ void SendCustomHandlerParamCreated(Qt3DSDMHandlerParamHandle inParameter,
+ Qt3DSDMHandlerHandle inHandler) override
+ {
+ CHECK_SIGNALS_ENABLED();
+ Q_EMIT customHandlerParamCreated(inParameter, inHandler);
+ }
+ void SendCustomHandlerParamDeleted(Qt3DSDMHandlerParamHandle inParameter,
+ Qt3DSDMHandlerHandle inHandler) override
+ {
+ CHECK_SIGNALS_ENABLED();
+ Q_EMIT customHandlerParamDeleted(inParameter, inHandler);
+ }
+ void SendCustomHandlerParamModified(Qt3DSDMHandlerParamHandle inParameter) override
+ {
+ CHECK_SIGNALS_ENABLED();
+ Q_EMIT customHandlerParamModified(inParameter);
+ }
+ void SendCustomReferencesModified(Qt3DSDMInstanceHandle inOwner,
+ const TCharStr &inString) override
+ {
+ CHECK_SIGNALS_ENABLED();
+ Q_EMIT customReferencesModified(inOwner, inString);
+ }
+};
+
+TSignalItemPtr CreateCustomPropCoreSignaller()
+{
+ return TSignalItemPtr(
+ static_cast<ICustomPropCoreSignalProvider *>(new CCustomPropCoreSignaller()));
+}
+
+class CStudioFullSystemSignaller : public QObject, public IStudioFullSystemSignalProvider,
+ public IStudioFullSystemSignalSender
+{
+ Q_OBJECT
+Q_SIGNALS:
+ void changeSetBegin();
+ void changeSetEnd();
+ void animationBegin();
+ void animationEnd();
+ void slideCreated(Qt3DSDMSlideHandle);
+ void slideDeleted(Qt3DSDMSlideHandle);
+ void slideRearranged(Qt3DSDMSlideHandle, int, int);
+ void componentSeconds(Qt3DSDMSlideHandle);
+ void beginComponentSeconds(Qt3DSDMSlideHandle);
+ void propertyLinked(Qt3DSDMSlideHandle, Qt3DSDMInstanceHandle, Qt3DSDMPropertyHandle);
+ void propertyUnlinked(Qt3DSDMSlideHandle, Qt3DSDMInstanceHandle, Qt3DSDMPropertyHandle);
+ void activeSlide(Qt3DSDMSlideHandle, int, Qt3DSDMSlideHandle);
+ void instanceCreated(Qt3DSDMInstanceHandle);
+ void instanceDeleted(Qt3DSDMInstanceHandle);
+ void animationCreated(Qt3DSDMAnimationHandle, Qt3DSDMInstanceHandle, Qt3DSDMPropertyHandle);
+ void animationDeleted(Qt3DSDMAnimationHandle, Qt3DSDMInstanceHandle, Qt3DSDMPropertyHandle);
+ void controlledToggled(Qt3DSDMInstanceHandle, Qt3DSDMPropertyHandle);
+ void keyframeInserted(Qt3DSDMAnimationHandle, Qt3DSDMKeyframeHandle);
+ void keyframeErased(Qt3DSDMAnimationHandle, Qt3DSDMKeyframeHandle);
+ void keyframeUpdated(Qt3DSDMKeyframeHandle);
+ void connectFirstKeyframeDynamicSet(Qt3DSDMAnimationHandle, bool);
+ void instancePropertyValue(Qt3DSDMInstanceHandle, Qt3DSDMPropertyHandle);
+ void actionCreated(Qt3DSDMActionHandle, Qt3DSDMSlideHandle, Qt3DSDMInstanceHandle);
+ void actionDeleted(Qt3DSDMActionHandle, Qt3DSDMSlideHandle, Qt3DSDMInstanceHandle);
+ void triggerObjectSet(Qt3DSDMActionHandle);
+ void targetObjectSet(Qt3DSDMActionHandle);
+ void eventHandleSet(Qt3DSDMActionHandle);
+ void handlerHandleSet(Qt3DSDMActionHandle);
+ void handlerArgumentValueSet(Qt3DSDMHandlerArgHandle);
+ void customPropertyCreated(Qt3DSDMPropertyHandle, Qt3DSDMInstanceHandle);
+ void customPropertyDeleted(Qt3DSDMPropertyHandle, Qt3DSDMInstanceHandle);
+ void customPropertyModified(Qt3DSDMPropertyHandle);
+ void customEventCreated(Qt3DSDMEventHandle, Qt3DSDMInstanceHandle);
+ void customEventDeleted(Qt3DSDMEventHandle, Qt3DSDMInstanceHandle);
+ void customEventModified(Qt3DSDMEventHandle);
+ void customHandlerCreated(Qt3DSDMHandlerHandle, Qt3DSDMInstanceHandle);
+ void customHandlerDeleted(Qt3DSDMHandlerHandle, Qt3DSDMInstanceHandle);
+ void customHandlerModified(Qt3DSDMHandlerHandle);
+ void customHandlerParamCreated(Qt3DSDMHandlerParamHandle, Qt3DSDMHandlerHandle);
+ void customHandlerParamDeleted(Qt3DSDMHandlerParamHandle, Qt3DSDMHandlerHandle);
+ void customHandlerParamModified(Qt3DSDMHandlerParamHandle);
+ void customReferencesModified(Qt3DSDMInstanceHandle, const TCharStr &);
+private:
+ ISlideSystemSignalProvider *m_SlideSystemSignalProvider;
+
+public:
+ CStudioFullSystemSignaller(ISlideSystemSignalProvider *inProvider)
+ : m_SlideSystemSignalProvider(inProvider)
+ {
+ }
+
+ virtual TSignalConnectionPtr ConnectChangeSetBegin(const std::function<void()> &inCallback)
+ {
+ return CONNECT_SIGNAL_QT(&CStudioFullSystemSignaller::changeSetBegin);
+ }
+ virtual TSignalConnectionPtr ConnectChangeSetEnd(const std::function<void()> &inCallback)
+ {
+ return CONNECT_SIGNAL_QT(&CStudioFullSystemSignaller::changeSetEnd);
+ }
+
+ // Used when people start to set component times.
+ virtual TSignalConnectionPtr ConnectAnimationSetBegin(const std::function<void()> &inCallback)
+ {
+ return CONNECT_SIGNAL_QT(&CStudioFullSystemSignaller::animationBegin);
+ }
+ virtual TSignalConnectionPtr ConnectAnimationSetEnd(const std::function<void()> &inCallback)
+ {
+ return CONNECT_SIGNAL_QT(&CStudioFullSystemSignaller::animationEnd);
+ }
+
+ virtual TSignalConnectionPtr
+ ConnectSlideCreated(const std::function<void(Qt3DSDMSlideHandle)> &inCallback) override
+ {
+ return CONNECT_SIGNAL_QT(&CStudioFullSystemSignaller::slideCreated);
+ }
+ virtual TSignalConnectionPtr
+ ConnectSlideDeleted(const std::function<void(Qt3DSDMSlideHandle)> &inCallback) override
+ {
+ return CONNECT_SIGNAL_QT(&CStudioFullSystemSignaller::slideDeleted);
+ }
+ virtual TSignalConnectionPtr
+ ConnectSlideRearranged(const std::function<void(Qt3DSDMSlideHandle, int, int)> &inCallback) override
+ {
+ return CONNECT_SIGNAL_QT(&CStudioFullSystemSignaller::slideRearranged);
+ }
+ virtual TSignalConnectionPtr
+ ConnectBeginComponentSeconds(const std::function<void(Qt3DSDMSlideHandle)> &inCallback) override
+ {
+ return CONNECT_SIGNAL_QT(&CStudioFullSystemSignaller::beginComponentSeconds);
+ }
+ virtual TSignalConnectionPtr
+ ConnectComponentSeconds(const std::function<void(Qt3DSDMSlideHandle)> &inCallback) override
+ {
+ return CONNECT_SIGNAL_QT(&CStudioFullSystemSignaller::componentSeconds);
+ }
+ TSignalConnectionPtr ConnectPropertyLinked(
+ const std::function<void(Qt3DSDMSlideHandle, Qt3DSDMInstanceHandle, Qt3DSDMPropertyHandle)>
+ &inCallback) override
+ {
+ return CONNECT_SIGNAL_QT(&CStudioFullSystemSignaller::propertyLinked);
+ }
+ TSignalConnectionPtr ConnectPropertyUnlinked(
+ const std::function<void(Qt3DSDMSlideHandle, Qt3DSDMInstanceHandle, Qt3DSDMPropertyHandle)>
+ &inCallback) override
+ {
+ return CONNECT_SIGNAL_QT(&CStudioFullSystemSignaller::propertyUnlinked);
+ }
+ TSignalConnectionPtr ConnectActiveSlide(
+ const std::function<void(Qt3DSDMSlideHandle, int, Qt3DSDMSlideHandle)> &inCallback) override
+ {
+ return CONNECT_SIGNAL_QT(&CStudioFullSystemSignaller::activeSlide);
+ }
+
+ virtual TSignalConnectionPtr
+ ConnectInstanceCreated(const std::function<void(Qt3DSDMInstanceHandle)> &inCallback) override
+ {
+ return CONNECT_SIGNAL_QT(&CStudioFullSystemSignaller::instanceCreated);
+ }
+ virtual TSignalConnectionPtr
+ ConnectInstanceDeleted(const std::function<void(Qt3DSDMInstanceHandle)> &inCallback) override
+ {
+ return CONNECT_SIGNAL_QT(&CStudioFullSystemSignaller::instanceDeleted);
+ }
+ virtual TSignalConnectionPtr
+ ConnectAnimationCreated(const std::function<void(Qt3DSDMAnimationHandle, Qt3DSDMInstanceHandle,
+ Qt3DSDMPropertyHandle)> &inCallback) override
+ {
+ return CONNECT_SIGNAL_QT(&CStudioFullSystemSignaller::animationCreated);
+ }
+ virtual TSignalConnectionPtr
+ ConnectAnimationDeleted(const std::function<void(Qt3DSDMAnimationHandle, Qt3DSDMInstanceHandle,
+ Qt3DSDMPropertyHandle)> &inCallback) override
+ {
+ return CONNECT_SIGNAL_QT(&CStudioFullSystemSignaller::animationDeleted);
+ }
+ TSignalConnectionPtr ConnectKeyframeInserted(
+ const std::function<void(Qt3DSDMAnimationHandle, Qt3DSDMKeyframeHandle)> &inCallback) override
+ {
+ return CONNECT_SIGNAL_QT(&CStudioFullSystemSignaller::keyframeInserted);
+ }
+ TSignalConnectionPtr ConnectKeyframeErased(
+ const std::function<void(Qt3DSDMAnimationHandle, Qt3DSDMKeyframeHandle)> &inCallback) override
+ {
+ return CONNECT_SIGNAL_QT(&CStudioFullSystemSignaller::keyframeErased);
+ }
+ virtual TSignalConnectionPtr
+ ConnectKeyframeUpdated(const std::function<void(Qt3DSDMKeyframeHandle)> &inCallback) override
+ {
+ return CONNECT_SIGNAL_QT(&CStudioFullSystemSignaller::keyframeUpdated);
+ }
+ TSignalConnectionPtr ConnectInstancePropertyValue(
+ const std::function<void(Qt3DSDMInstanceHandle, Qt3DSDMPropertyHandle)> &inCallback) override
+ {
+ return CONNECT_SIGNAL_QT(&CStudioFullSystemSignaller::instancePropertyValue);
+ }
+ TSignalConnectionPtr ConnectFirstKeyframeDynamicSet(
+ const std::function<void(Qt3DSDMAnimationHandle, bool)> &inCallback) override
+ {
+ return CONNECT_SIGNAL_QT(&CStudioFullSystemSignaller::connectFirstKeyframeDynamicSet);
+ }
+
+ TSignalConnectionPtr ConnectActionCreated(
+ const std::function<void(Qt3DSDMActionHandle, Qt3DSDMSlideHandle, Qt3DSDMInstanceHandle)>
+ &inCallback) override
+ {
+ return CONNECT_SIGNAL_QT(&CStudioFullSystemSignaller::actionCreated);
+ }
+ TSignalConnectionPtr ConnectActionDeleted(
+ const std::function<void(Qt3DSDMActionHandle, Qt3DSDMSlideHandle, Qt3DSDMInstanceHandle)>
+ &inCallback) override
+ {
+ return CONNECT_SIGNAL_QT(&CStudioFullSystemSignaller::actionDeleted);
+ }
+ virtual TSignalConnectionPtr
+ ConnectTriggerObjectSet(const std::function<void(Qt3DSDMActionHandle)> &inCallback) override
+ {
+ return CONNECT_SIGNAL_QT(&CStudioFullSystemSignaller::triggerObjectSet);
+ }
+ virtual TSignalConnectionPtr
+ ConnectTargetObjectSet(const std::function<void(Qt3DSDMActionHandle)> &inCallback) override
+ {
+ return CONNECT_SIGNAL_QT(&CStudioFullSystemSignaller::targetObjectSet);
+ }
+ virtual TSignalConnectionPtr
+ ConnectEventSet(const std::function<void(Qt3DSDMActionHandle)> &inCallback) override
+ {
+ return CONNECT_SIGNAL_QT(&CStudioFullSystemSignaller::eventHandleSet);
+ }
+ virtual TSignalConnectionPtr
+ ConnectHandlerSet(const std::function<void(Qt3DSDMActionHandle)> &inCallback) override
+ {
+ return CONNECT_SIGNAL_QT(&CStudioFullSystemSignaller::handlerHandleSet);
+ }
+ virtual TSignalConnectionPtr
+ ConnectHandlerArgumentValueSet(const std::function<void(Qt3DSDMHandlerArgHandle)> &inCallback) override
+ {
+ return CONNECT_SIGNAL_QT(&CStudioFullSystemSignaller::handlerArgumentValueSet);
+ }
+
+ TSignalConnectionPtr ConnectCustomPropertyCreated(
+ const std::function<void(Qt3DSDMPropertyHandle, Qt3DSDMInstanceHandle)> &inCallback) override
+ {
+ return CONNECT_SIGNAL_QT(&CStudioFullSystemSignaller::customPropertyCreated);
+ }
+ TSignalConnectionPtr ConnectCustomPropertyDeleted(
+ const std::function<void(Qt3DSDMPropertyHandle, Qt3DSDMInstanceHandle)> &inCallback) override
+ {
+ return CONNECT_SIGNAL_QT(&CStudioFullSystemSignaller::customPropertyDeleted);
+ }
+ virtual TSignalConnectionPtr
+ ConnectCustomPropertyModified(const std::function<void(Qt3DSDMPropertyHandle)> &inCallback) override
+ {
+ return CONNECT_SIGNAL_QT(&CStudioFullSystemSignaller::customPropertyModified);
+ }
+ TSignalConnectionPtr ConnectCustomEventCreated(
+ const std::function<void(Qt3DSDMEventHandle, Qt3DSDMInstanceHandle)> &inCallback) override
+ {
+ return CONNECT_SIGNAL_QT(&CStudioFullSystemSignaller::customEventCreated);
+ }
+ TSignalConnectionPtr ConnectCustomEventDeleted(
+ const std::function<void(Qt3DSDMEventHandle, Qt3DSDMInstanceHandle)> &inCallback) override
+ {
+ return CONNECT_SIGNAL_QT(&CStudioFullSystemSignaller::customEventDeleted);
+ }
+ virtual TSignalConnectionPtr
+ ConnectCustomEventModified(const std::function<void(Qt3DSDMEventHandle)> &inCallback) override
+ {
+ return CONNECT_SIGNAL_QT(&CStudioFullSystemSignaller::customEventModified);
+ }
+ TSignalConnectionPtr ConnectCustomHandlerCreated(
+ const std::function<void(Qt3DSDMHandlerHandle, Qt3DSDMInstanceHandle)> &inCallback) override
+ {
+ return CONNECT_SIGNAL_QT(&CStudioFullSystemSignaller::customHandlerCreated);
+ }
+ TSignalConnectionPtr ConnectCustomHandlerDeleted(
+ const std::function<void(Qt3DSDMHandlerHandle, Qt3DSDMInstanceHandle)> &inCallback) override
+ {
+ return CONNECT_SIGNAL_QT(&CStudioFullSystemSignaller::customHandlerDeleted);
+ }
+ virtual TSignalConnectionPtr
+ ConnectCustomHandlerModified(const std::function<void(Qt3DSDMHandlerHandle)> &inCallback) override
+ {
+ return CONNECT_SIGNAL_QT(&CStudioFullSystemSignaller::customHandlerModified);
+ }
+ TSignalConnectionPtr ConnectCustomHandlerParamCreated(
+ const std::function<void(Qt3DSDMHandlerParamHandle, Qt3DSDMHandlerHandle)> &inCallback) override
+ {
+ return CONNECT_SIGNAL_QT(&CStudioFullSystemSignaller::customHandlerParamCreated);
+ }
+ TSignalConnectionPtr ConnectCustomHandlerParamDeleted(
+ const std::function<void(Qt3DSDMHandlerParamHandle, Qt3DSDMHandlerHandle)> &inCallback) override
+ {
+ return CONNECT_SIGNAL_QT(&CStudioFullSystemSignaller::customHandlerParamDeleted);
+ }
+ TSignalConnectionPtr ConnectCustomHandlerParamModified(
+ const std::function<void(Qt3DSDMHandlerParamHandle)> &inCallback) override
+ {
+ return CONNECT_SIGNAL_QT(&CStudioFullSystemSignaller::customHandlerParamModified);
+ }
+ TSignalConnectionPtr ConnectCustomReferencesModified(
+ const std::function<void(Qt3DSDMInstanceHandle, const TCharStr &)> &inCallback) override
+ {
+ return CONNECT_SIGNAL_QT(&CStudioFullSystemSignaller::customReferencesModified);
+ }
+ TSignalConnectionPtr ConnectControlledToggled(
+ const std::function<void(
+ Qt3DSDMInstanceHandle, Qt3DSDMPropertyHandle)> &inCallback) override
+ {
+ return CONNECT_SIGNAL_QT(&CStudioFullSystemSignaller::controlledToggled);
+ }
+
+ virtual void SendChangeSetBegin()
+ {
+ CHECK_SIGNALS_ENABLED();
+ Q_EMIT changeSetBegin();
+ }
+ virtual void SendChangeSetEnd()
+ {
+ CHECK_SIGNALS_ENABLED();
+ Q_EMIT changeSetEnd();
+ }
+
+ virtual void SendAnimationSetBegin()
+ {
+ CHECK_SIGNALS_ENABLED();
+ Q_EMIT animationBegin();
+ }
+ virtual void SendAnimationSetEnd()
+ {
+ CHECK_SIGNALS_ENABLED();
+ Q_EMIT animationEnd();
+ }
+
+ void SendSlideCreated(Qt3DSDMSlideHandle inSlide) override
+ {
+ CHECK_SIGNALS_ENABLED();
+ Q_EMIT slideCreated(inSlide);
+ }
+ void SendSlideDeleted(Qt3DSDMSlideHandle inSlide) override
+ {
+ CHECK_SIGNALS_ENABLED();
+ Q_EMIT slideDeleted(inSlide);
+ }
+ void SendSlideRearranged(Qt3DSDMSlideHandle inMaster, int inOldIndex, int inNewIndex) override
+ {
+ CHECK_SIGNALS_ENABLED();
+ Q_EMIT slideRearranged(inMaster, inOldIndex, inNewIndex);
+ }
+ void SendBeginComponentSeconds(Qt3DSDMSlideHandle inMaster) override
+ {
+ CHECK_SIGNALS_ENABLED();
+ Q_EMIT beginComponentSeconds(inMaster);
+ }
+ void SendComponentSeconds(Qt3DSDMSlideHandle inMaster) override
+ {
+ CHECK_SIGNALS_ENABLED();
+ Q_EMIT componentSeconds(inMaster);
+ }
+ void SendPropertyLinked(Qt3DSDMSlideHandle inMaster, Qt3DSDMInstanceHandle inInstance,
+ Qt3DSDMPropertyHandle inProperty) override
+ {
+ CHECK_SIGNALS_ENABLED();
+ Q_EMIT propertyLinked(inMaster, inInstance, inProperty);
+ }
+ void SendPropertyUnlinked(Qt3DSDMSlideHandle inMaster, Qt3DSDMInstanceHandle inInstance,
+ Qt3DSDMPropertyHandle inProperty) override
+ {
+ CHECK_SIGNALS_ENABLED();
+ Q_EMIT propertyUnlinked(inMaster, inInstance, inProperty);
+ }
+ void SendActiveSlide(Qt3DSDMSlideHandle inMaster, int inIndex, Qt3DSDMSlideHandle inSlide) override
+ {
+ CHECK_SIGNALS_ENABLED();
+ Q_EMIT activeSlide(inMaster, inIndex, inSlide);
+ }
+
+ void SendInstanceCreated(Qt3DSDMInstanceHandle inInstance) override
+ {
+ CHECK_SIGNALS_ENABLED();
+ Q_EMIT instanceCreated(inInstance);
+ }
+ void SendInstanceDeleted(Qt3DSDMInstanceHandle inInstance) override
+ {
+ CHECK_SIGNALS_ENABLED();
+ Q_EMIT instanceDeleted(inInstance);
+ }
+
+ void SendAnimationCreated(Qt3DSDMAnimationHandle inAnimation,
+ Qt3DSDMInstanceHandle inInstance,
+ Qt3DSDMPropertyHandle inProperty) override
+ {
+ CHECK_SIGNALS_ENABLED();
+ Q_EMIT animationCreated(inAnimation, inInstance, inProperty);
+ }
+ void SendAnimationDeleted(Qt3DSDMAnimationHandle inAnimation,
+ Qt3DSDMInstanceHandle inInstance,
+ Qt3DSDMPropertyHandle inProperty) override
+ {
+ CHECK_SIGNALS_ENABLED();
+ Q_EMIT animationDeleted(inAnimation, inInstance, inProperty);
+ }
+ void SendKeyframeInserted(Qt3DSDMAnimationHandle inAnimation,
+ Qt3DSDMKeyframeHandle inKeyframe) override
+ {
+ CHECK_SIGNALS_ENABLED();
+ Q_EMIT keyframeInserted(inAnimation, inKeyframe);
+ }
+ void SendKeyframeErased(Qt3DSDMAnimationHandle inAnimation,
+ Qt3DSDMKeyframeHandle inKeyframe) override
+ {
+ CHECK_SIGNALS_ENABLED();
+ Q_EMIT keyframeErased(inAnimation, inKeyframe);
+ }
+ void SendKeyframeUpdated(Qt3DSDMKeyframeHandle inKeyframe) override
+ {
+ CHECK_SIGNALS_ENABLED();
+ Q_EMIT keyframeUpdated(inKeyframe);
+ }
+ void SendConnectFirstKeyframeDynamicSet(Qt3DSDMAnimationHandle inAnimation,
+ bool inDynamic) override
+ {
+ CHECK_SIGNALS_ENABLED();
+ Q_EMIT connectFirstKeyframeDynamicSet(inAnimation, inDynamic);
+ }
+
+ void SendInstancePropertyValue(Qt3DSDMInstanceHandle inInstance,
+ Qt3DSDMPropertyHandle inProperty) override
+ {
+ CHECK_SIGNALS_ENABLED();
+ Q_EMIT instancePropertyValue(inInstance, inProperty);
+ }
+
+ void SendActionCreated(Qt3DSDMActionHandle inAction, Qt3DSDMSlideHandle inSlide,
+ Qt3DSDMInstanceHandle inOwner) override
+ {
+ CHECK_SIGNALS_ENABLED();
+ Q_EMIT actionCreated(inAction, inSlide, inOwner);
+ }
+ void SendActionDeleted(Qt3DSDMActionHandle inAction, Qt3DSDMSlideHandle inSlide,
+ Qt3DSDMInstanceHandle inOwner) override
+ {
+ CHECK_SIGNALS_ENABLED();
+ Q_EMIT actionDeleted(inAction, inSlide, inOwner);
+ }
+ void SendTriggerObjectSet(Qt3DSDMActionHandle inAction) override
+ {
+ CHECK_SIGNALS_ENABLED();
+ Q_EMIT triggerObjectSet(inAction);
+ }
+ void SendTargetObjectSet(Qt3DSDMActionHandle inAction) override
+ {
+ CHECK_SIGNALS_ENABLED();
+ Q_EMIT targetObjectSet(inAction);
+ }
+ void SendEventSet(Qt3DSDMActionHandle inAction) override
+ {
+ CHECK_SIGNALS_ENABLED();
+ Q_EMIT eventHandleSet(inAction);
+ }
+ void SendHandlerSet(Qt3DSDMActionHandle inAction) override
+ {
+ CHECK_SIGNALS_ENABLED();
+ Q_EMIT handlerHandleSet(inAction);
+ }
+ void SendHandlerArgumentValueSet(Qt3DSDMHandlerArgHandle inHandlerArgument) override
+ {
+ CHECK_SIGNALS_ENABLED();
+ Q_EMIT handlerArgumentValueSet(inHandlerArgument);
+ }
+
+ void SendCustomPropertyCreated(Qt3DSDMPropertyHandle inProp,
+ Qt3DSDMInstanceHandle inOwner) override
+ {
+ CHECK_SIGNALS_ENABLED();
+ Q_EMIT customPropertyCreated(inProp, inOwner);
+ }
+ void SendCustomPropertyDeleted(Qt3DSDMPropertyHandle inProp,
+ Qt3DSDMInstanceHandle inOwner) override
+ {
+ CHECK_SIGNALS_ENABLED();
+ Q_EMIT customPropertyDeleted(inProp, inOwner);
+ }
+ void SendCustomPropertyModified(Qt3DSDMPropertyHandle inProp) override
+ {
+ CHECK_SIGNALS_ENABLED();
+ Q_EMIT customPropertyModified(inProp);
+ }
+ void SendCustomEventCreated(Qt3DSDMEventHandle inEvent, Qt3DSDMInstanceHandle inOwner) override
+ {
+ CHECK_SIGNALS_ENABLED();
+ Q_EMIT customEventCreated(inEvent, inOwner);
+ }
+ void SendCustomEventDeleted(Qt3DSDMEventHandle inEvent, Qt3DSDMInstanceHandle inOwner) override
+ {
+ CHECK_SIGNALS_ENABLED();
+ Q_EMIT customEventDeleted(inEvent, inOwner);
+ }
+ void SendCustomEventModified(Qt3DSDMEventHandle inEvent) override
+ {
+ CHECK_SIGNALS_ENABLED();
+ Q_EMIT customEventModified(inEvent);
+ }
+ void SendCustomHandlerCreated(Qt3DSDMHandlerHandle inHandler,
+ Qt3DSDMInstanceHandle inOwner) override
+ {
+ CHECK_SIGNALS_ENABLED();
+ Q_EMIT customHandlerCreated(inHandler, inOwner);
+ }
+ void SendCustomHandlerDeleted(Qt3DSDMHandlerHandle inHandler,
+ Qt3DSDMInstanceHandle inOwner) override
+ {
+ CHECK_SIGNALS_ENABLED();
+ Q_EMIT customHandlerDeleted(inHandler, inOwner);
+ }
+ void SendCustomHandlerModified(Qt3DSDMHandlerHandle inHandler) override
+ {
+ CHECK_SIGNALS_ENABLED();
+ Q_EMIT customHandlerModified(inHandler);
+ }
+ void SendCustomHandlerParamCreated(Qt3DSDMHandlerParamHandle inParameter,
+ Qt3DSDMHandlerHandle inHandler) override
+ {
+ CHECK_SIGNALS_ENABLED();
+ Q_EMIT customHandlerParamCreated(inParameter, inHandler);
+ }
+ void SendCustomHandlerParamDeleted(Qt3DSDMHandlerParamHandle inParameter,
+ Qt3DSDMHandlerHandle inHandler) override
+ {
+ CHECK_SIGNALS_ENABLED();
+ Q_EMIT customHandlerParamDeleted(inParameter, inHandler);
+ }
+ void SendCustomHandlerParamModified(Qt3DSDMHandlerParamHandle inParameter) override
+ {
+ CHECK_SIGNALS_ENABLED();
+ Q_EMIT customHandlerParamModified(inParameter);
+ }
+ void SendCustomReferencesModified(Qt3DSDMInstanceHandle inOwner,
+ const TCharStr &inString) override
+ {
+ CHECK_SIGNALS_ENABLED();
+ Q_EMIT customReferencesModified(inOwner, inString);
+ }
+
+ void SendControlledToggled(Qt3DSDMInstanceHandle inInstance,
+ Qt3DSDMPropertyHandle inProperty) override
+ {
+ CHECK_SIGNALS_ENABLED();
+ Q_EMIT controlledToggled(inInstance, inProperty);
+ }
+};
+
+TSignalItemPtr
+CreateStudioFullSystemSignaller(ISlideSystemSignalProvider *inSlideSystemSignalProvider)
+{
+ return TSignalItemPtr(static_cast<IStudioFullSystemSignalProvider *>(
+ new CStudioFullSystemSignaller(inSlideSystemSignalProvider)));
+}
+}
+
+#include "SignalsImpl.moc"
diff --git a/src/dm/systems/SignalsImpl.h b/src/dm/systems/SignalsImpl.h
new file mode 100644
index 0000000..988270e
--- /dev/null
+++ b/src/dm/systems/SignalsImpl.h
@@ -0,0 +1,50 @@
+/****************************************************************************
+**
+** 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 SIGNALSIMPLH
+#define SIGNALSIMPLH
+#include "Qt3DSDMSignals.h"
+
+namespace qt3dsdm {
+class ISlideSystemSignalProvider;
+
+TSignalItemPtr CreatePropertyCoreSignaller();
+TSignalItemPtr CreateDataCoreSignaller();
+TSignalItemPtr CreateSlideCoreSignaller();
+TSignalItemPtr CreateSlideGraphCoreSignaller();
+TSignalItemPtr CreateAnimationCoreSignaller();
+TSignalItemPtr CreateActionCoreSignaller();
+TSignalItemPtr CreateActionSystemSignaller();
+TSignalItemPtr CreateSlideSystemSignaller();
+TSignalItemPtr CreateCustomPropCoreSignaller();
+TSignalItemPtr
+CreateStudioFullSystemSignaller(ISlideSystemSignalProvider *inSlideSystemSignalProvider);
+}
+
+#endif \ No newline at end of file
diff --git a/src/dm/systems/SlideSystem.cpp b/src/dm/systems/SlideSystem.cpp
new file mode 100644
index 0000000..d6d8893
--- /dev/null
+++ b/src/dm/systems/SlideSystem.cpp
@@ -0,0 +1,867 @@
+/****************************************************************************
+**
+** 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)
+#endif
+#include "SlideSystem.h"
+#include "SimpleSlideCore.h"
+
+using namespace std;
+
+namespace qt3dsdm {
+
+SSlideSystem::SSlideSystem(TDataCorePtr inDataCore, TSlideCorePtr inSlideCore,
+ TSlideGraphCorePtr inSlideGraphCore, TAnimationCorePtr inAnimationCore,
+ Qt3DSDMInstanceHandle inSlideInstance,
+ Qt3DSDMPropertyHandle inComponentGuidProperty)
+ : m_DataCore(inDataCore)
+ , m_SlideCore(inSlideCore)
+ , m_SlideGraphCore(inSlideGraphCore)
+ , m_AnimationCore(inAnimationCore)
+ , m_SlideInstance(inSlideInstance)
+ , m_ComponentGuid(inComponentGuidProperty)
+{
+ m_Signaller = CreateSlideSystemSignaller();
+}
+void SSlideSystem::SetPropertySystem(TPropertySystemPtr inPropertySystem)
+{
+ m_PropertySystem = inPropertySystem;
+}
+
+Qt3DSDMSlideHandle SSlideSystem::CreateMasterSlide()
+{
+ Qt3DSDMInstanceHandle theSlideInstance = m_DataCore->CreateInstance();
+ m_DataCore->DeriveInstance(theSlideInstance, m_SlideInstance);
+ Qt3DSDMSlideHandle retval = m_SlideCore->CreateSlide(theSlideInstance);
+ m_SlideGraphCore->CreateSlideGraph(retval);
+ GetSignalSender()->SendMasterCreated(retval);
+ return retval;
+}
+
+inline bool PropertyHandlePairEquals(const TPropertyHandlePropertyInfoPair &inPair,
+ Qt3DSDMPropertyHandle inProperty)
+{
+ return (inProperty == inPair.first);
+}
+
+void AddReferencedInstance(const TSlideEntry &inEntry,
+ const TPropertyHandlePropertyInfoPairList &inInfoPairList,
+ Qt3DSDMSlideHandle inSourceSlide, Qt3DSDMSlideHandle inDestSlide,
+ TInstanceHandleList &outInstances, TSlideEntryList &outReferencedEntries)
+{
+ TPropertyHandlePropertyInfoPairList::const_iterator theFind =
+ find_if<TPropertyHandlePropertyInfoPairList::const_iterator>(
+ inInfoPairList, std::bind(PropertyHandlePairEquals,
+ std::placeholders::_1, get<1>(inEntry)));
+ if (theFind != inInfoPairList.end()) {
+ TPropertyInstanceInfoPtr theInfo(theFind->second);
+ Qt3DSDMInstanceHandle theReferenced(theInfo->GetInstanceForProperty(get<2>(inEntry)));
+ if (theReferenced.Valid()
+ && !exists(outInstances, std::bind(equal_to<int>(), theReferenced,
+ std::placeholders::_1))) {
+ insert_unique(outInstances, theReferenced);
+ SValue theNewValue(
+ theInfo->CreateInstanceForProperty(inSourceSlide, inDestSlide, theReferenced));
+ outReferencedEntries.push_back(
+ make_tuple(get<0>(inEntry), get<1>(inEntry), theNewValue));
+ }
+ }
+}
+
+void CopySpecificAnimation(Qt3DSDMSlideHandle inMaster, Qt3DSDMSlideHandle inTarget,
+ TInstancePropertyPair inPropertyPair, TAnimationCorePtr inAnimationCore,
+ size_t inIndex)
+{
+ Qt3DSDMAnimationHandle theAnimation = inAnimationCore->GetAnimation(
+ inMaster, inPropertyPair.first, inPropertyPair.second, inIndex);
+ if (theAnimation.Valid())
+ CopyAnimation(inAnimationCore, theAnimation, inTarget, inPropertyPair.first,
+ inPropertyPair.second, inIndex);
+}
+
+void CopyAnimationIfExist(Qt3DSDMSlideHandle inMaster, Qt3DSDMSlideHandle inTarget,
+ TInstancePropertyPair inPropertyPair, TPropertySystemPtr inPropertySystem,
+ TAnimationCorePtr inAnimationCore)
+{
+ DataModelDataType::Value thePropertyType = inPropertySystem->GetDataType(inPropertyPair.second);
+ std::tuple<bool, size_t> theArity = GetDatatypeAnimatableAndArity(thePropertyType);
+ if (std::get<0>(theArity))
+ do_times(std::get<1>(theArity), std::bind(CopySpecificAnimation, inMaster, inTarget,
+ inPropertyPair, inAnimationCore,
+ std::placeholders::_1));
+}
+
+void SetEntryValueIfNotReferenced(const TSlideEntry &inEntry,
+ const TInstanceHandleList &inReferencedInstances,
+ const TSlideEntryList &inReferencedEntries,
+ Qt3DSDMSlideHandle inSource, Qt3DSDMSlideHandle inDestSlide,
+ TPropertySystemPtr inPropertySystem, TSlideCorePtr inDestCore,
+ TAnimationCorePtr inAnimationCore)
+{
+ // Don't copy referenced instance properties.
+ if (exists(inReferencedInstances, std::bind(equal_to<int>(), get<0>(inEntry),
+ std::placeholders::_1)))
+ return;
+ TSlideEntryList::const_iterator theFind = find_if<TSlideEntryList::const_iterator>(
+ inReferencedEntries,
+ std::bind(CSimpleSlideCore::PropertyFound, get<0>(inEntry), get<1>(inEntry),
+ std::placeholders::_1));
+ if (theFind != inReferencedEntries.end())
+ inDestCore->ForceSetInstancePropertyValue(inDestSlide, get<0>(inEntry), get<1>(inEntry),
+ get<2>(*theFind));
+ else
+ inDestCore->ForceSetInstancePropertyValue(inDestSlide, get<0>(inEntry), get<1>(inEntry),
+ get<2>(inEntry));
+ CopyAnimationIfExist(inSource, inDestSlide, make_pair(get<0>(inEntry), get<1>(inEntry)),
+ inPropertySystem, inAnimationCore);
+}
+
+Qt3DSDMSlideHandle SSlideSystem::CreateSlide(Qt3DSDMSlideHandle inMaster, int inIndex)
+{
+ return DuplicateSlide(inMaster, inIndex);
+}
+
+Qt3DSDMSlideHandle SSlideSystem::DuplicateSlide(Qt3DSDMSlideHandle inSourceSlide, int inIndex)
+{
+ Qt3DSDMSlideHandle theMaster = GetMasterSlide(inSourceSlide);
+ Qt3DSDMInstanceHandle theSlideInstance = m_DataCore->CreateInstance();
+ m_DataCore->DeriveInstance(theSlideInstance, m_SlideInstance);
+ Qt3DSDMSlideHandle retval = m_SlideCore->CreateSlide(theSlideInstance);
+
+ TSlideHandleList theChildren;
+ m_SlideCore->GetChildSlides(theMaster, theChildren);
+ m_SlideCore->DeriveSlide(retval, theMaster, inIndex - 1);
+ int finalIndex = m_SlideCore->GetChildIndex(theMaster, retval) + 1;
+ if (!theChildren.empty()) {
+ // If the master was passed in, we get the intersecting properties
+ // of the master and first child.
+ // if another slide was passed in, we again do the intersection but we
+ // take the values from the source slide instead of the master.
+ TSlideEntryList theIntersectingEntries;
+ if (inSourceSlide == theMaster)
+ m_SlideCore->GetIntersectingProperties(theMaster, theChildren.at(0),
+ theIntersectingEntries);
+ else
+ m_SlideCore->GetIntersectingProperties(inSourceSlide, theMaster,
+ theIntersectingEntries);
+
+ // duplicates the instance properties, from source slide (could be master (a new slide
+ // command) or another other slides (duplicate slide) to the newly created slide
+ m_DataCore->CopyInstanceProperties(this->GetSlideInstance(inSourceSlide), theSlideInstance);
+
+ TInstanceHandleList theReferencedInstances;
+ TSlideEntryList theReferencedEntries;
+ do_all(theIntersectingEntries,
+ std::bind(AddReferencedInstance, std::placeholders::_1,
+ std::cref(m_PropertyInfoPairList),
+ inSourceSlide, retval, std::ref(theReferencedInstances),
+ std::ref(theReferencedEntries)));
+ do_all(theIntersectingEntries,
+ std::bind(SetEntryValueIfNotReferenced, std::placeholders::_1,
+ std::cref(theReferencedInstances),
+ std::cref(theReferencedEntries), inSourceSlide, retval,
+ m_PropertySystem, m_SlideCore, m_AnimationCore));
+ }
+ GetSignalSender()->SendSlideCreated(theMaster, finalIndex, retval);
+ return retval;
+}
+
+Qt3DSDMSlideHandle SSlideSystem::GetMasterSlide(Qt3DSDMSlideHandle inSlide) const
+{
+ if (inSlide.Valid() && m_SlideCore->IsSlide(inSlide)) {
+ Qt3DSDMSlideHandle theParent = m_SlideCore->GetParentSlide(inSlide);
+ if (theParent.Valid())
+ return theParent;
+ return inSlide;
+ }
+ return 0;
+}
+
+bool SSlideSystem::IsMasterSlide(Qt3DSDMSlideHandle inSlide) const
+{
+ Qt3DSDMSlideHandle theParent = m_SlideCore->GetParentSlide(inSlide);
+ if (!theParent.Valid())
+ return true;
+ else
+ return false;
+}
+
+inline bool GraphGuidMatches(Qt3DSDMSlideGraphHandle inGraph, TSlideGraphCorePtr inSlideGraph,
+ TSlideCorePtr inSlideCore, TDataCorePtr inDataCore,
+ Qt3DSDMPropertyHandle inProperty, SValue inValue)
+{
+ Qt3DSDMSlideHandle theMaster = inSlideGraph->GetGraphRoot(inGraph);
+ Qt3DSDMInstanceHandle theInstance = inSlideCore->GetSlideInstance(theMaster);
+ SValue theValue;
+ if (inDataCore->GetInstancePropertyValue(theInstance, inProperty, theValue)
+ && Equals(inValue, theValue.toOldSkool()))
+ return true;
+ return false;
+}
+
+Qt3DSDMSlideHandle SSlideSystem::GetMasterSlideByComponentGuid(SLong4 inGuid) const
+{
+ TSlideGraphHandleList theGraphs;
+ m_SlideGraphCore->GetSlideGraphs(theGraphs);
+ TSlideGraphHandleList::iterator theFind = find_if<TSlideGraphHandleList::iterator>(
+ theGraphs, std::bind(GraphGuidMatches,
+ std::placeholders::_1, m_SlideGraphCore, m_SlideCore, m_DataCore,
+ m_ComponentGuid, inGuid));
+ if (theFind != theGraphs.end())
+ return m_SlideGraphCore->GetGraphRoot(*theFind);
+ return 0;
+}
+
+void InsertIfReferencedProperty(const TSlideEntry &inEntry,
+ const TPropertyHandlePropertyInfoPairList &inRefProperties,
+ TInstanceHandleList &inInstances)
+{
+ TPropertyHandlePropertyInfoPairList::const_iterator theFind =
+ find_if<TPropertyHandlePropertyInfoPairList::const_iterator>(
+ inRefProperties, std::bind(PropertyHandlePairEquals, std::placeholders::_1, get<1>(inEntry)));
+ if (theFind != inRefProperties.end()) {
+ Qt3DSDMInstanceHandle theInstance(theFind->second->GetInstanceForProperty(get<2>(inEntry)));
+ if (theInstance.Valid())
+ inInstances.push_back(theInstance);
+ }
+}
+
+void SSlideSystem::InsertEntryAndPropertyInstance(const TSlideEntry &inEntry,
+ TInstanceHandleList &inInstances,
+ Qt3DSDMSlideHandle inSlide)
+{
+ Qt3DSDMInstanceHandle theEntryInstance = get<0>(inEntry);
+ if (find(inInstances.begin(), inInstances.end(), theEntryInstance) == inInstances.end()) {
+ TGraphSlidePair thePair = m_SlideGraphCore->GetAssociatedGraph(theEntryInstance);
+ if (thePair.second == inSlide) // if this instance belongs to this slide
+ {
+ // get all references belong to this instance (ex: image instances that belong to this
+ // material instance)
+ qt3dsdm::SValue theValue;
+ for (TPropertyHandlePropertyInfoPairList::iterator theIter =
+ m_PropertyInfoPairList.begin();
+ theIter != m_PropertyInfoPairList.end(); ++theIter) {
+ if (m_DataCore->HasAggregateInstanceProperty(
+ theEntryInstance,
+ theIter->first) // check if the property exists before querying the value
+ && m_DataCore->GetInstancePropertyValue(
+ theEntryInstance, theIter->first,
+ theValue)) // this function may throw error if the property doesn't exist
+ {
+ Qt3DSDMInstanceHandle theInstance(
+ theIter->second->GetInstanceForProperty(theValue.toOldSkool()));
+ if (theInstance.Valid())
+ inInstances.push_back(theInstance);
+ }
+ }
+ // get this instance as well
+ inInstances.push_back(theEntryInstance);
+ }
+ }
+}
+
+// Delete the referenced instances of this slide
+// This function is very similar to GetReferencedInstances
+// You change one function, you need to change the other function
+void SSlideSystem::DeleteReferencedInstances(Qt3DSDMSlideHandle inSlide)
+{
+ // Recursively delete the children of this slide
+ // Usually the slide has children if it is a Master slide (for example when deleting a
+ // Component)
+ TSlideHandleList theChildren;
+ m_SlideCore->GetChildSlides(inSlide, theChildren);
+ do_all(theChildren, std::bind(&SSlideSystem::DeleteReferencedInstances, this,
+ std::placeholders::_1));
+
+ // Delete the referenced instances from this slide
+ TSlideEntryList theEntries;
+ m_SlideCore->GetSlidePropertyEntries(inSlide, theEntries);
+
+ // Run through all entries, if you find a reference property delete the associated instance.
+ // This is for properties that are set on this slide (because you can set property on slide or
+ // on instance)
+ TInstanceHandleList theReferencedInstances;
+ do_all(theEntries,
+ std::bind(InsertIfReferencedProperty, std::placeholders::_1,
+ std::cref(m_PropertyInfoPairList),
+ std::ref(theReferencedInstances)));
+ do_all(theReferencedInstances, std::bind(&IDataCore::DeleteInstance, m_DataCore,
+ std::placeholders::_1));
+
+ // Run through all entries, delete all instances that belong to this slide and its reference
+ // property instances
+ // This is for properties that are set on instance
+ theReferencedInstances.clear();
+ do_all(theEntries, std::bind(&SSlideSystem::InsertEntryAndPropertyInstance, this,
+ std::placeholders::_1,
+ std::ref(theReferencedInstances), inSlide));
+ do_all(theReferencedInstances, std::bind(&IDataCore::DeleteInstance, m_DataCore,
+ std::placeholders::_1));
+}
+
+// Get the referenced instances of this slide
+// This function is very similar to DeleteReferencedInstances
+// You change one function, you need to change the other function
+void SSlideSystem::GetReferencedInstances(Qt3DSDMSlideHandle inSlide,
+ TInstanceHandleList &outReferencedInstances)
+{
+ // Recursively get the children of this slide
+ // Usually the slide has children if it is a Master slide (for example Component)
+ TSlideHandleList theChildren;
+ m_SlideCore->GetChildSlides(inSlide, theChildren);
+ do_all(theChildren, std::bind(&SSlideSystem::GetReferencedInstances, this,
+ std::placeholders::_1,
+ std::ref(outReferencedInstances)));
+
+ // Get the referenced instances from this slide
+ TSlideEntryList theEntries;
+ m_SlideCore->GetSlidePropertyEntries(inSlide, theEntries);
+
+ // Run through all entries, if you find a reference property get the associated instance.
+ // This is for properties that are set on this slide (because you can set property on slide or
+ // on instance)
+ do_all(theEntries,
+ std::bind(InsertIfReferencedProperty, std::placeholders::_1,
+ std::cref(m_PropertyInfoPairList),
+ std::ref(outReferencedInstances)));
+
+ // Run through all entries, get all instances that belong to this slide and its reference
+ // property instances
+ // This is for properties that are set on instance
+ do_all(theEntries, std::bind(&SSlideSystem::InsertEntryAndPropertyInstance, this,
+ std::placeholders::_1,
+ std::ref(outReferencedInstances), inSlide));
+}
+
+void SSlideSystem::DeleteSlideByIndex(Qt3DSDMSlideHandle inMaster, size_t inIndex)
+{
+ Qt3DSDMSlideHandle theChild = GetSlideByIndex(inMaster, inIndex);
+ TInstanceHandleList theInstances;
+ if (theChild.Valid()) {
+ DeleteReferencedInstances(theChild);
+ m_SlideCore->DeleteSlide(theChild, theInstances);
+ do_all(theInstances, std::bind(&IDataCore::DeleteInstance, m_DataCore,
+ std::placeholders::_1));
+ }
+ if (inIndex == 0)
+ GetSignalSender()->SendMasterDeleted(inMaster);
+ else
+ GetSignalSender()->SendSlideDeleted(inMaster, (int)inIndex, theChild);
+}
+
+void SSlideSystem::GetSlideReferencedInstances(Qt3DSDMSlideHandle inMaster, size_t inIndex,
+ TInstanceHandleList &outReferencedInstances)
+{
+ outReferencedInstances.clear();
+ Qt3DSDMSlideHandle theChild = GetSlideByIndex(inMaster, inIndex);
+ if (theChild.Valid()) {
+ GetReferencedInstances(theChild, outReferencedInstances);
+ }
+}
+
+Qt3DSDMSlideHandle SSlideSystem::GetSlideByIndex(Qt3DSDMSlideHandle inMaster, size_t inIndex) const
+{
+ if (inIndex == 0)
+ return inMaster;
+ --inIndex;
+ TSlideHandleList theChildren;
+ m_SlideCore->GetChildSlides(inMaster, theChildren);
+ if (inIndex < theChildren.size())
+ return theChildren[inIndex];
+ return Qt3DSDMSlideHandle();
+}
+
+void SSlideSystem::SetActiveSlide(Qt3DSDMSlideHandle inMaster, size_t inIndex)
+{
+ Qt3DSDMSlideGraphHandle theGraph = m_SlideGraphCore->GetSlideGraph(inMaster);
+ Qt3DSDMSlideHandle theActiveSlide = inMaster;
+ if (inIndex > 0)
+ theActiveSlide = GetSlideByIndex(inMaster, inIndex);
+ Qt3DSDMSlideHandle theOldSlide = m_SlideGraphCore->GetGraphActiveSlide(theGraph);
+ m_SlideGraphCore->SetGraphActiveSlide(theGraph, theActiveSlide);
+ GetSignalSender()->SendActiveSlide(inMaster, (int)inIndex, theOldSlide, theActiveSlide);
+}
+
+size_t SSlideSystem::GetSlideCount(Qt3DSDMSlideHandle inMaster) const
+{
+ TSlideHandleList theChildren;
+ m_SlideCore->GetChildSlides(inMaster, theChildren);
+ return 1 + theChildren.size();
+}
+
+void SSlideSystem::RearrangeSlide(Qt3DSDMSlideHandle inMaster, size_t inOldIndex, size_t inNewIndex)
+{
+ if (inOldIndex == 0)
+ throw RearrangeSlideArgumentsMustNotBeZero(L"");
+ TSlideHandleList theChildren;
+ m_SlideCore->GetChildSlides(inMaster, theChildren);
+ Qt3DSDMSlideHandle theChild = theChildren.at(inOldIndex - 1);
+ m_SlideCore->DeriveSlide(theChild, inMaster, (int)inNewIndex - 1);
+ GetSignalSender()->SendSlideRearranged(inMaster, (int)inOldIndex, (int)inNewIndex);
+}
+
+void SSlideSystem::SetComponentSeconds(Qt3DSDMSlideHandle inSlide, float inSeconds)
+{
+ Qt3DSDMSlideGraphHandle theGraph = m_SlideGraphCore->GetSlideGraph(GetMasterSlide(inSlide));
+ m_SlideCore->SetSlideTime(m_SlideGraphCore->GetGraphActiveSlide(theGraph), inSeconds);
+}
+
+float SSlideSystem::GetComponentSeconds(Qt3DSDMSlideHandle inSlide) const
+{
+ Qt3DSDMSlideGraphHandle theGraph = m_SlideGraphCore->GetSlideGraph(GetMasterSlide(inSlide));
+ return m_SlideCore->GetSlideTime(m_SlideGraphCore->GetGraphActiveSlide(theGraph));
+}
+
+long SSlideSystem::GetComponentSecondsLong(Qt3DSDMSlideHandle inSlide) const
+{
+ float seconds(GetComponentSeconds(inSlide));
+ return static_cast<long>((seconds * 1000) + .5f);
+}
+
+long SSlideSystem::GetComponentSecondsLong(Qt3DSDMInstanceHandle inInstance) const
+{
+ Qt3DSDMSlideGraphHandle theGraph = m_SlideGraphCore->GetAssociatedGraph(inInstance).first;
+ float seconds = m_SlideCore->GetSlideTime(m_SlideGraphCore->GetGraphActiveSlide(theGraph));
+ return static_cast<long>((seconds * 1000) + .5f);
+}
+
+SInstanceSlideInformation
+SSlideSystem::GetInstanceSlideInformation(Qt3DSDMInstanceHandle inInstance) const
+{
+ TGraphSlidePair theGraphSlidePair = m_SlideGraphCore->GetAssociatedGraph(inInstance);
+ Qt3DSDMSlideHandle theAssociatedSlide(theGraphSlidePair.second);
+ if (theAssociatedSlide.Valid() == false)
+ return SInstanceSlideInformation();
+ Qt3DSDMSlideHandle theMasterSlide(GetMasterSlide(theGraphSlidePair.second));
+ Qt3DSDMSlideHandle theActiveSlide(
+ m_SlideGraphCore->GetGraphActiveSlide(theGraphSlidePair.first));
+ float seconds = m_SlideCore->GetSlideTime(theActiveSlide);
+ long theMilliseconds = static_cast<long>((seconds * 1000) + .5f);
+ return SInstanceSlideInformation(theAssociatedSlide, theMasterSlide, theActiveSlide,
+ theMilliseconds);
+}
+
+/**
+ * Use the instance for storing information such as name, or the GUID of the object
+ * this slide links to.
+ */
+Qt3DSDMInstanceHandle SSlideSystem::GetSlideInstance(Qt3DSDMSlideHandle inSlide) const
+{
+ return m_SlideCore->GetSlideInstance(inSlide);
+}
+/**
+ * Reverse lookup into the slide system so you can match slides to instances.
+ */
+Qt3DSDMSlideHandle SSlideSystem::GetSlideByInstance(Qt3DSDMInstanceHandle inSlide) const
+{
+ return m_SlideCore->GetSlideByInstance(inSlide);
+}
+
+/**
+ * Slide may be either a master slide
+ */
+void SSlideSystem::AssociateInstanceWithSlide(Qt3DSDMSlideHandle inSlide,
+ Qt3DSDMInstanceHandle inInstance)
+{
+ Qt3DSDMSlideGraphHandle theGraph = m_SlideGraphCore->GetSlideGraph(GetMasterSlide(inSlide));
+ m_SlideGraphCore->AssociateInstance(theGraph, inSlide, inInstance);
+ GetSignalSender()->SendInstanceAssociated(inSlide, inInstance);
+}
+
+Qt3DSDMSlideHandle SSlideSystem::GetAssociatedSlide(Qt3DSDMInstanceHandle inInstance) const
+{
+ return m_SlideGraphCore->GetAssociatedGraph(inInstance).second;
+}
+
+/**
+ * This gets the instances that resides int the SlideGraph, i.e. all the instances in all the
+ *slides for this component/scene
+ * TODO rename this to make it more clear
+ */
+void SSlideSystem::GetAssociatedInstances(Qt3DSDMSlideHandle inMaster,
+ TSlideInstancePairList &outAssociations) const
+{
+ m_SlideGraphCore->GetAssociatedInstances(
+ m_SlideGraphCore->GetSlideGraph(GetMasterSlide(inMaster)), outAssociations);
+}
+
+/**
+ * Gets all the instances in this slide
+ */
+void SSlideSystem::GetAssociatedInstances(Qt3DSDMSlideHandle inSlide,
+ TInstanceHandleList &outAssociations) const
+{
+ Qt3DSDMSlideHandle theMasterSlide = GetMasterSlide(inSlide);
+ TSlideInstancePairList theGraphInstances;
+ m_SlideGraphCore->GetAssociatedInstances(m_SlideGraphCore->GetSlideGraph(theMasterSlide),
+ theGraphInstances);
+ for (TSlideInstancePairList::const_iterator theIter = theGraphInstances.begin();
+ theIter != theGraphInstances.end(); ++theIter) {
+ if (theIter->first == inSlide || theIter->first == theMasterSlide) {
+ // in the current slide or master slide
+ outAssociations.push_back(theIter->second);
+ }
+ }
+}
+
+void DeleteInstanceIfExistsAsProperty(Qt3DSDMSlideHandle inSlide, Qt3DSDMInstanceHandle inInstance,
+ Qt3DSDMPropertyHandle inProperty, TSlideCorePtr inSlideCore,
+ TPropertyInstanceInfoPtr inPropertyInfoPtr,
+ TDataCorePtr inDataCore)
+{
+ SValue theValue;
+ if (inSlideCore->GetSpecificInstancePropertyValue(inSlide, inInstance, inProperty, theValue)) {
+ Qt3DSDMInstanceHandle theInstance(inPropertyInfoPtr->GetInstanceForProperty(theValue));
+ if (theInstance.Valid())
+ inDataCore->DeleteInstance(theInstance);
+ }
+}
+
+void SSlideSystem::LinkProperty(Qt3DSDMInstanceHandle inInstance, Qt3DSDMPropertyHandle inProperty)
+{
+ Qt3DSDMSlideGraphHandle theGraph = m_SlideGraphCore->GetAssociatedGraph(inInstance).first;
+ Qt3DSDMSlideHandle theSlide = m_SlideGraphCore->GetGraphRoot(theGraph);
+ TPropertyHandlePropertyInfoPairList::const_iterator theFind =
+ find_if<TPropertyHandlePropertyInfoPairList::const_iterator>(
+ m_PropertyInfoPairList, std::bind(PropertyHandlePairEquals,
+ std::placeholders::_1, inProperty));
+ if (theFind != m_PropertyInfoPairList.end()) {
+ TSlideHandleList theChildren;
+ m_SlideCore->GetChildSlides(theSlide, theChildren);
+ do_all(theChildren, std::bind(DeleteInstanceIfExistsAsProperty, std::placeholders::_1, inInstance,
+ inProperty, m_SlideCore, theFind->second, m_DataCore));
+ }
+ m_SlideCore->ClearChildrenPropertyValues(theSlide, inInstance, inProperty);
+ GetSignalSender()->SendPropertyLinked(theSlide, inInstance, inProperty);
+}
+
+void ClearPropertyValueIfLinked(Qt3DSDMSlideHandle inMaster, const TSlideHandleList &inChildren,
+ Qt3DSDMInstanceHandle inInstance, Qt3DSDMPropertyHandle inProperty,
+ TSlideCorePtr inSlideCore)
+{
+ if (inChildren.empty())
+ return;
+
+ if (inSlideCore->ContainsProperty(inChildren.at(0), inInstance,
+ inProperty)) // if property is linked,
+ inSlideCore->ClearChildrenPropertyValues(inMaster, inInstance,
+ inProperty); // get it off non-master slides
+}
+
+void SetReferencedEntryValue(Qt3DSDMSlideHandle inMaster, Qt3DSDMSlideHandle inDestSlide,
+ TPropertyInstanceInfoPtr inInfo, Qt3DSDMInstanceHandle inInstance,
+ Qt3DSDMPropertyHandle inProperty,
+ Qt3DSDMInstanceHandle inReferencedInstance, TSlideCorePtr inSlideCore)
+{
+ SValue theNewValue(
+ inInfo->CreateInstanceForProperty(inMaster, inDestSlide, inReferencedInstance));
+ inSlideCore->ForceSetInstancePropertyValue(inDestSlide, inInstance, inProperty, theNewValue);
+}
+
+void SSlideSystem::UnlinkProperty(Qt3DSDMInstanceHandle inInstance, Qt3DSDMPropertyHandle inProperty)
+{
+ Qt3DSDMSlideGraphHandle theGraph = m_SlideGraphCore->GetAssociatedGraph(inInstance).first;
+ Qt3DSDMSlideHandle theSlide = m_SlideGraphCore->GetGraphRoot(theGraph);
+ SValue theValue;
+ SValue theTempValue;
+ if (!m_SlideCore->GetInstancePropertyValue(theSlide, inInstance, inProperty, theValue)) {
+ if (!m_PropertySystem->GetInstancePropertyValue(inInstance, inProperty, theTempValue))
+ throw PropertyLinkError(L"");
+ theValue = theTempValue.toOldSkool();
+ }
+
+ m_SlideCore->ForceSetInstancePropertyValue(theSlide, inInstance, inProperty, theValue);
+ TSlideHandleList theChildren;
+ m_SlideCore->GetChildSlides(theSlide, theChildren);
+
+ Qt3DSDMInstanceHandle theReferenced;
+ TPropertyHandlePropertyInfoPairList::const_iterator theFind =
+ find_if<TPropertyHandlePropertyInfoPairList::const_iterator>(
+ m_PropertyInfoPairList, std::bind(PropertyHandlePairEquals,
+ std::placeholders::_1, inProperty));
+ TPropertyInstanceInfoPtr theInfo;
+ if (theFind != m_PropertyInfoPairList.end()) {
+ theInfo = theFind->second;
+ theReferenced = theInfo->GetInstanceForProperty(theValue);
+ }
+ if (theReferenced.Valid()) {
+ TPropertyHandleList theProperties;
+ m_PropertySystem->GetAggregateInstanceProperties(
+ theReferenced,
+ theProperties); // TODO: We should make the method return the custom properties.
+ // Remove the property instance's unlinked properties from non-master slides.
+ do_all(theProperties,
+ std::bind(ClearPropertyValueIfLinked, theSlide, std::cref(theChildren),
+ theReferenced, std::placeholders::_1, m_SlideCore));
+ // Remove all property values from the children from that instance.
+ do_all(theChildren, std::bind(SetReferencedEntryValue, theSlide,
+ std::placeholders::_1, theInfo, inInstance,
+ inProperty, theReferenced, m_SlideCore));
+ } else {
+ do_all(theChildren, std::bind(&ISlideCore::ForceSetInstancePropertyValue, m_SlideCore,
+ std::placeholders::_1,
+ inInstance, inProperty, theValue));
+ do_all(theChildren,
+ std::bind(CopyAnimationIfExist, theSlide, std::placeholders::_1, make_pair(inInstance, inProperty),
+ m_PropertySystem, m_AnimationCore));
+ }
+ GetSignalSender()->SendPropertyUnlinked(theSlide, inInstance, inProperty);
+}
+
+bool SSlideSystem::IsPropertyLinked(Qt3DSDMInstanceHandle inInstance,
+ Qt3DSDMPropertyHandle inProperty) const
+{
+ TGraphSlidePair theGraphSlidePair = m_SlideGraphCore->GetAssociatedGraph(inInstance);
+ Qt3DSDMSlideGraphHandle theGraph = theGraphSlidePair.first;
+ if (!theGraph.Valid())
+ return false;
+
+ Qt3DSDMSlideHandle theSlide = m_SlideGraphCore->GetGraphRoot(theGraph);
+ if (theGraphSlidePair.second != theSlide)
+ return false;
+
+ TSlideHandleList theChildren;
+ m_SlideCore->GetChildSlides(theSlide, theChildren);
+ bool containsProperty = false;
+ for (TSlideHandleList::iterator theIter = theChildren.begin();
+ theIter != theChildren.end() && !containsProperty; ++theIter) {
+ containsProperty =
+ containsProperty || m_SlideCore->ContainsProperty(*theIter, inInstance, inProperty);
+ }
+
+ return !containsProperty;
+}
+
+bool SSlideSystem::CanPropertyBeLinked(Qt3DSDMInstanceHandle inInstance,
+ Qt3DSDMPropertyHandle inProperty) const
+{
+ TGraphSlidePair theGraphSlidePair = m_SlideGraphCore->GetAssociatedGraph(inInstance);
+ if (theGraphSlidePair.first.Valid()
+ && theGraphSlidePair.second == m_SlideGraphCore->GetGraphRoot(theGraphSlidePair.first))
+ return true;
+ return false;
+}
+
+bool SSlideSystem::GetSlidePropertyValue(size_t inSlide, Qt3DSDMInstanceHandle inInstance,
+ Qt3DSDMPropertyHandle inProperty, SValue &outValue)
+{
+ TGraphSlidePair theGraphSlidePair = m_SlideGraphCore->GetAssociatedGraph(inInstance);
+ Qt3DSDMSlideGraphHandle theGraph = theGraphSlidePair.first;
+ if (!theGraph.Valid())
+ return false;
+ Qt3DSDMSlideHandle theSlide = GetSlideByIndex(m_SlideGraphCore->GetGraphRoot(theGraph), inSlide);
+ if (!theSlide.Valid())
+ return false;
+ return m_SlideCore->GetSpecificInstancePropertyValue(theSlide, inInstance, inProperty,
+ outValue);
+}
+
+void AddEntriesToHash(const TSlideEntryList &theSlideEntries, TSlideEntryHash &theEntryHash,
+ TInstancePropertyPairList &outProperties)
+{
+ for (size_t idx = 0, end = theSlideEntries.size(); idx < end; ++idx) {
+ const TSlideEntry &theEntry(theSlideEntries[idx]);
+ pair<TSlideEntryHash::iterator, bool> insertRecord(theEntryHash.insert(
+ make_pair(TSlideInstancePropertyPair(get<0>(theEntry), get<1>(theEntry)),
+ SInternValue::ISwearThisHasAlreadyBeenInternalized(get<2>(theEntry)))));
+ if (insertRecord.second)
+ outProperties.push_back(insertRecord.first->first);
+ }
+}
+
+void SSlideSystem::GetUnionOfProperties(Qt3DSDMSlideHandle inSlide1, Qt3DSDMSlideHandle inSlide2,
+ TInstancePropertyPairList &outProperties) const
+{
+ TSlideEntryHash theEntryHash;
+ TSlideEntryList theSlideEntries;
+ if (m_SlideCore->IsSlide(inSlide1)) {
+ m_SlideCore->GetSlidePropertyEntries(inSlide1, theSlideEntries);
+ AddEntriesToHash(theSlideEntries, theEntryHash, outProperties);
+ }
+ if (m_SlideCore->IsSlide(inSlide2)) {
+ m_SlideCore->GetSlidePropertyEntries(inSlide2, theSlideEntries);
+ AddEntriesToHash(theSlideEntries, theEntryHash, outProperties);
+ }
+}
+
+void SSlideSystem::SetActiveSlide(Qt3DSDMSlideHandle inSlide)
+{
+ Qt3DSDMSlideHandle theMaster = GetMasterSlide(inSlide);
+ int theIndex = GetSlideIndex(inSlide);
+ SetActiveSlide(theMaster, theIndex);
+}
+
+Qt3DSDMSlideHandle SSlideSystem::GetAssociatedSlide(Qt3DSDMInstanceHandle inInstance,
+ Qt3DSDMPropertyHandle inProperty) const
+{
+ TGraphSlidePair theGraphSlidePair = m_SlideGraphCore->GetAssociatedGraph(inInstance);
+ Qt3DSDMSlideGraphHandle theGraph = theGraphSlidePair.first;
+ if (!theGraph.Valid())
+ return 0;
+ Qt3DSDMSlideHandle theSlide = m_SlideGraphCore->GetGraphActiveSlide(theGraph);
+ if (theSlide.Valid()) {
+ if (m_SlideCore->ContainsProperty(theSlide, inInstance, inProperty))
+ return theSlide;
+ theSlide = m_SlideCore->GetParentSlide(theSlide);
+ if (theSlide.Valid() && m_SlideCore->ContainsProperty(theSlide, inInstance, inProperty))
+ return theSlide;
+ return theGraphSlidePair.second;
+ }
+ return 0;
+}
+
+bool SSlideSystem::SlideValid(Qt3DSDMSlideHandle inSlide) const
+{
+ return m_SlideCore->HandleValid(inSlide);
+}
+
+int SSlideSystem::GetSlideIndex(Qt3DSDMSlideHandle inSlide) const
+{
+ Qt3DSDMSlideHandle theMaster = GetMasterSlide(inSlide);
+ if (inSlide.Valid() && inSlide != theMaster)
+ return m_SlideCore->GetChildIndex(theMaster, inSlide) + 1;
+ return 0;
+}
+
+int SSlideSystem::GetActiveSlideIndex(Qt3DSDMSlideHandle inMaster) const
+{
+ Qt3DSDMSlideGraphHandle theGraph = m_SlideGraphCore->GetSlideGraph(inMaster);
+ Qt3DSDMSlideHandle theActiveSlide = m_SlideGraphCore->GetGraphActiveSlide(theGraph);
+ if (theActiveSlide == inMaster)
+ return 0;
+ return GetSlideIndex(theActiveSlide);
+}
+
+Qt3DSDMSlideHandle SSlideSystem::GetActiveSlide(Qt3DSDMSlideHandle inMaster) const
+{
+ Qt3DSDMSlideGraphHandle theGraph = m_SlideGraphCore->GetSlideGraph(inMaster);
+ return m_SlideGraphCore->GetGraphActiveSlide(theGraph);
+}
+
+Qt3DSDMInstanceHandle SSlideSystem::GetSlideSelectedInstance(Qt3DSDMSlideHandle inSlide) const
+{
+ TIntIntMap::const_iterator theIter = m_SlideSelectedInstances.find(inSlide);
+ if (theIter != m_SlideSelectedInstances.end() && m_DataCore->IsInstance(theIter->second))
+ return theIter->second;
+ return 0;
+}
+
+void SSlideSystem::SetSlideSelectedInstance(Qt3DSDMSlideHandle inSlide,
+ Qt3DSDMInstanceHandle inInstance)
+{
+ m_SlideSelectedInstances[inSlide] = inInstance;
+}
+
+void SSlideSystem::RegisterPropertyInstance(Qt3DSDMPropertyHandle inPropertyHandle,
+ TPropertyInstanceInfoPtr inPropertyInfo)
+{
+ m_PropertyInfoPairList.push_back(make_pair(inPropertyHandle, inPropertyInfo));
+}
+
+ISlideSystemSignalProvider *SSlideSystem::GetSignalProvider()
+{
+ return dynamic_cast<ISlideSystemSignalProvider *>(m_Signaller.get());
+}
+
+ISlideSystemSignalSender *SSlideSystem::GetSignalSender()
+{
+ return dynamic_cast<ISlideSystemSignalSender *>(m_Signaller.get());
+}
+
+qt3dsdm::Qt3DSDMSlideHandle SSlideSystem::GetApplicableSlide(Qt3DSDMInstanceHandle inHandle)
+{
+ TGraphSlidePair theGraphSlidePair = m_SlideGraphCore->GetAssociatedGraph(inHandle);
+ if (!theGraphSlidePair.first.Valid())
+ return Qt3DSDMSlideHandle();
+
+ Qt3DSDMSlideHandle theMaster = m_SlideGraphCore->GetGraphRoot(theGraphSlidePair.first);
+ if (theGraphSlidePair.second != theMaster)
+ return theGraphSlidePair.second;
+
+ return theMaster;
+}
+
+qt3dsdm::Qt3DSDMSlideHandle SSlideSystem::GetApplicableSlide(Qt3DSDMInstanceHandle inHandle,
+ Qt3DSDMPropertyHandle inProperty)
+{
+ TGraphSlidePair theGraphSlidePair = m_SlideGraphCore->GetAssociatedGraph(inHandle);
+ if (!theGraphSlidePair.first.Valid())
+ return Qt3DSDMSlideHandle();
+
+ Qt3DSDMSlideHandle theMaster = m_SlideGraphCore->GetGraphRoot(theGraphSlidePair.first);
+ if (theGraphSlidePair.second != theMaster)
+ return theGraphSlidePair.second;
+
+ Qt3DSDMSlideHandle theActive = m_SlideGraphCore->GetGraphActiveSlide(theGraphSlidePair.first);
+ if (m_SlideCore->ContainsProperty(theActive, inHandle, inProperty))
+ return theActive;
+
+ return theMaster;
+}
+
+bool SSlideSystem::GetInstancePropertyValue(Qt3DSDMSlideHandle inSlide,
+ Qt3DSDMInstanceHandle inInstance,
+ Qt3DSDMPropertyHandle inProperty, SValue &outValue) const
+{
+ return m_SlideCore->GetInstancePropertyValue(inSlide, inInstance, inProperty, outValue);
+}
+
+bool SSlideSystem::GetCanonicalInstancePropertyValue(Qt3DSDMInstanceHandle inInstance,
+ Qt3DSDMPropertyHandle inProperty,
+ SValue &outValue) const
+{
+ TGraphSlidePair theGraphSlidePair = m_SlideGraphCore->GetAssociatedGraph(inInstance);
+ if (theGraphSlidePair.first.Valid()) {
+ // Check to see if the object is on the master slide;
+ if (theGraphSlidePair.second == m_SlideGraphCore->GetGraphRoot(theGraphSlidePair.first)) {
+ TSlideHandleList theChildren;
+ m_SlideCore->GetChildSlides(theGraphSlidePair.second, theChildren);
+ // See if the value exists on slide 1.
+ if (!theChildren.empty()
+ && m_SlideCore->GetSpecificInstancePropertyValue(theChildren.at(0), inInstance,
+ inProperty, outValue))
+ return true;
+ }
+
+ if (m_SlideCore->GetSpecificInstancePropertyValue(theGraphSlidePair.second, inInstance,
+ inProperty, outValue))
+ return true;
+ }
+ return false;
+}
+
+void SSlideSystem::ForceSetInstancePropertyValue(Qt3DSDMSlideHandle inSlide,
+ Qt3DSDMInstanceHandle inInstance,
+ Qt3DSDMPropertyHandle inProperty,
+ const SValue &inValue)
+{
+ m_SlideCore->ForceSetInstancePropertyValue(inSlide, inInstance, inProperty, inValue);
+}
+}
diff --git a/src/dm/systems/SlideSystem.h b/src/dm/systems/SlideSystem.h
new file mode 100644
index 0000000..1ea3f81
--- /dev/null
+++ b/src/dm/systems/SlideSystem.h
@@ -0,0 +1,179 @@
+/****************************************************************************
+**
+** 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 SLIDESYSTEMH
+#define SLIDESYSTEMH
+#include "Qt3DSDMDataCore.h"
+#include "Qt3DSDMSlideCore.h"
+#include "Qt3DSDMSlideGraphCore.h"
+#include "Qt3DSDMTransactions.h"
+#include "Qt3DSDMSlides.h"
+#include "Qt3DSDMAnimation.h"
+#include "StudioPropertySystem.h"
+#include "SignalsImpl.h"
+
+/**
+ * The systems aggregate the various cores and provide further information or
+ * integrity checking taking the various cores into account.
+ */
+
+namespace qt3dsdm {
+
+typedef std::pair<Qt3DSDMPropertyHandle, TPropertyInstanceInfoPtr> TPropertyHandlePropertyInfoPair;
+typedef std::vector<TPropertyHandlePropertyInfoPair> TPropertyHandlePropertyInfoPairList;
+/**
+ * Provides more thorough checking and will return an appropriate
+ * slide graph when calling GetSlideGraph
+ */
+struct SSlideSystem : public ISlideSystem
+{
+ Q_DISABLE_COPY(SSlideSystem)
+
+ TDataCorePtr m_DataCore; // TODO: We might want to throw this away and use the PropertySystem,
+ // unless we have a clean seperate of IPropertySystem and IDataCore
+ TPropertySystemPtr m_PropertySystem;
+ TSlideCorePtr m_SlideCore;
+ TSlideGraphCorePtr m_SlideGraphCore;
+ TAnimationCorePtr m_AnimationCore;
+ Qt3DSDMInstanceHandle m_SlideInstance;
+ Qt3DSDMPropertyHandle m_ComponentGuid;
+ std::shared_ptr<ISignalItem> m_Signaller;
+ TPropertyHandlePropertyInfoPairList m_PropertyInfoPairList;
+ typedef std::unordered_map<int, int> TIntIntMap;
+ TIntIntMap m_SlideSelectedInstances;
+
+ SSlideSystem(TDataCorePtr inDataCore, TSlideCorePtr inSlideCore,
+ TSlideGraphCorePtr inSlideGraphCore, TAnimationCorePtr inAnimationCore,
+ Qt3DSDMInstanceHandle inSlideInstance,
+ Qt3DSDMPropertyHandle inComponentGuidProperty);
+
+ void SetPropertySystem(TPropertySystemPtr inPropertySystem);
+
+ Qt3DSDMSlideHandle CreateMasterSlide() override;
+ Qt3DSDMSlideHandle CreateSlide(Qt3DSDMSlideHandle inMaster, int inIndex = -1) override;
+ Qt3DSDMSlideHandle DuplicateSlide(Qt3DSDMSlideHandle inSourceSlide, int inDestIndex = -1) override;
+ Qt3DSDMSlideHandle GetMasterSlide(Qt3DSDMSlideHandle inSlide) const override;
+ bool IsMasterSlide(Qt3DSDMSlideHandle inSlide) const override;
+ Qt3DSDMSlideHandle GetMasterSlideByComponentGuid(SLong4 inGuid) const override;
+ // Indexes are 1 based. Index 0 refers to the master slide; you can't delete this.
+ void DeleteSlideByIndex(Qt3DSDMSlideHandle inMaster, size_t inIndex) override;
+ void GetSlideReferencedInstances(Qt3DSDMSlideHandle inMaster, size_t inIndex,
+ TInstanceHandleList &outReferencedInstances) override;
+ Qt3DSDMSlideHandle GetSlideByIndex(Qt3DSDMSlideHandle inMaster, size_t inIndex) const override;
+ void SetActiveSlide(Qt3DSDMSlideHandle inMaster, size_t inIndex) override;
+ size_t GetSlideCount(Qt3DSDMSlideHandle inMaster) const override;
+ void RearrangeSlide(Qt3DSDMSlideHandle inMaster, size_t inOldIndex, size_t inNewIndex) override;
+
+ void SetComponentSeconds(Qt3DSDMSlideHandle inSlide, float inSeconds) override;
+ float GetComponentSeconds(Qt3DSDMSlideHandle inSlide) const override;
+ long GetComponentSecondsLong(Qt3DSDMSlideHandle inSlide) const override;
+ // For any given instance, find the current seconds via backtracking to the graph, finding the
+ // active
+ // slide, and return.
+ long GetComponentSecondsLong(Qt3DSDMInstanceHandle inInstance) const override;
+ virtual SInstanceSlideInformation
+ GetInstanceSlideInformation(Qt3DSDMInstanceHandle inInstance) const override;
+ /**
+ * Use the instance for storing information such as name, or the GUID of the object
+ * this slide links to.
+ */
+ Qt3DSDMInstanceHandle GetSlideInstance(Qt3DSDMSlideHandle inInstance) const override;
+ /**
+ * Reverse lookup into the slide system so you can match slides to instances.
+ */
+ Qt3DSDMSlideHandle GetSlideByInstance(Qt3DSDMInstanceHandle inInstance) const override;
+
+ /**
+ * Slide may be either a master slide or a normal slide. This will associate this instance
+ * with this set of slides. Property lookups (using the above IInstancePropertyCore interface)
+ * will now run through the slide set before hitting the main data core database.
+ */
+ void AssociateInstanceWithSlide(Qt3DSDMSlideHandle inSlide,
+ Qt3DSDMInstanceHandle inInstance) override;
+ Qt3DSDMSlideHandle GetAssociatedSlide(Qt3DSDMInstanceHandle inInstance) const override;
+ void GetAssociatedInstances(
+ Qt3DSDMSlideHandle inMaster,
+ std::vector<std::pair<Qt3DSDMSlideHandle, Qt3DSDMInstanceHandle>> &outAssociations) const override;
+ void GetAssociatedInstances(Qt3DSDMSlideHandle inSlide,
+ TInstanceHandleList &outAssociations) const override;
+ void LinkProperty(Qt3DSDMInstanceHandle inInstance, Qt3DSDMPropertyHandle inProperty) override;
+ void UnlinkProperty(Qt3DSDMInstanceHandle inInstance, Qt3DSDMPropertyHandle inProperty) override;
+ bool IsPropertyLinked(Qt3DSDMInstanceHandle inInstance,
+ Qt3DSDMPropertyHandle inProperty) const override;
+ bool CanPropertyBeLinked(Qt3DSDMInstanceHandle inInstance,
+ Qt3DSDMPropertyHandle inProperty) const override;
+ bool GetSlidePropertyValue(size_t inSlide, Qt3DSDMInstanceHandle inInstance,
+ Qt3DSDMPropertyHandle inProperty, SValue &outValue) override;
+ void GetUnionOfProperties(Qt3DSDMSlideHandle inSlide1, Qt3DSDMSlideHandle inSlide,
+ TInstancePropertyPairList &outProperties) const override;
+
+ void SetActiveSlide(Qt3DSDMSlideHandle inSlide) override;
+ Qt3DSDMSlideHandle GetAssociatedSlide(Qt3DSDMInstanceHandle inInstance,
+ Qt3DSDMPropertyHandle inProperty) const override;
+
+ bool SlideValid(Qt3DSDMSlideHandle inSlide) const override;
+ int GetSlideIndex(Qt3DSDMSlideHandle inSlide) const override;
+ int GetActiveSlideIndex(Qt3DSDMSlideHandle inMaster) const override;
+ Qt3DSDMSlideHandle GetActiveSlide(Qt3DSDMSlideHandle inMaster) const override;
+ Qt3DSDMInstanceHandle GetSlideSelectedInstance(Qt3DSDMSlideHandle inSlide) const override;
+ void SetSlideSelectedInstance(Qt3DSDMSlideHandle inSlide, Qt3DSDMInstanceHandle inInstance) override;
+
+ Qt3DSDMSlideHandle GetApplicableSlide(Qt3DSDMInstanceHandle inHandle) override;
+ Qt3DSDMSlideHandle GetApplicableSlide(Qt3DSDMInstanceHandle inHandle,
+ Qt3DSDMPropertyHandle inProperty) override;
+
+ bool GetInstancePropertyValue(Qt3DSDMSlideHandle inSlide,
+ Qt3DSDMInstanceHandle inInstance,
+ Qt3DSDMPropertyHandle inProperty, SValue &outValue) const override;
+ bool GetCanonicalInstancePropertyValue(Qt3DSDMInstanceHandle inInstance,
+ Qt3DSDMPropertyHandle inProperty,
+ SValue &outValue) const override;
+ void ForceSetInstancePropertyValue(Qt3DSDMSlideHandle inSlide,
+ Qt3DSDMInstanceHandle inInstance,
+ Qt3DSDMPropertyHandle inProperty,
+ const SValue &inValue) override;
+
+ void RegisterPropertyInstance(Qt3DSDMPropertyHandle inPropertyHandle,
+ TPropertyInstanceInfoPtr inPropertyInfo) override;
+
+ virtual ISlideSystemSignalProvider *GetSignalProvider();
+
+private:
+ virtual ISlideSystemSignalSender *GetSignalSender();
+ // helper method
+ void InsertEntryAndPropertyInstance(const TSlideEntry &inEntry,
+ TInstanceHandleList &inInstances,
+ Qt3DSDMSlideHandle inSlide);
+ void DeleteReferencedInstances(Qt3DSDMSlideHandle inSlide);
+ void GetReferencedInstances(Qt3DSDMSlideHandle inSlide,
+ TInstanceHandleList &outReferencedInstances);
+};
+}
+
+#endif
diff --git a/src/dm/systems/StandardExtensions.h b/src/dm/systems/StandardExtensions.h
new file mode 100644
index 0000000..a994600
--- /dev/null
+++ b/src/dm/systems/StandardExtensions.h
@@ -0,0 +1,196 @@
+/****************************************************************************
+**
+** 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 STANDARDEXTENSIONSH
+#define STANDARDEXTENSIONSH
+#include <algorithm>
+
+namespace qt3dsdm {
+template <typename TContainer, typename TPred>
+inline void erase_if(TContainer &inContainer, TPred inPred)
+{
+ inContainer.erase(std::remove_if(inContainer.begin(), inContainer.end(), inPred),
+ inContainer.end());
+}
+
+template <typename TRetType, typename TContainerType, typename TPred>
+inline TRetType find_if(TContainerType &inContainer, TPred inPred)
+{
+ return std::find_if(inContainer.begin(), inContainer.end(), inPred);
+}
+
+template <typename TContainer, typename TTransaction>
+inline void do_all(TContainer &inContainer, TTransaction inTransaction)
+{
+ std::for_each(inContainer.begin(), inContainer.end(), inTransaction);
+}
+
+template <typename TNumType, typename TTransaction>
+inline void do_times(TNumType numberOfTimes, TTransaction inTransaction)
+{
+ for (TNumType index = 0; index < numberOfTimes; ++index)
+ inTransaction(index);
+}
+
+template <typename TCountFunc, typename TItemByIndexFunc, typename TTransaction>
+inline void for_each_item(TCountFunc inCountFunc, TItemByIndexFunc inItemByIndex,
+ TTransaction inTransaction)
+{
+ int theEnd = static_cast<int>(inCountFunc());
+ for (int index = 0; index < theEnd; ++index)
+ inTransaction(inItemByIndex(index));
+}
+
+template <typename TContainerType, typename TItemType>
+inline void insert_unique(TContainerType &inContainer, const TItemType &inItem)
+{
+ if (find(inContainer.begin(), inContainer.end(), inItem) == inContainer.end())
+ inContainer.insert(inContainer.end(), inItem);
+}
+
+template <typename TContainerType, typename TItemType, typename TPred>
+inline void insert_unique_if(TContainerType &inContainer, const TItemType &inItem, TPred inPred)
+{
+ if (find_if(inContainer.begin(), inContainer.end(), inPred) == inContainer.end())
+ inContainer.insert(inContainer.end(), inItem);
+}
+
+template <typename TItemType>
+inline TItemType identity(const TItemType &inValue)
+{
+ return inValue;
+}
+
+template <typename TItemType, typename TOutContainerType>
+inline void transformv_all(const std::vector<TItemType> &inSource, TOutContainerType &outDest)
+{
+ outDest.resize(inSource.size());
+ std::transform(inSource.begin(), inSource.end(), outDest.begin(), identity<TItemType>);
+}
+
+template <typename TContainerType, typename Pred>
+inline bool exists(TContainerType &inContainer, Pred inPredicate)
+{
+ return std::find_if(inContainer.begin(), inContainer.end(), inPredicate) != inContainer.end();
+}
+
+// Always return a default value (useful for default true for false)
+template <typename TRetType>
+inline TRetType always(TRetType inValue)
+{
+ return inValue;
+}
+
+template <typename TRetType, typename TIgnoreType>
+inline TRetType always_ignore(TIgnoreType, TRetType inValue)
+{
+ return inValue;
+}
+
+template <typename TArgument, typename TTransaction, typename TPredicate>
+inline void predicate_apply(TArgument inArgument, TTransaction inTransaction,
+ TPredicate inPredicate)
+{
+ if (inPredicate(inArgument))
+ inTransaction(inArgument);
+}
+
+template <typename TItemType>
+inline void assign_to(const TItemType &inSource, TItemType &inDest)
+{
+ inDest = inSource;
+}
+
+template <typename TPredType, typename TArgType>
+bool complement(TPredType inPredicate, TArgType inArgument)
+{
+ return !(inPredicate(inArgument));
+}
+
+template <typename TItemType, typename TPredicate>
+void insert_or_update(const TItemType &inItem, std::vector<TItemType> &inItems,
+ TPredicate inPredicate)
+{
+ typename std::vector<TItemType>::iterator theIter =
+ find_if<typename std::vector<TItemType>::iterator>(inItems, inPredicate);
+ if (theIter == inItems.end())
+ inItems.push_back(inItem);
+ else
+ *theIter = inItem;
+}
+
+template <typename TItemType>
+typename std::vector<TItemType>::iterator binary_sort_find(std::vector<TItemType> &inItems,
+ const TItemType &inItem)
+{
+ typedef typename std::vector<TItemType>::iterator TIterType;
+ TIterType insertPos = std::lower_bound(inItems.begin(), inItems.end(), inItem);
+ if (insertPos != inItems.end() && *insertPos == inItem)
+ return insertPos;
+ return inItems.end();
+}
+
+template <typename TItemType, typename TPredicate>
+std::pair<typename std::vector<TItemType>::iterator, bool>
+binary_sort_insert_unique(std::vector<TItemType> &inItems, const TItemType &inItem,
+ TPredicate inPredicate)
+{
+ typedef typename std::vector<TItemType>::iterator TIterType;
+ TIterType insertPos = std::lower_bound(inItems.begin(), inItems.end(), inItem, inPredicate);
+ // OK, insertPos can equal begin, it can equal end, or somewhere in between.
+ // If it doesn't equal end, then we may be pointing at the object and we let
+ // the caller figure out what to do. Else we insert
+ if (insertPos != inItems.end() && *insertPos == inItem)
+ return std::make_pair(insertPos, false);
+ size_t diff = insertPos - inItems.begin();
+ inItems.insert(insertPos, inItem);
+ return std::make_pair(inItems.begin() + diff, true);
+}
+
+template <typename TItemType>
+std::pair<typename std::vector<TItemType>::iterator, bool>
+binary_sort_insert_unique(std::vector<TItemType> &inItems, const TItemType &inItem)
+{
+ return binary_sort_insert_unique(inItems, inItem, std::less<TItemType>());
+}
+
+template <typename TItemType>
+bool binary_sort_erase(std::vector<TItemType> &inItems, const TItemType &inItem)
+{
+ typedef typename std::vector<TItemType>::iterator TIterType;
+ TIterType insertPos = binary_sort_find(inItems, inItem);
+ if (insertPos != inItems.end()) {
+ inItems.erase(insertPos);
+ return true;
+ }
+ return false;
+}
+}
+
+#endif
diff --git a/src/dm/systems/StudioAnimationSystem.cpp b/src/dm/systems/StudioAnimationSystem.cpp
new file mode 100644
index 0000000..2b78888
--- /dev/null
+++ b/src/dm/systems/StudioAnimationSystem.cpp
@@ -0,0 +1,610 @@
+/****************************************************************************
+**
+** 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 "StudioAnimationSystem.h"
+#include "StudioPropertySystem.h"
+
+using namespace std;
+
+namespace qt3dsdm {
+
+bool AnimationFloatPairContainsAnimation(Qt3DSDMAnimationHandle inAnimation,
+ const TAnimationFloatPair &inPair)
+{
+ return inAnimation == inPair.first;
+}
+
+CStudioAnimationSystem::CStudioAnimationSystem(TPropertySystemPtr inPropertySystem,
+ TSlideSystemPtr inSlideSystem,
+ TSlideCorePtr inSlideCore,
+ TSlideGraphCorePtr inSlideGraphCore,
+ TAnimationCorePtr inAnimationCore)
+ : m_PropertySystem(inPropertySystem)
+ , m_SlideSystem(inSlideSystem)
+ , m_SlideCore(inSlideCore)
+ , m_SlideGraphCore(inSlideGraphCore)
+ , m_AnimationCore(inAnimationCore)
+ , m_AutoKeyframe(false)
+ , m_SmoothInterpolation(false)
+{
+ IAnimationCoreSignalProvider *theAnimationSignals =
+ dynamic_cast<IAnimationCoreSignalProvider *>(m_AnimationCore.get());
+ m_Connections.push_back(theAnimationSignals->ConnectAnimationDeleted(
+ std::bind(&CStudioAnimationSystem::OnAnimationDeleted, this, std::placeholders::_1)));
+}
+
+void CStudioAnimationSystem::OnAnimationDeleted(Qt3DSDMAnimationHandle inAnimation)
+{
+ ClearTemporaryAnimationValues(inAnimation);
+}
+
+void CStudioAnimationSystem::ClearTemporaryAnimationValues()
+{
+ m_AnimationFloatPairs.clear();
+}
+
+void CStudioAnimationSystem::ClearTemporaryAnimationValues(Qt3DSDMAnimationHandle inAnimation)
+{
+ erase_if(m_AnimationFloatPairs,
+ std::bind(AnimationFloatPairContainsAnimation, inAnimation, std::placeholders::_1));
+}
+
+inline bool IsAnimationInfoEqual(const SAnimationInfo &inInfo, Qt3DSDMSlideHandle inSlide,
+ Qt3DSDMInstanceHandle inInstance, Qt3DSDMPropertyHandle inProperty)
+{
+ if (inInfo.m_Slide == inSlide && inInfo.m_Instance == inInstance
+ && inInfo.m_Property == inProperty)
+ return true;
+ return false;
+}
+inline bool IsAnimationInfoEqual(const SAnimationInfo &inInfo, Qt3DSDMSlideHandle inSlide,
+ Qt3DSDMInstanceHandle inInstance, Qt3DSDMPropertyHandle inProperty,
+ size_t inIndex)
+{
+ if (IsAnimationInfoEqual(inInfo, inSlide, inInstance, inProperty) && inInfo.m_Index == inIndex)
+ return true;
+ return false;
+}
+
+inline bool ApplyIfAnimationMatches(TAnimationFloatPair inAnimationFloatPair,
+ Qt3DSDMSlideHandle inSlide, Qt3DSDMInstanceHandle inInstance,
+ Qt3DSDMPropertyHandle inProperty,
+ TAnimationCorePtr inAnimationCore, SValue &outValue)
+{
+ SAnimationInfo theInfo = inAnimationCore->GetAnimationInfo(inAnimationFloatPair.first);
+ if (IsAnimationInfoEqual(theInfo, inSlide, inInstance, inProperty)) {
+ SetAnimationValue(inAnimationFloatPair.second, theInfo.m_Index, outValue);
+ return true;
+ }
+ return false;
+}
+
+void CStudioAnimationSystem::OverrideChannelIfAnimated(Qt3DSDMSlideHandle inSlide,
+ Qt3DSDMInstanceHandle inInstance,
+ Qt3DSDMPropertyHandle inProperty,
+ size_t inIndex, float inSeconds,
+ bool &ioAnimated, SValue &outValue) const
+{
+ Qt3DSDMAnimationHandle theAnimation =
+ m_AnimationCore->GetAnimation(inSlide, inInstance, inProperty, inIndex);
+ if (theAnimation.Valid() && m_AnimationCore->GetKeyframeCount(theAnimation)) {
+ float theValue = m_AnimationCore->EvaluateAnimation(theAnimation, inSeconds);
+ SetAnimationValue(theValue, inIndex, outValue);
+ ioAnimated |= true;
+ }
+}
+
+// Value must be *primed* first.
+bool CStudioAnimationSystem::GetAnimatedInstancePropertyValue(Qt3DSDMSlideHandle inSlide,
+ Qt3DSDMInstanceHandle inInstance,
+ Qt3DSDMPropertyHandle inProperty,
+ SValue &outValue) const
+{
+ bool retval = false;
+
+ tuple<bool, size_t> arity = GetVariantAnimatableAndArity(outValue);
+ if (get<0>(arity)) {
+ for (size_t index = 0; index < m_AnimationFloatPairs.size(); ++index)
+ retval |= ApplyIfAnimationMatches(m_AnimationFloatPairs.at(index), inSlide, inInstance,
+ inProperty, m_AnimationCore, outValue);
+ }
+
+ if (!retval) {
+ bool animatable;
+ size_t numChannels;
+ bool animated = false;
+
+ std::tie(animatable, numChannels) = GetVariantAnimatableAndArity(outValue);
+ if (animatable) {
+ TGraphSlidePair theGraphSlidePair = m_SlideGraphCore->GetAssociatedGraph(inInstance);
+ float theSeconds = m_SlideCore->GetSlideTime(
+ m_SlideGraphCore->GetGraphActiveSlide(theGraphSlidePair.first));
+
+ do_times(numChannels, std::bind(&CStudioAnimationSystem::OverrideChannelIfAnimated,
+ this, inSlide, inInstance, inProperty,
+ std::placeholders::_1, theSeconds,
+ std::ref(animated), std::ref(outValue)));
+ }
+
+ if (animated)
+ retval = true;
+ }
+
+ return retval;
+}
+
+bool KeyframeNear(const TKeyframe &inKeyframe, float inSeconds)
+{
+ return fabs(KeyframeTime(inKeyframe) - inSeconds) < .01;
+}
+Qt3DSDMKeyframeHandle CreateKeyframeExplicit(Qt3DSDMAnimationHandle inAnimation, float inValue,
+ float inSeconds, TAnimationCorePtr inAnimationCore,
+ float inEaseIn, float inEaseOut)
+{
+ TKeyframeHandleList theKeyframes;
+ float theValue = inValue;
+ inAnimationCore->GetKeyframes(inAnimation, theKeyframes);
+ function<TKeyframe(Qt3DSDMKeyframeHandle)> theConverter(
+ std::bind(&IAnimationCore::GetKeyframeData, inAnimationCore, std::placeholders::_1));
+
+ TKeyframeHandleList::iterator theFind =
+ std::find_if(theKeyframes.begin(), theKeyframes.end(),
+ [theConverter, inSeconds](const Qt3DSDMKeyframeHandle &handle)
+ { return KeyframeNear(theConverter(handle), inSeconds); });
+
+ float theEaseIn = inEaseIn;
+ float theEaseOut = inEaseOut;
+ Qt3DSDMKeyframeHandle theKeyframe;
+ if (theFind != theKeyframes.end()) {
+ theKeyframe = *theFind;
+
+ inAnimationCore->SetKeyframeData(
+ theKeyframe, CreateEaseInEaseOutKeyframe(inSeconds, theValue, theEaseIn, theEaseOut));
+ } else {
+ theKeyframe = inAnimationCore->InsertKeyframe(
+ inAnimation, CreateEaseInEaseOutKeyframe(inSeconds, theValue, theEaseIn, theEaseOut));
+ }
+ return theKeyframe;
+}
+
+Qt3DSDMKeyframeHandle CreateKeyframe(Qt3DSDMAnimationHandle inAnimation, const SValue &inValue,
+ float inSeconds, TAnimationCorePtr inAnimationCore,
+ float inEaseIn, float inEaseOut)
+{
+ SAnimationInfo theInfo(inAnimationCore->GetAnimationInfo(inAnimation));
+ return CreateKeyframeExplicit(inAnimation, GetAnimationValue(theInfo.m_Index, inValue),
+ inSeconds, inAnimationCore, inEaseIn, inEaseOut);
+}
+
+void MaybeAddAnimation(Qt3DSDMSlideHandle inSlide, Qt3DSDMInstanceHandle inInstance,
+ Qt3DSDMPropertyHandle inProperty, Qt3DSDMAnimationHandle inAnimation,
+ TAnimationCorePtr inAnimationCore, TAnimationHandleList &outAnimations)
+{
+ SAnimationInfo theInfo(inAnimationCore->GetAnimationInfo(inAnimation));
+ if (IsAnimationInfoEqual(theInfo, inSlide, inInstance, inProperty))
+ outAnimations.push_back(inAnimation);
+}
+
+bool SortAnimationHandlesByIndex(Qt3DSDMAnimationHandle lhs, Qt3DSDMAnimationHandle rhs,
+ TAnimationCorePtr inCore)
+{
+ return inCore->GetAnimationInfo(lhs).m_Index < inCore->GetAnimationInfo(rhs).m_Index;
+}
+
+void GetPresentAnimations(Qt3DSDMSlideHandle inSlide, Qt3DSDMInstanceHandle inInstance,
+ Qt3DSDMPropertyHandle inProperty,
+ const TAnimationFloatPairList &inAnimationPairs,
+ TAnimationCorePtr inAnimationCore, TAnimationHandleList &outAnimations)
+{
+ function<void(Qt3DSDMAnimationHandle)> theOperation(
+ std::bind(MaybeAddAnimation, inSlide, inInstance, inProperty,
+ std::placeholders::_1, inAnimationCore,
+ std::ref(outAnimations)));
+
+ for (auto animation : inAnimationPairs) {
+ MaybeAddAnimation(inSlide, inInstance, inProperty, animation.first, inAnimationCore,
+ std::ref(outAnimations));
+ }
+
+ if (outAnimations.empty()) {
+ TAnimationHandleList theAnimationHandles;
+ inAnimationCore->GetAnimations(theAnimationHandles);
+ do_all(theAnimationHandles, theOperation);
+ }
+ std::sort(outAnimations.begin(), outAnimations.end(),
+ std::bind(SortAnimationHandlesByIndex,
+ std::placeholders::_1, std::placeholders::_2, inAnimationCore));
+}
+
+void CreateAnimationAndAdd(Qt3DSDMSlideHandle inSlide, Qt3DSDMInstanceHandle inInstance,
+ Qt3DSDMPropertyHandle inProperty, size_t inIndex,
+ TAnimationCorePtr inAnimationCore, TAnimationHandleList &outAnimations)
+{
+ outAnimations.push_back(inAnimationCore->CreateAnimation(
+ inSlide, inInstance, inProperty, inIndex, EAnimationTypeEaseInOut, false));
+}
+
+bool AnimationValueDiffers(Qt3DSDMAnimationHandle inAnimation, const SValue &inValue,
+ float inSeconds, TAnimationCorePtr inAnimationCore)
+{
+ SAnimationInfo theInfo(inAnimationCore->GetAnimationInfo(inAnimation));
+ if (inAnimationCore->GetKeyframeCount(inAnimation) == 0)
+ return true; // currently there is no keyframe, so return true
+ float theValue = GetAnimationValue(theInfo.m_Index, inValue);
+ float theAnimatedValue = inAnimationCore->EvaluateAnimation(inAnimation, inSeconds);
+ return fabs(theValue - theAnimatedValue) > .001;
+}
+
+bool AnimationExistsInPresentAnimations(const TAnimationFloatPair &inAnimation,
+ TAnimationHandleList &inPresentAnimations)
+{
+ return exists(inPresentAnimations,
+ std::bind(equal_to<Qt3DSDMAnimationHandle>(), inAnimation.first,
+ std::placeholders::_1));
+}
+
+void DoKeyframeProperty(Qt3DSDMSlideHandle inSlide, Qt3DSDMInstanceHandle inInstance,
+ Qt3DSDMPropertyHandle inProperty, const SValue &inValue, float inTimeInSecs,
+ bool inDoDiffValue, TAnimationCorePtr inAnimationCore,
+ TAnimationFloatPairList &inAnimationFloatPairs, float inEaseIn,
+ float inEaseOut)
+{
+ tuple<bool, size_t> arity = GetVariantAnimatableAndArity(inValue);
+ TAnimationHandleList thePresentAnimations;
+ GetPresentAnimations(inSlide, inInstance, inProperty, std::cref(inAnimationFloatPairs),
+ inAnimationCore, thePresentAnimations);
+ if (thePresentAnimations.empty())
+ do_times(get<1>(arity), std::bind(CreateAnimationAndAdd, inSlide, inInstance, inProperty,
+ std::placeholders::_1,
+ inAnimationCore, std::ref(thePresentAnimations)));
+ if (!inDoDiffValue
+ || find_if(thePresentAnimations.begin(), thePresentAnimations.end(),
+ std::bind(AnimationValueDiffers,
+ std::placeholders::_1, inValue, inTimeInSecs, inAnimationCore))
+ != thePresentAnimations.end()) {
+ do_all(thePresentAnimations,
+ std::bind(CreateKeyframe, std::placeholders::_1,
+ std::cref(inValue), inTimeInSecs, inAnimationCore,
+ inEaseIn, inEaseOut));
+ erase_if(inAnimationFloatPairs, std::bind(AnimationExistsInPresentAnimations,
+ std::placeholders::_1,
+ std::ref(thePresentAnimations)));
+ }
+}
+
+void DoKeyframeProperty(Qt3DSDMSlideHandle inSlide, Qt3DSDMInstanceHandle inInstance,
+ Qt3DSDMPropertyHandle inProperty, const SValue &inValue, bool inDoDiffValue,
+ TAnimationCorePtr inAnimationCore, TSlideGraphCorePtr inSlideGraphCore,
+ TSlideCorePtr inSlideCore, TAnimationFloatPairList &inAnimationFloatPairs,
+ float inEaseIn, float inEaseOut)
+{
+ TGraphSlidePair theGraphSlidePair = inSlideGraphCore->GetAssociatedGraph(inInstance);
+ float theCurrentTime =
+ inSlideCore->GetSlideTime(inSlideGraphCore->GetGraphActiveSlide(theGraphSlidePair.first));
+ DoKeyframeProperty(inSlide, inInstance, inProperty, inValue, theCurrentTime, inDoDiffValue,
+ inAnimationCore, inAnimationFloatPairs, inEaseIn, inEaseOut);
+}
+
+void DoKeyframeProperty(Qt3DSDMSlideHandle inSlide, Qt3DSDMInstanceHandle inInstance,
+ Qt3DSDMPropertyHandle inProperty, const SValue &inValue, bool inDoDiffValue,
+ TAnimationCorePtr inAnimationCore, TSlideGraphCorePtr inSlideGraphCore,
+ TSlideCorePtr inSlideCore, TAnimationFloatPairList &inAnimationFloatPairs,
+ bool inSmoothInterpolation)
+{
+ float theEaseIn = 0.0f, theEaseOut = 0.0f;
+ if (inSmoothInterpolation)
+ theEaseIn = theEaseOut = 100.f;
+ DoKeyframeProperty(inSlide, inInstance, inProperty, inValue, inDoDiffValue, inAnimationCore,
+ inSlideGraphCore, inSlideCore, inAnimationFloatPairs, theEaseIn, theEaseOut);
+}
+
+TAnimationFloatPair CreateAnimationFloatPair(Qt3DSDMAnimationHandle inAnimation,
+ const SValue &inValue,
+ TAnimationCorePtr inAnimationCore)
+{
+ SAnimationInfo theInfo(inAnimationCore->GetAnimationInfo(inAnimation));
+ float theValue = GetAnimationValue(theInfo.m_Index, inValue);
+ return make_pair(inAnimation, theValue);
+}
+
+void InsertUniqueAnimationFloatPair(Qt3DSDMAnimationHandle inAnimation,
+ TAnimationFloatPairList &inList, const SValue &inValue,
+ TAnimationCorePtr inAnimationCore)
+{
+ TAnimationFloatPair thePair = CreateAnimationFloatPair(inAnimation, inValue, inAnimationCore);
+ insert_or_update(thePair, inList,
+ std::bind(AnimationFloatPairContainsAnimation, inAnimation, std::placeholders::_1));
+}
+
+bool CStudioAnimationSystem::SetAnimatedInstancePropertyValue(Qt3DSDMSlideHandle inSlide,
+ Qt3DSDMInstanceHandle inInstance,
+ Qt3DSDMPropertyHandle inProperty,
+ const SValue &inValue)
+{
+ tuple<bool, size_t> arity = GetVariantAnimatableAndArity(inValue);
+ if (get<0>(arity)) {
+ if (m_AutoKeyframe && IsPropertyAnimated(inInstance, inProperty)) // prerequisite for
+ // autoset-keyframes is
+ // that the property is
+ // already animated.
+ {
+ DoKeyframeProperty(inSlide, inInstance, inProperty, inValue, true, m_AnimationCore,
+ m_SlideGraphCore, m_SlideCore, m_AnimationFloatPairs,
+ m_SmoothInterpolation);
+ return true;
+ }
+
+ TAnimationHandleList thePresentAnimations;
+ GetPresentAnimations(inSlide, inInstance, inProperty, std::cref(m_AnimationFloatPairs),
+ m_AnimationCore, thePresentAnimations);
+ if (!thePresentAnimations.empty()) {
+ TAnimationFloatPairList thePreList(m_AnimationFloatPairs);
+ do_all(thePresentAnimations, std::bind(InsertUniqueAnimationFloatPair, std::placeholders::_1,
+ std::ref(m_AnimationFloatPairs),
+ std::cref(inValue), m_AnimationCore));
+
+
+ if (m_Consumer && m_refreshCallback) {
+ // Only create a single refresh per transaction stack
+ if (((CTransactionConsumer *)m_Consumer.get())->m_TransactionList.size() == 0) {
+ CreateGenericTransactionWithConsumer(
+ __FILE__, __LINE__, m_Consumer,
+ std::bind(m_refreshCallback, inInstance),
+ std::bind(m_refreshCallback, inInstance));
+ }
+ }
+
+ CreateGenericTransactionWithConsumer(
+ __FILE__, __LINE__, m_Consumer,
+ std::bind(assign_to<TAnimationFloatPairList>, m_AnimationFloatPairs,
+ std::ref(m_AnimationFloatPairs)),
+ std::bind(assign_to<TAnimationFloatPairList>, thePreList,
+ std::ref(m_AnimationFloatPairs)));
+ return true;
+ }
+ }
+ return false;
+}
+
+void CStudioAnimationSystem::SetAutoKeyframe(bool inAutoKeyframe)
+{
+ m_AutoKeyframe = inAutoKeyframe;
+}
+bool CStudioAnimationSystem::GetAutoKeyframe() const
+{
+ return m_AutoKeyframe;
+}
+
+Qt3DSDMSlideHandle CStudioAnimationSystem::GetApplicableGraphAndSlide(
+ Qt3DSDMInstanceHandle inInstance, Qt3DSDMPropertyHandle inProperty, const SValue &inValue)
+{
+ Qt3DSDMSlideHandle theApplicableSlide;
+ tuple<bool, size_t> arity = GetVariantAnimatableAndArity(inValue);
+ if (get<0>(arity))
+ theApplicableSlide = m_SlideSystem->GetApplicableSlide(inInstance, inProperty);
+ return theApplicableSlide;
+}
+
+void InsertUniqueAnimationKeyframesPair(TAnimationKeyframesPairList &ioList, SAnimationInfo &inInfo,
+ TKeyframeList &inKeyframes)
+{
+ bool theFound = false;
+ for (TAnimationKeyframesPairList::iterator theAnimationKeyframeIter = ioList.begin();
+ theAnimationKeyframeIter < ioList.end(); ++theAnimationKeyframeIter) {
+ if (IsAnimationInfoEqual(theAnimationKeyframeIter->first, inInfo.m_Slide, inInfo.m_Instance,
+ inInfo.m_Property, inInfo.m_Index)) {
+ theFound = true;
+ // Overwrite the existing value
+ SAnimationInfo &theInfo = theAnimationKeyframeIter->first;
+ theInfo.m_AnimationType = inInfo.m_AnimationType;
+ theInfo.m_DynamicFirstKeyframe = inInfo.m_DynamicFirstKeyframe;
+ theAnimationKeyframeIter->second = inKeyframes;
+ break;
+ }
+ }
+ if (!theFound) {
+ ioList.push_back(std::make_pair(inInfo, inKeyframes));
+ }
+}
+
+void CStudioAnimationSystem::Animate(Qt3DSDMInstanceHandle inInstance,
+ Qt3DSDMPropertyHandle inProperty)
+{
+ SValue theValue;
+ m_PropertySystem->GetInstancePropertyValue(inInstance, inProperty, theValue);
+ Qt3DSDMSlideHandle theApplicableSlide =
+ GetApplicableGraphAndSlide(inInstance, inProperty, theValue.toOldSkool());
+ if (theApplicableSlide.Valid()) {
+ // Check if previously we have set animation & keyframes
+ DataModelDataType::Value theDataType = m_PropertySystem->GetDataType(inProperty);
+ std::tuple<bool, size_t> theArity = GetDatatypeAnimatableAndArity(theDataType);
+ bool theFound = false;
+ for (size_t i = 0; i < std::get<1>(theArity); ++i) {
+ TAnimationKeyframesPairList::iterator theAnimationKeyframeIter =
+ m_DeletedAnimationData.begin();
+ for (; theAnimationKeyframeIter < m_DeletedAnimationData.end();
+ ++theAnimationKeyframeIter) {
+ if (IsAnimationInfoEqual(theAnimationKeyframeIter->first, theApplicableSlide,
+ inInstance, inProperty, i)) {
+ theFound = true;
+
+ // We use previously set animation & keyframes to create new animation &
+ // keyframe
+ SAnimationInfo &theInfo = theAnimationKeyframeIter->first;
+ Qt3DSDMAnimationHandle theAnimation = m_AnimationCore->CreateAnimation(
+ theInfo.m_Slide, theInfo.m_Instance, theInfo.m_Property, theInfo.m_Index,
+ theInfo.m_AnimationType, theInfo.m_DynamicFirstKeyframe);
+
+ TKeyframeList theKeyframes = theAnimationKeyframeIter->second;
+ for (TKeyframeList::const_iterator theKeyframeIter = theKeyframes.begin();
+ theKeyframeIter < theKeyframes.end(); ++theKeyframeIter)
+ m_AnimationCore->InsertKeyframe(theAnimation, *theKeyframeIter);
+
+ break;
+ }
+ }
+ }
+
+ if (!theFound)
+ DoKeyframeProperty(theApplicableSlide, inInstance, inProperty, theValue.toOldSkool(),
+ true, m_AnimationCore, m_SlideGraphCore, m_SlideCore,
+ m_AnimationFloatPairs, m_SmoothInterpolation);
+ }
+}
+
+void CStudioAnimationSystem::Deanimate(Qt3DSDMInstanceHandle inInstance,
+ Qt3DSDMPropertyHandle inProperty)
+{
+ DataModelDataType::Value theDataType = m_PropertySystem->GetDataType(inProperty);
+ std::tuple<bool, size_t> theArity = GetDatatypeAnimatableAndArity(theDataType);
+ for (size_t i = 0; i < std::get<1>(theArity); ++i) {
+ Qt3DSDMAnimationHandle theAnimationHandle =
+ GetControllingAnimation(inInstance, inProperty, i);
+
+ if (theAnimationHandle.Valid()) {
+ // Get animation & keyframe data and save it
+ SAnimationInfo theInfo(m_AnimationCore->GetAnimationInfo(theAnimationHandle));
+ TKeyframeHandleList theKeyframeHandles;
+ m_AnimationCore->GetKeyframes(theAnimationHandle, theKeyframeHandles);
+ TKeyframeList theKeyframeList;
+ for (TKeyframeHandleList::const_iterator theKeyframeIter = theKeyframeHandles.begin();
+ theKeyframeIter < theKeyframeHandles.end(); ++theKeyframeIter)
+ theKeyframeList.push_back(m_AnimationCore->GetKeyframeData(*theKeyframeIter));
+ InsertUniqueAnimationKeyframesPair(m_DeletedAnimationData, theInfo, theKeyframeList);
+
+ // Delete the animation
+ m_AnimationCore->DeleteAnimation(theAnimationHandle);
+ }
+ }
+}
+
+void CStudioAnimationSystem::KeyframeProperty(Qt3DSDMInstanceHandle inInstance,
+ Qt3DSDMPropertyHandle inProperty, bool inDoDiffValue)
+{
+ SValue theValue;
+ m_PropertySystem->GetInstancePropertyValue(inInstance, inProperty, theValue);
+ Qt3DSDMSlideHandle theApplicableSlide =
+ GetApplicableGraphAndSlide(inInstance, inProperty, theValue.toOldSkool());
+ if (theApplicableSlide.Valid())
+ DoKeyframeProperty(theApplicableSlide, inInstance, inProperty, theValue.toOldSkool(),
+ inDoDiffValue, m_AnimationCore, m_SlideGraphCore, m_SlideCore,
+ m_AnimationFloatPairs, m_SmoothInterpolation);
+}
+void CStudioAnimationSystem::SetOrCreateKeyframe(Qt3DSDMInstanceHandle inInstance,
+ Qt3DSDMPropertyHandle inProperty,
+ float inTimeInSeconds,
+ SGetOrSetKeyframeInfo *inKeyframeInfo,
+ size_t inNumInfos)
+{
+ qt3dsdm::DataModelDataType::Value thePropertyType = m_PropertySystem->GetDataType(inProperty);
+ Qt3DSDMSlideHandle theApplicableSlide;
+ std::tuple<bool, size_t> arity = GetDatatypeAnimatableAndArity(thePropertyType);
+ if (std::get<0>(arity)) {
+ theApplicableSlide = m_SlideSystem->GetApplicableSlide(inInstance, inProperty);
+ if (theApplicableSlide.Valid()) {
+
+ TAnimationHandleList thePresentAnimations;
+ GetPresentAnimations(theApplicableSlide, inInstance, inProperty,
+ std::cref(m_AnimationFloatPairs), m_AnimationCore,
+ thePresentAnimations);
+ size_t numIterations = std::min(inNumInfos, get<1>(arity));
+ if (thePresentAnimations.empty()) {
+ for (size_t idx = 0, end = numIterations; idx < end; ++idx) {
+ CreateAnimationAndAdd(theApplicableSlide, inInstance, inProperty, idx,
+ m_AnimationCore, thePresentAnimations);
+ }
+ }
+ for (size_t idx = 0, end = numIterations; idx < end; ++idx) {
+ CreateKeyframeExplicit(thePresentAnimations[idx], inKeyframeInfo[idx].m_Value,
+ inTimeInSeconds, m_AnimationCore,
+ inKeyframeInfo[idx].m_EaseIn, inKeyframeInfo[idx].m_EaseOut);
+ if (inKeyframeInfo[idx].m_AnimationTrackIsDynamic)
+ m_AnimationCore->SetFirstKeyframeDynamic(thePresentAnimations[idx], true);
+ }
+ erase_if(m_AnimationFloatPairs, std::bind(AnimationExistsInPresentAnimations,
+ std::placeholders::_1,
+ std::ref(thePresentAnimations)));
+ }
+ }
+}
+
+inline bool FindMatchingAnimation(Qt3DSDMAnimationHandle inAnimation,
+ TAnimationCorePtr inAnimationCore, size_t inIndex)
+{
+ return inAnimationCore->GetAnimationInfo(inAnimation).m_Index == inIndex;
+}
+
+Qt3DSDMAnimationHandle CStudioAnimationSystem::GetControllingAnimation(
+ Qt3DSDMInstanceHandle inInstance, Qt3DSDMPropertyHandle inProperty, size_t inIndex) const
+{
+ Qt3DSDMSlideHandle theApplicableSlide =
+ m_SlideSystem->GetApplicableSlide(inInstance, inProperty);
+ // first check our anim float pairs
+ for (size_t idx = 0, end = m_AnimationFloatPairs.size(); idx < end; ++idx) {
+ const SAnimationInfo &theInfo =
+ m_AnimationCore->GetAnimationInfo(m_AnimationFloatPairs[idx].first);
+ if (IsAnimationInfoEqual(theInfo, theApplicableSlide, inInstance, inProperty, inIndex))
+ return m_AnimationFloatPairs[idx].first;
+ }
+ // Use the cache lookup instead of linear search algorithm
+ return m_AnimationCore->GetAnimation(theApplicableSlide, inInstance, inProperty, inIndex);
+}
+
+bool CStudioAnimationSystem::IsPropertyAnimatable(Qt3DSDMInstanceHandle inInstance,
+ Qt3DSDMPropertyHandle inProperty) const
+{
+ DataModelDataType::Value theDataType = m_PropertySystem->GetDataType(inProperty);
+ std::tuple<bool, size_t> theArity = GetDatatypeAnimatableAndArity(theDataType);
+ if (std::get<0>(theArity))
+ return m_SlideGraphCore->GetAssociatedGraph(inInstance).first.Valid();
+ return false;
+}
+
+bool CStudioAnimationSystem::IsPropertyAnimated(Qt3DSDMInstanceHandle inInstance,
+ Qt3DSDMPropertyHandle inProperty) const
+{
+ DataModelDataType::Value theDataType = m_PropertySystem->GetDataType(inProperty);
+ std::tuple<bool, size_t> theArity = GetDatatypeAnimatableAndArity(theDataType);
+ for (size_t i = 0; i < std::get<1>(theArity); ++i) {
+ if (GetControllingAnimation(inInstance, inProperty, i).Valid())
+ return true;
+ }
+ return false;
+}
+
+void CStudioAnimationSystem::SetConsumer(TTransactionConsumerPtr inConsumer)
+{
+ m_Consumer = inConsumer;
+}
+
+void CStudioAnimationSystem::setRefreshCallback(TRefreshCallbackFunc func)
+{
+ m_refreshCallback = func;
+}
+}
diff --git a/src/dm/systems/StudioAnimationSystem.h b/src/dm/systems/StudioAnimationSystem.h
new file mode 100644
index 0000000..e6fdf75
--- /dev/null
+++ b/src/dm/systems/StudioAnimationSystem.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 STUDIOANIMATIONSYSTEMIMPLH
+#define STUDIOANIMATIONSYSTEMIMPLH
+
+#include "Qt3DSDMAnimation.h"
+#include "Qt3DSDMSlides.h"
+#include "Qt3DSDMSlideCore.h"
+#include "Qt3DSDMSlideGraphCore.h"
+#include "Qt3DSDMTransactions.h"
+#include "Qt3DSDMDataCore.h"
+#include "Qt3DSDMSignals.h"
+
+namespace qt3dsdm {
+
+typedef std::pair<Qt3DSDMAnimationHandle, float> TAnimationFloatPair;
+typedef std::vector<TAnimationFloatPair> TAnimationFloatPairList;
+
+class CStudioAnimationSystem : public IStudioAnimationSystem,
+ public ITransactionProducer
+{
+ Q_DISABLE_COPY(CStudioAnimationSystem)
+
+ TPropertySystemPtr m_PropertySystem;
+ TSlideSystemPtr m_SlideSystem;
+ TSlideCorePtr m_SlideCore;
+ TSlideGraphCorePtr m_SlideGraphCore;
+ TAnimationCorePtr m_AnimationCore;
+ TRefreshCallbackFunc m_refreshCallback = nullptr;
+
+ bool m_AutoKeyframe;
+ // When a property has an animation associated with it, then writes
+ // do not go all the way down to the db. They stay on this object.
+ TAnimationFloatPairList m_AnimationFloatPairs;
+ bool m_SmoothInterpolation;
+
+ TAnimationKeyframesPairList m_DeletedAnimationData; // list to store deanimated animation &
+ // keyframe data. This will be use if user
+ // wants to animate the same property again
+
+ TTransactionConsumerPtr m_Consumer;
+
+ std::vector<std::shared_ptr<ISignalConnection>> m_Connections;
+
+public:
+ CStudioAnimationSystem(TPropertySystemPtr inPropertySystem, TSlideSystemPtr inSlideSystem,
+ TSlideCorePtr inSlideCore, TSlideGraphCorePtr inSlideGraphCore,
+ TAnimationCorePtr inAnimationCore);
+
+ void ClearTemporaryAnimationValues();
+ void ClearTemporaryAnimationValues(Qt3DSDMAnimationHandle inAnimation);
+
+ void SetPropertySystem(TPropertySystemPtr inPropertySystem)
+ {
+ m_PropertySystem = inPropertySystem;
+ } // HACK: TODO: We should really consider having all the subsytem know everyone else without
+ // passing in so many things in the constructor
+
+ //====================================================================
+ // IStudioAnimationSystem implementation
+ //====================================================================
+ void SetAutoKeyframe(bool inAutoKeyframe) override;
+ bool GetAutoKeyframe() const override;
+ void Animate(Qt3DSDMInstanceHandle inInstance, Qt3DSDMPropertyHandle inProperty) override;
+ void Deanimate(Qt3DSDMInstanceHandle inInstance, Qt3DSDMPropertyHandle inProperty) override;
+ void KeyframeProperty(Qt3DSDMInstanceHandle inInstance, Qt3DSDMPropertyHandle inProperty,
+ bool inDoDiffValue) override;
+ void SetOrCreateKeyframe(Qt3DSDMInstanceHandle inInstance,
+ Qt3DSDMPropertyHandle inProperty, float inTimeInSeconds,
+ SGetOrSetKeyframeInfo *inKeyframeInfo, size_t inNumInfos) override;
+ Qt3DSDMAnimationHandle GetControllingAnimation(Qt3DSDMInstanceHandle inInstance,
+ Qt3DSDMPropertyHandle inProperty,
+ size_t inIndex) const override;
+ bool IsPropertyAnimatable(Qt3DSDMInstanceHandle inInstance,
+ Qt3DSDMPropertyHandle inProperty) const override;
+ bool IsPropertyAnimated(Qt3DSDMInstanceHandle inInstance,
+ Qt3DSDMPropertyHandle inProperty) const override;
+ void SetInterpolation(bool inSmooth) override { m_SmoothInterpolation = inSmooth; }
+
+ bool GetAnimatedInstancePropertyValue(Qt3DSDMSlideHandle inSlide,
+ Qt3DSDMInstanceHandle inInstance,
+ Qt3DSDMPropertyHandle inProperty,
+ SValue &outValue) const override;
+ bool SetAnimatedInstancePropertyValue(Qt3DSDMSlideHandle inSlide,
+ Qt3DSDMInstanceHandle inInstance,
+ Qt3DSDMPropertyHandle inProperty,
+ const SValue &inValue) override;
+ //====================================================================
+
+ void SetConsumer(TTransactionConsumerPtr inConsumer) override;
+
+ void setRefreshCallback(TRefreshCallbackFunc func) override;
+
+private:
+ void OnAnimationDeleted(Qt3DSDMAnimationHandle inAnimation);
+
+ Qt3DSDMSlideHandle GetApplicableGraphAndSlide(Qt3DSDMInstanceHandle inInstance,
+ Qt3DSDMPropertyHandle inProperty,
+ const SValue &inValue);
+
+ void OverrideChannelIfAnimated(Qt3DSDMSlideHandle inSlide, Qt3DSDMInstanceHandle inInstance,
+ Qt3DSDMPropertyHandle inProperty, size_t inIndex, float inSeconds,
+ bool &ioAnimated, SValue &outValue) const;
+};
+}
+
+#endif
diff --git a/src/dm/systems/StudioCoreSystem.cpp b/src/dm/systems/StudioCoreSystem.cpp
new file mode 100644
index 0000000..f9f0e2c
--- /dev/null
+++ b/src/dm/systems/StudioCoreSystem.cpp
@@ -0,0 +1,409 @@
+/****************************************************************************
+**
+** 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 "StudioCoreSystem.h"
+#include "SlideCoreProducer.h"
+#include "SlideGraphCoreProducer.h"
+#include "DataCoreProducer.h"
+#include "AnimationCoreProducer.h"
+#include "ActionCoreProducer.h"
+#include "Qt3DSDMSignals.h"
+#include "Qt3DSDMMetaData.h"
+#include "Qt3DSDMGuides.h"
+
+using namespace std;
+
+namespace qt3dsdm {
+
+inline bool AnimationInstanceMatches(Qt3DSDMAnimationHandle inAnimation,
+ TAnimationCorePtr inAnimationCore,
+ Qt3DSDMInstanceHandle inInstance)
+{
+ return inInstance == inAnimationCore->GetAnimationInfo(inAnimation).m_Instance;
+}
+
+inline bool AnimationPropertyMatches(Qt3DSDMAnimationHandle inAnimation,
+ TAnimationCorePtr inAnimationCore,
+ Qt3DSDMPropertyHandle inProperty)
+{
+ return inProperty == inAnimationCore->GetAnimationInfo(inAnimation).m_Property;
+}
+
+inline bool AnimationSlideMatches(Qt3DSDMAnimationHandle inAnimation,
+ TAnimationCorePtr inAnimationCore, Qt3DSDMSlideHandle inSlide)
+{
+ return inSlide == inAnimationCore->GetAnimationInfo(inAnimation).m_Slide;
+}
+
+inline bool AnimationSlideInstancePropertyMatch(Qt3DSDMAnimationHandle inAnimation,
+ TAnimationCorePtr inAnimationCore,
+ Qt3DSDMSlideHandle inSlide,
+ Qt3DSDMInstanceHandle inInstance,
+ Qt3DSDMPropertyHandle inProperty)
+{
+ SAnimationInfo theInfo = inAnimationCore->GetAnimationInfo(inAnimation);
+ return theInfo.m_Slide == inSlide && theInfo.m_Instance == inInstance
+ && theInfo.m_Property == inProperty;
+}
+
+inline bool AnimationInstancesPropertiesMatch(Qt3DSDMAnimationHandle inAnimation,
+ TAnimationCorePtr inAnimationCore,
+ const TInstanceHandleList &inInstances,
+ const TPropertyHandleList &inProperties)
+{
+ SAnimationInfo theInfo = inAnimationCore->GetAnimationInfo(inAnimation);
+ return exists(inInstances, std::bind(equal_to<int>(), theInfo.m_Instance,
+ std::placeholders::_1))
+ && exists(inProperties, std::bind(equal_to<int>(), theInfo.m_Property,
+ std::placeholders::_1));
+}
+
+void EraseAnimationsThatMatch(TAnimationCorePtr inAnimationCore,
+ function<bool(Qt3DSDMAnimationHandle)> inPredicate)
+{
+ TAnimationHandleList theAnimations;
+ inAnimationCore->GetAnimations(theAnimations);
+ function<bool(Qt3DSDMAnimationHandle)> theComp(std::bind(
+ complement<function<bool(Qt3DSDMAnimationHandle)>, Qt3DSDMAnimationHandle>, inPredicate,
+ std::placeholders::_1));
+ TAnimationHandleList::iterator theRemovals =
+ remove_if(theAnimations.begin(), theAnimations.end(), theComp);
+ for_each(theAnimations.begin(), theRemovals,
+ std::bind(&IAnimationCore::DeleteAnimation, inAnimationCore, std::placeholders::_1));
+}
+
+void EraseActions(TDataCorePtr inDataCore, TActionCorePtr inActionCore,
+ const TActionHandleList &inActions)
+{
+ for (TActionHandleList::const_iterator theActionIter = inActions.begin();
+ theActionIter != inActions.end(); ++theActionIter) {
+ Qt3DSDMInstanceHandle theActionInstance;
+ inActionCore->DeleteAction(*theActionIter, theActionInstance);
+ inDataCore->DeleteInstance(theActionInstance);
+ }
+}
+
+void CascadeInstanceDelete(Qt3DSDMInstanceHandle inInstance, TDataCorePtr inDataCore,
+ TSlideCorePtr inSlideCore, TSlideGraphCorePtr inSlideGraphCore,
+ TAnimationCorePtr inAnimationCore, TActionCorePtr inActionCore)
+{
+ inSlideCore->DeleteAllInstanceEntries(inInstance);
+
+ inSlideGraphCore->DissociateInstance(inInstance);
+
+ function<bool(Qt3DSDMAnimationHandle)> thePredicate(
+ std::bind(AnimationInstanceMatches, std::placeholders::_1, inAnimationCore, inInstance));
+ EraseAnimationsThatMatch(inAnimationCore, thePredicate);
+
+ TActionHandleList theActions;
+ inActionCore->GetActions(inInstance, theActions);
+ EraseActions(inDataCore, inActionCore, theActions);
+}
+
+void CascadePropertyRemove(Qt3DSDMInstanceHandle inInstance, Qt3DSDMPropertyHandle inProperty,
+ TSlideCorePtr inSlideCore, TSlideGraphCorePtr inSlideGraphCore,
+ TAnimationCorePtr inAnimationCore)
+{
+ inSlideCore->DeleteAllPropertyEntries(inProperty);
+ function<bool(Qt3DSDMAnimationHandle)> thePredicate(
+ std::bind(AnimationPropertyMatches, std::placeholders::_1, inAnimationCore, inProperty));
+ EraseAnimationsThatMatch(inAnimationCore, thePredicate);
+}
+
+void CascadeSlideDelete(Qt3DSDMSlideHandle inSlide, TDataCorePtr inDataCore,
+ TSlideCorePtr inSlideCore, TSlideGraphCorePtr inSlideGraphCore,
+ TAnimationCorePtr inAnimationCore, TActionCorePtr inActionCore)
+{
+ Qt3DSDMSlideGraphHandle theGraph = inSlideGraphCore->GetSlideGraph(inSlide);
+ if (theGraph.Valid()) {
+ TSlideHandleList theChildren;
+ inSlideCore->GetChildSlides(inSlide, theChildren);
+ TInstanceHandleList instances;
+ for (size_t idx = 0, end = theChildren.size(); idx < end; ++idx) {
+ instances.clear();
+ inSlideCore->DeleteSlide(theChildren[idx], instances);
+ for (size_t instIdx = 0, instEnd = instances.size(); instIdx < instEnd; ++instIdx)
+ inDataCore->DeleteInstance(instances[instIdx]);
+ }
+ inSlideGraphCore->DeleteSlideGraph(theGraph);
+ }
+
+ else {
+ Qt3DSDMSlideHandle theMaster(inSlideCore->GetParentSlide(inSlide));
+ if (theMaster.Valid()) {
+ Qt3DSDMSlideGraphHandle theGraph = inSlideGraphCore->GetSlideGraph(theMaster);
+ if (theGraph.Valid()) {
+ /*
+ tricky stuff. The slide change was recorded in the transaction system when the
+ slide was created. But since there didn't *have* to be a slide change when the
+ slide was destroyed there was no slide change recorded at that point.
+
+ Then on the first redo, the system quietly switched the active slide to the new
+ slide. On the second redo the system crashed due to attempting to access the
+ new slide after it had been deleted (as nothing switched the system back to the
+ current slide).
+
+ So the correct answer is that the cascading system needs to *always* set the
+ active slide, even if it seems like it would be, at the moment, unnecessary
+ because the slide getting deleted is not currently active. This is the mirror
+ of the fact that new slide *always* sets the active slide so it does make
+ logical sense.*/
+ Qt3DSDMSlideHandle theNewActiveSlide =
+ inSlideGraphCore->GetGraphActiveSlide(theGraph);
+ if (theNewActiveSlide == inSlide) {
+ TSlideHandleList theChildren;
+ inSlideCore->GetChildSlides(theMaster, theChildren);
+ size_t idx = 0;
+ for (size_t end = theChildren.size(); idx < end; ++idx) {
+ if (theChildren[idx] != inSlide) {
+ theNewActiveSlide = theChildren[idx];
+ break;
+ }
+ }
+ if (theNewActiveSlide == inSlide)
+ theNewActiveSlide = theMaster;
+ }
+ inSlideGraphCore->SetGraphActiveSlide(theGraph, theNewActiveSlide);
+ }
+ }
+ }
+ EraseAnimationsThatMatch(inAnimationCore,
+ std::bind(AnimationSlideMatches,
+ std::placeholders::_1, inAnimationCore, inSlide));
+
+ TActionHandleList theActions;
+ inActionCore->GetActions(inSlide, theActions);
+ EraseActions(inDataCore, inActionCore, theActions);
+}
+
+void CascadeSlidePropertyRemove(Qt3DSDMSlideHandle inSlide, Qt3DSDMInstanceHandle inInstance,
+ Qt3DSDMPropertyHandle inProperty, TAnimationCorePtr inAnimationCore)
+{
+ EraseAnimationsThatMatch(inAnimationCore,
+ std::bind(AnimationSlideInstancePropertyMatch,
+ std::placeholders::_1, inAnimationCore,
+ inSlide, inInstance, inProperty));
+}
+
+void CascadeInstanceParentRemoved(Qt3DSDMInstanceHandle inInstance, Qt3DSDMInstanceHandle inParent,
+ TDataCorePtr inDataCore, TSlideCorePtr inSlideCore,
+ TAnimationCorePtr inAnimationCore)
+{
+ TPropertyHandleList theProperties;
+ inDataCore->GetInstanceProperties(inParent, theProperties);
+ TInstanceHandleList allInstances;
+ inDataCore->GetInstances(allInstances);
+ function<bool(Qt3DSDMInstanceHandle)> InstanceOrDerived(
+ std::bind(&IDataCore::IsInstanceOrDerivedFrom, inDataCore,
+ std::placeholders::_1, inInstance));
+ function<bool(Qt3DSDMInstanceHandle)> DerivedComplement(
+ std::bind(complement<function<bool(Qt3DSDMInstanceHandle)>, Qt3DSDMInstanceHandle>,
+ InstanceOrDerived, std::placeholders::_1));
+ TInstanceHandleList::iterator all_derived =
+ remove_if(allInstances.begin(), allInstances.end(), DerivedComplement);
+ TInstanceHandleList derivedInstances(allInstances.begin(), all_derived);
+ inSlideCore->DeleteAllInstancePropertyEntries(derivedInstances, theProperties);
+ EraseAnimationsThatMatch(
+ inAnimationCore, std::bind(AnimationInstancesPropertiesMatch,
+ std::placeholders::_1, inAnimationCore,
+ std::cref(derivedInstances), std::cref(theProperties)));
+}
+
+void CascadeBeforeAnimationDeleted(Qt3DSDMAnimationHandle inAnimation,
+ TAnimationCorePtr inAnimationCore, TDataCorePtr inDataCore,
+ TSlideCorePtr inSlideCore)
+{
+ SAnimationInfo theInfo = inAnimationCore->GetAnimationInfo(inAnimation);
+ SValue theSlideValue;
+ if (inDataCore->IsInstance(theInfo.m_Instance) && inSlideCore->IsSlide(theInfo.m_Slide)
+ && inSlideCore->GetSpecificInstancePropertyValue(theInfo.m_Slide, theInfo.m_Instance,
+ theInfo.m_Property, theSlideValue)
+ && inAnimationCore->GetKeyframeCount(inAnimation)) {
+ float theTime = inSlideCore->GetSlideTime(theInfo.m_Slide);
+ float theValue = inAnimationCore->EvaluateAnimation(inAnimation, theTime);
+ SetAnimationValue(theValue, theInfo.m_Index, theSlideValue);
+ inSlideCore->ForceSetInstancePropertyValue(theInfo.m_Slide, theInfo.m_Instance,
+ theInfo.m_Property, theSlideValue);
+ }
+}
+
+void CascadeBeforeKeyframeErased(Qt3DSDMKeyframeHandle inKeyframe, TAnimationCorePtr inAnimationCore,
+ TDataCorePtr inDataCore, TSlideCorePtr inSlideCore)
+{
+ Qt3DSDMAnimationHandle theAnimation = inAnimationCore->GetAnimationForKeyframe(inKeyframe);
+ if (inAnimationCore->GetKeyframeCount(theAnimation) == 1)
+ CascadeBeforeAnimationDeleted(theAnimation, inAnimationCore, inDataCore, inSlideCore);
+}
+
+CStudioCoreSystem::CStudioCoreSystem(TStringTablePtr strTable)
+ : m_StringTable(strTable.get() != NULL ? strTable : IStringTable::CreateStringTable())
+ , m_DataCore(new CDataCoreProducer(m_StringTable))
+ , m_SlideCore(new CSlideCoreProducer(m_StringTable))
+ , m_SlideGraphCore(new CSlideGraphCoreProducer())
+ , m_AnimationCore(new CAnimationCoreProducer())
+ , m_ActionCore(new CActionCoreProducer(m_StringTable))
+ , m_NewMetaData(
+ IMetaData::CreateNewMetaData(dynamic_pointer_cast<CDataCoreProducer>(m_DataCore)))
+ , m_GuideSystem(IGuideSystem::CreateGuideSystem())
+{
+ IDataCoreSignalProvider *theProvider =
+ dynamic_cast<IDataCoreSignalProvider *>(m_DataCore.get());
+ m_Connections.push_back(theProvider->ConnectInstanceDeleted(
+ std::bind(CascadeInstanceDelete, std::placeholders::_1, m_DataCore, m_SlideCore,
+ m_SlideGraphCore, m_AnimationCore, m_ActionCore)));
+ m_Connections.push_back(theProvider->ConnectPropertyRemoved(std::bind(
+ CascadePropertyRemove, std::placeholders::_1,
+ std::placeholders::_2, m_SlideCore, m_SlideGraphCore, m_AnimationCore)));
+ m_Connections.push_back(theProvider->ConnectInstanceParentRemoved(std::bind(
+ CascadeInstanceParentRemoved, std::placeholders::_1,
+ std::placeholders::_2, m_DataCore, m_SlideCore, m_AnimationCore)));
+ ISlideCoreSignalProvider *theSlideCoreSignalProvider =
+ dynamic_cast<ISlideCoreSignalProvider *>(m_SlideCore.get());
+ m_Connections.push_back(theSlideCoreSignalProvider->ConnectBeforeSlideDeleted(
+ std::bind(CascadeSlideDelete, std::placeholders::_1, m_DataCore, m_SlideCore,
+ m_SlideGraphCore, m_AnimationCore, m_ActionCore)));
+ m_Connections.push_back(theSlideCoreSignalProvider->ConnectInstancePropertyValueRemoved(
+ std::bind(CascadeSlidePropertyRemove, std::placeholders::_1,
+ std::placeholders::_2, std::placeholders::_3, m_AnimationCore)));
+ IAnimationCoreSignalProvider *theAnimProvider =
+ dynamic_cast<IAnimationCoreSignalProvider *>(m_AnimationCore.get());
+ m_Connections.push_back(theAnimProvider->ConnectBeforeAnimationDeleted(
+ std::bind(CascadeBeforeAnimationDeleted, std::placeholders::_1,
+ m_AnimationCore, m_DataCore, m_SlideCore)));
+ m_Connections.push_back(theAnimProvider->ConnectBeforeKeyframeErased(
+ std::bind(CascadeBeforeKeyframeErased, std::placeholders::_1,
+ m_AnimationCore, m_DataCore, m_SlideCore)));
+ m_Connections.push_back(theAnimProvider->ConnectBeforeAllKeyframesErased(
+ std::bind(CascadeBeforeAnimationDeleted, std::placeholders::_1,
+ m_AnimationCore, m_DataCore, m_SlideCore)));
+}
+
+CStudioCoreSystem::~CStudioCoreSystem()
+{
+}
+
+std::shared_ptr<IDataCore> CStudioCoreSystem::GetDataCore()
+{
+ return m_DataCore;
+}
+std::shared_ptr<ISlideCore> CStudioCoreSystem::GetSlideCore()
+{
+ return m_SlideCore;
+}
+std::shared_ptr<ISlideGraphCore> CStudioCoreSystem::GetSlideGraphCore()
+{
+ return m_SlideGraphCore;
+}
+std::shared_ptr<IAnimationCore> CStudioCoreSystem::GetAnimationCore()
+{
+ return m_AnimationCore;
+}
+std::shared_ptr<IActionCore> CStudioCoreSystem::GetActionCore()
+{
+ return m_ActionCore;
+}
+std::shared_ptr<ICustomPropCore> CStudioCoreSystem::GetCustomPropCore()
+{
+ return m_CustomPropCore;
+}
+std::shared_ptr<IMetaData> CStudioCoreSystem::GetNewMetaData()
+{
+ return m_NewMetaData;
+}
+std::shared_ptr<IGuideSystem> CStudioCoreSystem::GetGuideSystem()
+{
+ return m_GuideSystem;
+}
+
+std::shared_ptr<IDataCore> CStudioCoreSystem::GetTransactionlessDataCore()
+{
+ return dynamic_cast<CDataCoreProducer *>(m_DataCore.get())->GetTransactionlessDataCore();
+}
+std::shared_ptr<ISlideCore> CStudioCoreSystem::GetTransactionlessSlideCore()
+{
+ return dynamic_cast<CSlideCoreProducer *>(m_SlideCore.get())->GetTransactionlessSlideCore();
+}
+std::shared_ptr<ISlideGraphCore> CStudioCoreSystem::GetTransactionlessSlideGraphCore()
+{
+ return dynamic_cast<CSlideGraphCoreProducer *>(m_SlideGraphCore.get())
+ ->GetTransactionlessSlideGraphCore();
+}
+std::shared_ptr<IAnimationCore> CStudioCoreSystem::GetTransactionlessAnimationCore()
+{
+ return dynamic_cast<CAnimationCoreProducer *>(m_AnimationCore.get())
+ ->GetTransactionlessAnimationCore();
+}
+std::shared_ptr<IActionCore> CStudioCoreSystem::GetTransactionlessActionCore()
+{
+ return dynamic_cast<CActionCoreProducer *>(m_ActionCore.get())->GetTransactionlessActionCore();
+}
+
+inline bool InstanceSpecificNameMatches(Qt3DSDMInstanceHandle inInstance,
+ Qt3DSDMPropertyHandle inProperty, const TCharStr &inName,
+ const CSimpleDataCore &inData)
+{
+ TPropertyHandleList theProperties;
+ inData.GetAggregateInstanceProperties(inInstance, theProperties);
+ SValue theValue;
+ if (exists(theProperties, std::bind(equal_to<int>(), inProperty, std::placeholders::_1))
+ && inData.GetSpecificInstancePropertyValue(inInstance, inProperty, theValue)) {
+ return inName == get<TDataStrPtr>(theValue)->GetData();
+ }
+ return false;
+}
+
+Qt3DSDMInstanceHandle CStudioCoreSystem::FindInstanceByName(Qt3DSDMPropertyHandle inNameProperty,
+ const TCharStr &inName) const
+{
+ TInstanceHandleList theInstances;
+ m_DataCore->GetInstances(theInstances);
+ TInstanceHandleList::iterator theFind = find_if<TInstanceHandleList::iterator>(
+ theInstances,
+ std::bind(InstanceSpecificNameMatches, std::placeholders::_1, inNameProperty, std::cref(inName),
+ std::cref(*dynamic_cast<CDataCoreProducer *>(m_DataCore.get())
+ ->GetTransactionlessDataCore())));
+ if (theFind != theInstances.end())
+ return *theFind;
+ return 0;
+}
+
+void CStudioCoreSystem::SetConsumer(TTransactionConsumerPtr inConsumer)
+{
+ DoSetConsumer(inConsumer, m_DataCore);
+ DoSetConsumer(inConsumer, m_SlideCore);
+ DoSetConsumer(inConsumer, m_SlideGraphCore);
+ DoSetConsumer(inConsumer, m_AnimationCore);
+ DoSetConsumer(inConsumer, m_ActionCore);
+ DoSetConsumer(inConsumer, m_GuideSystem);
+ // In general the meta data doesn't participate in the undo/redo system except
+ // in special cases.
+ if (!inConsumer)
+ DoSetConsumer(inConsumer, m_NewMetaData);
+}
+}
diff --git a/src/dm/systems/StudioCoreSystem.h b/src/dm/systems/StudioCoreSystem.h
new file mode 100644
index 0000000..18f1dad
--- /dev/null
+++ b/src/dm/systems/StudioCoreSystem.h
@@ -0,0 +1,94 @@
+/****************************************************************************
+**
+** 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 STUDIOCORESYSTEMH
+#define STUDIOCORESYSTEMH
+#include "Qt3DSDMTransactions.h"
+#include "Qt3DSDMHandles.h"
+
+namespace qt3dsdm {
+class IDataCore;
+class ISlideCore;
+class ISlideGraphCore;
+class IAnimationCore;
+class IActionCore;
+class ICustomPropCore;
+class ISignalConnection;
+class IMetaData;
+class IGuideSystem;
+
+// Manages cascading operations between cores so that the entire group of
+// cores stays up to date.
+class CStudioCoreSystem : public ITransactionProducer
+{
+ Q_DISABLE_COPY(CStudioCoreSystem)
+
+ TStringTablePtr m_StringTable;
+ std::shared_ptr<IDataCore> m_DataCore;
+ std::shared_ptr<ISlideCore> m_SlideCore;
+ std::shared_ptr<ISlideGraphCore> m_SlideGraphCore;
+ std::shared_ptr<IAnimationCore> m_AnimationCore;
+ std::shared_ptr<IActionCore> m_ActionCore;
+ std::shared_ptr<ICustomPropCore> m_CustomPropCore;
+ std::shared_ptr<IMetaData> m_NewMetaData;
+ std::shared_ptr<IGuideSystem> m_GuideSystem;
+
+ std::vector<std::shared_ptr<ISignalConnection>> m_Connections;
+
+public:
+ CStudioCoreSystem(TStringTablePtr strTable = TStringTablePtr());
+ virtual ~CStudioCoreSystem();
+ TStringTablePtr GetStringTablePtr() const { return m_StringTable; }
+
+ std::shared_ptr<IDataCore> GetDataCore();
+ std::shared_ptr<ISlideCore> GetSlideCore();
+ std::shared_ptr<ISlideGraphCore> GetSlideGraphCore();
+ std::shared_ptr<IAnimationCore> GetAnimationCore();
+ std::shared_ptr<IActionCore> GetActionCore();
+ std::shared_ptr<ICustomPropCore> GetCustomPropCore();
+ std::shared_ptr<IMetaData> GetNewMetaData();
+ std::shared_ptr<IGuideSystem> GetGuideSystem();
+
+ std::shared_ptr<IDataCore> GetTransactionlessDataCore();
+ std::shared_ptr<ISlideCore> GetTransactionlessSlideCore();
+ std::shared_ptr<ISlideGraphCore> GetTransactionlessSlideGraphCore();
+ std::shared_ptr<IAnimationCore> GetTransactionlessAnimationCore();
+ std::shared_ptr<IActionCore> GetTransactionlessActionCore();
+ std::shared_ptr<ICustomPropCore> GetTransactionlessCustomPropCore();
+
+ Qt3DSDMInstanceHandle FindInstanceByName(Qt3DSDMPropertyHandle inNameProperty,
+ const TCharStr &inName) const;
+
+ void SetConsumer(TTransactionConsumerPtr inConsumer) override;
+};
+
+typedef std::shared_ptr<CStudioCoreSystem> TStudioCoreSystemPtr;
+}
+
+#endif
diff --git a/src/dm/systems/StudioFullSystem.cpp b/src/dm/systems/StudioFullSystem.cpp
new file mode 100644
index 0000000..c98f8a8
--- /dev/null
+++ b/src/dm/systems/StudioFullSystem.cpp
@@ -0,0 +1,647 @@
+/****************************************************************************
+**
+** 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 "StudioFullSystem.h"
+#include "StudioCoreSystem.h"
+#include "StudioPropertySystem.h"
+#include "SlideSystem.h"
+#include "StudioAnimationSystem.h"
+#include "ActionSystem.h"
+#include "SignalsImpl.h"
+#include "SimpleDataCore.h"
+#include "SimpleSlideCore.h"
+#include "SimpleSlideGraphCore.h"
+#include "SimpleAnimationCore.h"
+#include "DataCoreProducer.h"
+#include "SlideCoreProducer.h"
+#include "SlideGraphCoreProducer.h"
+#include "ActionCoreProducer.h"
+
+using namespace std;
+
+namespace qt3dsdm {
+
+template <typename TDoTransaction, typename TUndoTransaction>
+inline void NotifyConsumer(TTransactionConsumerPtr inConsumer, TDoTransaction inDoNotification,
+ TUndoTransaction inUndoNotification)
+{
+ if (inConsumer) {
+ inConsumer->OnDoNotification(inDoNotification);
+ inConsumer->OnUndoNotification(inUndoNotification);
+ } else {
+ inDoNotification(); // No consumer, send notification right away
+ }
+}
+
+void NotifySlideCreated(TTransactionConsumerPtr &inConsumer,
+ IStudioFullSystemSignalSender *inSender, Qt3DSDMSlideHandle inSlide)
+{
+ NotifyConsumer(inConsumer,
+ bind(&IStudioFullSystemSignalSender::SendSlideCreated, inSender, inSlide),
+ bind(&IStudioFullSystemSignalSender::SendSlideDeleted, inSender, inSlide));
+}
+
+void NotifySlideDeleted(TTransactionConsumerPtr &inConsumer,
+ IStudioFullSystemSignalSender *inSender, Qt3DSDMSlideHandle inSlide)
+{
+ NotifyConsumer(inConsumer,
+ bind(&IStudioFullSystemSignalSender::SendSlideDeleted, inSender, inSlide),
+ bind(&IStudioFullSystemSignalSender::SendSlideCreated, inSender, inSlide));
+}
+
+void NotifySlideRearranged(TTransactionConsumerPtr &inConsumer,
+ IStudioFullSystemSignalSender *inSender, Qt3DSDMSlideHandle inSlide,
+ int inOldIndex, int inNewIndex)
+{
+ NotifyConsumer(inConsumer, bind(&IStudioFullSystemSignalSender::SendSlideRearranged, inSender,
+ inSlide, inOldIndex, inNewIndex),
+ bind(&IStudioFullSystemSignalSender::SendSlideRearranged, inSender, inSlide,
+ inNewIndex, inOldIndex));
+}
+
+void SendInstancePropertyValueChanged(TDataCorePtr inCore, IStudioFullSystemSignalSender *inSender,
+ Qt3DSDMInstanceHandle inInstance,
+ Qt3DSDMPropertyHandle inProperty)
+{
+ // Ignore when the instance is not an instance (undoing an add operation may create this, as
+ // transactions are run first and notifications second).
+ if (inCore->IsInstance(inInstance))
+ inSender->SendInstancePropertyValue(inInstance, inProperty);
+}
+
+void NotifyInstancePropertyChanged(TTransactionConsumerPtr &inConsumer, TDataCorePtr inCore,
+ IStudioFullSystemSignalSender *inSender,
+ Qt3DSDMInstanceHandle inInstance, Qt3DSDMPropertyHandle inProperty,
+ bool inIsAggregate)
+{
+ if (inConsumer) {
+ if (inIsAggregate == false) {
+ NotifyConsumer(
+ inConsumer,
+ bind(SendInstancePropertyValueChanged, inCore, inSender, inInstance, inProperty),
+ bind(SendInstancePropertyValueChanged, inCore, inSender, inInstance, inProperty));
+ }
+ } else {
+ SendInstancePropertyValueChanged(inCore, inSender, inInstance, inProperty);
+ }
+}
+
+void RunAnimations(IStudioFullSystemSignalSender *inSender, Qt3DSDMSlideHandle inMaster,
+ Qt3DSDMSlideHandle inSlide, TAnimationCorePtr inAnimationCore,
+ TDataCorePtr inDataCore, TTransactionConsumerPtr &inConsumer)
+{
+ TAnimationInfoList theAnimations;
+ inAnimationCore->GetAnimations(theAnimations, inMaster, inSlide);
+ size_t theEnd = theAnimations.size();
+ for (size_t theIndex = 0; theIndex < theEnd; ++theIndex) {
+ SAnimationInfo &theInfo(theAnimations[theIndex]);
+ NotifyInstancePropertyChanged(inConsumer, inDataCore, inSender, theInfo.m_Instance,
+ theInfo.m_Property, false);
+ }
+}
+
+void NotifyComponentSeconds(TTransactionConsumerPtr &inConsumer,
+ IStudioFullSystemSignalSender *inSender, Qt3DSDMSlideHandle inSlide,
+ TDataCorePtr inCore, TAnimationCorePtr inAnimationCore,
+ TStudioAnimationSystemPtr inAnimationSystem,
+ TSlideSystemPtr inSlideSystem)
+{
+ Qt3DSDMSlideHandle theMaster = inSlideSystem->GetMasterSlide(inSlide);
+ NotifyConsumer(inConsumer, bind(&IStudioFullSystemSignalSender::SendBeginComponentSeconds,
+ inSender, theMaster),
+ bind(&IStudioFullSystemSignalSender::SendComponentSeconds, inSender, theMaster));
+ RunAnimations(inSender, theMaster, inSlide, inAnimationCore, inCore, inConsumer);
+ dynamic_cast<CStudioAnimationSystem *>(inAnimationSystem.get())
+ ->ClearTemporaryAnimationValues();
+ NotifyConsumer(
+ inConsumer, bind(&IStudioFullSystemSignalSender::SendComponentSeconds, inSender, theMaster),
+ bind(&IStudioFullSystemSignalSender::SendBeginComponentSeconds, inSender, theMaster));
+}
+
+void NotifyPropertyLinked(TTransactionConsumerPtr &inConsumer, TDataCorePtr inCore,
+ IStudioFullSystemSignalSender *inSender, Qt3DSDMSlideHandle inMaster,
+ Qt3DSDMInstanceHandle inInstance, Qt3DSDMPropertyHandle inProperty,
+ bool inAggregate)
+{
+ if (inAggregate == false) {
+ NotifyConsumer(inConsumer, bind(&IStudioFullSystemSignalSender::SendPropertyLinked,
+ inSender, inMaster, inInstance, inProperty),
+ bind(&IStudioFullSystemSignalSender::SendPropertyUnlinked, inSender,
+ inMaster, inInstance, inProperty));
+ NotifyInstancePropertyChanged(inConsumer, inCore, inSender, inInstance, inProperty,
+ inAggregate);
+ }
+}
+
+void NotifyPropertyUnlinked(TTransactionConsumerPtr &inConsumer, TDataCorePtr inCore,
+ IStudioFullSystemSignalSender *inSender, Qt3DSDMSlideHandle inMaster,
+ Qt3DSDMInstanceHandle inInstance, Qt3DSDMPropertyHandle inProperty,
+ bool inAggregate)
+{
+ if (inAggregate == false) {
+ NotifyConsumer(inConsumer, bind(&IStudioFullSystemSignalSender::SendPropertyUnlinked,
+ inSender, inMaster, inInstance, inProperty),
+ bind(&IStudioFullSystemSignalSender::SendPropertyLinked, inSender, inMaster,
+ inInstance, inProperty));
+ NotifyInstancePropertyChanged(inConsumer, inCore, inSender, inInstance, inProperty,
+ inAggregate);
+ }
+}
+
+void NotifyActiveSlide(TTransactionConsumerPtr &inConsumer, TDataCorePtr inCore,
+ IStudioFullSystemSignalSender *inSender, Qt3DSDMSlideHandle inMaster,
+ int /*inIndex*/, Qt3DSDMSlideHandle inOldSlide, Qt3DSDMSlideHandle inNewSlide,
+ TAnimationCorePtr inAnimationCore, TSlideSystemPtr inSlideSystem)
+{
+ TInstancePropertyPairList thePropertyList;
+ inSlideSystem->GetUnionOfProperties(inOldSlide, inNewSlide, thePropertyList);
+ for (size_t idx = 0, end = thePropertyList.size(); idx < end; ++idx)
+ NotifyInstancePropertyChanged(inConsumer, inCore, inSender, thePropertyList[idx].first,
+ thePropertyList[idx].second, false);
+
+ RunAnimations(inSender, inMaster, inNewSlide, inAnimationCore, inCore, inConsumer);
+}
+
+void NotifyAnimationCreated(TTransactionConsumerPtr &inConsumer,
+ IStudioFullSystemSignalSender *inSender,
+ Qt3DSDMAnimationHandle inAnimation, Qt3DSDMInstanceHandle inInstance,
+ Qt3DSDMPropertyHandle inProperty, bool inIsAggregate)
+{
+ if (!inIsAggregate) {
+ NotifyConsumer(inConsumer, bind(&IStudioFullSystemSignalSender::SendAnimationCreated,
+ inSender, inAnimation, inInstance, inProperty),
+ bind(&IStudioFullSystemSignalSender::SendAnimationDeleted, inSender,
+ inAnimation, inInstance, inProperty));
+ }
+}
+
+void NotifyAnimationDeleted(TTransactionConsumerPtr &inConsumer, TDataCorePtr inCore,
+ IStudioFullSystemSignalSender *inSender,
+ Qt3DSDMAnimationHandle inAnimation, Qt3DSDMInstanceHandle inInstance,
+ Qt3DSDMPropertyHandle inProperty)
+{
+ NotifyConsumer(inConsumer, bind(&IStudioFullSystemSignalSender::SendAnimationDeleted, inSender,
+ inAnimation, inInstance, inProperty),
+ bind(&IStudioFullSystemSignalSender::SendAnimationCreated, inSender, inAnimation,
+ inInstance, inProperty));
+ NotifyInstancePropertyChanged(inConsumer, inCore, inSender, inInstance, inProperty, false);
+}
+
+void NotifyAnimationChanged(TTransactionConsumerPtr &inConsumer, TDataCorePtr inCore,
+ IStudioFullSystemSignalSender *inSender,
+ Qt3DSDMAnimationHandle inAnimation, TAnimationCorePtr inAnimationCore,
+ bool inIsAggregate)
+{
+ if (!inIsAggregate) {
+ SAnimationInfo theInfo(inAnimationCore->GetAnimationInfo(inAnimation));
+ NotifyInstancePropertyChanged(inConsumer, inCore, inSender, theInfo.m_Instance,
+ theInfo.m_Property, inIsAggregate);
+ }
+}
+
+void NotifyKeyframeInserted(TTransactionConsumerPtr &inConsumer, TDataCorePtr inCore,
+ IStudioFullSystemSignalSender *inSender,
+ Qt3DSDMAnimationHandle inAnimation, Qt3DSDMKeyframeHandle inKeyframe,
+ TAnimationCorePtr inAnimationCore, bool inIsAggregate)
+{
+ if (!inIsAggregate) {
+ NotifyConsumer(inConsumer, bind(&IStudioFullSystemSignalSender::SendKeyframeInserted,
+ inSender, inAnimation, inKeyframe),
+ bind(&IStudioFullSystemSignalSender::SendKeyframeErased, inSender,
+ inAnimation, inKeyframe));
+ NotifyAnimationChanged(inConsumer, inCore, inSender, inAnimation, inAnimationCore, false);
+ }
+}
+
+void NotifyKeyframeErased(TTransactionConsumerPtr &inConsumer, TDataCorePtr inCore,
+ IStudioFullSystemSignalSender *inSender,
+ Qt3DSDMAnimationHandle inAnimation, Qt3DSDMKeyframeHandle inKeyframe,
+ TAnimationCorePtr inAnimationCore)
+{
+ NotifyConsumer(inConsumer, bind(&IStudioFullSystemSignalSender::SendKeyframeErased, inSender,
+ inAnimation, inKeyframe),
+ bind(&IStudioFullSystemSignalSender::SendKeyframeInserted, inSender, inAnimation,
+ inKeyframe));
+ NotifyAnimationChanged(inConsumer, inCore, inSender, inAnimation, inAnimationCore, false);
+}
+
+void NotifyKeyframeUpdated(TTransactionConsumerPtr &inConsumer, TDataCorePtr inCore,
+ IStudioFullSystemSignalSender *inSender, Qt3DSDMKeyframeHandle inKeyframe,
+ TAnimationCorePtr inAnimationCore)
+{
+ NotifyConsumer(inConsumer,
+ bind(&IStudioFullSystemSignalSender::SendKeyframeUpdated, inSender, inKeyframe),
+ bind(&IStudioFullSystemSignalSender::SendKeyframeUpdated, inSender, inKeyframe));
+ Qt3DSDMAnimationHandle theAnimation(inAnimationCore->GetAnimationForKeyframe(inKeyframe));
+ NotifyAnimationChanged(inConsumer, inCore, inSender, theAnimation, inAnimationCore, false);
+}
+
+void NotifyConnectFirstKeyframeDynamicSet(TTransactionConsumerPtr &inConsumer, TDataCorePtr inCore,
+ IStudioFullSystemSignalSender *inSender,
+ Qt3DSDMAnimationHandle inAnimation, bool inDynamic,
+ TAnimationCorePtr inAnimationCore)
+{
+ NotifyConsumer(inConsumer,
+ bind(&IStudioFullSystemSignalSender::SendConnectFirstKeyframeDynamicSet,
+ inSender, inAnimation, inDynamic),
+ bind(&IStudioFullSystemSignalSender::SendConnectFirstKeyframeDynamicSet,
+ inSender, inAnimation, inDynamic));
+ NotifyAnimationChanged(inConsumer, inCore, inSender, inAnimation, inAnimationCore, false);
+}
+
+inline ISlideCoreSignalProvider *GetSlideSignaller(TSlideCorePtr inSlideCore)
+{
+ return dynamic_cast<CSlideCoreProducer *>(inSlideCore.get());
+}
+
+void NotifyInstanceCreated(TTransactionConsumerPtr &inConsumer,
+ IStudioFullSystemSignalSender *inSender, Qt3DSDMInstanceHandle instance)
+{
+ NotifyConsumer(inConsumer,
+ bind(&IStudioFullSystemSignalSender::SendInstanceCreated, inSender, instance),
+ bind(&IStudioFullSystemSignalSender::SendInstanceDeleted, inSender, instance));
+}
+
+void NotifyInstanceDeleted(TTransactionConsumerPtr &inConsumer,
+ IStudioFullSystemSignalSender *inSender, Qt3DSDMInstanceHandle instance)
+{
+ NotifyConsumer(inConsumer,
+ bind(&IStudioFullSystemSignalSender::SendInstanceDeleted, inSender, instance),
+ bind(&IStudioFullSystemSignalSender::SendInstanceCreated, inSender, instance));
+}
+
+void NotifyActionCreated(TTransactionConsumerPtr &inConsumer,
+ IStudioFullSystemSignalSender *inSender, Qt3DSDMActionHandle inAction,
+ Qt3DSDMSlideHandle inSlide, Qt3DSDMInstanceHandle inInstance)
+{
+ NotifyConsumer(inConsumer, bind(&IStudioFullSystemSignalSender::SendActionCreated, inSender,
+ inAction, inSlide, inInstance),
+ bind(&IStudioFullSystemSignalSender::SendActionDeleted, inSender, inAction,
+ inSlide, inInstance));
+}
+
+void NotifyActionDestroyed(TTransactionConsumerPtr &inConsumer,
+ IStudioFullSystemSignalSender *inSender, Qt3DSDMActionHandle inAction,
+ Qt3DSDMSlideHandle inSlide, Qt3DSDMInstanceHandle inInstance)
+{
+ NotifyConsumer(inConsumer, bind(&IStudioFullSystemSignalSender::SendActionDeleted, inSender,
+ inAction, inSlide, inInstance),
+ bind(&IStudioFullSystemSignalSender::SendActionCreated, inSender, inAction,
+ inSlide, inInstance));
+}
+
+void SendActionEvent(Qt3DSDMActionHandle inAction, TActionCorePtr inCore,
+ function<void()> inFunction)
+{
+ if (inCore->HandleValid(inAction))
+ inFunction();
+}
+
+void NotifyTriggerObjectSet(TTransactionConsumerPtr &inConsumer,
+ IStudioFullSystemSignalSender *inSender, Qt3DSDMActionHandle inAction,
+ TActionCorePtr inCore)
+{
+ function<void()> theFunc(
+ bind(&IStudioFullSystemSignalSender::SendTriggerObjectSet, inSender, inAction));
+ NotifyConsumer(inConsumer, bind(SendActionEvent, inAction, inCore, theFunc),
+ bind(SendActionEvent, inAction, inCore, theFunc));
+}
+
+void NotifyTargetObjectSet(TTransactionConsumerPtr &inConsumer,
+ IStudioFullSystemSignalSender *inSender, Qt3DSDMActionHandle inAction,
+ TActionCorePtr inCore)
+{
+ function<void()> theFunc(
+ bind(&IStudioFullSystemSignalSender::SendTargetObjectSet, inSender, inAction));
+ NotifyConsumer(inConsumer, bind(SendActionEvent, inAction, inCore, theFunc),
+ bind(SendActionEvent, inAction, inCore, theFunc));
+}
+
+void NotifyEventSet(TTransactionConsumerPtr &inConsumer, IStudioFullSystemSignalSender *inSender,
+ Qt3DSDMActionHandle inAction, TActionCorePtr inCore)
+{
+ function<void()> theFunc(
+ bind(&IStudioFullSystemSignalSender::SendEventSet, inSender, inAction));
+ NotifyConsumer(inConsumer, bind(SendActionEvent, inAction, inCore, theFunc),
+ bind(SendActionEvent, inAction, inCore, theFunc));
+}
+
+void NotifyHandlerSet(TTransactionConsumerPtr &inConsumer, IStudioFullSystemSignalSender *inSender,
+ Qt3DSDMActionHandle inAction, TActionCorePtr inCore)
+{
+ function<void()> theFunc(
+ bind(&IStudioFullSystemSignalSender::SendHandlerSet, inSender, inAction));
+ NotifyConsumer(inConsumer, bind(SendActionEvent, inAction, inCore, theFunc),
+ bind(SendActionEvent, inAction, inCore, theFunc));
+}
+
+void NotifyHandlerArgumentValueSet(TTransactionConsumerPtr &inConsumer,
+ IStudioFullSystemSignalSender *inSender,
+ Qt3DSDMHandlerArgHandle inAction, TActionCorePtr inCore)
+{
+ function<void()> theFunc(
+ bind(&IStudioFullSystemSignalSender::SendHandlerArgumentValueSet, inSender, inAction));
+ Qt3DSDMActionHandle theActionHdl(inCore->GetHandlerArgumentInfo(inAction).m_Action);
+ NotifyConsumer(inConsumer, bind(SendActionEvent, theActionHdl, inCore, theFunc),
+ bind(SendActionEvent, theActionHdl, inCore, theFunc));
+}
+
+void NotifyAllKeyframesErased(TTransactionConsumerPtr &inConsumer,
+ IStudioFullSystemSignalSender *inSender,
+ TAnimationCorePtr inAnimationCore, Qt3DSDMAnimationHandle inAnimation)
+{
+ if (inConsumer) {
+ TKeyframeHandleList theKeyframes;
+ inAnimationCore->GetKeyframes(inAnimation, theKeyframes);
+ for (size_t idx = 0, end = theKeyframes.size(); idx < end; ++idx) {
+ inConsumer->OnDoNotification(bind(&IStudioFullSystemSignalSender::SendKeyframeErased,
+ inSender, inAnimation, theKeyframes[idx]));
+ inConsumer->OnUndoNotification(
+ bind(&IStudioFullSystemSignalSender::SendKeyframeInserted, inSender, inAnimation,
+ theKeyframes[idx]));
+ }
+ }
+}
+
+CStudioFullSystem::CStudioFullSystem(std::shared_ptr<CStudioCoreSystem> inCoreSystem,
+ Qt3DSDMInstanceHandle inSlideInstance,
+ Qt3DSDMPropertyHandle inComponentGuidProperty,
+ Qt3DSDMInstanceHandle inActionInstance,
+ Qt3DSDMPropertyHandle inActionEyeball)
+ : m_CoreSystem(inCoreSystem)
+ , m_SlideSystem(new SSlideSystem(m_CoreSystem->GetDataCore(), m_CoreSystem->GetSlideCore(),
+ m_CoreSystem->GetSlideGraphCore(),
+ m_CoreSystem->GetAnimationCore(), inSlideInstance,
+ inComponentGuidProperty))
+ , m_ActionSystem(new CActionSystem(m_CoreSystem->GetDataCore(), m_CoreSystem->GetSlideCore(),
+ m_CoreSystem->GetSlideGraphCore(),
+ m_CoreSystem->GetActionCore(), m_SlideSystem,
+ inActionInstance, inActionEyeball))
+ , m_AggregateOperation(false)
+{
+ // TODO: Too many parameters passed in to the subsystem. Just make them know about FullSystem so
+ // they can get whatever they want
+ CStudioAnimationSystem *theAnimationSystem = new CStudioAnimationSystem(
+ m_PropertySystem, m_SlideSystem, m_CoreSystem->GetSlideCore(),
+ m_CoreSystem->GetSlideGraphCore(), m_CoreSystem->GetAnimationCore());
+ m_AnimationSystem = std::shared_ptr<qt3dsdm::IStudioAnimationSystem>(theAnimationSystem);
+
+ m_PropertySystem = std::shared_ptr<qt3dsdm::IPropertySystem>(
+ new CStudioPropertySystem(m_CoreSystem->GetNewMetaData(), m_CoreSystem->GetDataCore(),
+ m_SlideSystem, m_AnimationSystem));
+ theAnimationSystem->SetPropertySystem(m_PropertySystem);
+
+ TDataCorePtr dataCore(m_CoreSystem->GetDataCore());
+
+ static_cast<SSlideSystem *>(m_SlideSystem.get())->SetPropertySystem(m_PropertySystem);
+
+ ISlideSystemSignalProvider *theSlideSignaller =
+ dynamic_cast<SSlideSystem *>(m_SlideSystem.get())->GetSignalProvider();
+ m_Signaller = CreateStudioFullSystemSignaller(theSlideSignaller);
+ IStudioFullSystemSignalSender *theSystemSender =
+ dynamic_cast<IStudioFullSystemSignalSender *>(m_Signaller.get());
+ m_Connections.push_back(theSlideSignaller->ConnectSlideRearranged(
+ bind(NotifySlideRearranged, ref(m_Consumer), theSystemSender,
+ std::placeholders::_1,
+ std::placeholders::_2, std::placeholders::_3)));
+ m_Connections.push_back(theSlideSignaller->ConnectPropertyLinked(
+ bind(NotifyPropertyLinked, ref(m_Consumer), dataCore, theSystemSender,
+ std::placeholders::_1,
+ std::placeholders::_2, std::placeholders::_3,
+ std::cref(m_AggregateOperation))));
+ m_Connections.push_back(theSlideSignaller->ConnectPropertyUnlinked(
+ bind(NotifyPropertyUnlinked, ref(m_Consumer), dataCore, theSystemSender,
+ std::placeholders::_1,
+ std::placeholders::_2, std::placeholders::_3,
+ std::cref(m_AggregateOperation))));
+
+ m_Connections.push_back(theSlideSignaller->ConnectActiveSlide(
+ bind(NotifyActiveSlide, ref(m_Consumer), dataCore, theSystemSender,
+ std::placeholders::_1,
+ std::placeholders::_2, std::placeholders::_3, std::placeholders::_4,
+ GetAnimationCore(), GetSlideSystem())));
+
+ IDataCoreSignalProvider *theDataSignals =
+ dynamic_cast<IDataCoreSignalProvider *>(m_CoreSystem->GetDataCore().get());
+ m_Connections.push_back(theDataSignals->ConnectInstanceCreated(
+ bind(NotifyInstanceCreated, ref(m_Consumer), theSystemSender, std::placeholders::_1)));
+ m_Connections.push_back(theDataSignals->ConnectInstanceDeleted(
+ bind(NotifyInstanceDeleted, ref(m_Consumer), theSystemSender, std::placeholders::_1)));
+
+ ISlideCoreSignalProvider *theSlideCoreSignaller =
+ dynamic_cast<ISlideCoreSignalProvider *>(m_CoreSystem->GetSlideCore().get());
+ m_Connections.push_back(theSlideCoreSignaller->ConnectInstancePropertyValueSet(
+ bind(NotifyInstancePropertyChanged, ref(m_Consumer), dataCore, theSystemSender,
+ std::placeholders::_2, std::placeholders::_3,
+ std::cref(m_AggregateOperation))));
+ m_Connections.push_back(theSlideCoreSignaller->ConnectSlideTimeChanged(
+ bind(NotifyComponentSeconds, ref(m_Consumer), theSystemSender, std::placeholders::_1,
+ dataCore, GetAnimationCore(), GetAnimationSystem(), GetSlideSystem())));
+ m_Connections.push_back(theSlideCoreSignaller->ConnectSlideCreated(
+ bind(NotifySlideCreated, ref(m_Consumer), theSystemSender, std::placeholders::_1)));
+ m_Connections.push_back(theSlideCoreSignaller->ConnectSlideDeleted(
+ bind(NotifySlideDeleted, ref(m_Consumer), theSystemSender, std::placeholders::_1)));
+
+ IAnimationCoreSignalProvider *theAnimationSignals =
+ dynamic_cast<IAnimationCoreSignalProvider *>(GetAnimationCore().get());
+ m_Connections.push_back(theAnimationSignals->ConnectAnimationCreated(
+ bind(NotifyAnimationCreated, ref(m_Consumer), theSystemSender,
+ std::placeholders::_1, std::placeholders::_3, std::placeholders::_4,
+ std::cref(m_AggregateOperation))));
+ m_Connections.push_back(theAnimationSignals->ConnectAnimationDeleted(
+ bind(NotifyAnimationDeleted, ref(m_Consumer), dataCore, theSystemSender,
+ std::placeholders::_1, std::placeholders::_3, std::placeholders::_4)));
+ m_Connections.push_back(theAnimationSignals->ConnectKeyframeInserted(
+ bind(NotifyKeyframeInserted, ref(m_Consumer), dataCore, theSystemSender,
+ std::placeholders::_1, std::placeholders::_2,
+ GetAnimationCore(), std::cref(m_AggregateOperation))));
+ m_Connections.push_back(theAnimationSignals->ConnectKeyframeErased(
+ bind(NotifyKeyframeErased, ref(m_Consumer), dataCore, theSystemSender,
+ std::placeholders::_1, std::placeholders::_2,
+ GetAnimationCore())));
+ m_Connections.push_back(theAnimationSignals->ConnectKeyframeUpdated(
+ bind(NotifyKeyframeUpdated, ref(m_Consumer), dataCore, theSystemSender,
+ std::placeholders::_1, GetAnimationCore())));
+ m_Connections.push_back(theAnimationSignals->ConnectFirstKeyframeDynamicSet(
+ bind(NotifyConnectFirstKeyframeDynamicSet, ref(m_Consumer), dataCore,
+ theSystemSender, std::placeholders::_1,
+ std::placeholders::_2, GetAnimationCore())));
+ m_Connections.push_back(theAnimationSignals->ConnectBeforeAllKeyframesErased(
+ bind(NotifyAllKeyframesErased, ref(m_Consumer), theSystemSender,
+ GetAnimationCore(), std::placeholders::_1)));
+
+ IInstancePropertyCoreSignalProvider *thePropertyCoreSignaller =
+ dynamic_cast<CStudioPropertySystem *>(m_PropertySystem.get())
+ ->GetPropertyCoreSignalProvider();
+ m_Connections.push_back(thePropertyCoreSignaller->ConnectInstancePropertyValue(
+ bind(NotifyInstancePropertyChanged, ref(m_Consumer), dataCore, theSystemSender,
+ std::placeholders::_1, std::placeholders::_2, std::cref(m_AggregateOperation))));
+
+ thePropertyCoreSignaller = dynamic_cast<CStudioPropertySystem *>(m_PropertySystem.get())
+ ->GetImmediatePropertyCoreSignalProvider();
+ m_Connections.push_back(thePropertyCoreSignaller->ConnectInstancePropertyValue(
+ bind(&IStudioFullSystemSignalSender::SendInstancePropertyValue, theSystemSender,
+ std::placeholders::_1, std::placeholders::_2)));
+
+ thePropertyCoreSignaller =
+ dynamic_cast<IInstancePropertyCoreSignalProvider *>(m_CoreSystem->GetDataCore().get());
+ m_Connections.push_back(thePropertyCoreSignaller->ConnectInstancePropertyValue(
+ bind(NotifyInstancePropertyChanged, ref(m_Consumer), dataCore, theSystemSender,
+ std::placeholders::_1, std::placeholders::_2, std::cref(m_AggregateOperation))));
+
+ IActionCoreSignalProvider *theActionSignals =
+ dynamic_cast<IActionCoreSignalProvider *>(m_CoreSystem->GetActionCore().get());
+ m_Connections.push_back(theActionSignals->ConnectTriggerObjectSet(
+ bind(NotifyTriggerObjectSet, ref(m_Consumer), theSystemSender,
+ std::placeholders::_1, GetActionCore())));
+ m_Connections.push_back(theActionSignals->ConnectTargetObjectSet(
+ bind(NotifyTargetObjectSet, ref(m_Consumer), theSystemSender,
+ std::placeholders::_1, GetActionCore())));
+ m_Connections.push_back(theActionSignals->ConnectEventSet(
+ bind(NotifyEventSet, ref(m_Consumer), theSystemSender,
+ std::placeholders::_1, GetActionCore())));
+ m_Connections.push_back(theActionSignals->ConnectHandlerSet(
+ bind(NotifyHandlerSet, ref(m_Consumer), theSystemSender,
+ std::placeholders::_1, GetActionCore())));
+ m_Connections.push_back(theActionSignals->ConnectHandlerArgumentValueSet(bind(
+ NotifyHandlerArgumentValueSet, ref(m_Consumer), theSystemSender,
+ std::placeholders::_1, GetActionCore())));
+
+ IActionSystemSignalProvider *theActionSystemSignals =
+ dynamic_cast<CActionSystem *>(m_ActionSystem.get())->GetSignalProvider();
+ m_Connections.push_back(theActionSystemSignals->ConnectActionCreated(
+ bind(NotifyActionCreated, ref(m_Consumer), theSystemSender,
+ std::placeholders::_1, std::placeholders::_2, std::placeholders::_3)));
+ m_Connections.push_back(theActionSystemSignals->ConnectActionDeleted(
+ bind(NotifyActionDestroyed, ref(m_Consumer), theSystemSender,
+ std::placeholders::_1, std::placeholders::_2, std::placeholders::_3)));
+}
+
+CStudioFullSystem::~CStudioFullSystem()
+{
+}
+
+std::shared_ptr<IPropertySystem> CStudioFullSystem::GetPropertySystem()
+{
+ return m_PropertySystem;
+}
+std::shared_ptr<ISlideSystem> CStudioFullSystem::GetSlideSystem()
+{
+ return m_SlideSystem;
+}
+std::shared_ptr<ISlideCore> CStudioFullSystem::GetSlideCore()
+{
+ return m_CoreSystem->GetSlideCore();
+}
+std::shared_ptr<IAnimationCore> CStudioFullSystem::GetAnimationCore()
+{
+ return m_CoreSystem->GetAnimationCore();
+}
+std::shared_ptr<IStudioAnimationSystem> CStudioFullSystem::GetAnimationSystem()
+{
+ return m_AnimationSystem;
+}
+std::shared_ptr<IActionCore> CStudioFullSystem::GetActionCore()
+{
+ return m_CoreSystem->GetActionCore();
+}
+std::shared_ptr<IActionSystem> CStudioFullSystem::GetActionSystem()
+{
+ return m_ActionSystem;
+}
+
+std::shared_ptr<IPropertySystem> CStudioFullSystem::GetPropertySystem() const
+{
+ return m_PropertySystem;
+}
+std::shared_ptr<ISlideSystem> CStudioFullSystem::GetSlideSystem() const
+{
+ return m_SlideSystem;
+}
+std::shared_ptr<ISlideCore> CStudioFullSystem::GetSlideCore() const
+{
+ return m_CoreSystem->GetSlideCore();
+}
+std::shared_ptr<IAnimationCore> CStudioFullSystem::GetAnimationCore() const
+{
+ return m_CoreSystem->GetAnimationCore();
+}
+std::shared_ptr<IStudioAnimationSystem> CStudioFullSystem::GetAnimationSystem() const
+{
+ return m_AnimationSystem;
+}
+std::shared_ptr<IActionCore> CStudioFullSystem::GetActionCore() const
+{
+ return m_CoreSystem->GetActionCore();
+}
+std::shared_ptr<IActionSystem> CStudioFullSystem::GetActionSystem() const
+{
+ return m_ActionSystem;
+}
+
+std::shared_ptr<CStudioCoreSystem> CStudioFullSystem::GetCoreSystem()
+{
+ return m_CoreSystem;
+}
+
+bool CStudioFullSystem::GetCanonicalInstancePropertyValue(Qt3DSDMInstanceHandle inInstance,
+ Qt3DSDMPropertyHandle inProperty,
+ SValue &outValue) const
+{
+ SValue theTemp;
+ bool retval = dynamic_cast<const CStudioPropertySystem *>(m_PropertySystem.get())
+ ->GetCanonicalInstancePropertyValue(inInstance, inProperty, theTemp);
+ if (retval)
+ outValue = theTemp.toOldSkool();
+ return retval;
+}
+
+Qt3DSDMInstanceHandle CStudioFullSystem::FindInstanceByName(Qt3DSDMPropertyHandle inNameProperty,
+ const TCharStr &inName) const
+{
+ return m_CoreSystem->FindInstanceByName(inNameProperty, inName);
+}
+
+void CStudioFullSystem::SetConsumer(TTransactionConsumerPtr inConsumer)
+{
+ m_CoreSystem->SetConsumer(inConsumer);
+ DoSetConsumer(inConsumer, m_AnimationSystem);
+ m_Consumer = inConsumer;
+}
+
+IStudioFullSystemSignalProvider *CStudioFullSystem::GetSignalProvider()
+{
+ return dynamic_cast<IStudioFullSystemSignalProvider *>(m_Signaller.get());
+}
+
+IStudioFullSystemSignalSender *CStudioFullSystem::GetSignalSender()
+{
+ return dynamic_cast<IStudioFullSystemSignalSender *>(m_Signaller.get());
+}
+}
diff --git a/src/dm/systems/StudioFullSystem.h b/src/dm/systems/StudioFullSystem.h
new file mode 100644
index 0000000..9411e78
--- /dev/null
+++ b/src/dm/systems/StudioFullSystem.h
@@ -0,0 +1,164 @@
+/****************************************************************************
+**
+** 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 STUDIOFULLSYSTEMH
+#define STUDIOFULLSYSTEMH
+#include "Qt3DSDMTransactions.h"
+#include "Qt3DSDMHandles.h"
+#include "Qt3DSDMSignals.h"
+#include "Qt3DSDMDataTypes.h"
+
+namespace qt3dsdm {
+class IPropertySystem;
+class ISlideSystem;
+class IStudioAnimationSystem;
+class CStudioCoreSystem;
+class IInstancePropertyCore;
+class INotificationEngine;
+class IAnimationCore;
+class IActionCore;
+class ISlideCore;
+class IActionSystem;
+class ISignalConnection;
+
+class IStudioFullSystemSerializeHelper
+{
+public:
+ virtual ~IStudioFullSystemSerializeHelper() {}
+ /**
+ * Given an instance, set the name if possible. Called for parents of existing instances
+ * so we can find instances by name later. There is an implicit assumption for partial
+ * serialization that none of the instances that are serialized out are base instances
+ * for other serialized instances. There is another implicit assumption that the system
+ * can name any instances used a base.
+ */
+ virtual bool GetInstanceName(Qt3DSDMInstanceHandle inInstance, TCharStr &outName) = 0;
+};
+
+typedef std::shared_ptr<IStudioFullSystemSerializeHelper> TStudioFullSystemSerializeHelperPtr;
+
+// The full studio system needs extra information in the deserialize stage. This information
+// requires knowledge of the larger studio universe in order to work and thus clients need to
+// pass in an interface.
+class IStudioFullSystemDeserializeHelper
+{
+public:
+ virtual ~IStudioFullSystemDeserializeHelper() {}
+ /**
+ * Return an instance by name. Whatever method was used above to name instances
+ * should be used to find a given instance by name.
+ */
+ virtual Qt3DSDMInstanceHandle FindInstanceByName(const TCharStr &inName) = 0;
+ /**
+ * Translate a given guid. For pass 1, you should only translate ids and just return identity
+ * for anything that isn't an id.
+ */
+ virtual void TranslateGuidPass1(Qt3DSDMPropertyHandle inProperty, SLong4 inValue) = 0;
+ /**
+ * Now translate guids that are used as data variables. These are links to other objects and
+ *the GUID
+ * information should come from what was created in pass 1.
+ */
+ virtual SLong4 TranslateGuidPass2(Qt3DSDMInstanceHandle inInstance,
+ Qt3DSDMPropertyHandle inProperty, SLong4 inValue) = 0;
+};
+
+typedef std::shared_ptr<IStudioFullSystemDeserializeHelper> TStudioFullSystemDeserializeHelperPtr;
+
+class CStudioFullSystem : public ITransactionProducer
+{
+ Q_DISABLE_COPY(CStudioFullSystem)
+
+ // Base that the other types are built upon
+ std::shared_ptr<CStudioCoreSystem> m_CoreSystem;
+
+ // The data model exposed to studio
+ std::shared_ptr<IPropertySystem> m_PropertySystem;
+ std::shared_ptr<ISlideSystem> m_SlideSystem;
+ std::shared_ptr<IStudioAnimationSystem> m_AnimationSystem;
+ std::shared_ptr<IActionSystem> m_ActionSystem;
+
+ std::vector<std::shared_ptr<ISignalConnection>> m_Connections;
+
+ TTransactionConsumerPtr m_Consumer;
+ TSignalItemPtr m_Signaller;
+ bool m_AggregateOperation;
+
+public:
+ CStudioFullSystem(std::shared_ptr<CStudioCoreSystem> inCoreSystem,
+ Qt3DSDMInstanceHandle inSlideInstance,
+ Qt3DSDMPropertyHandle inComponentGuidProperty,
+ Qt3DSDMInstanceHandle inActionInstance, Qt3DSDMPropertyHandle inActionEyeball);
+ virtual ~CStudioFullSystem();
+
+ void BeginAggregateOperation() { m_AggregateOperation = true; }
+ void EndAggregateOperation() { m_AggregateOperation = false; }
+
+ std::shared_ptr<IPropertySystem> GetPropertySystem();
+ std::shared_ptr<ISlideSystem> GetSlideSystem();
+ std::shared_ptr<ISlideCore> GetSlideCore();
+ std::shared_ptr<IAnimationCore> GetAnimationCore();
+ std::shared_ptr<IStudioAnimationSystem> GetAnimationSystem();
+ std::shared_ptr<IActionCore> GetActionCore();
+ std::shared_ptr<IActionSystem> GetActionSystem();
+
+ std::shared_ptr<IPropertySystem> GetPropertySystem() const;
+ std::shared_ptr<ISlideSystem> GetSlideSystem() const;
+ std::shared_ptr<ISlideCore> GetSlideCore() const;
+ std::shared_ptr<IAnimationCore> GetAnimationCore() const;
+ std::shared_ptr<IStudioAnimationSystem> GetAnimationSystem() const;
+ std::shared_ptr<IActionCore> GetActionCore() const;
+ std::shared_ptr<IActionSystem> GetActionSystem() const;
+
+ // Don't use this unless you are a test harness or some other more-knowledgeable-than-ordinary
+ // entity.
+ std::shared_ptr<CStudioCoreSystem> GetCoreSystem();
+
+ // Ignoring animation and the currently active slide, get the canonical instance property value
+ // for this instance.
+ bool GetCanonicalInstancePropertyValue(Qt3DSDMInstanceHandle inInstance,
+ Qt3DSDMPropertyHandle inProperty, SValue &outValue) const;
+ Qt3DSDMInstanceHandle FindInstanceByName(Qt3DSDMPropertyHandle inNameProperty,
+ const TCharStr &inName) const;
+
+ void SetConsumer(TTransactionConsumerPtr inConsumer) override;
+ TTransactionConsumerPtr GetConsumer() { return m_Consumer; }
+
+ // This signal provider sends signals during undo/redo and during
+ // animation runs.
+ IStudioFullSystemSignalProvider *GetSignalProvider();
+
+ // Return the signal sender so that we can activate/deactivate signals
+ IStudioFullSystemSignalSender *GetSignalSender();
+};
+
+typedef std::shared_ptr<CStudioFullSystem> TStudioFullSystemPtr;
+}
+
+#endif
diff --git a/src/dm/systems/StudioPropertySystem.cpp b/src/dm/systems/StudioPropertySystem.cpp
new file mode 100644
index 0000000..78fabc6
--- /dev/null
+++ b/src/dm/systems/StudioPropertySystem.cpp
@@ -0,0 +1,233 @@
+/****************************************************************************
+**
+** 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 "StudioPropertySystem.h"
+#include "StudioAnimationSystem.h"
+#include "SignalsImpl.h"
+
+using namespace std;
+
+namespace qt3dsdm {
+
+CStudioPropertySystem::CStudioPropertySystem(std::shared_ptr<IMetaData> inMetaData,
+ TDataCorePtr inDataCore, TSlideSystemPtr inSlideSystem,
+ TStudioAnimationSystemPtr inStudioAnimationSystem)
+ : m_MetaData(inMetaData)
+ , m_DataCore(inDataCore)
+ , m_SlideSystem(inSlideSystem)
+ , m_StudioAnimationSystem(inStudioAnimationSystem)
+{
+ m_PropertyCoreSignaller = CreatePropertyCoreSignaller();
+ m_ImmediateModePropertyCoreSignaller = CreatePropertyCoreSignaller();
+}
+
+DataModelDataType::Value CStudioPropertySystem::GetDataType(Qt3DSDMPropertyHandle inProperty) const
+{
+ if (m_DataCore->IsProperty(inProperty))
+ return m_DataCore->GetProperty(inProperty).m_Type;
+ return DataModelDataType::None;
+}
+
+TCharStr CStudioPropertySystem::GetName(Qt3DSDMPropertyHandle inProperty) const
+{
+ if (m_DataCore->IsProperty(inProperty))
+ return m_DataCore->GetProperty(inProperty).m_Name;
+ return TCharStr();
+}
+
+TCharStr CStudioPropertySystem::GetFormalName(Qt3DSDMInstanceHandle inInstance,
+ Qt3DSDMPropertyHandle inProperty) const
+{
+ if (inInstance.Valid() && inProperty.Valid())
+ return m_MetaData->GetFormalName(inInstance, inProperty);
+ return TCharStr();
+}
+
+AdditionalMetaDataType::Value
+CStudioPropertySystem::GetAdditionalMetaDataType(Qt3DSDMInstanceHandle inInstance,
+ Qt3DSDMPropertyHandle inProperty) const
+{
+ return m_MetaData->GetAdditionalMetaDataType(inInstance, inProperty);
+}
+
+TMetaDataData
+CStudioPropertySystem::GetAdditionalMetaDataData(Qt3DSDMInstanceHandle inInstance,
+ Qt3DSDMPropertyHandle inProperty) const
+{
+ return m_MetaData->GetAdditionalMetaDataData(inInstance, inProperty);
+}
+
+Qt3DSDMInstanceHandle CStudioPropertySystem::GetPropertyOwner(Qt3DSDMPropertyHandle inProperty) const
+{
+
+ qt3dsdm::Qt3DSDMPropertyDefinition thePropDef = m_DataCore->GetProperty(inProperty);
+ return thePropDef.m_Instance;
+}
+
+Qt3DSDMPropertyHandle
+CStudioPropertySystem::GetAggregateInstancePropertyByName(Qt3DSDMInstanceHandle inInstance,
+ const TCharStr &inStr) const
+{
+ return m_DataCore->GetAggregateInstancePropertyByName(inInstance, inStr);
+}
+
+void CStudioPropertySystem::GetAggregateInstanceProperties(Qt3DSDMInstanceHandle inInstance,
+ TPropertyHandleList &outProperties) const
+{
+ m_DataCore->GetAggregateInstanceProperties(inInstance, outProperties);
+}
+
+bool CStudioPropertySystem::HasAggregateInstanceProperty(Qt3DSDMInstanceHandle inInstance,
+ Qt3DSDMPropertyHandle inProperty) const
+{
+ return m_DataCore->HasAggregateInstanceProperty(inInstance, inProperty);
+}
+
+bool ApplyValueAndReturnTrue(const SValue &inValue, SValue &outValue)
+{
+ outValue = inValue;
+ return true;
+}
+
+bool CStudioPropertySystem::GetInstancePropertyValue(Qt3DSDMInstanceHandle inInstance,
+ Qt3DSDMPropertyHandle inProperty,
+ SValue &outValue) const
+{
+ if (!m_DataCore->IsInstance(inInstance))
+ return false;
+ if (!m_DataCore->IsProperty(inProperty))
+ return false;
+
+ Qt3DSDMSlideHandle theAnimationSlide;
+ theAnimationSlide = m_SlideSystem->GetApplicableSlide(inInstance, inProperty);
+ SValue theTemp;
+ bool retval = SetDefault(GetDataType(inProperty), theTemp);
+ if (retval && theAnimationSlide.Valid()
+ && m_StudioAnimationSystem->GetAnimatedInstancePropertyValue(theAnimationSlide, inInstance,
+ inProperty, theTemp))
+ return ApplyValueAndReturnTrue(theTemp, outValue);
+ if (theAnimationSlide.Valid()
+ && m_SlideSystem->GetInstancePropertyValue(theAnimationSlide, inInstance, inProperty,
+ theTemp))
+ return ApplyValueAndReturnTrue(theTemp, outValue);
+ return m_DataCore->GetInstancePropertyValue(inInstance, inProperty, outValue);
+}
+
+void CStudioPropertySystem::SetInstancePropertyValue(Qt3DSDMInstanceHandle inInstance,
+ Qt3DSDMPropertyHandle inProperty,
+ const SValue &inValue)
+{
+ m_DataCore->CheckValue(inInstance, inProperty, inValue);
+
+ Qt3DSDMSlideHandle theApplicableSlide;
+ theApplicableSlide = m_SlideSystem->GetApplicableSlide(inInstance, inProperty);
+ if (theApplicableSlide.Valid()) {
+ if (!m_StudioAnimationSystem->SetAnimatedInstancePropertyValue(
+ theApplicableSlide, inInstance, inProperty, inValue.toOldSkool())) {
+ // Force set on slide where item exists as it doesn't exist on the root.
+ m_SlideSystem->ForceSetInstancePropertyValue(theApplicableSlide, inInstance, inProperty,
+ inValue.toOldSkool());
+ }
+ } else {
+ m_DataCore->SetInstancePropertyValue(inInstance, inProperty, inValue);
+ }
+}
+
+Qt3DSDMInstanceHandle CStudioPropertySystem::CreateInstance()
+{
+ return m_DataCore->CreateInstance();
+}
+
+void CStudioPropertySystem::GetInstances(TInstanceHandleList &outInstances) const
+{
+ m_DataCore->GetInstances(outInstances);
+}
+
+void CStudioPropertySystem::DeleteInstance(Qt3DSDMInstanceHandle inHandle)
+{
+ m_DataCore->DeleteInstance(inHandle);
+}
+
+void CStudioPropertySystem::DeriveInstance(Qt3DSDMInstanceHandle inInstance,
+ Qt3DSDMInstanceHandle inParent)
+{
+ m_DataCore->DeriveInstance(inInstance, inParent);
+}
+
+bool CStudioPropertySystem::IsInstanceOrDerivedFrom(Qt3DSDMInstanceHandle inInstance,
+ Qt3DSDMInstanceHandle inParent) const
+{
+ return m_DataCore->IsInstanceOrDerivedFrom(inInstance, inParent);
+}
+
+QVector<Qt3DSDMPropertyHandle>
+CStudioPropertySystem::GetControllableProperties(Qt3DSDMInstanceHandle inInst) const
+{
+ vector<Qt3DSDMMetaDataPropertyHandle> propList;
+ QVector<Qt3DSDMPropertyHandle> outList;
+ m_MetaData->GetMetaDataProperties(inInst, propList);
+
+ for (const auto it : qAsConst(propList)) {
+ auto metadata = m_MetaData->GetMetaDataPropertyInfo(it).getValue();
+
+ if ((metadata.m_Controllable
+ || (metadata.m_Animatable
+ && m_StudioAnimationSystem->IsPropertyAnimatable(inInst, metadata.m_Property)))
+ && !metadata.m_IsHidden) {
+ outList.append(metadata.m_Property);
+ }
+ }
+ return outList;
+}
+
+Qt3DSDMPropertyHandle CStudioPropertySystem::AddProperty(Qt3DSDMInstanceHandle inInstance,
+ TCharPtr inName,
+ DataModelDataType::Value inPropType)
+{
+ return m_DataCore->AddProperty(inInstance, inName, inPropType);
+}
+
+bool CStudioPropertySystem::HandleValid(int inHandle) const
+{
+ return m_DataCore->HandleValid(inHandle);
+}
+
+bool CStudioPropertySystem::GetCanonicalInstancePropertyValue(Qt3DSDMInstanceHandle inInstance,
+ Qt3DSDMPropertyHandle inProperty,
+ SValue &outValue) const
+{
+ SValue theTempValue;
+ if (m_SlideSystem->GetCanonicalInstancePropertyValue(inInstance, inProperty, theTempValue)) {
+ outValue = SValue(theTempValue);
+ return true;
+ }
+ return m_DataCore->GetInstancePropertyValue(inInstance, inProperty, outValue);
+}
+}
diff --git a/src/dm/systems/StudioPropertySystem.h b/src/dm/systems/StudioPropertySystem.h
new file mode 100644
index 0000000..67abcf9
--- /dev/null
+++ b/src/dm/systems/StudioPropertySystem.h
@@ -0,0 +1,132 @@
+/****************************************************************************
+**
+** 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 INSTANCEPROPERTYCORESYSTEMH
+#define INSTANCEPROPERTYCORESYSTEMH
+
+#include "Qt3DSDMSlides.h"
+#include "Qt3DSDMAnimation.h"
+#include "Qt3DSDMSignals.h"
+#include "Qt3DSDMDataCore.h"
+
+namespace qt3dsdm {
+
+typedef std::tuple<Qt3DSDMInstanceHandle, Qt3DSDMPropertyHandle, SValue> TTemporaryPropertyValue;
+typedef std::vector<TTemporaryPropertyValue> TTemporaryPropertyValueList;
+
+/**
+ * Get/set instance properties taking the slide and slide graph, and animation systems into
+ *account.
+ * Also takes care of notifying external entities when a property changes.
+ */
+class CStudioPropertySystem : public IPropertySystem
+{
+ std::shared_ptr<IMetaData> m_MetaData;
+ TDataCorePtr m_DataCore;
+
+ TSlideSystemPtr m_SlideSystem;
+ TStudioAnimationSystemPtr m_StudioAnimationSystem;
+
+ TSignalItemPtr m_PropertyCoreSignaller;
+ TSignalItemPtr m_ImmediateModePropertyCoreSignaller;
+
+public:
+ CStudioPropertySystem(std::shared_ptr<IMetaData> inMetaData, TDataCorePtr inDataCore,
+ TSlideSystemPtr inSlideSystem,
+ TStudioAnimationSystemPtr inStudioAnimationSystem);
+
+ IInstancePropertyCoreSignalProvider *GetPropertyCoreSignalProvider()
+ {
+ return dynamic_cast<IInstancePropertyCoreSignalProvider *>(m_PropertyCoreSignaller.get());
+ }
+ // The immediate signaller is used before changes have been committed for very live feedback.
+ IInstancePropertyCoreSignalProvider *GetImmediatePropertyCoreSignalProvider()
+ {
+ return dynamic_cast<IInstancePropertyCoreSignalProvider *>(
+ m_ImmediateModePropertyCoreSignaller.get());
+ }
+
+ IInstancePropertyCoreSignalSender *GetPropertyCoreSignalSender()
+ {
+ return dynamic_cast<IInstancePropertyCoreSignalSender *>(m_PropertyCoreSignaller.get());
+ }
+
+ DataModelDataType::Value GetDataType(Qt3DSDMPropertyHandle inProperty) const override;
+ TCharStr GetName(Qt3DSDMPropertyHandle inProperty) const override;
+ TCharStr GetFormalName(Qt3DSDMInstanceHandle inInstance,
+ Qt3DSDMPropertyHandle inProperty) const override;
+ virtual AdditionalMetaDataType::Value
+ GetAdditionalMetaDataType(Qt3DSDMInstanceHandle inInstance,
+ Qt3DSDMPropertyHandle inProperty) const override;
+ TMetaDataData GetAdditionalMetaDataData(Qt3DSDMInstanceHandle inInstance,
+ Qt3DSDMPropertyHandle inProperty) const override;
+ Qt3DSDMInstanceHandle GetPropertyOwner(Qt3DSDMPropertyHandle inProperty) const override;
+
+ Qt3DSDMPropertyHandle GetAggregateInstancePropertyByName(Qt3DSDMInstanceHandle inInstance,
+ const TCharStr &inStr) const override;
+ void GetAggregateInstanceProperties(Qt3DSDMInstanceHandle inInstance,
+ TPropertyHandleList &outProperties) const override;
+ bool HasAggregateInstanceProperty(Qt3DSDMInstanceHandle inInstance,
+ Qt3DSDMPropertyHandle inProperty) const override;
+
+ bool GetInstancePropertyValue(Qt3DSDMInstanceHandle inInstance,
+ Qt3DSDMPropertyHandle inProperty, SValue &outValue) const override;
+ void SetInstancePropertyValue(Qt3DSDMInstanceHandle inInstance,
+ Qt3DSDMPropertyHandle inProperty, const SValue &inValue) override;
+
+ Qt3DSDMInstanceHandle CreateInstance() override;
+ void GetInstances(TInstanceHandleList &outInstances) const override;
+ void DeleteInstance(Qt3DSDMInstanceHandle inHandle) override;
+
+ void DeriveInstance(Qt3DSDMInstanceHandle inInstance, Qt3DSDMInstanceHandle inParent) override;
+ bool IsInstanceOrDerivedFrom(Qt3DSDMInstanceHandle inInstance,
+ Qt3DSDMInstanceHandle inParent) const override;
+
+ Qt3DSDMPropertyHandle AddProperty(Qt3DSDMInstanceHandle inInstance, TCharPtr inName,
+ DataModelDataType::Value inPropType) override;
+ bool HandleValid(int inHandle) const override;
+
+ // Get the instance property value from the slide that owns the instance or the data core if the
+ // slide doesn't have the value
+ bool GetCanonicalInstancePropertyValue(Qt3DSDMInstanceHandle inInstance,
+ Qt3DSDMPropertyHandle inProperty, SValue &outValue) const;
+
+ QVector<Qt3DSDMPropertyHandle> GetControllableProperties(
+ Qt3DSDMInstanceHandle inInst) const override;
+
+private:
+ static bool DerivedGuidMatches(qt3dsdm::IDataCore &inDataCore,
+ qt3dsdm::Qt3DSDMInstanceHandle inInstance,
+ qt3dsdm::Qt3DSDMPropertyHandle inProperty, qt3dsdm::SLong4 inGuid);
+ CStudioPropertySystem(const CStudioPropertySystem&) = delete;
+ CStudioPropertySystem& operator=(const CStudioPropertySystem&) = delete;
+};
+}
+
+#endif
diff --git a/src/dm/systems/VectorTransactions.h b/src/dm/systems/VectorTransactions.h
new file mode 100644
index 0000000..ff1fe2e
--- /dev/null
+++ b/src/dm/systems/VectorTransactions.h
@@ -0,0 +1,235 @@
+/****************************************************************************
+**
+** 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 VECTORTRANSACTIONSH
+#define VECTORTRANSACTIONSH
+
+namespace qt3dsdm {
+template <typename TItemType>
+inline void VecInsert(std::vector<TItemType> &inItems, const TItemType &inItem, size_t inIndex)
+{
+ inItems.insert(inItems.begin() + inIndex, inItem);
+}
+
+template <typename TItemType>
+inline void VecErase(std::vector<TItemType> &inItems, const TItemType &inItem)
+{
+ erase_if(inItems, std::bind(std::equal_to<TItemType>(), inItem, std::placeholders::_1));
+}
+
+template <typename TItemType>
+inline void VecInsertTransaction(const char *inFile, int inLine, std::vector<TItemType> &inItems,
+ size_t inIndex, TTransactionConsumerPtr &inConsumer)
+{
+ TItemType theItem = inItems.at(inIndex);
+ TTransactionPtr theTransaction(DoCreateGenericTransaction(
+ inFile, inLine, std::bind(VecInsert<TItemType>, std::ref(inItems), theItem, inIndex),
+ std::bind(VecErase<TItemType>, std::ref(inItems), theItem)));
+ inConsumer->OnTransaction(theTransaction);
+}
+
+template <typename TItemType>
+inline void VecEraseTransaction(const char *inFile, int inLine, std::vector<TItemType> &inItems,
+ size_t inIndex, const TItemType &inItem,
+ TTransactionConsumerPtr &inConsumer)
+{
+ TTransactionPtr theTransaction(DoCreateGenericTransaction(
+ inFile, inLine, std::bind(VecErase<TItemType>, std::ref(inItems), inItem),
+ std::bind(VecInsert<TItemType>, std::ref(inItems), inItem, inIndex)));
+ inConsumer->OnTransaction(theTransaction);
+}
+
+template <typename TItemType>
+inline void CreateVecInsertTransaction(const char *inFile, int inLine,
+ TTransactionConsumerPtr inConsumer, const TItemType &inItem,
+ std::vector<TItemType> &inItems)
+{
+ using namespace std;
+ size_t theDistance = distance(inItems.begin(), find(inItems.begin(), inItems.end(), inItem));
+ RunWithConsumer(inConsumer, std::bind(VecInsertTransaction<TItemType>, inFile, inLine,
+ std::ref(inItems), theDistance, std::placeholders::_1));
+}
+
+template <typename TItemType>
+inline void CreateVecEraseTransaction(const char *inFile, int inLine,
+ TTransactionConsumerPtr inConsumer, const TItemType &inItem,
+ std::vector<TItemType> &inItems)
+{
+ using namespace std;
+ size_t theDistance = distance(inItems.begin(), find(inItems.begin(), inItems.end(), inItem));
+ RunWithConsumer(inConsumer,
+ std::bind(VecEraseTransaction<TItemType>, inFile, inLine, std::ref(inItems),
+ theDistance, std::ref(inItem), std::placeholders::_1));
+}
+
+template <typename TKeyType, typename TValueType, typename THashType>
+struct HashMapAction
+{
+ std::unordered_map<TKeyType, TValueType, THashType> &m_HashMap;
+ std::pair<TKeyType, TValueType> m_Value;
+
+ HashMapAction(std::unordered_map<TKeyType, TValueType, THashType> &map,
+ const std::pair<TKeyType, TValueType> &val)
+ : m_HashMap(map)
+ , m_Value(val)
+ {
+ }
+ bool Exists() { return m_HashMap.find(m_Value.first) != m_HashMap.end(); }
+ void Add()
+ {
+ Q_ASSERT(!Exists());
+ m_HashMap.insert(m_Value);
+ }
+ void Remove()
+ {
+ Q_ASSERT(Exists());
+ m_HashMap.erase(m_HashMap.find(m_Value.first));
+ }
+};
+
+template <typename TKeyType, typename TValueType, typename THashType>
+struct HashMapInsertTransaction : public HashMapAction<TKeyType, TValueType, THashType>,
+ public ITransaction,
+ public IMergeableTransaction<TValueType>
+{
+ typedef HashMapAction<TKeyType, TValueType, THashType> base;
+ HashMapInsertTransaction(const char *inFile, int inLine,
+ std::unordered_map<TKeyType, TValueType, THashType> &map,
+ const std::pair<TKeyType, TValueType> &val)
+ : HashMapAction<TKeyType, TValueType, THashType>(map, val)
+ , ITransaction(inFile, inLine)
+ {
+ }
+ void Do() override { base::Add(); }
+ void Undo() override { base::Remove(); }
+ void Update(const TValueType &inValue) override { base::m_Value.second = inValue; }
+};
+
+template <typename TKeyType, typename TValueType, typename THashType>
+struct HashMapEraseTransaction : public HashMapAction<TKeyType, TValueType, THashType>,
+ public ITransaction
+{
+ typedef HashMapAction<TKeyType, TValueType, THashType> base;
+ HashMapEraseTransaction(const char *inFile, int inLine,
+ std::unordered_map<TKeyType, TValueType, THashType> &map,
+ const std::pair<TKeyType, TValueType> &val)
+ : HashMapAction<TKeyType, TValueType, THashType>(map, val)
+ , ITransaction(inFile, inLine)
+ {
+ }
+ void Do() override { base::Remove(); }
+ void Undo() override { base::Add(); }
+};
+
+template <typename TKeyType, typename TValueType, typename THashType>
+inline std::shared_ptr<IMergeableTransaction<TValueType>>
+CreateHashMapInsertTransaction(const char *inFile, int inLine, TTransactionConsumerPtr inConsumer,
+ const std::pair<TKeyType, TValueType> &inItem,
+ std::unordered_map<TKeyType, TValueType, THashType> &inItems)
+{
+ using namespace std;
+ std::shared_ptr<IMergeableTransaction<TValueType>> retval;
+ if (inConsumer) {
+ std::shared_ptr<HashMapInsertTransaction<TKeyType, TValueType, THashType>> transaction(
+ std::make_shared<HashMapInsertTransaction<TKeyType, TValueType, THashType>>(
+ inFile, inLine, std::ref(inItems), std::cref(inItem)));
+ retval = static_pointer_cast<IMergeableTransaction<TValueType>>(transaction);
+ inConsumer->OnTransaction(static_pointer_cast<ITransaction>(transaction));
+ }
+ return retval;
+}
+
+template <typename TKeyType, typename TValueType, typename THashType>
+inline void
+CreateHashMapEraseTransaction(const char *inFile, int inLine, TTransactionConsumerPtr inConsumer,
+ const std::pair<TKeyType, TValueType> &inItem,
+ std::unordered_map<TKeyType, TValueType, THashType> &inItems)
+{
+ using namespace std;
+ if (inConsumer)
+ inConsumer->OnTransaction(static_pointer_cast<ITransaction>(
+ std::make_shared<HashMapEraseTransaction<TKeyType, TValueType, THashType>>(
+ inFile, inLine, std::ref(inItems), std::cref(inItem))));
+}
+
+template <typename TKeyType, typename TValueType, typename THashType>
+struct HashMapSwapTransaction : public ITransaction, public IMergeableTransaction<TValueType>
+{
+ typedef std::unordered_map<TKeyType, TValueType, THashType> TMapType;
+
+ TMapType &m_HashMap;
+ TKeyType m_Key;
+ TValueType m_OldValue;
+ TValueType m_NewValue;
+
+ HashMapSwapTransaction(const char *inFile, int inLine, TMapType &inMap, const TKeyType &inKey,
+ const TValueType &inOldVal, const TValueType &inNewVal)
+ : ITransaction(inFile, inLine)
+ , m_HashMap(inMap)
+ , m_Key(inKey)
+ , m_OldValue(inOldVal)
+ , m_NewValue(inNewVal)
+ {
+ }
+
+ bool Exists() { return m_HashMap.find(m_Key) != m_HashMap.end(); }
+ void SetValue(const TValueType &inVal)
+ {
+ typename TMapType::iterator find(m_HashMap.find(m_Key));
+ if (find != m_HashMap.end())
+ find->second = inVal;
+ else
+ m_HashMap.insert(std::make_pair(m_Key, inVal));
+ }
+ void Do() override { SetValue(m_NewValue); }
+ void Undo() override { SetValue(m_OldValue); }
+ void Update(const TValueType &inValue) override { m_NewValue = inValue; }
+};
+
+template <typename TKeyType, typename TValueType, typename THashType>
+inline std::shared_ptr<IMergeableTransaction<TValueType>>
+CreateHashMapSwapTransaction(const char *inFile, int inLine, TTransactionConsumerPtr inConsumer,
+ const TKeyType &inKey, const TValueType &inOldValue,
+ const TValueType &inNewValue,
+ std::unordered_map<TKeyType, TValueType, THashType> &inItems)
+{
+ using namespace std;
+ std::shared_ptr<IMergeableTransaction<TValueType>> retval;
+ if (inConsumer) {
+ std::shared_ptr<HashMapSwapTransaction<TKeyType, TValueType, THashType>> transaction =
+ std::make_shared<HashMapSwapTransaction<TKeyType, TValueType, THashType>>(
+ inFile, inLine, std::ref(inItems), inKey, inOldValue, inNewValue);
+ retval = static_pointer_cast<IMergeableTransaction<TValueType>>(transaction);
+ inConsumer->OnTransaction(static_pointer_cast<ITransaction>(transaction));
+ }
+ return retval;
+}
+}
+
+#endif
diff --git a/src/dm/systems/cores/ActionCoreProducer.cpp b/src/dm/systems/cores/ActionCoreProducer.cpp
new file mode 100644
index 0000000..c262c23
--- /dev/null
+++ b/src/dm/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 {
+
+Qt3DSDMActionHandle CActionCoreProducer::CreateAction(Qt3DSDMInstanceHandle inInstance,
+ Qt3DSDMSlideHandle inSlide,
+ Qt3DSDMInstanceHandle inOwner,
+ SLong4 inTriggerTargetObjects)
+{
+ Qt3DSDMActionHandle retval =
+ m_Data->CreateAction(inInstance, inSlide, inOwner, inTriggerTargetObjects);
+ CREATE_HANDLE_CREATE_TRANSACTION(m_Consumer, retval, m_Data->m_Objects);
+ return retval;
+}
+
+void CActionCoreProducer::DeleteAction(Qt3DSDMActionHandle 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(Qt3DSDMActionHandle inAction) const
+{
+ return m_Data->GetActionInfo(inAction);
+}
+
+void CActionCoreProducer::GetActions(Qt3DSDMSlideHandle inSlide, Qt3DSDMInstanceHandle inOwner,
+ TActionHandleList &outActions) const
+{
+ return m_Data->GetActions(inSlide, inOwner, outActions);
+}
+
+void CActionCoreProducer::GetActions(Qt3DSDMSlideHandle 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(Qt3DSDMActionHandle inAction) const
+{
+ return m_Data->GetActionInstance(inAction);
+}
+
+Qt3DSDMActionHandle
+CActionCoreProducer::GetActionByInstance(Qt3DSDMInstanceHandle inActionInstance) const
+{
+ return m_Data->GetActionByInstance(inActionInstance);
+}
+
+void CActionCoreProducer::SetTriggerObject(Qt3DSDMActionHandle 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(Qt3DSDMActionHandle 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(Qt3DSDMActionHandle 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(Qt3DSDMActionHandle 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);
+}
+
+Qt3DSDMHandlerArgHandle CActionCoreProducer::AddHandlerArgument(Qt3DSDMActionHandle inAction,
+ const TCharStr &inName,
+ HandlerArgumentType::Value inArgType,
+ DataModelDataType::Value inValueType)
+{
+ Qt3DSDMHandlerArgHandle retval =
+ m_Data->AddHandlerArgument(inAction, inName, inArgType, inValueType);
+ SAction *theAction = CSimpleActionCore::GetActionNF(inAction, m_Data->m_Objects);
+ CreateVecInsertTransaction<Qt3DSDMHandlerArgHandle>(__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(Qt3DSDMHandlerArgHandle 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<Qt3DSDMHandlerArgHandle>(), inHandlerArgument,
+ std::placeholders::_1))) {
+ CreateVecEraseTransaction<Qt3DSDMHandlerArgHandle>(__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(Qt3DSDMHandlerArgHandle inHandlerArgument) const
+{
+ return m_Data->GetHandlerArgumentInfo(inHandlerArgument);
+}
+
+void CActionCoreProducer::GetHandlerArguments(Qt3DSDMActionHandle inAction,
+ THandlerArgHandleList &outHandlerArguments) const
+{
+ return m_Data->GetHandlerArguments(inAction, outHandlerArguments);
+}
+
+void CActionCoreProducer::GetHandlerArgumentValue(Qt3DSDMHandlerArgHandle inHandlerArgument,
+ SValue &outValue) const
+{
+ return m_Data->GetHandlerArgumentValue(inHandlerArgument, outValue);
+}
+
+void CActionCoreProducer::SetHandlerArgumentValue(Qt3DSDMHandlerArgHandle 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(Qt3DSDMActionHandle, SObjectRefType &)> &inCallback)
+{
+ return GetSignalProvider()->ConnectTriggerObjectSet(inCallback);
+}
+TSignalConnectionPtr CActionCoreProducer::ConnectTargetObjectSet(
+ const std::function<void(Qt3DSDMActionHandle, SObjectRefType &)> &inCallback)
+{
+ return GetSignalProvider()->ConnectTargetObjectSet(inCallback);
+}
+TSignalConnectionPtr CActionCoreProducer::ConnectEventSet(
+ const std::function<void(Qt3DSDMActionHandle, const wstring &)> &inCallback)
+{
+ return GetSignalProvider()->ConnectEventSet(inCallback);
+}
+TSignalConnectionPtr CActionCoreProducer::ConnectHandlerSet(
+ const std::function<void(Qt3DSDMActionHandle, const wstring &)> &inCallback)
+{
+ return GetSignalProvider()->ConnectHandlerSet(inCallback);
+}
+
+TSignalConnectionPtr CActionCoreProducer::ConnectHandlerArgumentAdded(
+ const std::function<void(Qt3DSDMActionHandle, Qt3DSDMHandlerArgHandle, const TCharStr &,
+ HandlerArgumentType::Value, DataModelDataType::Value)> &inCallback)
+{
+ return GetSignalProvider()->ConnectHandlerArgumentAdded(inCallback);
+}
+TSignalConnectionPtr CActionCoreProducer::ConnectHandlerArgumentRemoved(
+ const std::function<void(Qt3DSDMActionHandle, Qt3DSDMHandlerArgHandle, const TCharStr &,
+ HandlerArgumentType::Value, DataModelDataType::Value)> &inCallback)
+{
+ return GetSignalProvider()->ConnectHandlerArgumentRemoved(inCallback);
+}
+TSignalConnectionPtr CActionCoreProducer::ConnectHandlerArgumentValueSet(
+ const std::function<void(Qt3DSDMHandlerArgHandle, 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/dm/systems/cores/ActionCoreProducer.h b/src/dm/systems/cores/ActionCoreProducer.h
new file mode 100644
index 0000000..bf65a38
--- /dev/null
+++ b/src/dm/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
+ Qt3DSDMActionHandle CreateAction(Qt3DSDMInstanceHandle inInstance, Qt3DSDMSlideHandle inSlide,
+ Qt3DSDMInstanceHandle inOwner, SLong4 inTriggerTargetObjects) override;
+ void DeleteAction(Qt3DSDMActionHandle inAction, Qt3DSDMInstanceHandle &outInstance) override;
+ const SActionInfo &GetActionInfo(Qt3DSDMActionHandle inAction) const override;
+ void GetActions(Qt3DSDMSlideHandle inSlide, Qt3DSDMInstanceHandle inOwner,
+ TActionHandleList &outActions) const override;
+ void GetActions(Qt3DSDMSlideHandle inSlide, TActionHandleList &outActions) const override;
+ void GetActions(Qt3DSDMInstanceHandle inOwner, TActionHandleList &outActions) const override;
+ void GetActions(TActionHandleList &outActions) const override;
+ Qt3DSDMInstanceHandle GetActionInstance(Qt3DSDMActionHandle inAction) const override;
+ Qt3DSDMActionHandle GetActionByInstance(Qt3DSDMInstanceHandle inActionInstance) const override;
+
+ // Action Properties
+ void SetTriggerObject(Qt3DSDMActionHandle inAction, const SObjectRefType &inTriggerObject) override;
+ void SetTargetObject(Qt3DSDMActionHandle inAction, const SObjectRefType &inTargetObject) override;
+ void SetEvent(Qt3DSDMActionHandle inAction, const wstring &inEventHandle) override;
+ void SetHandler(Qt3DSDMActionHandle inAction, const wstring &inHandlerHandle) override;
+
+ // Action Argument
+ Qt3DSDMHandlerArgHandle AddHandlerArgument(Qt3DSDMActionHandle inAction, const TCharStr &inName,
+ HandlerArgumentType::Value inArgType,
+ DataModelDataType::Value inValueType) override;
+ void RemoveHandlerArgument(Qt3DSDMHandlerArgHandle inHandlerArgument) override;
+ const SHandlerArgumentInfo &
+ GetHandlerArgumentInfo(Qt3DSDMHandlerArgHandle inHandlerArgument) const override;
+ void GetHandlerArguments(Qt3DSDMActionHandle inAction,
+ THandlerArgHandleList &outHandlerArguments) const override;
+
+ // Action Argument Properties
+ void GetHandlerArgumentValue(Qt3DSDMHandlerArgHandle inHandlerArgument, SValue &outValue) const override;
+ void SetHandlerArgumentValue(Qt3DSDMHandlerArgHandle 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(Qt3DSDMActionHandle, SObjectRefType &)> &inCallback) override;
+ TSignalConnectionPtr ConnectTargetObjectSet(
+ const std::function<void(Qt3DSDMActionHandle, SObjectRefType &)> &inCallback) override;
+ virtual TSignalConnectionPtr
+ ConnectEventSet(const std::function<void(Qt3DSDMActionHandle, const wstring &)> &inCallback) override;
+ virtual TSignalConnectionPtr
+ ConnectHandlerSet(const std::function<void(Qt3DSDMActionHandle, const wstring &)> &inCallback) override;
+
+ TSignalConnectionPtr ConnectHandlerArgumentAdded(
+ const std::function<void(Qt3DSDMActionHandle, Qt3DSDMHandlerArgHandle, const TCharStr &,
+ HandlerArgumentType::Value, DataModelDataType::Value)> &inCallback) override;
+ TSignalConnectionPtr ConnectHandlerArgumentRemoved(
+ const std::function<void(Qt3DSDMActionHandle, Qt3DSDMHandlerArgHandle, const TCharStr &,
+ HandlerArgumentType::Value, DataModelDataType::Value)> &inCallback) override;
+ TSignalConnectionPtr ConnectHandlerArgumentValueSet(
+ const std::function<void(Qt3DSDMHandlerArgHandle, const SValue &)> &inCallback) override;
+
+private:
+ void InitSignaller();
+ IActionCoreSignalProvider *GetSignalProvider();
+ IActionCoreSignalSender *GetSignalSender();
+};
+}
+
+#endif
diff --git a/src/dm/systems/cores/AnimationCoreProducer.cpp b/src/dm/systems/cores/AnimationCoreProducer.cpp
new file mode 100644
index 0000000..14d1824
--- /dev/null
+++ b/src/dm/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;
+ Qt3DSDMAnimationHandle m_Animation;
+ TTransactionConsumerPtr m_Consumer;
+ bool m_ArtistEdited;
+ SArtistEditedUndoRedoScope(TSimpleAnimationCorePtr inAnimCore, Qt3DSDMAnimationHandle 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, Qt3DSDMAnimationHandle 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();
+ }
+};
+
+Qt3DSDMAnimationHandle
+CAnimationCoreProducer::CreateAnimation(Qt3DSDMSlideHandle inSlide, Qt3DSDMInstanceHandle inInstance,
+ Qt3DSDMPropertyHandle inProperty, size_t inIndex,
+ EAnimationType inAnimationType, bool inFirstKeyframeDynamic)
+{
+ Qt3DSDMAnimationHandle 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(Qt3DSDMAnimationHandle 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);
+}
+
+Qt3DSDMAnimationHandle CAnimationCoreProducer::GetAnimation(Qt3DSDMSlideHandle inSlide,
+ Qt3DSDMInstanceHandle inInstance,
+ Qt3DSDMPropertyHandle inProperty,
+ size_t inIndex) const
+{
+ return m_Data->GetAnimation(inSlide, inInstance, inProperty, inIndex);
+}
+
+SAnimationInfo CAnimationCoreProducer::GetAnimationInfo(Qt3DSDMAnimationHandle inAnimation) const
+{
+ return m_Data->GetAnimationInfo(inAnimation);
+}
+
+void CAnimationCoreProducer::GetAnimations(TAnimationHandleList &outAnimations) const
+{
+ return m_Data->GetAnimations(outAnimations);
+}
+
+void CAnimationCoreProducer::GetAnimations(TAnimationInfoList &outAnimations,
+ Qt3DSDMSlideHandle inMaster,
+ Qt3DSDMSlideHandle inSlide) const
+{
+ return m_Data->GetAnimations(outAnimations, inMaster, inSlide);
+}
+
+void CAnimationCoreProducer::SetFirstKeyframeDynamic(Qt3DSDMAnimationHandle 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(Qt3DSDMAnimationHandle inAnimation, THandleObjectMap &inObjects)
+{
+ SAnimationTrack *theAnimation = CSimpleAnimationCore::GetAnimationNF(inAnimation, inObjects);
+ theAnimation->m_KeyframesDirty = true;
+}
+
+inline void CreateDirtyKeyframesTransaction(TTransactionConsumerPtr inConsumer,
+ Qt3DSDMAnimationHandle 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)))));
+ }
+}
+
+Qt3DSDMKeyframeHandle CAnimationCoreProducer::InsertKeyframe(Qt3DSDMAnimationHandle inAnimation,
+ const TKeyframe &inKeyframe)
+{
+ SArtistEditedUndoRedoScope __editedScope(m_Data, inAnimation, m_Consumer);
+ Qt3DSDMKeyframeHandle retval = m_Data->InsertKeyframe(inAnimation, inKeyframe);
+ SAnimationTrack *theAnimation =
+ CSimpleAnimationCore::GetAnimationNF(inAnimation, m_Data->m_Objects);
+ CreateVecInsertTransaction<Qt3DSDMKeyframeHandle>(__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(Qt3DSDMKeyframeHandle 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<Qt3DSDMKeyframeHandle>(__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(Qt3DSDMAnimationHandle 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<Qt3DSDMKeyframeHandle>>(
+ __FILE__, __LINE__, std::ref(theAnimation->m_Keyframes)));
+ theAnimation->m_Keyframes.clear();
+}
+
+Qt3DSDMAnimationHandle
+CAnimationCoreProducer::GetAnimationForKeyframe(Qt3DSDMKeyframeHandle inKeyframe) const
+{
+ return m_Data->GetAnimationForKeyframe(inKeyframe);
+}
+
+struct KeyframeDataTransaction : public ITransaction, public IMergeableTransaction<TKeyframe>
+{
+ TSimpleAnimationCorePtr m_AnimationCore;
+ Qt3DSDMKeyframeHandle m_Keyframe;
+ TKeyframe m_OldData;
+ TKeyframe m_NewData;
+
+ KeyframeDataTransaction(const char *inFile, int inLine, TSimpleAnimationCorePtr animCore,
+ Qt3DSDMKeyframeHandle 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(Qt3DSDMKeyframeHandle 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(Qt3DSDMKeyframeHandle inKeyframe) const
+{
+ return m_Data->GetKeyframeData(inKeyframe);
+}
+
+void CAnimationCoreProducer::GetKeyframes(Qt3DSDMAnimationHandle inAnimation,
+ TKeyframeHandleList &outKeyframes) const
+{
+ return m_Data->GetKeyframes(inAnimation, outKeyframes);
+}
+
+size_t CAnimationCoreProducer::GetKeyframeCount(Qt3DSDMAnimationHandle inAnimation) const
+{
+ return m_Data->GetKeyframeCount(inAnimation);
+}
+
+void CAnimationCoreProducer::OffsetAnimations(Qt3DSDMSlideHandle 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) {
+ Qt3DSDMKeyframeHandle 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(Qt3DSDMAnimationHandle inAnimation, bool inEdited)
+{
+ SArtistEditedUndoRedoScope __editedScope(m_Data, inAnimation, m_Consumer);
+ m_Data->SetIsArtistEdited(inAnimation, inEdited);
+}
+
+bool CAnimationCoreProducer::IsArtistEdited(Qt3DSDMAnimationHandle inAnimation) const
+{
+ return m_Data->IsArtistEdited(inAnimation);
+}
+// Animation Evaluation.
+float CAnimationCoreProducer::EvaluateAnimation(Qt3DSDMAnimationHandle inAnimation,
+ float inSeconds) const
+{
+ return m_Data->EvaluateAnimation(inAnimation, inSeconds);
+}
+
+bool CAnimationCoreProducer::KeyframeValid(Qt3DSDMKeyframeHandle inKeyframe) const
+{
+ return m_Data->KeyframeValid(inKeyframe);
+}
+
+bool CAnimationCoreProducer::AnimationValid(Qt3DSDMAnimationHandle inAnimation) const
+{
+ return m_Data->AnimationValid(inAnimation);
+}
+
+void CAnimationCoreProducer::CopyAnimations(Qt3DSDMSlideHandle inSourceSlide,
+ Qt3DSDMInstanceHandle inSourceInstance,
+ Qt3DSDMSlideHandle 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]);
+ Qt3DSDMAnimationHandle 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(Qt3DSDMAnimationHandle, Qt3DSDMSlideHandle, Qt3DSDMInstanceHandle,
+ Qt3DSDMPropertyHandle, size_t, EAnimationType)> &inCallback)
+{
+ return GetSignalProvider()->ConnectAnimationCreated(inCallback);
+}
+TSignalConnectionPtr CAnimationCoreProducer::ConnectBeforeAnimationDeleted(
+ const std::function<void(Qt3DSDMAnimationHandle)> &inCallback)
+{
+ return GetSignalProvider()->ConnectBeforeAnimationDeleted(inCallback);
+}
+TSignalConnectionPtr CAnimationCoreProducer::ConnectAnimationDeleted(
+ const std::function<void(Qt3DSDMAnimationHandle, Qt3DSDMSlideHandle, Qt3DSDMInstanceHandle,
+ Qt3DSDMPropertyHandle, size_t, EAnimationType)> &inCallback)
+{
+ return GetSignalProvider()->ConnectAnimationDeleted(inCallback);
+}
+TSignalConnectionPtr CAnimationCoreProducer::ConnectKeyframeInserted(
+ const std::function<void(Qt3DSDMAnimationHandle, Qt3DSDMKeyframeHandle, const TKeyframe &)>
+ &inCallback)
+{
+ return GetSignalProvider()->ConnectKeyframeInserted(inCallback);
+}
+TSignalConnectionPtr CAnimationCoreProducer::ConnectBeforeKeyframeErased(
+ const std::function<void(Qt3DSDMKeyframeHandle)> &inCallback)
+{
+ return GetSignalProvider()->ConnectBeforeKeyframeErased(inCallback);
+}
+TSignalConnectionPtr CAnimationCoreProducer::ConnectKeyframeErased(
+ const std::function<void(Qt3DSDMAnimationHandle, Qt3DSDMKeyframeHandle, const TKeyframe &)>
+ &inCallback)
+{
+ return GetSignalProvider()->ConnectKeyframeErased(inCallback);
+}
+TSignalConnectionPtr CAnimationCoreProducer::ConnectBeforeAllKeyframesErased(
+ const std::function<void(Qt3DSDMAnimationHandle)> &inCallback)
+{
+ return GetSignalProvider()->ConnectBeforeAllKeyframesErased(inCallback);
+}
+TSignalConnectionPtr CAnimationCoreProducer::ConnectKeyframeUpdated(
+ const std::function<void(Qt3DSDMKeyframeHandle, const TKeyframe &)> &inCallback)
+{
+ return GetSignalProvider()->ConnectKeyframeUpdated(inCallback);
+}
+TSignalConnectionPtr CAnimationCoreProducer::ConnectFirstKeyframeDynamicSet(
+ const std::function<void(Qt3DSDMAnimationHandle, 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/dm/systems/cores/AnimationCoreProducer.h b/src/dm/systems/cores/AnimationCoreProducer.h
new file mode 100644
index 0000000..17603d6
--- /dev/null
+++ b/src/dm/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
+
+ Qt3DSDMAnimationHandle CreateAnimation(Qt3DSDMSlideHandle inSlide,
+ Qt3DSDMInstanceHandle inInstance,
+ Qt3DSDMPropertyHandle inProperty, size_t inIndex,
+ EAnimationType inAnimationType,
+ bool inFirstKeyframeDynamic) override;
+ void DeleteAnimation(Qt3DSDMAnimationHandle inAnimation) override;
+ Qt3DSDMAnimationHandle GetAnimation(Qt3DSDMSlideHandle inSlide, Qt3DSDMInstanceHandle inInstance,
+ Qt3DSDMPropertyHandle inProperty, size_t inIndex) const override;
+ SAnimationInfo GetAnimationInfo(Qt3DSDMAnimationHandle inAnimation) const override;
+ void GetAnimations(TAnimationHandleList &outAnimations) const override;
+ void GetAnimations(TAnimationInfoList &outAnimations, Qt3DSDMSlideHandle inMaster,
+ Qt3DSDMSlideHandle inSlide) const override;
+ void GetSpecificInstanceAnimations(Qt3DSDMSlideHandle inSlide, Qt3DSDMInstanceHandle inInstance,
+ TAnimationHandleList &outAnimations) override
+ {
+ m_Data->GetSpecificInstanceAnimations(inSlide, inInstance, outAnimations);
+ }
+
+ void SetFirstKeyframeDynamic(Qt3DSDMAnimationHandle inAnimation, bool inValue) override;
+
+ Qt3DSDMKeyframeHandle InsertKeyframe(Qt3DSDMAnimationHandle inAnimation,
+ const TKeyframe &inKeyframe) override;
+ void EraseKeyframe(Qt3DSDMKeyframeHandle) override;
+ void DeleteAllKeyframes(Qt3DSDMAnimationHandle inAnimation) override;
+ Qt3DSDMAnimationHandle GetAnimationForKeyframe(Qt3DSDMKeyframeHandle inKeyframe) const override;
+ TKeyframe GetKeyframeData(Qt3DSDMKeyframeHandle inKeyframe) const override;
+ void SetKeyframeData(Qt3DSDMKeyframeHandle inKeyframe, const TKeyframe &inData) override;
+ void GetKeyframes(Qt3DSDMAnimationHandle inAnimation, TKeyframeHandleList &outKeyframes) const override;
+ size_t GetKeyframeCount(Qt3DSDMAnimationHandle inAnimation) const override;
+ bool IsFirstKeyframe(Qt3DSDMKeyframeHandle inKeyframe) const override
+ {
+ return m_Data->IsFirstKeyframe(inKeyframe);
+ }
+ void OffsetAnimations(Qt3DSDMSlideHandle inSlide, Qt3DSDMInstanceHandle inInstance,
+ long inMillisecondOffset) override;
+
+ void SetIsArtistEdited(Qt3DSDMAnimationHandle inAnimation, bool inEdited = true) override;
+ bool IsArtistEdited(Qt3DSDMAnimationHandle inAnimation) const override;
+
+ // Animation Evaluation.
+ float EvaluateAnimation(Qt3DSDMAnimationHandle inAnimation, float inSeconds) const override;
+
+ bool KeyframeValid(Qt3DSDMKeyframeHandle inKeyframe) const override;
+ bool AnimationValid(Qt3DSDMAnimationHandle inAnimation) const override;
+
+ void CopyAnimations(Qt3DSDMSlideHandle inSourceSlide, Qt3DSDMInstanceHandle inSourceInstance,
+ Qt3DSDMSlideHandle inDestSlide, Qt3DSDMInstanceHandle inDestInstance) override;
+
+ // ITransactionProducer implementation
+ void SetConsumer(TTransactionConsumerPtr inConsumer) override;
+
+ TSignalConnectionPtr ConnectAnimationCreated(
+ const std::function<void(Qt3DSDMAnimationHandle, Qt3DSDMSlideHandle, Qt3DSDMInstanceHandle,
+ Qt3DSDMPropertyHandle, size_t, EAnimationType)> &inCallback) override;
+ virtual TSignalConnectionPtr
+ ConnectBeforeAnimationDeleted(const std::function<void(Qt3DSDMAnimationHandle)> &inCallback) override;
+ TSignalConnectionPtr ConnectAnimationDeleted(
+ const std::function<void(Qt3DSDMAnimationHandle, Qt3DSDMSlideHandle, Qt3DSDMInstanceHandle,
+ Qt3DSDMPropertyHandle, size_t, EAnimationType)> &inCallback) override;
+ TSignalConnectionPtr ConnectKeyframeInserted(
+ const std::function<void(Qt3DSDMAnimationHandle, Qt3DSDMKeyframeHandle, const TKeyframe &)>
+ &inCallback) override;
+ virtual TSignalConnectionPtr
+ ConnectBeforeKeyframeErased(const std::function<void(Qt3DSDMKeyframeHandle)> &inCallback) override;
+ TSignalConnectionPtr ConnectKeyframeErased(
+ const std::function<void(Qt3DSDMAnimationHandle, Qt3DSDMKeyframeHandle, const TKeyframe &)>
+ &inCallback) override;
+ virtual TSignalConnectionPtr
+ ConnectBeforeAllKeyframesErased(const std::function<void(Qt3DSDMAnimationHandle)> &inCallback) override;
+ TSignalConnectionPtr ConnectKeyframeUpdated(
+ const std::function<void(Qt3DSDMKeyframeHandle, const TKeyframe &)> &inCallback) override;
+ TSignalConnectionPtr ConnectFirstKeyframeDynamicSet(
+ const std::function<void(Qt3DSDMAnimationHandle, bool)> &inCallback) override;
+
+private:
+ void InitSignaller();
+ IAnimationCoreSignalProvider *GetSignalProvider();
+ IAnimationCoreSignalSender *GetSignalSender();
+};
+}
+
+#endif
diff --git a/src/dm/systems/cores/DataCoreProducer.cpp b/src/dm/systems/cores/DataCoreProducer.cpp
new file mode 100644
index 0000000..5c3cc92
--- /dev/null
+++ b/src/dm/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, Qt3DSDMPropertyDefinition>
+TransformProperty(Qt3DSDMPropertyHandle inProperty, CSimpleDataCore &inData)
+{
+ return make_tuple(inProperty, inData.GetProperty(inProperty));
+}
+
+inline void SignalPropertyRemoved(Qt3DSDMInstanceHandle inInstance,
+ tuple<Qt3DSDMPropertyHandle, Qt3DSDMPropertyDefinition> 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, Qt3DSDMPropertyDefinition>> theDefinitionList;
+ theDefinitionList.resize(theProperties.size());
+
+ function<tuple<Qt3DSDMPropertyHandle, Qt3DSDMPropertyDefinition>(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 Qt3DSDMPropertyDefinition &
+CDataCoreProducer::GetProperty(Qt3DSDMPropertyHandle inProperty) const
+{
+ return m_Data->GetProperty(inProperty);
+}
+
+void CDataCoreProducer::RemoveProperty(Qt3DSDMPropertyHandle inProperty)
+{
+ Qt3DSDMPropertyDefinition 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/dm/systems/cores/DataCoreProducer.h b/src/dm/systems/cores/DataCoreProducer.h
new file mode 100644
index 0000000..8d89bfa
--- /dev/null
+++ b/src/dm/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 Qt3DSDMPropertyDefinition &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/dm/systems/cores/SimpleActionCore.cpp b/src/dm/systems/cores/SimpleActionCore.cpp
new file mode 100644
index 0000000..b2f3553
--- /dev/null
+++ b/src/dm/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 {
+
+Qt3DSDMActionHandle CSimpleActionCore::CreateAction(Qt3DSDMInstanceHandle inInstance,
+ Qt3DSDMSlideHandle inSlide,
+ Qt3DSDMInstanceHandle inOwner,
+ SLong4 inTriggerTargetObjects)
+{
+ int nextId = GetNextId();
+ Qt3DSDMActionHandle retval = CreateActionWithHandle(nextId, inInstance, inSlide, inOwner);
+ SetTriggerObject(retval, inTriggerTargetObjects);
+ SetTargetObject(retval, inTriggerTargetObjects);
+ return retval;
+}
+
+void CSimpleActionCore::DeleteAction(Qt3DSDMActionHandle 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(Qt3DSDMActionHandle inAction) const
+{
+ const SAction *theAction = GetActionNF(inAction, m_Objects);
+ return theAction->m_ActionInfo;
+}
+
+inline void AddIfActionMatches(const THandleObjectPair &inPair, Qt3DSDMSlideHandle 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(Qt3DSDMSlideHandle 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(Qt3DSDMSlideHandle 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, Qt3DSDMActionHandle>,
+ std::placeholders::_1, std::ref(outActions)));
+}
+
+// Return the instance that was allocated for this action.
+Qt3DSDMInstanceHandle CSimpleActionCore::GetActionInstance(Qt3DSDMActionHandle 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.
+Qt3DSDMActionHandle
+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(Qt3DSDMActionHandle inAction,
+ const SObjectRefType &inTriggerObject)
+{
+ SAction *theAction = GetActionNF(inAction, m_Objects);
+ theAction->m_ActionInfo.m_TriggerObject = inTriggerObject;
+}
+
+void CSimpleActionCore::SetTargetObject(Qt3DSDMActionHandle inAction,
+ const SObjectRefType &inTargetObject)
+{
+ SAction *theAction = GetActionNF(inAction, m_Objects);
+ theAction->m_ActionInfo.m_TargetObject = inTargetObject;
+}
+
+void CSimpleActionCore::SetEvent(Qt3DSDMActionHandle inAction, const wstring &inEventHandle)
+{
+ SAction *theAction = GetActionNF(inAction, m_Objects);
+ theAction->m_ActionInfo.m_Event = inEventHandle;
+}
+
+void CSimpleActionCore::SetHandler(Qt3DSDMActionHandle inAction, const wstring &inHandlerHandle)
+{
+ SAction *theAction = GetActionNF(inAction, m_Objects);
+ theAction->m_ActionInfo.m_Handler = inHandlerHandle;
+}
+
+// Action Argument
+Qt3DSDMHandlerArgHandle CSimpleActionCore::AddHandlerArgument(Qt3DSDMActionHandle inAction,
+ const TCharStr &inName,
+ HandlerArgumentType::Value inArgType,
+ DataModelDataType::Value inValueType)
+{
+ int nextId = GetNextId();
+ return AddHandlerArgumentWithHandle(nextId, inAction, inName, inArgType, inValueType);
+}
+
+void CSimpleActionCore::RemoveHandlerArgument(Qt3DSDMHandlerArgHandle 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(Qt3DSDMHandlerArgHandle 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(Qt3DSDMActionHandle inAction,
+ THandlerArgHandleList &outHandlerArguments) const
+{
+ const SAction *theAction = GetActionNF(inAction, m_Objects);
+ outHandlerArguments = theAction->m_ActionInfo.m_HandlerArgs;
+}
+
+// Action Argument Properties
+void CSimpleActionCore::GetHandlerArgumentValue(Qt3DSDMHandlerArgHandle inHandlerArgument,
+ SValue &outValue) const
+{
+ const SHandlerArgument *theHandlerArgument = GetHandlerArgumentNF(inHandlerArgument, m_Objects);
+ outValue = theHandlerArgument->m_HandlerArgInfo.m_Value;
+}
+
+void CSimpleActionCore::SetHandlerArgumentValue(Qt3DSDMHandlerArgHandle inHandlerArgument,
+ const SValue &inValue)
+{
+ SHandlerArgument *theHandlerArgument = GetHandlerArgumentNF(inHandlerArgument, m_Objects);
+ theHandlerArgument->m_HandlerArgInfo.m_Value = inValue;
+}
+
+// Helper functions
+Qt3DSDMActionHandle CSimpleActionCore::CreateActionWithHandle(int inHandle,
+ Qt3DSDMInstanceHandle inInstance,
+ Qt3DSDMSlideHandle inSlide,
+ Qt3DSDMInstanceHandle inOwner)
+{
+ if (HandleValid(inHandle))
+ throw HandleExists(L"");
+ m_Objects.insert(make_pair(
+ inHandle, (THandleObjectPtr) new SAction(inHandle, inInstance, inSlide, inOwner)));
+ return inHandle;
+}
+
+Qt3DSDMHandlerArgHandle
+CSimpleActionCore::AddHandlerArgumentWithHandle(int inHandle, Qt3DSDMActionHandle 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/dm/systems/cores/SimpleActionCore.h b/src/dm/systems/cores/SimpleActionCore.h
new file mode 100644
index 0000000..1e229f1
--- /dev/null
+++ b/src/dm/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, Qt3DSDMSlideHandle 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, Qt3DSDMActionHandle 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
+ Qt3DSDMActionHandle CreateAction(Qt3DSDMInstanceHandle inInstance, Qt3DSDMSlideHandle inSlide,
+ Qt3DSDMInstanceHandle inOwner, SLong4 inTriggerTargetObjects) override;
+ void DeleteAction(Qt3DSDMActionHandle inAction, Qt3DSDMInstanceHandle &outInstance) override;
+ const SActionInfo &GetActionInfo(Qt3DSDMActionHandle inAction) const override;
+ void GetActions(Qt3DSDMSlideHandle inSlide, Qt3DSDMInstanceHandle inOwner,
+ TActionHandleList &outActions) const override;
+ void GetActions(Qt3DSDMSlideHandle 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(Qt3DSDMActionHandle inAction) const override;
+ // Reverse lookup into the action system so you can match actions to instances.
+ Qt3DSDMActionHandle GetActionByInstance(Qt3DSDMInstanceHandle inActionInstance) const override;
+
+ // Action Properties
+ void SetTriggerObject(Qt3DSDMActionHandle inAction, const SObjectRefType &inTriggerObject) override;
+ void SetTargetObject(Qt3DSDMActionHandle inAction, const SObjectRefType &inTargetObject) override;
+ void SetEvent(Qt3DSDMActionHandle inAction, const wstring &inEvent) override;
+ void SetHandler(Qt3DSDMActionHandle inAction, const wstring &inHandler) override;
+
+ // Action Argument
+ Qt3DSDMHandlerArgHandle AddHandlerArgument(Qt3DSDMActionHandle inAction, const TCharStr &inName,
+ HandlerArgumentType::Value inArgType,
+ DataModelDataType::Value inValueType) override;
+ void RemoveHandlerArgument(Qt3DSDMHandlerArgHandle inHandlerArgument) override;
+ const SHandlerArgumentInfo &
+ GetHandlerArgumentInfo(Qt3DSDMHandlerArgHandle inHandlerArgument) const override;
+ void GetHandlerArguments(Qt3DSDMActionHandle inAction,
+ THandlerArgHandleList &outHandlerArguments) const override;
+
+ // Action Argument Properties
+ void GetHandlerArgumentValue(Qt3DSDMHandlerArgHandle inHandlerArgument, SValue &outValue) const override;
+ void SetHandlerArgumentValue(Qt3DSDMHandlerArgHandle inHandlerArgument, const SValue &inValue) override;
+
+ // CHandleBase
+ bool HandleValid(int inHandle) const override { return CHandleBase::HandleValid(inHandle); }
+
+ // Helper functions
+ Qt3DSDMActionHandle CreateActionWithHandle(int inHandle, Qt3DSDMInstanceHandle inInstance,
+ Qt3DSDMSlideHandle inSlide,
+ Qt3DSDMInstanceHandle inOwner);
+ Qt3DSDMHandlerArgHandle AddHandlerArgumentWithHandle(int inHandle, Qt3DSDMActionHandle 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/dm/systems/cores/SimpleAnimationCore.cpp b/src/dm/systems/cores/SimpleAnimationCore.cpp
new file mode 100644
index 0000000..00d6df4
--- /dev/null
+++ b/src/dm/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"
+
+#ifdef _WIN32
+#pragma warning(disable : 4503) // decorated name length exceeded
+#endif
+
+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"
+using namespace std;
+
+namespace qt3dsdm {
+
+Qt3DSDMAnimationHandle
+CSimpleAnimationCore::CreateAnimation(Qt3DSDMSlideHandle 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();
+ Qt3DSDMAnimationHandle retval = CreateAnimationWithHandle(
+ nextId, inSlide, inInstance, inProperty, inIndex, inAnimationType, inFirstKeyframeDynamic);
+ AddAnimationToLookupCache(retval);
+ return retval;
+}
+
+void CSimpleAnimationCore::DeleteAnimation(Qt3DSDMAnimationHandle 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));
+ }
+ }
+}
+
+Qt3DSDMAnimationHandle CSimpleAnimationCore::GetAnimation(Qt3DSDMSlideHandle 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(Qt3DSDMAnimationHandle 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,
+ Qt3DSDMSlideHandle inMaster,
+ Qt3DSDMSlideHandle 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, Qt3DSDMSlideHandle 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(Qt3DSDMSlideHandle 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(Qt3DSDMAnimationHandle 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
+Qt3DSDMKeyframeHandle CSimpleAnimationCore::InsertKeyframe(Qt3DSDMAnimationHandle 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(Qt3DSDMKeyframeHandle 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(Qt3DSDMAnimationHandle 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);
+}
+
+Qt3DSDMAnimationHandle
+CSimpleAnimationCore::GetAnimationForKeyframe(Qt3DSDMKeyframeHandle inKeyframe) const
+{
+ const SKeyframe *theKeyframe = GetKeyframeNF(inKeyframe, m_Objects);
+ return theKeyframe->m_Animation;
+}
+
+TKeyframe CSimpleAnimationCore::GetKeyframeData(Qt3DSDMKeyframeHandle inKeyframe) const
+{
+ const SKeyframe *theKeyframe = GetKeyframeNF(inKeyframe, m_Objects);
+ return theKeyframe->m_Keyframe;
+}
+
+void CSimpleAnimationCore::SetKeyframeData(Qt3DSDMKeyframeHandle inKeyframe, const TKeyframe &inData)
+{
+ DoSetKeyframeData(inKeyframe, inData);
+ SKeyframe *theKeyframe = GetKeyframeNF(inKeyframe, m_Objects);
+ SetIsArtistEdited(theKeyframe->m_Animation);
+}
+
+void CSimpleAnimationCore::DoSetKeyframeData(Qt3DSDMKeyframeHandle 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(Qt3DSDMAnimationHandle inAnimation,
+ TKeyframeHandleList &outKeyframes) const
+{
+ const SAnimationTrack *theItem = GetAnimationNF(inAnimation, m_Objects);
+ CheckKeyframesSorted(theItem, m_Objects);
+ outKeyframes = theItem->m_Keyframes;
+}
+
+size_t CSimpleAnimationCore::GetKeyframeCount(Qt3DSDMAnimationHandle inAnimation) const
+{
+ const SAnimationTrack *theItem = GetAnimationNF(inAnimation, m_Objects);
+ return theItem->m_Keyframes.size();
+}
+
+bool CSimpleAnimationCore::IsFirstKeyframe(Qt3DSDMKeyframeHandle inKeyframe) const
+{
+ Qt3DSDMAnimationHandle 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(Qt3DSDMSlideHandle /*inSlide*/,
+ Qt3DSDMInstanceHandle /*inInstance*/, long /*inOffset*/)
+{
+ throw std::runtime_error("unimplemented");
+}
+
+void CSimpleAnimationCore::SetIsArtistEdited(Qt3DSDMAnimationHandle 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(Qt3DSDMAnimationHandle 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(Qt3DSDMAnimationHandle 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)));
+
+ TKeyframeHandleList::const_iterator theBound =
+ lower_bound(theItem->m_Keyframes.begin(), theItem->m_Keyframes.end(), theSearchKey,
+ [theIntToKeyframe](const Qt3DSDMKeyframeHandle &inLeft,
+ const TKeyframe &inRight)
+ {return KeyframeTime(theIntToKeyframe(inLeft)) < KeyframeTime(inRight);});
+
+ if (theBound == theItem->m_Keyframes.end())
+ return KeyframeValue(theItem->m_Keyframes.back(), m_Objects);
+ if (theBound == theItem->m_Keyframes.begin())
+ return KeyframeValue(*theItem->m_Keyframes.begin(), m_Objects);
+
+ TKeyframeHandleList::const_iterator theStartIter = theBound;
+ --theStartIter;
+
+ // Both iterators must be valid at this point...
+ Qt3DSDMKeyframeHandle theStart = *theStartIter;
+ Qt3DSDMKeyframeHandle theFinish = *theBound;
+ switch (theItem->m_AnimationType) {
+ default:
+ throw AnimationEvaluationError(L"");
+ case EAnimationTypeLinear: {
+ SLinearKeyframe k1 = get<SLinearKeyframe>(theIntToKeyframe(theStart));
+ SLinearKeyframe k2 = get<SLinearKeyframe>(theIntToKeyframe(theFinish));
+ return EvaluateLinearKeyframe(k1, k2, inSeconds);
+ }
+ case EAnimationTypeBezier: {
+ SBezierKeyframe k1 = get<SBezierKeyframe>(theIntToKeyframe(theStart));
+ SBezierKeyframe k2 = get<SBezierKeyframe>(theIntToKeyframe(theFinish));
+ return DoBezierEvaluation(inSeconds, k1, k2);
+ }
+ case EAnimationTypeEaseInOut: {
+ SEaseInEaseOutKeyframe k1 = get<SEaseInEaseOutKeyframe>(theIntToKeyframe(theStart));
+ SEaseInEaseOutKeyframe k2 = get<SEaseInEaseOutKeyframe>(theIntToKeyframe(theFinish));
+ return DoBezierEvaluation(
+ inSeconds, CreateBezierKeyframeFromEaseInEaseOutKeyframe(NULL, k1, &k2.m_KeyframeValue),
+ CreateBezierKeyframeFromEaseInEaseOutKeyframe(&k1.m_KeyframeValue, k2, NULL));
+ }
+ }
+}
+
+bool CSimpleAnimationCore::KeyframeValid(Qt3DSDMKeyframeHandle inKeyframe) const
+{
+ return HandleObjectValid<SKeyframe>(inKeyframe, m_Objects);
+}
+
+bool CSimpleAnimationCore::AnimationValid(Qt3DSDMAnimationHandle inAnimation) const
+{
+ return HandleObjectValid<SAnimationTrack>(inAnimation, m_Objects);
+}
+
+Qt3DSDMAnimationHandle CSimpleAnimationCore::CreateAnimationWithHandle(
+ int inHandle, Qt3DSDMSlideHandle 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(Qt3DSDMAnimationHandle 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(Qt3DSDMAnimationHandle 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
+{
+ Qt3DSDMSlideHandle 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);
+ Qt3DSDMSlideHandle 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(Qt3DSDMAnimationHandle inAnimation, Qt3DSDMKeyframeHandle inKeyframe,
+ const IAnimationCore &inSourceAnimationCore, IAnimationCore &inDestAnimationCore)
+{
+ TKeyframe theData = inSourceAnimationCore.GetKeyframeData(inKeyframe);
+ inDestAnimationCore.InsertKeyframe(inAnimation, theData);
+}
+
+void CopyKeyframes(const IAnimationCore &inSourceAnimationCore, IAnimationCore &inDestAnimationCore,
+ Qt3DSDMAnimationHandle inDestAnimation, const TKeyframeHandleList &inKeyframes)
+{
+ do_all(inKeyframes,
+ std::bind(CopyKeyframe, inDestAnimation, std::placeholders::_1,
+ std::cref(inSourceAnimationCore), std::ref(inDestAnimationCore)));
+}
+
+Qt3DSDMAnimationHandle CopyAnimation(TAnimationCorePtr inAnimationCore,
+ Qt3DSDMAnimationHandle inAnimation, Qt3DSDMSlideHandle inNewSlide,
+ Qt3DSDMInstanceHandle inNewInstance,
+ Qt3DSDMPropertyHandle inNewProperty, size_t inNewIndex)
+{
+ TKeyframeHandleList theKeyframes;
+ inAnimationCore->GetKeyframes(inAnimation, theKeyframes);
+ SAnimationInfo theInfo(inAnimationCore->GetAnimationInfo(inAnimation));
+ Qt3DSDMAnimationHandle theAnimation =
+ inAnimationCore->CreateAnimation(inNewSlide, inNewInstance, inNewProperty, inNewIndex,
+ theInfo.m_AnimationType, theInfo.m_DynamicFirstKeyframe);
+ CopyKeyframes(*inAnimationCore, *inAnimationCore, theAnimation, theKeyframes);
+ return theAnimation;
+}
+
+SBezierKeyframe GetBezierKeyframeData(Qt3DSDMKeyframeHandle inKeyframe,
+ const IAnimationCore &inAnimationCore)
+{
+ return get<SBezierKeyframe>(inAnimationCore.GetKeyframeData(inKeyframe));
+}
+
+SEaseInEaseOutKeyframe GetEaseInEaseOutKeyframeData(Qt3DSDMKeyframeHandle 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(Qt3DSDMAnimationHandle 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(Qt3DSDMKeyframeHandle)> TConvertFunc;
+ TConvertFunc theDataConverter(
+ std::bind(GetEaseInEaseOutKeyframeData, std::placeholders::_1,
+ std::cref(inAnimationCore)));
+
+ TKeyframeHandleList::iterator thePreviousKeyframe = theKeyframes.begin();
+
+ TKeyframeHandleList::iterator theCurrentKeyframe =
+ SafeIncrementIterator(thePreviousKeyframe, theEndKeyframe);
+
+ TKeyframeHandleList::iterator theNextKeyframe =
+ SafeIncrementIterator(theCurrentKeyframe, theEndKeyframe);
+
+ TBezierKeyframeList::iterator theResult(outKeyframes.begin());
+
+ if (thePreviousKeyframe != theEndKeyframe) {
+ float *theNextValuePtr = NULL;
+ float theNextValue;
+ if (theCurrentKeyframe != theEndKeyframe) {
+ theNextValue = theDataConverter(*theCurrentKeyframe).m_KeyframeValue;
+ theNextValuePtr = &theNextValue;
+ }
+ *theResult = CreateBezierKeyframeFromEaseInEaseOutKeyframe(
+ NULL, theDataConverter(*thePreviousKeyframe), theNextValuePtr);
+ theResult = theResult + 1;
+ }
+ for (; theCurrentKeyframe != theEndKeyframe;
+ ++thePreviousKeyframe,
+ theCurrentKeyframe = SafeIncrementIterator(theCurrentKeyframe, theEndKeyframe),
+ theNextKeyframe = SafeIncrementIterator(theNextKeyframe, theEndKeyframe),
+ ++theResult) {
+ float theLastValue(theDataConverter(*thePreviousKeyframe).m_KeyframeValue);
+ float *theNextValuePtr = NULL;
+ float theNextValue;
+ if (theNextKeyframe != theEndKeyframe) {
+ theNextValue = theDataConverter(*theNextKeyframe).m_KeyframeValue;
+ theNextValuePtr = &theNextValue;
+ }
+ *theResult = CreateBezierKeyframeFromEaseInEaseOutKeyframe(
+ &theLastValue, theDataConverter(*theCurrentKeyframe), theNextValuePtr);
+ }
+ } break;
+ }
+}
+}
diff --git a/src/dm/systems/cores/SimpleAnimationCore.h b/src/dm/systems/cores/SimpleAnimationCore.h
new file mode 100644
index 0000000..cb4c415
--- /dev/null
+++ b/src/dm/systems/cores/SimpleAnimationCore.h
@@ -0,0 +1,230 @@
+/****************************************************************************
+**
+** 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 <unordered_map>
+
+namespace {
+struct pair_hash {
+ template <class T1, class T2>
+ std::size_t operator () (const std::pair<T1, T2> &p) const {
+ auto h1 = std::hash<T1>{}(p.first);
+ auto h2 = std::hash<T2>{}(p.second);
+
+ return h1 ^ h2;
+ }
+ };
+}
+
+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, Qt3DSDMSlideHandle 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 std::unordered_multimap<std::pair<int, int>,
+ std::shared_ptr<SAnimationTrack>, pair_hash> 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; }
+
+ Qt3DSDMAnimationHandle CreateAnimation(Qt3DSDMSlideHandle inSlide,
+ Qt3DSDMInstanceHandle inInstance,
+ Qt3DSDMPropertyHandle inProperty, size_t inIndex,
+ EAnimationType inAnimationType,
+ bool inFirstKeyframeDynamic) override;
+ void DeleteAnimation(Qt3DSDMAnimationHandle inAnimation) override;
+ Qt3DSDMAnimationHandle GetAnimation(Qt3DSDMSlideHandle inSlide, Qt3DSDMInstanceHandle inInstance,
+ Qt3DSDMPropertyHandle inProperty, size_t inIndex) const override;
+ SAnimationInfo GetAnimationInfo(Qt3DSDMAnimationHandle inAnimation) const override;
+ void GetAnimations(TAnimationHandleList &outAnimations) const override;
+ void GetAnimations(TAnimationInfoList &outAnimations, Qt3DSDMSlideHandle inMaster,
+ Qt3DSDMSlideHandle inSlide) const override;
+ void GetSpecificInstanceAnimations(Qt3DSDMSlideHandle inSlide, Qt3DSDMInstanceHandle inInstance,
+ TAnimationHandleList &outAnimations) override;
+
+ void SetFirstKeyframeDynamic(Qt3DSDMAnimationHandle inAnimation, bool inValue) override;
+
+ // keyframe manipulation
+ Qt3DSDMKeyframeHandle InsertKeyframe(Qt3DSDMAnimationHandle inAnimation,
+ const TKeyframe &inKeyframe) override;
+ void EraseKeyframe(Qt3DSDMKeyframeHandle inKeyframe) override;
+ void DeleteAllKeyframes(Qt3DSDMAnimationHandle inAnimation) override;
+ Qt3DSDMAnimationHandle GetAnimationForKeyframe(Qt3DSDMKeyframeHandle inKeyframe) const override;
+ TKeyframe GetKeyframeData(Qt3DSDMKeyframeHandle inKeyframe) const override;
+ void SetKeyframeData(Qt3DSDMKeyframeHandle 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(Qt3DSDMKeyframeHandle inKeyframe, const TKeyframe &inData);
+ void GetKeyframes(Qt3DSDMAnimationHandle inAnimation, TKeyframeHandleList &outKeyframes) const override;
+ size_t GetKeyframeCount(Qt3DSDMAnimationHandle inAnimation) const override;
+ bool IsFirstKeyframe(Qt3DSDMKeyframeHandle inKeyframe) const override;
+ // Only implemented in the producer for now.
+ void OffsetAnimations(Qt3DSDMSlideHandle inSlide, Qt3DSDMInstanceHandle inInstance,
+ long inOffset) override;
+
+ void SetIsArtistEdited(Qt3DSDMAnimationHandle inAnimation, bool inEdited = true) override;
+ bool IsArtistEdited(Qt3DSDMAnimationHandle inAnimation) const override;
+
+ // Animation Evaluation.
+ float EvaluateAnimation(Qt3DSDMAnimationHandle inAnimation, float inSeconds) const override;
+
+ bool KeyframeValid(Qt3DSDMKeyframeHandle inKeyframe) const override;
+ bool AnimationValid(Qt3DSDMAnimationHandle inAnimation) const override;
+
+ // Only implemented at the producer level, not at the simple core level.
+ void CopyAnimations(Qt3DSDMSlideHandle /*inSourceSlide*/,
+ Qt3DSDMInstanceHandle /*inSourceInstance*/,
+ Qt3DSDMSlideHandle /*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(Qt3DSDMAnimationHandle inAnimation) const;
+ void RemoveAnimationFromLookupCache(Qt3DSDMAnimationHandle inAnimation) const;
+ void AddAnimationToLookupCache(std::shared_ptr<SAnimationTrack> inAnimation) const;
+ void RemoveAnimationFromLookupCache(std::shared_ptr<SAnimationTrack> inAnimation) const;
+
+ void EnsureAnimationCache() const;
+
+ Qt3DSDMAnimationHandle CreateAnimationWithHandle(int inHandle, Qt3DSDMSlideHandle 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/dm/systems/cores/SimpleDataCore.cpp b/src/dm/systems/cores/SimpleDataCore.cpp
new file mode 100644
index 0000000..d6a1470
--- /dev/null
+++ b/src/dm/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 {
+Qt3DSDMDebugLogFunction g_DataModelDebugLogger = 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_DataModelDebugLogger)
+ g_DataModelDebugLogger("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_DataModelDebugLogger)
+ g_DataModelDebugLogger("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)
+{
+ QT3DSDM_LOG_FUNCTION("CSimpleDataCore::AddProperty");
+ QT3DSDM_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()) {
+ QT3DSDM_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 Qt3DSDMPropertyDefinition &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 Qt3DSDMPropertyDefinition &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_DataModelDebugLogger)
+ g_DataModelDebugLogger("CSimpleDataCore::CreateInstance Enter");
+ if (HandleValid(inHandle)) {
+ if (g_DataModelDebugLogger) {
+ g_DataModelDebugLogger("CSimpleDataCore::CreateInstance Handle Exists!!");
+ char buf[32];
+ sprintf(buf, "%d", inHandle);
+ g_DataModelDebugLogger(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_DataModelDebugLogger)
+ g_DataModelDebugLogger("CSimpleDataCore::CreateInstance Leave");
+
+ return inHandle;
+}
+
+Qt3DSDMPropertyHandle CSimpleDataCore::AddPropertyWithHandle(int inHandle,
+ Qt3DSDMInstanceHandle inInstance,
+ TCharPtr inName,
+ DataModelDataType::Value inPropType)
+{
+ QT3DSDM_DEBUG_LOG("CSimpleDataCore::AddPropertyWithHandle Enter");
+ QT3DSDM_DEBUG_LOG(m_StringTable->GetNarrowStr(inName));
+ if (HandleValid(inHandle)) {
+ if (g_DataModelDebugLogger) {
+ g_DataModelDebugLogger("CSimpleDataCore::AddPropertyWithHandle Handle Exists!!");
+ char buf[32];
+ sprintf(buf, "%d", inHandle);
+ g_DataModelDebugLogger(buf);
+ }
+
+ throw HandleExists(L"");
+ }
+
+ TDataModelInstancePtr theInstance = GetInstanceNF(inInstance, m_Objects);
+
+ Qt3DSDMPropertyDefinition 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);
+ QT3DSDM_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/dm/systems/cores/SimpleDataCore.h b/src/dm/systems/cores/SimpleDataCore.h
new file mode 100644
index 0000000..2664dab
--- /dev/null
+++ b/src/dm/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:
+ Qt3DSDMPropertyDefinition m_Definition;
+
+ CDataModelPropertyDefinitionObject(int inHandle, const Qt3DSDMPropertyDefinition &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 Qt3DSDMPropertyDefinition &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/dm/systems/cores/SimpleSlideCore.cpp b/src/dm/systems/cores/SimpleSlideCore.cpp
new file mode 100644
index 0000000..87eadb9
--- /dev/null
+++ b/src/dm/systems/cores/SimpleSlideCore.cpp
@@ -0,0 +1,420 @@
+/****************************************************************************
+**
+** 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 {
+
+Qt3DSDMSlideHandle CSimpleSlideCore::CreateSlide(Qt3DSDMInstanceHandle inInstance)
+{
+ int nextId = GetNextId();
+ return CreateSlideWithHandle(nextId, inInstance);
+}
+
+Qt3DSDMInstanceHandle CSimpleSlideCore::GetSlideInstance(Qt3DSDMSlideHandle 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;
+}
+
+Qt3DSDMSlideHandle 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(Qt3DSDMSlideHandle 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(Qt3DSDMSlideHandle 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, Qt3DSDMSlideHandle>,
+ std::placeholders::_1, std::ref(outSlides)));
+}
+
+float CSimpleSlideCore::GetSlideTime(Qt3DSDMSlideHandle inSlide) const
+{
+ return GetSlideNF(inSlide, m_Objects)->m_Time;
+}
+
+void CSimpleSlideCore::SetSlideTime(Qt3DSDMSlideHandle inSlide, float inNewTime)
+{
+ GetSlideNF(inSlide, m_Objects)->m_Time = inNewTime;
+}
+
+void CSimpleSlideCore::DeriveSlide(Qt3DSDMSlideHandle inSlide, Qt3DSDMSlideHandle 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;
+}
+
+Qt3DSDMSlideHandle CSimpleSlideCore::GetParentSlide(Qt3DSDMSlideHandle inSlide) const
+{
+ return GetSlideNF(inSlide, m_Objects)->m_Parent;
+}
+
+void CSimpleSlideCore::GetChildSlides(Qt3DSDMSlideHandle inSlide,
+ TSlideHandleList &outChildren) const
+{
+ transformv_all(GetSlideNF(inSlide, m_Objects)->m_Children, outChildren);
+}
+
+int CSimpleSlideCore::GetChildIndex(Qt3DSDMSlideHandle inParent, Qt3DSDMSlideHandle 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(Qt3DSDMSlideHandle 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(
+ Qt3DSDMSlideHandle 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(Qt3DSDMSlideHandle 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(Qt3DSDMSlideHandle inSlide,
+ Qt3DSDMInstanceHandle inHandle,
+ Qt3DSDMPropertyHandle inProperty,
+ const SValue &inValue)
+{
+ CSimpleSlideCore::ForceSetPropertyValue(GetStringTable(), m_Objects, inSlide, inHandle,
+ inProperty, inValue);
+}
+
+void CSimpleSlideCore::forceSetInstancePropertyValueOnAllSlides(Qt3DSDMInstanceHandle inInstance,
+ Qt3DSDMPropertyHandle inProperty,
+ const SValue &inValue)
+{
+ for (auto &it : m_Objects) {
+ if (it.second->GetType() == SSlide::s_Type) {
+ Qt3DSDMSlideHandle slide(it.first);
+ ForceSetInstancePropertyValue(slide, inInstance, inProperty, inValue);
+ }
+ }
+}
+
+bool CSimpleSlideCore::GetSpecificInstancePropertyValue(Qt3DSDMSlideHandle 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(Qt3DSDMSlideHandle inSlide,
+ Qt3DSDMInstanceHandle inInstance,
+ TPropertyHandleValuePairList &outValues)
+{
+ const SSlide *theSlide = GetSlideNF(inSlide, m_Objects);
+ theSlide->GetSpecificInstancePropertyValues(inInstance, outValues);
+}
+
+void CSimpleSlideCore::GetSlidePropertyEntries(Qt3DSDMSlideHandle inSlide,
+ TSlideEntryList &outEntries) const
+{
+ const SSlide *theSlide = GetSlideNF(inSlide, m_Objects);
+ theSlide->ToSlideEntryList(outEntries);
+}
+
+bool CSimpleSlideCore::ContainsProperty(Qt3DSDMSlideHandle inSlide, Qt3DSDMInstanceHandle inHandle,
+ Qt3DSDMPropertyHandle inProperty) const
+{
+ const SSlide *theSlide = GetSlideNF(inSlide, m_Objects);
+ return theSlide->GetInstancePropertyValue(inHandle, inProperty) != NULL;
+}
+
+Qt3DSDMSlideHandle 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(Qt3DSDMSlideHandle inSlide,
+ TSlideEntryList &outProperties) const
+{
+ outProperties.clear();
+ GetSlidePropertyEntries(inSlide, outProperties);
+}
+
+bool CSimpleSlideCore::IsSlide(Qt3DSDMSlideHandle inSlide) const
+{
+ return m_Objects.find(inSlide) != m_Objects.end();
+}
+
+void CSimpleSlideCore::ForceSetPropertyValue(IStringTable &inStringTable,
+ THandleObjectMap &inObjects, Qt3DSDMSlideHandle inSlide,
+ Qt3DSDMInstanceHandle inHandle,
+ Qt3DSDMPropertyHandle inProperty, const SValue &inValue)
+{
+ CSimpleSlideCore::GetSlideNF(inSlide, inObjects)
+ ->SetInstancePropertyValue(inHandle, inProperty, SInternValue(inValue, inStringTable));
+}
+
+void CSimpleSlideCore::PushPropertyValueToChildren(Qt3DSDMSlideHandle 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(Qt3DSDMSlideHandle inSlide1,
+ Qt3DSDMSlideHandle 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(Qt3DSDMSlideHandle inSlide1,
+ Qt3DSDMSlideHandle inSlide2,
+ Qt3DSDMSlideHandle 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, Qt3DSDMSlideHandle 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(Qt3DSDMSlideHandle inSlide, THandleObjectMap &inObjects,
+ std::function<void(SSlide *)> inFunction)
+{
+ inFunction(CSimpleSlideCore::GetSlideNF(inSlide, inObjects));
+}
+
+void CSimpleSlideCore::ForEachChild(Qt3DSDMSlideHandle 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(Qt3DSDMSlideHandle 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/dm/systems/cores/SimpleSlideCore.h b/src/dm/systems/cores/SimpleSlideCore.h
new file mode 100644
index 0000000..278ef77
--- /dev/null
+++ b/src/dm/systems/cores/SimpleSlideCore.h
@@ -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$
+**
+****************************************************************************/
+#pragma once
+#ifndef SLIDECOREH
+#define SLIDECOREH
+#include "HandleSystemBase.h"
+#include "Qt3DSDMSlideCore.h"
+#include "SimpleDataCore.h"
+#include "Qt3DSDMStringTable.h"
+#include <unordered_map>
+#include <QtCore/qdebug.h>
+
+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]));
+
+ if (m_Properties.find(theKey) != m_Properties.end()) {
+ // The only known case when this condition happens is when DnD a sub-presentation to
+ // the scene as a texture rect then undoing.
+ qWarning() << __FUNCTION__ << ": Instance/Property Pair" << theKey
+ << "already exists, erasing it.";
+ m_Properties.erase(theKey);
+ }
+
+ 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(); }
+ Qt3DSDMSlideHandle CreateSlide(Qt3DSDMInstanceHandle inInstance) override;
+ Qt3DSDMInstanceHandle GetSlideInstance(Qt3DSDMSlideHandle inSlide) const override;
+ Qt3DSDMSlideHandle GetSlideByInstance(Qt3DSDMInstanceHandle inInstance) const override;
+ void DeleteSlide(Qt3DSDMSlideHandle inSlide, TInstanceHandleList &outInstances) override;
+ void GetSlides(TSlideHandleList &outSlides) const override;
+
+ float GetSlideTime(Qt3DSDMSlideHandle inSlide) const override;
+ void SetSlideTime(Qt3DSDMSlideHandle inSlide, float inNewTime) override;
+
+ void DeriveSlide(Qt3DSDMSlideHandle inSlide, Qt3DSDMSlideHandle inParent, int inIndex = -1) override;
+ Qt3DSDMSlideHandle GetParentSlide(Qt3DSDMSlideHandle inSlide) const override;
+ void GetChildSlides(Qt3DSDMSlideHandle inSlide, TSlideHandleList &outChildren) const override;
+ int GetChildIndex(Qt3DSDMSlideHandle inParent, Qt3DSDMSlideHandle inChild) const override;
+
+ bool GetInstancePropertyValue(Qt3DSDMSlideHandle inSlide, Qt3DSDMInstanceHandle inHandle,
+ Qt3DSDMPropertyHandle inProperty, SValue &outValue) const override;
+ void SetInstancePropertyValue(Qt3DSDMSlideHandle 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(Qt3DSDMSlideHandle inSlide, Qt3DSDMInstanceHandle inHandle,
+ Qt3DSDMPropertyHandle inProperty);
+ void ForceSetInstancePropertyValue(Qt3DSDMSlideHandle inSlide, Qt3DSDMInstanceHandle inHandle,
+ Qt3DSDMPropertyHandle inProperty, const SValue &inValue) override;
+ void forceSetInstancePropertyValueOnAllSlides(Qt3DSDMInstanceHandle inInstance,
+ Qt3DSDMPropertyHandle inProperty,
+ const SValue &inValue) override;
+
+ bool GetSpecificInstancePropertyValue(Qt3DSDMSlideHandle inSlide,
+ Qt3DSDMInstanceHandle inInstance,
+ Qt3DSDMPropertyHandle inProperty, SValue &outValue) const override;
+
+ void GetSpecificInstancePropertyValues(Qt3DSDMSlideHandle inSlide,
+ Qt3DSDMInstanceHandle inInstance,
+ TPropertyHandleValuePairList &outValues) override;
+
+ void GetSlidePropertyEntries(Qt3DSDMSlideHandle inSlide, TSlideEntryList &outEntries) const override;
+
+ void PushPropertyValueToChildren(Qt3DSDMSlideHandle inParent, Qt3DSDMInstanceHandle inHandle,
+ Qt3DSDMPropertyHandle inProperty, const SValue &inValue) override;
+
+ void GetIntersectingProperties(Qt3DSDMSlideHandle inSlide1, Qt3DSDMSlideHandle inSlide2,
+ TSlideEntryList &outEntries) const override;
+ void PushIntersectingProperties(Qt3DSDMSlideHandle inSlide1, Qt3DSDMSlideHandle inSlide2,
+ Qt3DSDMSlideHandle inDestination) override;
+
+ void ClearChildrenPropertyValues(Qt3DSDMSlideHandle 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(Qt3DSDMSlideHandle inSlide, Qt3DSDMInstanceHandle inHandle,
+ Qt3DSDMPropertyHandle inProperty) const override;
+ bool HandleValid(int inHandle) const override { return CHandleBase::HandleValid(inHandle); }
+
+ Qt3DSDMSlideHandle CreateSlideWithHandle(int inHandle, Qt3DSDMInstanceHandle inInstance);
+ void GetSlideProperties(Qt3DSDMSlideHandle inSlide, TSlideEntryList &outProperties) const;
+
+ bool IsSlide(Qt3DSDMSlideHandle inSlide) const override;
+
+ // Possibly alter every slide in the database
+ void ForEachSlide(std::function<void(SSlide *)> inFunction);
+ void ForEachChild(Qt3DSDMSlideHandle inSlide, std::function<void(SSlide *)> inFunction);
+
+ // Only implemented at the producer level, not at this lower level.
+ void CopyProperties(Qt3DSDMSlideHandle /*inSourceSlide*/,
+ Qt3DSDMInstanceHandle /*inSourceInstance*/,
+ Qt3DSDMSlideHandle /*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,
+ Qt3DSDMSlideHandle inSlide, Qt3DSDMInstanceHandle inHandle,
+ Qt3DSDMPropertyHandle inProperty, const SValue &inValue);
+
+ static void ClearPropertyValue(THandleObjectMap &inObjects, Qt3DSDMSlideHandle 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/dm/systems/cores/SimpleSlideGraphCore.cpp b/src/dm/systems/cores/SimpleSlideGraphCore.cpp
new file mode 100644
index 0000000..5f1de1e
--- /dev/null
+++ b/src/dm/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 {
+
+Qt3DSDMSlideGraphHandle CSimpleSlideGraphCore::CreateSlideGraph(Qt3DSDMSlideHandle inRoot)
+{
+ int nextId = GetNextId();
+ return CreateSlideGraphWithHandle(nextId, inRoot);
+}
+
+Qt3DSDMSlideHandle CSimpleSlideGraphCore::GetGraphRoot(Qt3DSDMSlideGraphHandle inGraph) const
+{
+ return GetSlideGraphNF(inGraph, m_Objects)->m_Root;
+}
+
+inline bool RootSlideMatches(const THandleObjectPair &inPair, Qt3DSDMSlideHandle inSlide)
+{
+ const SSlideGraph *theGraph = static_cast<SSlideGraph *>(inPair.second.get());
+ if (theGraph->m_Root == inSlide)
+ return true;
+ return false;
+}
+
+Qt3DSDMSlideGraphHandle CSimpleSlideGraphCore::GetSlideGraph(Qt3DSDMSlideHandle 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 Qt3DSDMSlideGraphHandle 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(Qt3DSDMSlideGraphHandle 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(Qt3DSDMSlideGraphHandle inSlideGraph,
+ Qt3DSDMSlideHandle 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(Qt3DSDMSlideGraphHandle 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<Qt3DSDMSlideHandle, 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(Qt3DSDMSlideGraphHandle inGraph,
+ Qt3DSDMSlideHandle inSlide)
+{
+ GetSlideGraphNF(inGraph, m_Objects)->m_ActiveSlide = inSlide;
+}
+
+Qt3DSDMSlideHandle CSimpleSlideGraphCore::GetGraphActiveSlide(Qt3DSDMSlideGraphHandle 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);
+}
+
+Qt3DSDMSlideGraphHandle CSimpleSlideGraphCore::CreateSlideGraphWithHandle(int inHandle,
+ Qt3DSDMSlideHandle inRoot)
+{
+ m_Objects.insert(make_pair(inHandle, (THandleObjectPtr) new SSlideGraph(inHandle, inRoot)));
+ return inHandle;
+}
+}
diff --git a/src/dm/systems/cores/SimpleSlideGraphCore.h b/src/dm/systems/cores/SimpleSlideGraphCore.h
new file mode 100644
index 0000000..484d675
--- /dev/null
+++ b/src/dm/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)
+ {
+ }
+ Qt3DSDMSlideHandle m_Root;
+ Qt3DSDMSlideHandle 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<Qt3DSDMSlideGraphHandle, Qt3DSDMSlideHandle>, std::hash<int>>
+ TInstanceToGraphMap;
+ typedef std::unordered_map<Qt3DSDMSlideGraphHandle, 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.
+ */
+ Qt3DSDMSlideGraphHandle CreateSlideGraph(Qt3DSDMSlideHandle inRoot) override;
+ Qt3DSDMSlideHandle GetGraphRoot(Qt3DSDMSlideGraphHandle inGraph) const override;
+ Qt3DSDMSlideGraphHandle GetSlideGraph(Qt3DSDMSlideHandle inSlide) const override;
+ void GetSlideGraphs(TSlideGraphHandleList &outGraphs) const override;
+ void DeleteSlideGraph(Qt3DSDMSlideGraphHandle 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(Qt3DSDMSlideGraphHandle inSlideGraph, Qt3DSDMSlideHandle inSlide,
+ Qt3DSDMInstanceHandle inInstance) override;
+ void GetAssociatedInstances(Qt3DSDMSlideGraphHandle 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(Qt3DSDMSlideGraphHandle inGraph, Qt3DSDMSlideHandle inSlide) override;
+ Qt3DSDMSlideHandle GetGraphActiveSlide(Qt3DSDMSlideGraphHandle inGraph) const override;
+
+ bool HandleValid(int inHandle) const override;
+
+ Qt3DSDMSlideGraphHandle CreateSlideGraphWithHandle(int inHandle, Qt3DSDMSlideHandle 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/dm/systems/cores/SlideCoreProducer.cpp b/src/dm/systems/cores/SlideCoreProducer.cpp
new file mode 100644
index 0000000..86b0d1f
--- /dev/null
+++ b/src/dm/systems/cores/SlideCoreProducer.cpp
@@ -0,0 +1,562 @@
+/****************************************************************************
+**
+** 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 {
+
+Qt3DSDMSlideHandle CSlideCoreProducer::CreateSlide(Qt3DSDMInstanceHandle inInstance)
+{
+ Qt3DSDMSlideHandle retval = m_Data->CreateSlide(inInstance);
+ CREATE_HANDLE_CREATE_TRANSACTION(m_Consumer, retval, m_Data->m_Objects);
+ GetSignalSender()->SendSlideCreated(retval);
+ return retval;
+}
+
+Qt3DSDMInstanceHandle CSlideCoreProducer::GetSlideInstance(Qt3DSDMSlideHandle inSlide) const
+{
+ return m_Data->GetSlideInstance(inSlide);
+}
+
+Qt3DSDMSlideHandle CSlideCoreProducer::GetSlideByInstance(Qt3DSDMInstanceHandle inSlide) const
+{
+ return m_Data->GetSlideByInstance(inSlide);
+}
+
+void SendPropertyRemoved(const TSlideEntry &inEntry, Qt3DSDMSlideHandle inSlide,
+ ISlideCoreSignalSender *inSender)
+{
+ inSender->SendPropertyValueRemoved(inSlide, get<0>(inEntry), get<1>(inEntry), get<2>(inEntry));
+}
+
+void RecurseCreateDeleteTransactions(TTransactionConsumerPtr inConsumer, Qt3DSDMSlideHandle 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(Qt3DSDMSlideHandle 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(Qt3DSDMSlideHandle inSlide) const
+{
+ return m_Data->GetSlideTime(inSlide);
+}
+
+void CSlideCoreProducer::SetSlideTime(Qt3DSDMSlideHandle 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(Qt3DSDMSlideHandle inSlide, Qt3DSDMSlideHandle 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);
+}
+
+Qt3DSDMSlideHandle CSlideCoreProducer::GetParentSlide(Qt3DSDMSlideHandle inSlide) const
+{
+ return m_Data->GetParentSlide(inSlide);
+}
+
+void CSlideCoreProducer::GetChildSlides(Qt3DSDMSlideHandle inSlide,
+ TSlideHandleList &outChildren) const
+{
+ m_Data->GetChildSlides(inSlide, outChildren);
+}
+
+int CSlideCoreProducer::GetChildIndex(Qt3DSDMSlideHandle inParent, Qt3DSDMSlideHandle inChild) const
+{
+ return m_Data->GetChildIndex(inParent, inChild);
+}
+
+bool CSlideCoreProducer::GetInstancePropertyValue(Qt3DSDMSlideHandle 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(Qt3DSDMSlideHandle 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(Qt3DSDMSlideHandle 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);
+ QT3DSDM_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(Qt3DSDMSlideHandle inSlide,
+ Qt3DSDMInstanceHandle inHandle,
+ Qt3DSDMPropertyHandle inProperty,
+ const SValue &inValue)
+{
+ if (m_Consumer)
+ DoForceSetInstancePropertyValue(inSlide, inHandle, inProperty, inValue);
+ else
+ m_Data->ForceSetInstancePropertyValue(inSlide, inHandle, inProperty, inValue);
+}
+
+void CSlideCoreProducer::forceSetInstancePropertyValueOnAllSlides(Qt3DSDMInstanceHandle inInstance,
+ Qt3DSDMPropertyHandle inProperty,
+ const SValue &inValue)
+{
+ m_Data->forceSetInstancePropertyValueOnAllSlides(inInstance, inProperty, inValue);
+}
+
+bool CSlideCoreProducer::GetSpecificInstancePropertyValue(Qt3DSDMSlideHandle inSlide,
+ Qt3DSDMInstanceHandle inInstance,
+ Qt3DSDMPropertyHandle inProperty,
+ SValue &outValue) const
+{
+ return m_Data->GetSpecificInstancePropertyValue(inSlide, inInstance, inProperty, outValue);
+}
+
+bool CSlideCoreProducer::ContainsProperty(Qt3DSDMSlideHandle inSlide, Qt3DSDMInstanceHandle inHandle,
+ Qt3DSDMPropertyHandle inProperty) const
+{
+ return m_Data->ContainsProperty(inSlide, inHandle, inProperty);
+}
+
+void CSlideCoreProducer::GetSlidePropertyEntries(Qt3DSDMSlideHandle inSlide,
+ TSlideEntryList &outEntries) const
+{
+ return m_Data->GetSlidePropertyEntries(inSlide, outEntries);
+}
+
+void CSlideCoreProducer::PushPropertyValueToChildren(Qt3DSDMSlideHandle 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(Qt3DSDMSlideHandle 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(Qt3DSDMSlideHandle inSlide1,
+ Qt3DSDMSlideHandle 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,
+ Qt3DSDMSlideHandle inSource, Qt3DSDMSlideHandle 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(Qt3DSDMSlideHandle inSlide1,
+ Qt3DSDMSlideHandle inSlide2,
+ Qt3DSDMSlideHandle 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(Qt3DSDMSlideHandle inSourceSlide,
+ Qt3DSDMInstanceHandle inSourceInstance,
+ Qt3DSDMSlideHandle 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(Qt3DSDMSlideHandle 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(Qt3DSDMSlideHandle)> &inCallback)
+{
+ return GetSignalProvider()->ConnectSlideCreated(inCallback);
+}
+TSignalConnectionPtr CSlideCoreProducer::ConnectBeforeSlideDeleted(
+ const std::function<void(Qt3DSDMSlideHandle)> &inCallback)
+{
+ return GetSignalProvider()->ConnectBeforeSlideDeleted(inCallback);
+}
+TSignalConnectionPtr
+CSlideCoreProducer::ConnectSlideDeleted(const std::function<void(Qt3DSDMSlideHandle)> &inCallback)
+{
+ return GetSignalProvider()->ConnectSlideDeleted(inCallback);
+}
+TSignalConnectionPtr CSlideCoreProducer::ConnectSlideDerived(
+ const std::function<void(Qt3DSDMSlideHandle, Qt3DSDMSlideHandle, int)> &inCallback)
+{
+ return GetSignalProvider()->ConnectSlideDerived(inCallback);
+}
+TSignalConnectionPtr CSlideCoreProducer::ConnectInstancePropertyValueSet(
+ const std::function<void(Qt3DSDMSlideHandle, Qt3DSDMInstanceHandle, Qt3DSDMPropertyHandle,
+ const SValue &)> &inCallback)
+{
+ return GetSignalProvider()->ConnectInstancePropertyValueSet(inCallback);
+}
+TSignalConnectionPtr CSlideCoreProducer::ConnectInstancePropertyValueRemoved(
+ const std::function<void(Qt3DSDMSlideHandle, Qt3DSDMInstanceHandle, Qt3DSDMPropertyHandle,
+ const SValue &)> &inCallback)
+{
+ return GetSignalProvider()->ConnectInstancePropertyValueRemoved(inCallback);
+}
+TSignalConnectionPtr CSlideCoreProducer::ConnectSlideTimeChanged(
+ const std::function<void(Qt3DSDMSlideHandle)> &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/dm/systems/cores/SlideCoreProducer.h b/src/dm/systems/cores/SlideCoreProducer.h
new file mode 100644
index 0000000..dec0297
--- /dev/null
+++ b/src/dm/systems/cores/SlideCoreProducer.h
@@ -0,0 +1,190 @@
+/****************************************************************************
+**
+** 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; }
+
+ Qt3DSDMSlideHandle CreateSlide(Qt3DSDMInstanceHandle inInstance) override;
+ Qt3DSDMInstanceHandle GetSlideInstance(Qt3DSDMSlideHandle inSlide) const override;
+ Qt3DSDMSlideHandle GetSlideByInstance(Qt3DSDMInstanceHandle inSlide) const override;
+ void DeleteSlide(Qt3DSDMSlideHandle inSlide, TInstanceHandleList &outInstances) override;
+ void GetSlides(TSlideHandleList &outSlides) const override;
+
+ float GetSlideTime(Qt3DSDMSlideHandle inSlide) const override;
+ void SetSlideTime(Qt3DSDMSlideHandle inSlide, float inNewTime) override;
+
+ void DeriveSlide(Qt3DSDMSlideHandle inSlide, Qt3DSDMSlideHandle inParent, int inIndex = -1) override;
+ Qt3DSDMSlideHandle GetParentSlide(Qt3DSDMSlideHandle inSlide) const override;
+ void GetChildSlides(Qt3DSDMSlideHandle inSlide, TSlideHandleList &outChildren) const override;
+ int GetChildIndex(Qt3DSDMSlideHandle inParent, Qt3DSDMSlideHandle inChild) const override;
+
+ bool GetInstancePropertyValue(Qt3DSDMSlideHandle inSlide, Qt3DSDMInstanceHandle inHandle,
+ Qt3DSDMPropertyHandle inProperty, SValue &outValue) const override;
+ void SetInstancePropertyValue(Qt3DSDMSlideHandle inSlide, Qt3DSDMInstanceHandle inHandle,
+ Qt3DSDMPropertyHandle inProperty, const SValue &inValue) override;
+ void ForceSetInstancePropertyValue(Qt3DSDMSlideHandle inSlide, Qt3DSDMInstanceHandle inHandle,
+ Qt3DSDMPropertyHandle inProperty, const SValue &inValue) override;
+ void forceSetInstancePropertyValueOnAllSlides(Qt3DSDMInstanceHandle inInstance,
+ Qt3DSDMPropertyHandle inProperty,
+ const SValue &inValue) override;
+ bool GetSpecificInstancePropertyValue(Qt3DSDMSlideHandle inSlide,
+ Qt3DSDMInstanceHandle inInstance,
+ Qt3DSDMPropertyHandle inProperty, SValue &outValue) const override;
+ void GetSpecificInstancePropertyValues(Qt3DSDMSlideHandle inSlide,
+ Qt3DSDMInstanceHandle inInstance,
+ TPropertyHandleValuePairList &outValues) override
+ {
+ return m_Data->GetSpecificInstancePropertyValues(inSlide, inInstance, outValues);
+ }
+ bool ContainsProperty(Qt3DSDMSlideHandle inSlide, Qt3DSDMInstanceHandle inHandle,
+ Qt3DSDMPropertyHandle inProperty) const override;
+ void GetSlidePropertyEntries(Qt3DSDMSlideHandle inSlide, TSlideEntryList &outEntries) const override;
+
+ void PushPropertyValueToChildren(Qt3DSDMSlideHandle inParent, Qt3DSDMInstanceHandle inHandle,
+ Qt3DSDMPropertyHandle inProperty, const SValue &inValue) override;
+ void ClearChildrenPropertyValues(Qt3DSDMSlideHandle 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(Qt3DSDMSlideHandle inSlide1, Qt3DSDMSlideHandle inSlide2,
+ TSlideEntryList &outEntries) const override;
+ void PushIntersectingProperties(Qt3DSDMSlideHandle inSlide1, Qt3DSDMSlideHandle inSlide2,
+ Qt3DSDMSlideHandle inDestination) override;
+ void CopyProperties(Qt3DSDMSlideHandle inSourceSlide, Qt3DSDMInstanceHandle inSourceInstance,
+ Qt3DSDMSlideHandle inDestSlide, Qt3DSDMInstanceHandle inDestInstance) override;
+
+ bool IsSlide(Qt3DSDMSlideHandle inSlide) const override;
+
+ bool HandleValid(int inHandle) const override;
+
+ void SetConsumer(TTransactionConsumerPtr inConsumer) override;
+
+ //===================================================================
+ // Signals
+ //===================================================================
+
+ virtual TSignalConnectionPtr
+ ConnectSlideCreated(const std::function<void(Qt3DSDMSlideHandle)> &inCallback) override;
+ virtual TSignalConnectionPtr
+ ConnectBeforeSlideDeleted(const std::function<void(Qt3DSDMSlideHandle)> &inCallback) override;
+ virtual TSignalConnectionPtr
+ ConnectSlideDeleted(const std::function<void(Qt3DSDMSlideHandle)> &inCallback) override;
+ TSignalConnectionPtr ConnectSlideDerived(
+ const std::function<void(Qt3DSDMSlideHandle, Qt3DSDMSlideHandle, int)> &inCallback) override;
+ TSignalConnectionPtr ConnectInstancePropertyValueSet(
+ const std::function<void(Qt3DSDMSlideHandle, Qt3DSDMInstanceHandle, Qt3DSDMPropertyHandle,
+ const SValue &)> &inCallback) override;
+ TSignalConnectionPtr ConnectInstancePropertyValueRemoved(
+ const std::function<void(Qt3DSDMSlideHandle, Qt3DSDMInstanceHandle, Qt3DSDMPropertyHandle,
+ const SValue &)> &inCallback) override;
+ virtual TSignalConnectionPtr
+ ConnectSlideTimeChanged(const std::function<void(Qt3DSDMSlideHandle)> &inCallback) override;
+
+private:
+ inline void DoForceSetInstancePropertyValue(Qt3DSDMSlideHandle inSlide,
+ Qt3DSDMInstanceHandle inHandle,
+ Qt3DSDMPropertyHandle inProperty,
+ const SValue &inValue);
+ void InitSignaller();
+ ISlideCoreSignalProvider *GetSignalProvider();
+ ISlideCoreSignalSender *GetSignalSender();
+};
+}
+
+#endif
diff --git a/src/dm/systems/cores/SlideGraphCoreProducer.cpp b/src/dm/systems/cores/SlideGraphCoreProducer.cpp
new file mode 100644
index 0000000..c514108
--- /dev/null
+++ b/src/dm/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 {
+
+Qt3DSDMSlideGraphHandle CSlideGraphCoreProducer::CreateSlideGraph(Qt3DSDMSlideHandle inRoot)
+{
+ Qt3DSDMSlideGraphHandle retval(m_Data->CreateSlideGraph(inRoot));
+ CREATE_HANDLE_CREATE_TRANSACTION(m_Consumer, retval, m_Data->m_Objects);
+ GetSignalSender()->SendGraphCreated(retval, inRoot);
+ return retval;
+}
+
+Qt3DSDMSlideHandle CSlideGraphCoreProducer::GetGraphRoot(Qt3DSDMSlideGraphHandle inGraph) const
+{
+ return m_Data->GetGraphRoot(inGraph);
+}
+
+Qt3DSDMSlideGraphHandle CSlideGraphCoreProducer::GetSlideGraph(Qt3DSDMSlideHandle 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;
+ Qt3DSDMSlideGraphHandle m_Handle;
+ TSlideInstancePairList m_Instances;
+ DissocateAllInstanceTrans(const char *inFile, int inLine,
+ std::shared_ptr<CSimpleSlideGraphCore> inGraph,
+ Qt3DSDMSlideGraphHandle 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(Qt3DSDMSlideGraphHandle inHandle)
+{
+ SSlideGraph *theGraph = CSimpleSlideGraphCore::GetSlideGraphNF(inHandle, m_Data->m_Objects);
+ Qt3DSDMSlideHandle 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;
+ Qt3DSDMSlideGraphHandle m_GraphHandle;
+ Qt3DSDMSlideHandle m_Slide;
+ Qt3DSDMInstanceHandle m_Instance;
+ bool m_InsertOnDo;
+ SInstanceAssociateTrans(const char *inFile, int inLine,
+ std::shared_ptr<CSimpleSlideGraphCore> inGraph,
+ Qt3DSDMSlideGraphHandle inGraphHandle, Qt3DSDMSlideHandle 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(Qt3DSDMSlideGraphHandle inSlideGraph,
+ Qt3DSDMSlideHandle 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(Qt3DSDMSlideGraphHandle 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(Qt3DSDMSlideGraphHandle inGraph,
+ Qt3DSDMSlideHandle inSlide)
+{
+ if (m_Consumer) {
+ Qt3DSDMSlideHandle 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);
+}
+
+Qt3DSDMSlideHandle CSlideGraphCoreProducer::GetGraphActiveSlide(Qt3DSDMSlideGraphHandle 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(Qt3DSDMSlideGraphHandle, Qt3DSDMSlideHandle)> &inCallback)
+{
+ return GetSignalProvider()->ConnectGraphCreated(inCallback);
+}
+TSignalConnectionPtr CSlideGraphCoreProducer::ConnectGraphDeleted(
+ const std::function<void(Qt3DSDMSlideGraphHandle, Qt3DSDMSlideHandle)> &inCallback)
+{
+ return GetSignalProvider()->ConnectGraphDeleted(inCallback);
+}
+TSignalConnectionPtr CSlideGraphCoreProducer::ConnectInstanceAssociated(
+ const std::function<void(Qt3DSDMSlideGraphHandle, Qt3DSDMSlideHandle, Qt3DSDMInstanceHandle)>
+ &inCallback)
+{
+ return GetSignalProvider()->ConnectInstanceAssociated(inCallback);
+}
+TSignalConnectionPtr CSlideGraphCoreProducer::ConnectInstanceDissociated(
+ const std::function<void(Qt3DSDMSlideGraphHandle, Qt3DSDMSlideHandle, Qt3DSDMInstanceHandle)>
+ &inCallback)
+{
+ return GetSignalProvider()->ConnectInstanceDissociated(inCallback);
+}
+TSignalConnectionPtr CSlideGraphCoreProducer::ConnectGraphActiveSlide(
+ const std::function<void(Qt3DSDMSlideGraphHandle, Qt3DSDMSlideHandle)> &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/dm/systems/cores/SlideGraphCoreProducer.h b/src/dm/systems/cores/SlideGraphCoreProducer.h
new file mode 100644
index 0000000..5b34cdb
--- /dev/null
+++ b/src/dm/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; }
+
+ Qt3DSDMSlideGraphHandle CreateSlideGraph(Qt3DSDMSlideHandle inRoot) override;
+ Qt3DSDMSlideHandle GetGraphRoot(Qt3DSDMSlideGraphHandle inGraph) const override;
+ Qt3DSDMSlideGraphHandle GetSlideGraph(Qt3DSDMSlideHandle inSlide) const override;
+ void GetSlideGraphs(TSlideGraphHandleList &outGraphs) const override;
+ void DeleteSlideGraph(Qt3DSDMSlideGraphHandle inHandle) override;
+
+ void AssociateInstance(Qt3DSDMSlideGraphHandle inSlideGraph, Qt3DSDMSlideHandle inSlide,
+ Qt3DSDMInstanceHandle inInstance) override;
+ void GetAssociatedInstances(Qt3DSDMSlideGraphHandle inSlideGraph,
+ TSlideInstancePairList &outAssociations) const override;
+ TGraphSlidePair GetAssociatedGraph(Qt3DSDMInstanceHandle inInstance) const override;
+ void DissociateInstance(Qt3DSDMInstanceHandle inInstance) override;
+
+ void SetGraphActiveSlide(Qt3DSDMSlideGraphHandle inGraph, Qt3DSDMSlideHandle inSlide) override;
+ Qt3DSDMSlideHandle GetGraphActiveSlide(Qt3DSDMSlideGraphHandle inGraph) const override;
+
+ bool HandleValid(int inHandle) const override;
+ void SetConsumer(TTransactionConsumerPtr inConsumer) override;
+
+ //===================================================================
+ // Signals
+ //===================================================================
+ TSignalConnectionPtr ConnectGraphCreated(
+ const std::function<void(Qt3DSDMSlideGraphHandle, Qt3DSDMSlideHandle)> &inCallback) override;
+ TSignalConnectionPtr ConnectGraphDeleted(
+ const std::function<void(Qt3DSDMSlideGraphHandle, Qt3DSDMSlideHandle)> &inCallback) override;
+ TSignalConnectionPtr ConnectInstanceAssociated(
+ const std::function<void(Qt3DSDMSlideGraphHandle, Qt3DSDMSlideHandle, Qt3DSDMInstanceHandle)>
+ &inCallback) override;
+ TSignalConnectionPtr ConnectInstanceDissociated(
+ const std::function<void(Qt3DSDMSlideGraphHandle, Qt3DSDMSlideHandle, Qt3DSDMInstanceHandle)>
+ &inCallback) override;
+ TSignalConnectionPtr ConnectGraphActiveSlide(
+ const std::function<void(Qt3DSDMSlideGraphHandle, Qt3DSDMSlideHandle)> &inCallback) override;
+
+private:
+ void InitSignaller();
+ ISlideGraphCoreSignalProvider *GetSignalProvider();
+ ISlideGraphCoreSignalSender *GetSignalSender();
+};
+}
+
+#endif