First version wof space working with Transaction & Collection

This commit is contained in:
Sam Gateau 2018-03-13 01:45:21 -07:00
parent 1af139a4d4
commit a2993c7cdb
11 changed files with 229 additions and 121 deletions

View file

@ -56,7 +56,7 @@ void GameSpaceToRender::run(const workload::WorkloadContextPointer& runContext,
return; return;
} }
std::vector<workload::Space::Proxy> proxies(space->getNumAllocatedProxies()); workload::Proxy::Vector proxies(space->getNumAllocatedProxies());
space->copyProxyValues(proxies.data(), (uint32_t)proxies.size()); space->copyProxyValues(proxies.data(), (uint32_t)proxies.size());
workload::Views views(space->getNumViews()); workload::Views views(space->getNumViews());
@ -130,9 +130,9 @@ void GameWorkloadRenderItem::showViews(bool show) {
} }
void GameWorkloadRenderItem::setAllProxies(const std::vector<workload::Space::Proxy>& proxies) { void GameWorkloadRenderItem::setAllProxies(const workload::Proxy::Vector& proxies) {
_myOwnProxies = proxies; _myOwnProxies = proxies;
static const uint32_t sizeOfProxy = sizeof(workload::Space::Proxy); static const uint32_t sizeOfProxy = sizeof(workload::Proxy);
if (!_allProxiesBuffer) { if (!_allProxiesBuffer) {
_allProxiesBuffer = std::make_shared<gpu::Buffer>(sizeOfProxy); _allProxiesBuffer = std::make_shared<gpu::Buffer>(sizeOfProxy);
} }

View file

@ -63,7 +63,7 @@ public:
void showProxies(bool show); void showProxies(bool show);
void showViews(bool show); void showViews(bool show);
void setAllProxies(const std::vector<workload::Space::Proxy>& proxies); void setAllProxies(const workload::Proxy::Vector& proxies);
void setAllViews(const workload::Views& views); void setAllViews(const workload::Views& views);
render::ItemKey getKey() const; render::ItemKey getKey() const;
@ -71,7 +71,7 @@ public:
protected: protected:
render::Item::Bound _bound; render::Item::Bound _bound;
std::vector<workload::Space::Proxy> _myOwnProxies; workload::Proxy::Vector _myOwnProxies;
gpu::BufferPointer _allProxiesBuffer; gpu::BufferPointer _allProxiesBuffer;
uint32_t _numAllProxies{ 0 }; uint32_t _numAllProxies{ 0 };

View file

@ -281,8 +281,11 @@ void EntityTreeRenderer::addPendingEntities(const render::ScenePointer& scene, r
} }
if (entity->getSpaceIndex() == -1) { if (entity->getSpaceIndex() == -1) {
std::unique_lock<std::mutex> lock(_spaceLock); std::unique_lock<std::mutex> lock(_spaceLock);
workload::Space::Sphere sphere(entity->getWorldPosition(), entity->getBoundingRadius()); auto spaceIndex = _space->allocateID();
int32_t spaceIndex = _space->createProxy(sphere); workload::Sphere sphere(entity->getWorldPosition(), entity->getBoundingRadius());
workload::Transaction transaction;
transaction.reset(spaceIndex, sphere);
_space->enqueueTransaction(transaction);
entity->setSpaceIndex(spaceIndex); entity->setSpaceIndex(spaceIndex);
connect(entity.get(), &EntityItem::spaceUpdate, this, &EntityTreeRenderer::handleSpaceUpdate, Qt::QueuedConnection); connect(entity.get(), &EntityItem::spaceUpdate, this, &EntityTreeRenderer::handleSpaceUpdate, Qt::QueuedConnection);
} }
@ -427,17 +430,19 @@ void EntityTreeRenderer::update(bool simulate) {
scene->enqueueTransaction(transaction); scene->enqueueTransaction(transaction);
} }
} }
workload::Transaction spaceTransaction;
{ // update proxies in the workload::Space { // update proxies in the workload::Space
std::unique_lock<std::mutex> lock(_spaceLock); std::unique_lock<std::mutex> lock(_spaceLock);
_space->updateProxies(_spaceUpdates); spaceTransaction.update(_spaceUpdates);
_spaceUpdates.clear(); _spaceUpdates.clear();
} }
{ {
std::vector<int32_t> staleProxies; std::vector<int32_t> staleProxies;
tree->swapStaleProxies(staleProxies); tree->swapStaleProxies(staleProxies);
spaceTransaction.remove(staleProxies);
{ {
std::unique_lock<std::mutex> lock(_spaceLock); std::unique_lock<std::mutex> lock(_spaceLock);
_space->deleteProxies(staleProxies); _space->enqueueTransaction(spaceTransaction);
} }
} }
@ -458,7 +463,7 @@ void EntityTreeRenderer::update(bool simulate) {
void EntityTreeRenderer::handleSpaceUpdate(std::pair<int32_t, glm::vec4> proxyUpdate) { void EntityTreeRenderer::handleSpaceUpdate(std::pair<int32_t, glm::vec4> proxyUpdate) {
std::unique_lock<std::mutex> lock(_spaceLock); std::unique_lock<std::mutex> lock(_spaceLock);
_spaceUpdates.push_back(proxyUpdate); _spaceUpdates.emplace_back(proxyUpdate.first, proxyUpdate.second);
} }
bool EntityTreeRenderer::findBestZoneAndMaybeContainingEntities(QVector<EntityItemID>* entitiesContainingAvatar) { bool EntityTreeRenderer::findBestZoneAndMaybeContainingEntities(QVector<EntityItemID>* entitiesContainingAvatar) {

View file

@ -270,7 +270,7 @@ private:
mutable std::mutex _spaceLock; mutable std::mutex _spaceLock;
workload::SpacePointer _space{ new workload::Space() }; workload::SpacePointer _space{ new workload::Space() };
std::vector<workload::Space::ProxyUpdate> _spaceUpdates; workload::Transaction::Updates _spaceUpdates;
}; };

View file

@ -29,6 +29,7 @@ namespace workload {
using JobModel = Task::ModelI<EngineBuilder, Inputs>; using JobModel = Task::ModelI<EngineBuilder, Inputs>;
void build(JobModel& model, const Varying& in, Varying& out) { void build(JobModel& model, const Varying& in, Varying& out) {
model.addJob<SetupViews>("setupViews", in); model.addJob<SetupViews>("setupViews", in);
model.addJob<PerformSpaceTransaction>("updateSpace");
const auto regionChanges = model.addJob<RegionTracker>("regionTracker"); const auto regionChanges = model.addJob<RegionTracker>("regionTracker");
model.addJob<RegionState>("regionState", regionChanges); model.addJob<RegionState>("regionState", regionChanges);
@ -38,5 +39,15 @@ namespace workload {
Engine::Engine(const WorkloadContextPointer& context) : Task("Engine", EngineBuilder::JobModel::create()), Engine::Engine(const WorkloadContextPointer& context) : Task("Engine", EngineBuilder::JobModel::create()),
_context(context) { _context(context) {
} }
void PerformSpaceTransaction::configure(const Config& config) {
}
void PerformSpaceTransaction::run(const WorkloadContextPointer& context) {
context->_space->enqueueFrame();
context->_space->processTransactionQueue();
}
} // namespace workload } // namespace workload

View file

@ -50,6 +50,24 @@ namespace workload {
}; };
using EnginePointer = std::shared_ptr<Engine>; using EnginePointer = std::shared_ptr<Engine>;
class PerformSpaceTransactionConfig : public Job::Config {
Q_OBJECT
public:
signals :
void dirty();
protected:
};
class PerformSpaceTransaction {
public:
using Config = PerformSpaceTransactionConfig;
using JobModel = Job::Model<PerformSpaceTransaction, Config>;
void configure(const Config& config);
void run(const WorkloadContextPointer& context);
protected:
};
} // namespace workload } // namespace workload
#endif // hifi_workload_Space_h #endif // hifi_workload_Space_h

View file

@ -21,10 +21,12 @@ public:
Proxy(const Sphere& s) : sphere(s) {} Proxy(const Sphere& s) : sphere(s) {}
Sphere sphere; Sphere sphere;
uint8_t region{ Region::UNKNOWN }; uint8_t region{ Region::INVALID };
uint8_t prevRegion{ Region::UNKNOWN }; uint8_t prevRegion{ Region::INVALID };
uint16_t _padding; uint16_t _padding;
uint32_t _paddings[3]; uint32_t _paddings[3];
using Vector = std::vector<Proxy>;
}; };

