diff options
Diffstat (limited to 'src/dm/systems/SlideSystem.cpp')
-rw-r--r-- | src/dm/systems/SlideSystem.cpp | 867 |
1 files changed, 867 insertions, 0 deletions
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); +} +} |