From f0daa3ebcb53846828ea98319de514929f520017 Mon Sep 17 00:00:00 2001 From: Sam Gateau Date: Thu, 21 May 2015 12:06:47 -0700 Subject: [PATCH] Refining the namings, creating the bucketing system, making a first example --- libraries/render/src/render/Scene.cpp | 26 ++++++++++++--- libraries/render/src/render/Scene.h | 48 ++++++++++++++++++++++----- 2 files changed, 61 insertions(+), 13 deletions(-) diff --git a/libraries/render/src/render/Scene.cpp b/libraries/render/src/render/Scene.cpp index 8d435913bd..11fc54c32d 100644 --- a/libraries/render/src/render/Scene.cpp +++ b/libraries/render/src/render/Scene.cpp @@ -13,7 +13,7 @@ using namespace render; void ItemBucketMap::insert(const ItemID& id, const ItemKey& key) { - // DIspatch insert the itemID in every bucket where it filters true + // Insert the itemID in every bucket where it filters true for (auto& bucket : (*this)) { if (filterTest(bucket.first, key)) { bucket.second.insert(id); @@ -21,7 +21,7 @@ void ItemBucketMap::insert(const ItemID& id, const ItemKey& key) { } } void ItemBucketMap::erase(const ItemID& id, const ItemKey& key) { - // DIspatch insert the itemID in every bucket where it filters true + // Remove the itemID in every bucket where it filters true for (auto& bucket : (*this)) { if (filterTest(bucket.first, key)) { bucket.second.erase(id); @@ -29,6 +29,22 @@ void ItemBucketMap::erase(const ItemID& id, const ItemKey& key) { } } +void ItemBucketMap::reset(const ItemID& id, const ItemKey& oldKey, const ItemKey& newKey) { + // Reset the itemID in every bucket, + // Remove from the buckets where oldKey filters true AND newKey filters false + // Insert into the buckets where newKey filters true + for (auto& bucket : (*this)) { + if (filterTest(bucket.first, oldKey)) { + if (!filterTest(bucket.first, newKey)) { + bucket.second.erase(id); + } + } else if (filterTest(bucket.first, newKey)) { + bucket.second.insert(id); + } + } +} + + void Scene::PendingChanges::resetItem(ItemID id, PayloadPointer& payload) { _resetItems.push_back(id); _resetPayloads.push_back(payload); @@ -102,9 +118,11 @@ void Scene::resetItems(const ItemIDs& ids, Payloads& payloads) { auto resetID = ids.begin(); auto resetPayload = payloads.begin(); for (;resetID != ids.end(); resetID++, resetPayload++) { - _items[(*resetID)].resetPayload(*resetPayload); + auto item = _items[(*resetID)]; + auto oldKey = item.getKey(); + item.resetPayload(*resetPayload); - _buckets.insert((*resetID), _items[(*resetID)].getKey()); + _buckets.reset((*resetID), oldKey, item.getKey()); } } diff --git a/libraries/render/src/render/Scene.h b/libraries/render/src/render/Scene.h index 68c0655a06..d4489ff637 100644 --- a/libraries/render/src/render/Scene.h +++ b/libraries/render/src/render/Scene.h @@ -117,29 +117,46 @@ protected: friend class Scene; }; +// THe Payload class is the real Payload to be used +// THis allow anything to be turned into a Payload as long as the required interface functions are available +// When creating a new kind of payload from a new "stuff" class then you need to create specialized version for "stuff" +// of th ePayload interface template const Item::Key payloadGetKey(const T* payload) { return Item::Key(); } template const Item::Bound payloadGetBound(const T* payload) { return Item::Bound(); } template void payloadRender(const T* payload) { } -template class PayloadModel : public Item::PayloadInterface { +template class Payload : public Item::PayloadInterface { public: virtual const Item::Key getState() const { return payloadGetKey(_data); } virtual const Item::Bound getBound() const { return payloadGetBound(_data); } virtual void render(Context& context) { payloadRender(_data, context); } - ItemPayload(std::shared_ptr& data) : _data(data) {} + Payload(std::shared_ptr& data) : _data(data) {} protected: std::shared_ptr _data; }; - -typedef Item::PayloadInterface Payload; + +// Let's show how to make a simple FooPayload example: +class Foo { +public: + mutable Item::Key _myownKey; + void makeMywnKey() const { + _myownKey.set(Item::TYPE_SHAPE); + } +}; + +typedef Payload FooPayload; + +template <> +const Item::Key payloadGetKey(const Foo* payload) { + payload->makeMywnKey(); + return payload->_myownKey; +} +// End of the example + typedef Item::PayloadPointer PayloadPointer; typedef std::vector< PayloadPointer > Payloads; -typedef Item::Vector Items; -typedef Item::ID ItemID; -typedef std::vector ItemIDs; -typedef std::set ItemIDSet; typedef Item::Key ItemKey; // Item Key operator testing if a key pass a filter test @@ -155,6 +172,12 @@ bool filterTest(const ItemKey& filter, const ItemKey& key) { } } +// A few typedefs for standard containers of ItemIDs +typedef Item::ID ItemID; +typedef std::vector ItemIDs; +typedef std::set ItemIDSet; + +// A map of ItemIDSets allowing to create bucket lists of items which are filtering correctly class ItemBucketMap : public std::map { public: @@ -162,11 +185,18 @@ public: void insert(const ItemID& id, const ItemKey& key); void erase(const ItemID& id, const ItemKey& key); + void reset(const ItemID& id, const ItemKey& oldKey, const ItemKey& newKey); + }; class Engine; class Observer; +// Scene is a container for Items +// Items are introduced, modified or erased in the scene through PendingChanges +// Once per Frame, the PendingChanges are all flushed +// During the flush the standard buckets are updated +// Items are notified accordingly on any update message happening class Scene { public: @@ -241,7 +271,7 @@ protected: // The actual database // database of items is protected for editing by a mutex std::mutex _itemsMutex; - Items _items; + Item::Vector _items; ItemBucketMap _buckets; void processPendingChangesQueue();