Refining the namings, creating the bucketing system, making a first example

This commit is contained in:
Sam Gateau 2015-05-21 12:06:47 -07:00
parent a71df42ca4
commit f0daa3ebcb
2 changed files with 61 additions and 13 deletions

View file

@ -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());
}
}

View file

@ -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 <class T> const Item::Key payloadGetKey(const T* payload) { return Item::Key(); }
template <class T> const Item::Bound payloadGetBound(const T* payload) { return Item::Bound(); }
template <class T> void payloadRender(const T* payload) { }
template <class T> class PayloadModel : public Item::PayloadInterface {
template <class T> class Payload : public Item::PayloadInterface {
public:
virtual const Item::Key getState() const { return payloadGetKey<T>(_data); }
virtual const Item::Bound getBound() const { return payloadGetBound<T>(_data); }
virtual void render(Context& context) { payloadRender<T>(_data, context); }
ItemPayload(std::shared_ptr<T>& data) : _data(data) {}
Payload(std::shared_ptr<T>& data) : _data(data) {}
protected:
std::shared_ptr<T> _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<Foo> 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<ItemID> ItemIDs;
typedef std::set<ItemID> 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<ItemID> ItemIDs;
typedef std::set<ItemID> ItemIDSet;
// A map of ItemIDSets allowing to create bucket lists of items which are filtering correctly
class ItemBucketMap : public std::map<ItemKey, ItemIDSet> {
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();