/**************************************************************************** ** ** 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 inline void VecInsert(std::vector &inItems, const TItemType &inItem, size_t inIndex) { inItems.insert(inItems.begin() + inIndex, inItem); } template inline void VecErase(std::vector &inItems, const TItemType &inItem) { erase_if(inItems, std::bind(std::equal_to(), inItem, std::placeholders::_1)); } template inline void VecInsertTransaction(const char *inFile, int inLine, std::vector &inItems, size_t inIndex, TTransactionConsumerPtr &inConsumer) { TItemType theItem = inItems.at(inIndex); TTransactionPtr theTransaction(DoCreateGenericTransaction( inFile, inLine, std::bind(VecInsert, std::ref(inItems), theItem, inIndex), std::bind(VecErase, std::ref(inItems), theItem))); inConsumer->OnTransaction(theTransaction); } template inline void VecEraseTransaction(const char *inFile, int inLine, std::vector &inItems, size_t inIndex, const TItemType &inItem, TTransactionConsumerPtr &inConsumer) { TTransactionPtr theTransaction(DoCreateGenericTransaction( inFile, inLine, std::bind(VecErase, std::ref(inItems), inItem), std::bind(VecInsert, std::ref(inItems), inItem, inIndex))); inConsumer->OnTransaction(theTransaction); } template inline void CreateVecInsertTransaction(const char *inFile, int inLine, TTransactionConsumerPtr inConsumer, const TItemType &inItem, std::vector &inItems) { using namespace std; size_t theDistance = distance(inItems.begin(), find(inItems.begin(), inItems.end(), inItem)); RunWithConsumer(inConsumer, std::bind(VecInsertTransaction, inFile, inLine, std::ref(inItems), theDistance, std::placeholders::_1)); } template inline void CreateVecEraseTransaction(const char *inFile, int inLine, TTransactionConsumerPtr inConsumer, const TItemType &inItem, std::vector &inItems) { using namespace std; size_t theDistance = distance(inItems.begin(), find(inItems.begin(), inItems.end(), inItem)); RunWithConsumer(inConsumer, std::bind(VecEraseTransaction, inFile, inLine, std::ref(inItems), theDistance, std::ref(inItem), std::placeholders::_1)); } template struct HashMapAction { std::unordered_map &m_HashMap; std::pair m_Value; HashMapAction(std::unordered_map &map, const std::pair &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 struct HashMapInsertTransaction : public HashMapAction, public ITransaction, public IMergeableTransaction { typedef HashMapAction base; HashMapInsertTransaction(const char *inFile, int inLine, std::unordered_map &map, const std::pair &val) : HashMapAction(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 struct HashMapEraseTransaction : public HashMapAction, public ITransaction { typedef HashMapAction base; HashMapEraseTransaction(const char *inFile, int inLine, std::unordered_map &map, const std::pair &val) : HashMapAction(map, val) , ITransaction(inFile, inLine) { } void Do() override { base::Remove(); } void Undo() override { base::Add(); } }; template inline std::shared_ptr> CreateHashMapInsertTransaction(const char *inFile, int inLine, TTransactionConsumerPtr inConsumer, const std::pair &inItem, std::unordered_map &inItems) { using namespace std; std::shared_ptr> retval; if (inConsumer) { std::shared_ptr> transaction( std::make_shared>( inFile, inLine, std::ref(inItems), std::cref(inItem))); retval = static_pointer_cast>(transaction); inConsumer->OnTransaction(static_pointer_cast(transaction)); } return retval; } template inline void CreateHashMapEraseTransaction(const char *inFile, int inLine, TTransactionConsumerPtr inConsumer, const std::pair &inItem, std::unordered_map &inItems) { using namespace std; if (inConsumer) inConsumer->OnTransaction(static_pointer_cast( std::make_shared>( inFile, inLine, std::ref(inItems), std::cref(inItem)))); } template struct HashMapSwapTransaction : public ITransaction, public IMergeableTransaction { typedef std::unordered_map 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 inline std::shared_ptr> CreateHashMapSwapTransaction(const char *inFile, int inLine, TTransactionConsumerPtr inConsumer, const TKeyType &inKey, const TValueType &inOldValue, const TValueType &inNewValue, std::unordered_map &inItems) { using namespace std; std::shared_ptr> retval; if (inConsumer) { std::shared_ptr> transaction = std::make_shared>( inFile, inLine, std::ref(inItems), inKey, inOldValue, inNewValue); retval = static_pointer_cast>(transaction); inConsumer->OnTransaction(static_pointer_cast(transaction)); } return retval; } } #endif