mirror of
https://github.com/overte-org/overte.git
synced 2025-08-08 14:37:46 +02:00
First version wof space working with Transaction & Collection
This commit is contained in:
parent
1af139a4d4
commit
a2993c7cdb
11 changed files with 229 additions and 121 deletions
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
|
@ -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 };
|
||||||
|
|
||||||
|
|
|
@ -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) {
|
||||||
|
|
|
@ -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;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -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
|
||||||
|
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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>;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -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;
|
||||||
|
}
|
||||||
|
|
|
@ -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>;
|
||||||
|
|
|
@ -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));
|
||||||
}
|
}*/
|
||||||
}
|
//}
|
|
@ -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
|
||||||
|
|
Loading…
Reference in a new issue