Adding the concept of selection to the scene

This commit is contained in:
samcake 2017-04-06 11:27:48 -07:00
parent b8cb79113e
commit 91f315f9ce
4 changed files with 104 additions and 12 deletions

View file

@ -18,8 +18,8 @@ using namespace render;
void Transaction::resetItem(ItemID id, const PayloadPointer& payload) { void Transaction::resetItem(ItemID id, const PayloadPointer& payload) {
if (payload) { if (payload) {
_resetItems.push_back(id); _resetItems.emplace_back(id);
_resetPayloads.push_back(payload); _resetPayloads.emplace_back(payload);
} else { } else {
qCDebug(renderlogging) << "WARNING: Transaction::resetItem with a null payload!"; qCDebug(renderlogging) << "WARNING: Transaction::resetItem with a null payload!";
removeItem(id); removeItem(id);
@ -27,12 +27,16 @@ void Transaction::resetItem(ItemID id, const PayloadPointer& payload) {
} }
void Transaction::removeItem(ItemID id) { void Transaction::removeItem(ItemID id) {
_removedItems.push_back(id); _removedItems.emplace_back(id);
} }
void Transaction::updateItem(ItemID id, const UpdateFunctorPointer& functor) { void Transaction::updateItem(ItemID id, const UpdateFunctorPointer& functor) {
_updatedItems.push_back(id); _updatedItems.emplace_back(id);
_updateFunctors.push_back(functor); _updateFunctors.emplace_back(functor);
}
void Transaction::resetSelection(const Selection& selection) {
_resetSelections.emplace_back(selection);
} }
void Transaction::merge(const Transaction& transaction) { 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()); _removedItems.insert(_removedItems.end(), transaction._removedItems.begin(), transaction._removedItems.end());
_updatedItems.insert(_updatedItems.end(), transaction._updatedItems.begin(), transaction._updatedItems.end()); _updatedItems.insert(_updatedItems.end(), transaction._updatedItems.begin(), transaction._updatedItems.end());
_updateFunctors.insert(_updateFunctors.end(), transaction._updateFunctors.begin(), transaction._updateFunctors.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) : Scene::Scene(glm::vec3 origin, float size) :
_masterSpatialTree(origin, size) _masterSpatialTree(origin, size)
{ {
@ -112,6 +118,13 @@ void Scene::processTransactionQueue() {
// Update the numItemsAtomic counter AFTER the pending changes went through // Update the numItemsAtomic counter AFTER the pending changes went through
_numAllocatedItems.exchange(maxID); _numAllocatedItems.exchange(maxID);
} }
if (consolidatedTransaction.touchTransactions()) {
std::unique_lock<std::mutex> lock(_selectionsMutex);
// resets and potential NEW items
resetSelections(consolidatedTransaction._resetSelections);
}
} }
void Scene::resetItems(const ItemIDs& ids, Payloads& payloads) { void Scene::resetItems(const ItemIDs& ids, Payloads& payloads) {
@ -202,3 +215,25 @@ void Scene::updateItems(const ItemIDs& ids, UpdateFunctors& functors) {
updateFunctor++; updateFunctor++;
} }
} }
// THis fucntion is thread safe
Selection Scene::getSelection(const Selection::Name& name) const {
std::unique_lock<std::mutex> 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;
}
}
}

View file

@ -34,6 +34,7 @@ public:
Transaction() {} Transaction() {}
~Transaction() {} ~Transaction() {}
// Item transactions
void resetItem(ItemID id, const PayloadPointer& payload); void resetItem(ItemID id, const PayloadPointer& payload);
void removeItem(ItemID id); void removeItem(ItemID id);
@ -44,14 +45,22 @@ public:
void updateItem(ItemID id, const UpdateFunctorPointer& functor); void updateItem(ItemID id, const UpdateFunctorPointer& functor);
void updateItem(ItemID id) { updateItem(id, nullptr); } void updateItem(ItemID id) { updateItem(id, nullptr); }
// Selection transactions
void resetSelection(const Selection& selection);
void merge(const Transaction& transaction); void merge(const Transaction& transaction);
// Checkers if there is work to do when processing the transaction
bool touchTransactions() const { return !_resetSelections.empty(); }
ItemIDs _resetItems; ItemIDs _resetItems;
Payloads _resetPayloads; Payloads _resetPayloads;
ItemIDs _removedItems; ItemIDs _removedItems;
ItemIDs _updatedItems; ItemIDs _updatedItems;
UpdateFunctors _updateFunctors; UpdateFunctors _updateFunctors;
Selections _resetSelections;
protected: protected:
}; };
typedef std::queue<Transaction> TransactionQueue; typedef std::queue<Transaction> TransactionQueue;
@ -82,6 +91,10 @@ public:
// Process the pending transactions queued // Process the pending transactions queued
void processTransactionQueue(); 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 // 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 // Access a particular item form its ID
@ -117,9 +130,15 @@ protected:
// The Selection map // 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; 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; friend class Engine;
}; };

View file

@ -14,11 +14,42 @@
using namespace render; 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), _name(name),
_items(items) _items(items)
{ {
} }
Selection::~Selection() { Selection::~Selection() {

View file

@ -18,21 +18,28 @@ namespace render {
class Selection { class Selection {
public: public:
using Name = std::string;
Selection(const std::string& name, const ItemIDs items);
~Selection(); ~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; } const ItemIDs& getItems() const { return _items; }
protected: protected:
const std::string _name; Name _name;
ItemIDs _items; ItemIDs _items;
}; };
using Selections = std::vector<Selection>; using Selections = std::vector<Selection>;
using SelectionMap = std::map<std::string, Selection>; using SelectionMap = std::map<const Selection::Name, Selection>;
} }