View file

@ -20,11 +20,80 @@
using namespace workload; using namespace workload;
void Space::clear() { Space::Space() : Collection() {
_proxies.clear();
_freeIndices.clear();
} }
void Space::processTransactionFrame(const Transaction& transaction) {
std::unique_lock<std::mutex> lock(_proxiesMutex);
// Here we should be able to check the value of last ProxyID allocated
// and allocate new proxies accordingly
ProxyID maxID = _IDAllocator.getNumAllocatedIndices();
if (maxID > _proxies.size()) {
_proxies.resize(maxID + 100); // allocate the maxId and more
}
// Now we know for sure that we have enough items in the array to
// capture anything coming from the transaction
// resets and potential NEW items
processResets(transaction._resetItems);
// Update the numItemsAtomic counter AFTER the reset changes went through
// _numAllocatedItems.exchange(maxID);
// updates
processUpdates(transaction._updatedItems);
// removes
processRemoves(transaction._removedItems);
// Update the numItemsAtomic counter AFTER the pending changes went through
// _numAllocatedItems.exchange(maxID);
}
void Space::processResets(const Transaction::Resets& transactions) {
for (auto& reset : transactions) {
// Access the true item
auto ProxyID = std::get<0>(reset);
auto& item = _proxies[ProxyID];
// Reset the item with a new payload
item.sphere = (std::get<1>(reset));
item.prevRegion = item.region = Region::UNKNOWN;
}
}
void Space::processRemoves(const Transaction::Removes& transactions) {
for (auto removedID : transactions) {
_IDAllocator.freeIndex(removedID);
// Access the true item
auto& item = _proxies[removedID];
// Kill it
item.prevRegion = item.region = Region::INVALID;
}
}
void Space::processUpdates(const Transaction::Updates& transactions) {
for (auto& update : transactions) {
auto updateID = std::get<0>(update);
if (updateID == INVALID_PROXY_ID) {
continue;
}
// Access the true item
auto& item = _proxies[updateID];
// Update the item
// item.update(std::get<1>(update));
item.sphere = (std::get<1>(update));
item.prevRegion = item.region = Region::UNKNOWN;
}
}
/*
int32_t Space::createProxy(const Space::Sphere& newSphere) { int32_t Space::createProxy(const Space::Sphere& newSphere) {
if (_freeIndices.empty()) { if (_freeIndices.empty()) {
_proxies.emplace_back(Space::Proxy(newSphere)); _proxies.emplace_back(Space::Proxy(newSphere));
@ -37,32 +106,25 @@ int32_t Space::createProxy(const Space::Sphere& newSphere) {
_proxies[index].prevRegion = Region::UNKNOWN; _proxies[index].prevRegion = Region::UNKNOWN;
return index; return index;
} }
} }*/
/*
void Space::deleteProxies(const std::vector<int32_t>& deadIndices) { void Space::deleteProxies(const std::vector<int32_t>& deadIndices) {
for (uint32_t i = 0; i < deadIndices.size(); ++i) { for (uint32_t i = 0; i < deadIndices.size(); ++i) {
deleteProxy(deadIndices[i]); deleteProxy(deadIndices[i]);
} }
} }
*/
void Space::updateProxies(const std::vector<ProxyUpdate>& changedProxies) { /*void Space::updateProxies(const std::vector<ProxyUpdate>& changedProxies) {
for (uint32_t i = 0; i < changedProxies.size(); ++i) { for (uint32_t i = 0; i < changedProxies.size(); ++i) {
int32_t proxyId = changedProxies[i].first; int32_t proxyId = changedProxies[i].first;
if (proxyId > -1 && proxyId < (int32_t)_proxies.size()) { if (proxyId > -1 && proxyId < (int32_t)_proxies.size()) {
updateProxy(changedProxies[i].first, changedProxies[i].second); updateProxy(changedProxies[i].first, changedProxies[i].second);
} }
} }
} }*/
void Space::setViews(const Views& views) {
_views = views;
}
void Space::copyViews(std::vector<View>& copy) const {
copy = _views;
}
void Space::categorizeAndGetChanges(std::vector<Space::Change>& changes) { void Space::categorizeAndGetChanges(std::vector<Space::Change>& changes) {
std::unique_lock<std::mutex> lock(_proxiesMutex);
uint32_t numProxies = (uint32_t)_proxies.size(); uint32_t numProxies = (uint32_t)_proxies.size();
uint32_t numViews = (uint32_t)_views.size(); uint32_t numViews = (uint32_t)_views.size();
for (uint32_t i = 0; i < numProxies; ++i) { for (uint32_t i = 0; i < numProxies; ++i) {
@ -92,7 +154,7 @@ void Space::categorizeAndGetChanges(std::vector<Space::Change>& changes) {
} }
// private // private
void Space::deleteProxy(int32_t proxyId) { /*void Space::deleteProxy(int32_t proxyId) {
if (proxyId > -1 && proxyId < (int32_t)_proxies.size()) { if (proxyId > -1 && proxyId < (int32_t)_proxies.size()) {
if (proxyId == (int32_t)_proxies.size() - 1) { if (proxyId == (int32_t)_proxies.size() - 1) {
// remove proxy on back // remove proxy on back
@ -110,9 +172,10 @@ void Space::deleteProxy(int32_t proxyId) {
_freeIndices.push_back(proxyId); _freeIndices.push_back(proxyId);
} }
} }
} }*/
uint32_t Space::copyProxyValues(Proxy* proxies, uint32_t numDestProxies) const { uint32_t Space::copyProxyValues(Proxy* proxies, uint32_t numDestProxies) const {
std::unique_lock<std::mutex> lock(_proxiesMutex);
auto numCopied = std::min(numDestProxies, (uint32_t)_proxies.size()); auto numCopied = std::min(numDestProxies, (uint32_t)_proxies.size());
memcpy(proxies, _proxies.data(), numCopied * sizeof(Proxy)); memcpy(proxies, _proxies.data(), numCopied * sizeof(Proxy));
return numCopied; return numCopied;
@ -120,9 +183,24 @@ uint32_t Space::copyProxyValues(Proxy* proxies, uint32_t numDestProxies) const {
// private // private
void Space::updateProxy(int32_t proxyId, const Space::Sphere& newSphere) { /*void Space::updateProxy(int32_t proxyId, const Space::Sphere& newSphere) {
if (proxyId > -1 && proxyId < (int32_t)_proxies.size()) { if (proxyId > -1 && proxyId < (int32_t)_proxies.size()) {
_proxies[proxyId].sphere = newSphere; _proxies[proxyId].sphere = newSphere;
} }
}*/
void Space::clear() {
std::unique_lock<std::mutex> lock(_proxiesMutex);
_IDAllocator.clear();
_proxies.clear();
_views.clear();
} }
void Space::setViews(const Views& views) {
_views = views;
}
void Space::copyViews(std::vector<View>& copy) const {
copy = _views;
}

View file

@ -23,7 +23,7 @@
namespace workload { namespace workload {
class Space { class Space : public Collection {
public: public:
using ProxyUpdate = std::pair<int32_t, Sphere>; using ProxyUpdate = std::pair<int32_t, Sphere>;
@ -35,55 +35,40 @@ public:
uint8_t prevRegion { 0 }; uint8_t prevRegion { 0 };
}; };
Space() {} Space();
// This call is thread safe, can be called from anywhere to allocate a new ID void setViews(const Views& views);
ProxyID allocateID();
// Check that the ID is valid and allocated for this space, this a threadsafe call
bool isAllocatedID(const ProxyID& id) const;
// THis is the total number of allocated proxies, this a threadsafe call
Index getNumAllocatedProxies() const { return _numAllocatedProxies.load(); }
// Enqueue transaction to the space
void enqueueTransaction(const Transaction& transaction);
// Enqueue transaction to the space
void enqueueTransaction(Transaction&& transaction);
// Enqueue end of frame transactions boundary
uint32_t enqueueFrame();
// Process the pending transactions queued
void processTransactionQueue();
void setViews(const std::vector<View>& views);
uint32_t getNumViews() const { return (uint32_t)(_views.size()); } uint32_t getNumViews() const { return (uint32_t)(_views.size()); }
void copyViews(std::vector<View>& copy) const; void copyViews(std::vector<View>& copy) const;
uint32_t getNumObjects() const { return _IDAllocator.getNumLiveIndices(); } // (uint32_t)(_proxies.size() - _freeIndices.size()); }
uint32_t getNumObjects() const { return (uint32_t)(_proxies.size() - _freeIndices.size()); } uint32_t getNumAllocatedProxies() const { return (uint32_t)(_IDAllocator.getNumAllocatedIndices()); }
uint32_t getNumAllocatedProxies() const { return (uint32_t)(_proxies.size()); }
void categorizeAndGetChanges(std::vector<Change>& changes); void categorizeAndGetChanges(std::vector<Change>& changes);
uint32_t copyProxyValues(Proxy* proxies, uint32_t numDestProxies) const; uint32_t copyProxyValues(Proxy* proxies, uint32_t numDestProxies) const;
void clear();
private: private:
virtual void processTransactionFrame(const Transaction& transaction);
void processResets(const Transaction::Resets& transactions);
void processRemoves(const Transaction::Removes& transactions);
void processUpdates(const Transaction::Updates& transactions);
void clear(); // int32_t createProxy(const Sphere& sphere);
int32_t createProxy(const Sphere& sphere); // void deleteProxies(const IndexVector& deadIndices);
void deleteProxies(const IndexVector& deadIndices); // void updateProxies(const std::vector<ProxyUpdate>& changedProxies);
void updateProxies(const std::vector<ProxyUpdate>& changedProxies);
void deleteProxy(int32_t proxyId); // void deleteProxy(int32_t proxyId);
void updateProxy(int32_t proxyId, const Sphere& sphere); // void updateProxy(int32_t proxyId, const Sphere& sphere);
// The database of proxies is protected for editing by a mutex
mutable std::mutex _proxiesMutex;
Proxy::Vector _proxies;
std::vector<Proxy> _proxies;
Views _views; Views _views;
IndexVector _freeIndices;
}; };
using SpacePointer = std::shared_ptr<Space>; using SpacePointer = std::shared_ptr<Space>;

View file

@ -13,21 +13,16 @@
using namespace workload; using namespace workload;
void Transaction::resetItem(ItemID id, PayloadPointer& payload) { void Transaction::reset(ProxyID id, const ProxyPayload& payload) {
if (payload) {
_resetItems.emplace_back(Reset{ id, payload }); _resetItems.emplace_back(Reset{ id, payload });
} else {
qCDebug(renderlogging) << "WARNING: Transaction::resetItem with a null payload!";
removeItem(id);
}
} }
void Transaction::removeItem(ItemID id) { void Transaction::remove(ProxyID id) {
_removedItems.emplace_back(id); _removedItems.emplace_back(id);
} }
void Transaction::updateItem(ItemID id, const UpdateFunctorPointer& functor) { void Transaction::update(ProxyID id, const ProxyPayload& payload) {
_updatedItems.emplace_back(id, functor); _updatedItems.emplace_back(id, payload);
} }
void Transaction::reserve(const std::vector<Transaction>& transactionContainer) { void Transaction::reserve(const std::vector<Transaction>& transactionContainer) {
@ -77,6 +72,18 @@ void copyElements(T& target, const T& source) {
} }
void Transaction::reset(const Resets& resets) {
copyElements(_resetItems, resets);
}
void Transaction::remove(const Removes& removes) {
copyElements(_removedItems, removes);
}
void Transaction::update(const Updates& updates) {
copyElements(_updatedItems, updates);
}
void Transaction::merge(Transaction&& transaction) { void Transaction::merge(Transaction&& transaction) {
moveElements(_resetItems, transaction._resetItems); moveElements(_resetItems, transaction._resetItems);
moveElements(_removedItems, transaction._removedItems); moveElements(_removedItems, transaction._removedItems);
@ -99,23 +106,22 @@ void Transaction::clear() {
Collection::Collection() { Collection::Collection() {
_items.push_back(Item()); // add the itemID #0 to nothing //_items.push_back(Item()); // add the ProxyID #0 to nothing
} }
Collection::~Collection() { Collection::~Collection() {
qCDebug(renderlogging) << "Scene::~Scene()";
} }
ItemID Collection::allocateID() { ProxyID Collection::allocateID() {
// Just increment and return the proevious value initialized at 0 // Just increment and return the previous value initialized at 0
return _IDAllocator.fetch_add(1); return _IDAllocator.allocateIndex();
} }
bool Collection::isAllocatedID(const ItemID& id) const { bool Collection::isAllocatedID(const ProxyID& id) const {
return Item::isValidID(id) && (id < _numAllocatedItems.load()); return _IDAllocator.checkIndex(id);
} }
/// Enqueue change batch to the scene /// Enqueue change batch to the Collection
void Collection::enqueueTransaction(const Transaction& transaction) { void Collection::enqueueTransaction(const Transaction& transaction) {
std::unique_lock<std::mutex> lock(_transactionQueueMutex); std::unique_lock<std::mutex> lock(_transactionQueueMutex);
_transactionQueue.emplace_back(transaction); _transactionQueue.emplace_back(transaction);
@ -127,7 +133,6 @@ void Collection::enqueueTransaction(Transaction&& transaction) {
} }
uint32_t Collection::enqueueFrame() { uint32_t Collection::enqueueFrame() {
PROFILE_RANGE(render, __FUNCTION__);
TransactionQueue localTransactionQueue; TransactionQueue localTransactionQueue;
{ {
std::unique_lock<std::mutex> lock(_transactionQueueMutex); std::unique_lock<std::mutex> lock(_transactionQueueMutex);
@ -146,8 +151,6 @@ uint32_t Collection::enqueueFrame() {
void Collection::processTransactionQueue() { void Collection::processTransactionQueue() {
PROFILE_RANGE(render, __FUNCTION__);
static TransactionFrames queuedFrames; static TransactionFrames queuedFrames;
{ {
// capture the queued frames and clear the queue // capture the queued frames and clear the queue
@ -163,13 +166,12 @@ void Collection::processTransactionQueue() {
queuedFrames.clear(); queuedFrames.clear();
} }
void Collection::processTransactionFrame(const Transaction& transaction) { //void Collection::processTransactionFrame(const Transaction& transaction) {
PROFILE_RANGE(render, __FUNCTION__); /**
{
std::unique_lock<std::mutex> lock(_itemsMutex); std::unique_lock<std::mutex> lock(_itemsMutex);
// Here we should be able to check the value of last ItemID allocated // Here we should be able to check the value of last ProxyID allocated
// and allocate new items accordingly // and allocate new items accordingly
ItemID maxID = _IDAllocator.load(); ProxyID maxID = _IDAllocator.getNumAllocatedIndices();
if (maxID > _items.size()) { if (maxID > _items.size()) {
_items.resize(maxID + 100); // allocate the maxId and more _items.resize(maxID + 100); // allocate the maxId and more
} }
@ -195,32 +197,32 @@ void Collection::processTransactionFrame(const Transaction& transaction) {
// 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);
} }*/
} //}
void Collection::resetItems(const Transaction::Resets& transactions) { //void Collection::resetItems(const Transaction::Resets& transactions) {
for (auto& reset : transactions) { /* for (auto& reset : transactions) {
// Access the true item // Access the true item
auto itemId = std::get<0>(reset); auto ProxyID = std::get<0>(reset);
auto& item = _items[itemId]; auto& item = _items[ProxyID];
// Reset the item with a new payload // Reset the item with a new payload
item.resetPayload(std::get<1>(reset)); item.resetPayload(std::get<1>(reset));
} }*/
} //}
void Collection::removeItems(const Transaction::Removes& transactions) { //void Collection::removeItems(const Transaction::Removes& transactions) {
for (auto removedID : transactions) { /* for (auto removedID : transactions) {
// Access the true item // Access the true item
auto& item = _items[removedID]; auto& item = _items[removedID];
// Kill it // Kill it
item.kill(); item.kill();
} }*/
} //}
void Collection::updateItems(const Transaction::Updates& transactions) { //void Collection::updateItems(const Transaction::Updates& transactions) {
for (auto& update : transactions) { /* for (auto& update : transactions) {
auto updateID = std::get<0>(update); auto updateID = std::get<0>(update);
if (updateID == Item::INVALID_ITEM_ID) { if (updateID == Item::INVALID_ITEM_ID) {
continue; continue;
@ -231,5 +233,5 @@ void Collection::updateItems(const Transaction::Updates& transactions) {
// Update the item // Update the item
item.update(std::get<1>(update)); item.update(std::get<1>(update));
} }*/
} //}

View file

@ -38,7 +38,7 @@ namespace workload {
Index _nextNewIndex{ 0 }; Index _nextNewIndex{ 0 };
bool checkIndex(Index index) const { return ((index >= 0) && (index < _nextNewIndex)); } bool checkIndex(Index index) const { return ((index >= 0) && (index < _nextNewIndex)); }
Index getNumIndices() const { return _nextNewIndex - (Index)_freeIndices.size(); } Index getNumLiveIndices() const { return _nextNewIndex - (Index)_freeIndices.size(); }
Index getNumFreeIndices() const { return (Index)_freeIndices.size(); } Index getNumFreeIndices() const { return (Index)_freeIndices.size(); }
Index getNumAllocatedIndices() const { return _nextNewIndex; } Index getNumAllocatedIndices() const { return _nextNewIndex; }
@ -64,6 +64,7 @@ namespace workload {
void freeIndex(Index index) { void freeIndex(Index index) {
if (checkIndex(index)) { if (checkIndex(index)) {
_freeIndices.push_back(index); _freeIndices.push_back(index);
//std::sort(_freeIndices.begin(), _freeIndices.end());
} }
} }
@ -79,7 +80,7 @@ namespace workload {
using IndexVector = indexed_container::Indices; using IndexVector = indexed_container::Indices;
using ProxyID = Index; using ProxyID = Index;
const ProxyID INVALID_PROXY_ID{ indexed_container ::INVALID_INDEX };
// Transaction is the mechanism to make any change to the Space. // Transaction is the mechanism to make any change to the Space.
// Whenever a new proxy need to be reset, // Whenever a new proxy need to be reset,
@ -94,15 +95,26 @@ class Transaction {
public: public:
using ProxyPayload = Sphere; using ProxyPayload = Sphere;
using Reset = std::tuple<ProxyID, ProxyPayload>;
using Remove = ProxyID;
using Update = std::tuple<ProxyID, ProxyPayload>;
using Resets = std::vector<Reset>;
using Removes = std::vector<Remove>;
using Updates = std::vector<Update>;
Transaction() {} Transaction() {}
~Transaction() {} ~Transaction() {}
// Proxy transactions // Proxy transactions
void reset(ProxyID id, const ProxyPayload& sphere); void reset(ProxyID id, const ProxyPayload& sphere);
void reset(const Resets& resets);
void remove(ProxyID id); void remove(ProxyID id);
void remove(const Removes& removes);
bool hasRemovals() const { return !_removedItems.empty(); } bool hasRemovals() const { return !_removedItems.empty(); }
void update(ProxyID id, const ProxyPayload& sphere); void update(ProxyID id, const ProxyPayload& sphere);
void update(const Updates& updates);
void reserve(const std::vector<Transaction>& transactionContainer); void reserve(const std::vector<Transaction>& transactionContainer);
void merge(const std::vector<Transaction>& transactionContainer); void merge(const std::vector<Transaction>& transactionContainer);
@ -113,13 +125,6 @@ public:
protected: protected:
using Reset = std::tuple<ProxyID, ProxyPayload>;
using Remove = ProxyID;
using Update = std::tuple<ProxyID, ProxyPayload>;
using Resets = std::vector<Reset>;
using Removes = std::vector<Remove>;
using Updates = std::vector<Update>;
Resets _resetItems; Resets _resetItems;
Removes _removedItems; Removes _removedItems;
@ -129,6 +134,8 @@ typedef std::vector<Transaction> TransactionQueue;
class Collection { class Collection {
public: public:
Collection();
~Collection();
// This call is thread safe, can be called from anywhere to allocate a new ID // This call is thread safe, can be called from anywhere to allocate a new ID
ProxyID allocateID(); ProxyID allocateID();
@ -149,7 +156,7 @@ public:
uint32_t enqueueFrame(); uint32_t enqueueFrame();
// Process the pending transactions queued // Process the pending transactions queued
void processTransactionQueue(); virtual void processTransactionQueue();
protected: protected:
@ -168,7 +175,7 @@ protected:
uint32_t _transactionFrameNumber{ 0 }; uint32_t _transactionFrameNumber{ 0 };
// Process one transaction frame // Process one transaction frame
void processTransactionFrame(const Transaction& transaction); virtual void processTransactionFrame(const Transaction& transaction) = 0;
}; };
} // namespace workload } // namespace workload