Cogs.Core
SwathPathMeshManager.cpp
1#include "Services/Variables.h"
2#include "SwathPathMeshManager.h"
3#include "Components/Core/MeshComponent.h"
4#include "Resources/Mesh.h"
5#include "Context.h"
6
7#include "Foundation/ComponentModel/Entity.h"
8
9#include <iostream>
10#include <algorithm>
11
12void Cogs::Core::EchoSounder::SwathPathMeshManager::discardEntity(WeakEntityPtr entity)
13{
14 if (entity.expired()) return;
15
16 auto e = entity.lock();
17 auto meshComp = e->getComponent<MeshComponent>();
18 meshComp->meshHandle = MeshHandle::NoHandle;
19 meshComp->setChanged();
20 entityPool.push_back(entity);
21}
22
23bool Cogs::Core::EchoSounder::SwathPathMeshManager::ready() {
24 if(persistent->running != 0)
25 return false;
26 for(auto &tmp : persistent->toBuild)
27 if(tmp.second && !tmp.second->isActive())
28 return false;
29 return true;
30}
31
32bool Cogs::Core::EchoSounder::SwathPathMeshManager::update(Context* context,
33 SwathPathChunks& chunks,
34 CreateBuildFunc& createBuildFunc,
35 CreateEntity & createEntity,
36 ActivateEntity & activateEntity)
37{
38 assert(persistent->running == 0);
39
40 if (chunkGen != chunks.getGeneration()) {
41 chunkGen = chunks.getGeneration();
42 handleClear = true;
43 }
44
45 if (handleClear) {
46 handleClear = false;
47
48 for (auto & i : current) {
49 discardEntity(i.second.entity);
50 }
51 current.clear();
52
53 // toBuild is cleared further down, which releases the meshhandles.
54 }
55 else {
56
57 for (auto & i : toDiscard) {
58 discardEntity(i.second.entity);
59 current.erase(i.first);
60 }
61
62 for (auto & i : persistent->toBuild) {
63
64 if (i.second) { // We only bother to actually setup an entity if there is any mesh.
65
66 EntityPtr entity;
67 if (!entityPool.empty()) {
68 if (!entityPool.back().expired()) {
69 entity = entityPool.back().lock();
70 }
71 entityPool.pop_back();
72 }
73
74 if (!entity) entity = createEntity();
75
76 auto meshComp = entity->getComponent<MeshComponent>();
77 meshComp->meshHandle = i.second;
78 meshComp->setChanged();
79
80 activateEntity(entity, i.first.index);
81
82 i.first.entity = entity;
83 }
84
85 current.insert(std::make_pair(i.first.index, i.first));
86 }
87 }
88 toDiscard.clear();
89 persistent->toBuild.clear();
90
91 if (update_current) {
92 for (auto & i : current) {
93 i.second.dirty = true;
94 }
95 update_current = false;
96 }
97
98 // Update discard
99 for (auto & i : current) {
100 if (!chunks.getChunks().validIndex(i.first)
101 || !(chunks.getChunks()[i.first].support == i.second.chunk.support)
102 || !(chunks.getChunks()[i.first].extent == i.second.chunk.extent)
103 || !(chunks.getChunks()[i.first].flags == i.second.chunk.flags))
104 {
105 toDiscard.insert(std::make_pair(i.first, i.second));
106 }
107 }
108
109 // Update toBuild
110 auto maxNewChunks = static_cast<uint32_t>(std::max(1, context->variables->get("echo.maxNewChunks", 0)));
111
112 for (uint32_t i = chunks.getChunks().count(); (0 < i) && ((persistent->toBuild.size() < maxNewChunks)); i--) {
113 const auto index = chunks.getChunks().frontIndex() + i - 1;
114 const auto & c = chunks.getChunks()[index];
115
116 auto it = current.find(index);
117 if (it == current.end()
118 || update_current
119 || !(c.extent == it->second.chunk.extent)
120 || !(c.support == it->second.chunk.support)
121 || !(c.flags == it->second.chunk.flags)
122 || it->second.dirty)
123 {
124 persistent->toBuild.push_back(std::make_pair(EntityInfo({ c, index, WeakEntityPtr(), false }), MeshHandle::NoHandle));
125 if (it != current.end()) { //entity already exists but was added to toBuild because it was dirty. Mark the old version for discarding
126 toDiscard.insert(std::make_pair(it->first, it->second));
127 }
128 }
129 }
130
131 if (!persistent->toBuild.empty()) {
132 persistent->running = 1;
133
134 auto group = context->taskManager->createGroup();
135 std::vector<TaskId> tasks;
136
137 for (auto & i : persistent->toBuild) {
138 tasks.push_back(context->taskManager->createChild(group, createBuildFunc(i.second, i.first.index)));
139 }
140
141 context->taskManager->enqueue(context->taskManager->GlobalQueue, [p=persistent, tasks, context, group]()
142 {
143 for (auto task : tasks) {
144 context->taskManager->enqueue(task);
145 }
146 context->taskManager->wait(group);
147 p->running = 0;
148 });
149
150 }
151
152 return !persistent->toBuild.empty() || !toDiscard.empty();
153}
std::shared_ptr< ComponentModel::Entity > EntityPtr
Smart pointer for Entity access.
Definition: EntityPtr.h:12
std::weak_ptr< ComponentModel::Entity > WeakEntityPtr
Weak Smart pointer for Entity access.
Definition: EntityPtr.h:18
static const ResourceHandle_t NoHandle
Handle representing a default (or none if default not present) resource.