From 91f315f9ce27e5ff95cb6f4c2a88673ded983bd8 Mon Sep 17 00:00:00 2001 From: samcake Date: Thu, 6 Apr 2017 11:27:48 -0700 Subject: [PATCH] Adding the concept of selection to the scene --- libraries/render/src/render/Scene.cpp | 45 ++++++++++++++++++++--- libraries/render/src/render/Scene.h | 21 ++++++++++- libraries/render/src/render/Selection.cpp | 35 +++++++++++++++++- libraries/render/src/render/Selection.h | 15 ++++++-- 4 files changed, 104 insertions(+), 12 deletions(-) diff --git a/libraries/render/src/render/Scene.cpp b/libraries/render/src/render/Scene.cpp index 537d8c1337..0e77b389a0 100644 --- a/libraries/render/src/render/Scene.cpp +++ b/libraries/render/src/render/Scene.cpp @@ -18,8 +18,8 @@ using namespace render; void Transaction::resetItem(ItemID id, const PayloadPointer& payload) { if (payload) { - _resetItems.push_back(id); - _resetPayloads.push_back(payload); + _resetItems.emplace_back(id); + _resetPayloads.emplace_back(payload); } else { qCDebug(renderlogging) << "WARNING: Transaction::resetItem with a null payload!"; removeItem(id); @@ -27,12 +27,16 @@ void Transaction::resetItem(ItemID id, const PayloadPointer& payload) { } void Transaction::removeItem(ItemID id) { - _removedItems.push_back(id); + _removedItems.emplace_back(id); } void Transaction::updateItem(ItemID id, const UpdateFunctorPointer& functor) { - _updatedItems.push_back(id); - _updateFunctors.push_back(functor); + _updatedItems.emplace_back(id); + _updateFunctors.emplace_back(functor); +} + +void Transaction::resetSelection(const Selection& selection) { + _resetSelections.emplace_back(selection); } void Transaction::merge(const Transaction& transaction) { @@ -41,8 +45,10 @@ void Transaction::merge(const Transaction& transaction) { _removedItems.insert(_removedItems.end(), transaction._removedItems.begin(), transaction._removedItems.end()); _updatedItems.insert(_updatedItems.end(), transaction._updatedItems.begin(), transaction._updatedItems.end()); _updateFunctors.insert(_updateFunctors.end(), transaction._updateFunctors.begin(), transaction._updateFunctors.end()); + _resetSelections.insert(_resetSelections.end(), transaction._resetSelections.begin(), transaction._resetSelections.end()); } + Scene::Scene(glm::vec3 origin, float size) : _masterSpatialTree(origin, size) { @@ -112,6 +118,13 @@ void Scene::processTransactionQueue() { // Update the numItemsAtomic counter AFTER the pending changes went through _numAllocatedItems.exchange(maxID); } + + if (consolidatedTransaction.touchTransactions()) { + std::unique_lock lock(_selectionsMutex); + + // resets and potential NEW items + resetSelections(consolidatedTransaction._resetSelections); + } } void Scene::resetItems(const ItemIDs& ids, Payloads& payloads) { @@ -202,3 +215,25 @@ void Scene::updateItems(const ItemIDs& ids, UpdateFunctors& functors) { updateFunctor++; } } + +// THis fucntion is thread safe +Selection Scene::getSelection(const Selection::Name& name) const { + std::unique_lock lock(_selectionsMutex); + auto found = _selections.find(name); + if (found == _selections.end()) { + return Selection(); + } else { + return (*found).second; + } +} + +void Scene::resetSelections(const Selections& selections) { + for (auto selection : selections) { + auto found = _selections.find(selection.getName()); + if (found == _selections.end()) { + _selections.insert(SelectionMap::value_type(selection.getName(), selection)); + } else { + (*found).second = selection; + } + } +} diff --git a/libraries/render/src/render/Scene.h b/libraries/render/src/render/Scene.h index b9aa6d3d2a..fc0a8c1fca 100644 --- a/libraries/render/src/render/Scene.h +++ b/libraries/render/src/render/Scene.h @@ -34,6 +34,7 @@ public: Transaction() {} ~Transaction() {} + // Item transactions void resetItem(ItemID id, const PayloadPointer& payload); void removeItem(ItemID id); @@ -44,14 +45,22 @@ public: void updateItem(ItemID id, const UpdateFunctorPointer& functor); void updateItem(ItemID id) { updateItem(id, nullptr); } + // Selection transactions + void resetSelection(const Selection& selection); + void merge(const Transaction& transaction); + // Checkers if there is work to do when processing the transaction + bool touchTransactions() const { return !_resetSelections.empty(); } + ItemIDs _resetItems; Payloads _resetPayloads; ItemIDs _removedItems; ItemIDs _updatedItems; UpdateFunctors _updateFunctors; + Selections _resetSelections; + protected: }; typedef std::queue TransactionQueue; @@ -82,6 +91,10 @@ public: // Process the pending transactions queued void processTransactionQueue(); + // Access a particular selection (empty if doesn't exist) + // Thread safe + Selection getSelection(const Selection::Name& name) const; + // This next call are NOT threadsafe, you have to call them from the correct thread to avoid any potential issues // Access a particular item form its ID @@ -117,9 +130,15 @@ protected: // The Selection map - std::mutex _selectionsMutex; + mutable std::mutex _selectionsMutex; // mutable so it can be used in the thread safe getSelection const method SelectionMap _selections; + void resetSelections(const Selections& selections); + // More actions coming to selections soon: + // void removeFromSelection(const Selection& selection); + // void appendToSelection(const Selection& selection); + // void mergeWithSelection(const Selection& selection); + friend class Engine; }; diff --git a/libraries/render/src/render/Selection.cpp b/libraries/render/src/render/Selection.cpp index ba72953455..0501a1f80d 100644 --- a/libraries/render/src/render/Selection.cpp +++ b/libraries/render/src/render/Selection.cpp @@ -14,11 +14,42 @@ using namespace render; -Selection::Selection(const std::string& name, const ItemIDs items) : + +Selection::Selection() : +_name(), +_items() +{ +} + +Selection::Selection(const Selection& selection) : +_name(selection._name), +_items(selection._items) +{ +} + +Selection& Selection::operator= (const Selection& selection) { + _name = (selection._name); + _items = (selection._items); + return (*this); +} + +Selection::Selection(Selection&& selection) : +_name(selection._name), +_items(selection._items) +{ +} + + +Selection& Selection::operator= (Selection&& selection) { + _name = (selection._name); + _items = (selection._items); + return (*this); +} + +Selection::Selection(const Name& name, const ItemIDs& items) : _name(name), _items(items) { - } Selection::~Selection() { diff --git a/libraries/render/src/render/Selection.h b/libraries/render/src/render/Selection.h index 64bfb2455f..7623e53910 100644 --- a/libraries/render/src/render/Selection.h +++ b/libraries/render/src/render/Selection.h @@ -18,21 +18,28 @@ namespace render { class Selection { public: + using Name = std::string; - Selection(const std::string& name, const ItemIDs items); ~Selection(); + Selection(); + Selection(const Selection& selection); + Selection& operator= (const Selection& selection); + Selection(Selection&& selection); + Selection& operator= (Selection&& selection); - const std::string& getName() const { return _name; } + Selection(const Name& name, const ItemIDs& items); + + const Name& getName() const { return _name; } const ItemIDs& getItems() const { return _items; } protected: - const std::string _name; + Name _name; ItemIDs _items; }; using Selections = std::vector; - using SelectionMap = std::map; + using SelectionMap = std::map; }