Cogs.Core
AssetInspector.cpp
1#include "Inspectors.h"
2
3#include "Context.h"
4
5#include "Resources/AssetManager.h"
6#include "Resources/Model.h"
7#include "Resources/Texture.h"
8
9#include "Systems/Core/AssetSystem.h"
10#include "Systems/Core/AssetInstanceData.h"
11
12#include "InspectorGuiRenderer.h"
13#include "InspectorGuiHelper.h"
14
15#include "Foundation/StringViewFormat.h"
16#include "Foundation/Platform/IO.h"
17
18#include <deque>
19#include <cinttypes>
20#include <span>
21
22namespace {
23
24 std::string byteString(size_t bytes)
25 {
26 if (bytes < 16 * 1024) {
27 return std::to_string(bytes) + " B";
28 }
29 bytes = bytes / 1024;
30 if (bytes < 16 * 1024) {
31 return std::to_string(bytes) + " KiB";
32 }
33 bytes = bytes / 1024;
34 if (bytes < 16 * 1024) {
35 return std::to_string(bytes) + " MiB";
36 }
37 bytes = bytes / 1024;
38 return std::to_string(bytes) + " GiB";
39 }
40
41}
42
43namespace Cogs::Core
44{
46 static std::deque<std::vector<std::string>> assetsInQueueHistory;
47 static std::vector<float> assetsInQueueGraph;
48 static size_t assetsInQueueTotal = 0;
49 static float assetsInQueueGraphHeight = 10.f;
50 static int assetsInQueueGraphScale = 50;
51 static std::deque<std::vector<std::string>> assetsProcessingHistory;
52 static std::vector<float> assetsProcessingGraph;
53 static size_t assetsProcessingTotal = 0;
54 static float assetsProcessingGraphHeight = 10.f;
55 static int assetsProcessingGraphScale = 50;
56
57 void showEntityDefinition(SceneDefinition & scene, const SceneEntityDefinition & definition)
58 {
59 ImGui::PushID(&definition);
60
61 std::string entityName(scene.properties.getString(definition.nameIndex));
62 if (entityName.empty()) entityName = "Anonymous";
63
64 if (ImGui::TreeNode(entityName.c_str())) {
65 ImGui::Text("Type: '%.*s'", StringViewFormat(definition.getTypeName()));
66
67 if (definition.numProperties) {
68 if (ImGui::TreeNode("Properties")) {
69 for (uint32_t i = definition.firstProperty; i < definition.firstProperty + definition.numProperties; ++i) {
70 PropertyInfo& prop = scene.properties.getPropertyByIndex(i);
71 std::string_view name = scene.properties.getKey(prop);
72
73 switch (prop.type) {
74 case PropertyType::Bool:
75 ImGui::Text("%.*s: %s", StringViewFormat(name), prop.boolValue ? "true" : "false");
76 break;
77 case PropertyType::Integer:
78 ImGui::Text("%.*s: %d", StringViewFormat(name), prop.intValue);
79 break;
80 case PropertyType::Int2:
81 ImGui::Text("%.*s: %d %d", StringViewFormat(name), prop.int2Value[0], prop.int2Value[1]);
82 break;
83 case PropertyType::UnsignedInteger:
84 ImGui::Text("%.*s: 0x%08x", StringViewFormat(name), prop.uintValue);
85 break;
86 case PropertyType::UInt2:
87 ImGui::Text("%.*s: %u %u", StringViewFormat(name), prop.uint2Value[0], prop.uint2Value[1]);
88 break;
89 case PropertyType::Float:
90 ImGui::Text("%.*s: %f", StringViewFormat(name), prop.floatValue);
91 break;
92 case PropertyType::Float2:
93 ImGui::Text("%.*s: %f %f", StringViewFormat(name), prop.float2Value[0], prop.float2Value[1]);
94 break;
95 case PropertyType::Double:
96 ImGui::Text("%.*s: %f", StringViewFormat(name), prop.doubleValue);
97 break;
98 case PropertyType::StringRef:
99 case PropertyType::String: {
100 std::string_view value = scene.properties.getString(prop);
101 ImGui::Text("%.*s: %.*s", StringViewFormat(name), StringViewFormat(value));
102 break;
103 }
104 case PropertyType::FloatArray: {
105 const std::span<float> value = scene.properties.getFloatArray(i);
106 if (value.size() == 6U) {
107 ImGui::Text("%.*s: float[%.2f, %.2f, %.2f, %.2f, %.2f, %.2f]", StringViewFormat(name), value[0], value[1], value[2], value[3], value[4], value[5]);
108 }
109 else {
110 ImGui::Text("%.*s: float[%zu]", StringViewFormat(name), value.size());
111 }
112 break;
113 }
114 case PropertyType::IntArray: {
115 const std::span<const int32_t> value = scene.properties.getIntArray(i);
116 ImGui::Text("%.*s: int[%zu]", StringViewFormat(name), value.size());
117 break;
118 }
119 case PropertyType::UIntArray: {
120 std::span<const uint32_t> value = scene.properties.getUIntArray(i);
121 ImGui::Text("%.*s: uint[%zu]", StringViewFormat(name), value.size());
122 break;
123 }
124 case PropertyType::DoubleArray: {
125 const std::span<const double> value = scene.properties.getDoubleArray(i);
126 ImGui::Text("%.*s: double[%zu]", StringViewFormat(name), value.size());
127 break;
128 }
129 default:
130 ImGui::Text("%.*s: ???", StringViewFormat(name));
131 break;
132 }
133 }
134 ImGui::TreePop();
135 }
136 }
137
138 if (definition.numChildren > 0) {
139 if (ImGui::TreeNode("Children")) {
140 uint32_t children = definition.numChildren;
141 uint32_t index = definition.firstChild;
142 while (index < scene.entities.size() && children > 0) {
143 const auto & child = scene.entities[index];
144
145 if (child.parentIndex == definition.index) {
146 showEntityDefinition(scene, child);
147 --children;
148 }
149
150 ++index;
151 }
152
153 ImGui::TreePop();
154 }
155 }
156
157 ImGui::TreePop();
158 }
159
160 ImGui::PopID();
161 }
162
163 void assetInspector(Context* context)
164 {
165 auto assets = context->assetManager->getAllocatedResources();
166
167 for (auto& resource : assets) {
168 auto asset = (Asset*)resource;
169
170 ImGui::PushID(asset);
171 std::string_view name = asset->getName();
172 if (name.empty()) name = "#anonymous";
173 if (ImGui::TreeNode(name.data())) {
174 if (ImGui::Button("Reload")) {
175 AssetHandle handle(asset);
176 context->assetManager->reloadAsset(handle);
177 }
178
179 ImGui::Text("Name: %.*s", StringViewFormat(name));
180
181 if (ImGui::TreeNode("Scene")) {
182 const SceneDefinition& scene = asset->definition.scene;
183
184 if (ImGui::TreeNode("Property", "Properties %zu (%s/%s allocated)",
185 scene.properties.getHeaders().size(),
186 byteString(scene.properties.currentByteSize()).c_str(),
187 byteString(scene.properties.allocatedByteSize()).c_str()))
188 {
189 std::span<const PropertyInfo> headers = scene.properties.getHeaders();
190
191 size_t boolCount = 0;
192 size_t intCount = 0;
193 size_t int2Count = 0;
194 size_t uintCount = 0;
195 size_t uint2Count = 0;
196 size_t floatCount = 0;
197 size_t float2Count = 0;
198 size_t doubleCount = 0;
199 size_t stringRefCount = 0;
200 size_t stringCount = 0;
201 size_t stringSizes = 0;
202 size_t floatArrayCount = 0;
203 size_t floatArraySizes = 0;
204 size_t intArrayCount = 0;
205 size_t intArraySizes = 0;
206 size_t uintArrayCount = 0;
207 size_t uintArraySizes = 0;
208 size_t doubleArrayCount = 0;
209 size_t doubleArraySizes = 0;
210 for (const PropertyInfo& info : headers) {
211 switch (info.type) {
212 case PropertyType::Bool: boolCount++; break;
213 case PropertyType::Integer: intCount++; break;
214 case PropertyType::UnsignedInteger: uintCount++; break;
215 case PropertyType::Float: floatCount++; break;
216 case PropertyType::Float2: float2Count++; break;
217 case PropertyType::Double: doubleCount++; break;
218 case PropertyType::StringRef: stringRefCount++; break;
219 case PropertyType::String: stringCount++; stringSizes += info.data.size; break;
220 case PropertyType::FloatArray: floatArrayCount++; floatArraySizes += info.data.size; break;
221 case PropertyType::IntArray: intArrayCount++; intArraySizes += info.data.size; break;
222 case PropertyType::UIntArray: uintArrayCount++; uintArraySizes += info.data.size; break;
223 case PropertyType::DoubleArray: doubleArrayCount++; doubleArraySizes += info.data.size; break;
224 default: break;
225 }
226 }
227
228
229 ImGui::BeginTable("sizes", 3, ImGuiTableFlags_SizingFixedFit);
230 ImGui::TableSetupColumn("Type", 0);
231 ImGui::TableSetupColumn("Count", ImGuiTableColumnFlags_WidthStretch);
232 ImGui::TableSetupColumn("ByteSize", ImGuiTableColumnFlags_WidthStretch);
233 ImGui::TableHeadersRow();
234
235 if (boolCount) {
236 ImGui::TableNextColumn(); ImGui::TextUnformatted("bool");
237 ImGui::TableNextColumn(); ImGui::Text("%zu", boolCount);
238 ImGui::TableNextColumn(); ImGui::TextUnformatted(byteString(boolCount * sizeof(PropertyInfo)).c_str());
239 }
240 if (intCount) {
241 ImGui::TableNextColumn(); ImGui::TextUnformatted("Int");
242 ImGui::TableNextColumn(); ImGui::Text("%zu", intCount);
243 ImGui::TableNextColumn(); ImGui::TextUnformatted(byteString(intCount * sizeof(PropertyInfo)).c_str());
244 }
245 if (int2Count) {
246 ImGui::TableNextColumn(); ImGui::TextUnformatted("Int2");
247 ImGui::TableNextColumn(); ImGui::Text("%zu", int2Count);
248 ImGui::TableNextColumn(); ImGui::TextUnformatted(byteString(int2Count * sizeof(PropertyInfo)).c_str());
249 }
250 if (uintCount) {
251 ImGui::TableNextColumn(); ImGui::TextUnformatted("Uint");
252 ImGui::TableNextColumn(); ImGui::Text("%zu", uintCount);
253 ImGui::TableNextColumn(); ImGui::TextUnformatted(byteString(uintCount * sizeof(PropertyInfo)).c_str());
254 }
255 if (uint2Count) {
256 ImGui::TableNextColumn(); ImGui::TextUnformatted("UInt2");
257 ImGui::TableNextColumn(); ImGui::Text("%zu", uint2Count);
258 ImGui::TableNextColumn(); ImGui::TextUnformatted(byteString(uint2Count * sizeof(PropertyInfo)).c_str());
259 }
260 if (floatCount) {
261 ImGui::TableNextColumn(); ImGui::TextUnformatted("Float");
262 ImGui::TableNextColumn(); ImGui::Text("%zu", floatCount);
263 ImGui::TableNextColumn(); ImGui::TextUnformatted(byteString(floatCount * sizeof(PropertyInfo)).c_str());
264 }
265 if (float2Count) {
266 ImGui::TableNextColumn(); ImGui::TextUnformatted("Float2");
267 ImGui::TableNextColumn(); ImGui::Text("%zu", float2Count);
268 ImGui::TableNextColumn(); ImGui::TextUnformatted(byteString(float2Count * sizeof(PropertyInfo)).c_str());
269 }
270 if (doubleCount) {
271 ImGui::TableNextColumn(); ImGui::TextUnformatted("Double");
272 ImGui::TableNextColumn(); ImGui::Text("%zu", doubleCount);
273 ImGui::TableNextColumn(); ImGui::TextUnformatted(byteString(doubleCount * sizeof(PropertyInfo)).c_str());
274 }
275 if (floatArrayCount) {
276 ImGui::TableNextColumn(); ImGui::TextUnformatted("Float array");
277 ImGui::TableNextColumn(); ImGui::Text("%zu", floatArrayCount);
278 ImGui::TableNextColumn(); ImGui::TextUnformatted(byteString(floatArrayCount * sizeof(PropertyInfo) + floatArraySizes).c_str());
279 }
280 if (intArrayCount) {
281 ImGui::TableNextColumn(); ImGui::TextUnformatted("Int array");
282 ImGui::TableNextColumn(); ImGui::Text("%zu", intArrayCount);
283 ImGui::TableNextColumn(); ImGui::TextUnformatted(byteString(intCount * sizeof(PropertyInfo) + intArraySizes).c_str());
284 }
285 if (uintArrayCount) {
286 ImGui::TableNextColumn(); ImGui::TextUnformatted("UInt array");
287 ImGui::TableNextColumn(); ImGui::Text("%zu", uintArrayCount);
288 ImGui::TableNextColumn(); ImGui::TextUnformatted(byteString(uintArrayCount * sizeof(PropertyInfo) + uintArraySizes).c_str());
289 }
290 if (doubleArrayCount) {
291 ImGui::TableNextColumn(); ImGui::TextUnformatted("Double array");
292 ImGui::TableNextColumn(); ImGui::Text("%zu", doubleArrayCount);
293 ImGui::TableNextColumn(); ImGui::TextUnformatted(byteString(doubleArrayCount * sizeof(PropertyInfo) + doubleArraySizes).c_str());
294 }
295 if (stringRefCount) {
296 ImGui::TableNextColumn(); ImGui::TextUnformatted("String ref");
297 ImGui::TableNextColumn(); ImGui::Text("%zu", stringRefCount);
298 ImGui::TableNextColumn(); ImGui::TextUnformatted(byteString(stringRefCount * sizeof(PropertyInfo)).c_str());
299 }
300 if (stringCount) {
301 ImGui::TableNextColumn(); ImGui::TextUnformatted("String");
302 ImGui::TableNextColumn(); ImGui::Text("%zu", stringCount);
303 ImGui::TableNextColumn(); ImGui::TextUnformatted(byteString(stringCount * sizeof(PropertyInfo) + stringSizes).c_str());
304 }
305
306 ImGui::EndTable();
307
308
309 ImGui::BeginTable("contents", 4, ImGuiTableFlags_SizingFixedFit);
310 ImGui::TableSetupColumn("Index", 0);
311 ImGui::TableSetupColumn("Key", 0);
312 ImGui::TableSetupColumn("Type", 0);
313 ImGui::TableSetupColumn("Value", ImGuiTableColumnFlags_WidthStretch);
314 ImGui::TableHeadersRow();
315
316 for (size_t i = 0, n = headers.size(); i < n; i++) {
317 const PropertyInfo& info = headers[i];
318 ImGui::TableNextColumn(); ImGui::Text("%zu", i);
319 ImGui::TableNextColumn(); ImGui::TextUnformatted(Strings::getC(info.key));
320 switch (info.type) {
321 case PropertyType::Bool:
322 ImGui::TableNextColumn(); ImGui::TextUnformatted("bool");
323 ImGui::TableNextColumn(); ImGui::TextUnformatted(info.boolValue ? "true" : "false");
324 break;
325 case PropertyType::Integer:
326 ImGui::TableNextColumn(); ImGui::TextUnformatted("int");
327 ImGui::TableNextColumn(); ImGui::Text("%d", info.intValue);
328 break;
329 case PropertyType::UnsignedInteger:
330 ImGui::TableNextColumn(); ImGui::TextUnformatted("uint");
331 ImGui::TableNextColumn(); ImGui::Text("0x%08x", info.uintValue);
332 break;
333 case PropertyType::Float:
334 ImGui::TableNextColumn(); ImGui::TextUnformatted("float");
335 ImGui::TableNextColumn(); ImGui::Text("%.2f", info.floatValue);
336 break;
337 case PropertyType::Double:
338 ImGui::TableNextColumn(); ImGui::TextUnformatted("double");
339 ImGui::TableNextColumn(); ImGui::Text("%.2f", info.doubleValue);
340 break;
341 case PropertyType::Float2:
342 case PropertyType::FloatArray: {
343 const std::span<const float> value = scene.properties.getFloatArray(uint32_t(i));
344 ImGui::TableNextColumn(); ImGui::Text("float[%zu]", value.size());
345 ImGui::TableNextColumn();
346 switch (value.size()) {
347 case 0: ImGui::TextUnformatted("{ }"); break;
348 case 1: ImGui::Text("{ %.2f }", value[0]); break;
349 case 2: ImGui::Text("{ %.2f, %.2f }", value[0], value[1]); break;
350 case 3: ImGui::Text("{ %.2f, %.2f, %.2f }", value[0], value[1], value[2]); break;
351 case 6: ImGui::Text("{ %.2f, %.2f, %.2f, %.2f, %.2f, %.2f }", value[0], value[1], value[2], value[3], value[4], value[5]); break;
352 default:ImGui::Text("{ %.2f, %.2f, %.2f, ... }", value[0], value[1], value[2]); break;
353 }
354 break;
355 }
356 case PropertyType::Int2:
357 case PropertyType::IntArray: {
358 const std::span<const int32_t> value = scene.properties.getIntArray(uint32_t(i));
359 ImGui::TableNextColumn(); ImGui::Text("int[%zu]", value.size());
360 ImGui::TableNextColumn();
361 switch (value.size()) {
362 case 0: ImGui::TextUnformatted("{ }"); break;
363 case 1: ImGui::Text("{ %d }", value[0]); break;
364 case 2: ImGui::Text("{ %d, %d }", value[0], value[1]); break;
365 case 3: ImGui::Text("{ %d, %d, %d }", value[0], value[1], value[2]); break;
366 default:ImGui::Text("{ %d, %d, %d, ... }", value[0], value[1], value[2]); break;
367 }
368 break;
369 }
370 case PropertyType::UInt2:
371 case PropertyType::UIntArray: {
372 const std::span<const uint32_t> value = scene.properties.getUIntArray(uint32_t(i));
373 ImGui::TableNextColumn(); ImGui::Text("uint[%zu]", value.size());
374 ImGui::TableNextColumn();
375 switch (value.size()) {
376 case 0: ImGui::TextUnformatted("{ }"); break;
377 case 1: ImGui::Text("{ %u }", value[0]); break;
378 case 2: ImGui::Text("{ %u, %u }", value[0], value[1]); break;
379 case 3: ImGui::Text("{ %u, %u, %u }", value[0], value[1], value[2]); break;
380 default:ImGui::Text("{ %u, %u, %u, ... }", value[0], value[1], value[2]); break;
381 }
382 break;
383 }
384 case PropertyType::DoubleArray: {
385 const std::span<const double> value = scene.properties.getDoubleArray(uint32_t(i));
386 ImGui::TableNextColumn(); ImGui::Text("double[%zu]", value.size());
387 ImGui::TableNextColumn();
388 switch (value.size()) {
389 case 0: ImGui::TextUnformatted("{ }"); break;
390 case 1: ImGui::Text("{ %.2f }", value[0]); break;
391 case 2: ImGui::Text("{ %.2f, %.2f }", value[0], value[1]); break;
392 case 3: ImGui::Text("{ %.2f, %.2f, %.2f }", value[0], value[1], value[2]); break;
393 default:ImGui::Text("{ %.2f, %.2f, %.2f, ... }", value[0], value[1], value[2]); break;
394 }
395 break;
396 }
397 case PropertyType::StringRef: {
398 std::string_view value = scene.properties.getString(info);
399 ImGui::TableNextColumn(); ImGui::Text("string ref[%zu]", value.size());
400 ImGui::TableNextColumn(); ImGui::Text("%.*s", StringViewFormat(value));
401 break;
402 }
403 case PropertyType::String: {
404 std::string_view value = scene.properties.getString(info);
405 ImGui::TableNextColumn(); ImGui::Text("string[%zu]", value.size());
406 ImGui::TableNextColumn(); ImGui::Text("%.*s", StringViewFormat(value));
407 break;
408 }
409 default:
410 ImGui::TableNextColumn(); ImGui::TextUnformatted("???");
411 ImGui::TableNextRow();
412 break;
413 }
414 //ImGui::TableNextRow();
415 }
416 ImGui::EndTable();
417
418
419
420 ImGui::TreePop();
421 }
422 for (auto& d : asset->definition.scene.entities) {
423 if (d.parentIndex == SceneEntityDefinition::NoIndex || d.isParentedByName()) {
424 showEntityDefinition(asset->definition.scene, d);
425 }
426 }
427
428 ImGui::TreePop();
429 }
430
431 if (ImGui::TreeNode("Models")) {
432 for (auto& m : asset->models) {
433 ImGui::PushID(m.resolve());
434 showModel(context, m.resolve(), std::string(m->getName()));
435 ImGui::PopID();
436 }
437
438 ImGui::TreePop();
439 }
440
441 if (ImGui::TreeNode("Textures")) {
442 for (auto& t : asset->textures) {
443 ImGui::PushID(t.resolve());
444 showTexture(context, dynamic_cast<Cogs::Core::Renderer*>(context->renderer), t.resolve(), false);
445 ImGui::PopID();
446 }
447
448 ImGui::TreePop();
449 }
450
451 ImGui::TreePop();
452 }
453
454 ImGui::PopID();
455 }
456
457 }
458
459 void assetInstanceInspector(Context * context)
460 {
461 for (auto & assetComponent : context->assetSystem->pool) {
462 ImGui::PushID(&assetComponent);
463
464 const auto & data = context->assetSystem->getData<AssetData>(&assetComponent);
465
466 std::string name = data.asset ? IO::stem(data.asset->getName()) : "Asset: N/A";
467
468 if (ImGui::TreeNode(name.c_str())) {
469 auto stats = context->assetSystem->getStats(&assetComponent);
470 if (stats) {
471 ImGui::Columns(4, "Stats");
472
473 ImGui::NextColumn();
474
475 ImGui::Text("Current");
476 ImGui::NextColumn();
477
478 ImGui::Text("Projected");
479 ImGui::NextColumn();
480
481 ImGui::Text("Limit");
482 ImGui::NextColumn();
483
484 ImGui::Separator();
485
486#if ENABLE_COST_TRACKING
487 // Next line
488
489 ImGui::Text("Memory");
490 ImGui::NextColumn();
491
492 ImGui::Text("%" PRIx64 "u", stats->current.memory);
493 ImGui::NextColumn();
494
495 ImGui::Text("%" PRIx64 "u", stats->projected.memory);
496 ImGui::NextColumn();
497
498 ImGui::Text("%" PRIx64 "u", stats->max.memory);
499 ImGui::NextColumn();
500
501 // Next line
502
503 ImGui::Text("Draw calls");
504 ImGui::NextColumn();
505
506 ImGui::Text("%u", stats->current.drawCalls);
507 ImGui::NextColumn();
508
509 ImGui::Text("%u", stats->projected.drawCalls);
510 ImGui::NextColumn();
511
512 ImGui::Text("%u", stats->max.drawCalls);
513 ImGui::NextColumn();
514
515 // Next line
516
517 ImGui::Text("Primitives");
518 ImGui::NextColumn();
519
520 ImGui::Text("%u", stats->current.primitiveCount);
521 ImGui::NextColumn();
522
523 ImGui::Text("%u", stats->projected.primitiveCount);
524 ImGui::NextColumn();
525
526 ImGui::Text("%u", stats->max.primitiveCount);
527 ImGui::NextColumn();
528#endif
529 ImGui::Columns(1);
530
531 ImGui::Separator();
532
533 ImGui::Text("Entities spawned: %d", stats->frame.spawnedEntities);
534 ImGui::Text("Entities destroyed: %d", stats->frame.destroyedEntities);
535 ImGui::Text("Entities alive: %d", stats->numEntities);
536
537#if ENABLE_COST_TRACKING
538 ImGui::Text("Tolerance scale: %f", stats->toleranceScale);
539#endif
540 ImGui::Text("Requests: %u", stats->numRequests);
541
542 ImGui::Separator();
543
544 ImGui::Text("Frustum cull in: %d", stats->frustumCullIn);
545 ImGui::Text("Frustum cull out: %d", stats->frustumCullOut);
546 ImGui::Text("BBox cull out: %d", stats->bboxCullOut);
547
548
549 ImGui::TreePop();
550 }
551 }
552
553 ImGui::PopID();
554 }
555 }
556
557}
558
559void Cogs::Core::assetInspector(Context * context, bool * show)
560{
561 if (*show) {
562 ImGui::SetNextWindowSize(ImVec2(600, 1000), ImGuiCond_FirstUseEver);
563
564 ImGui::Begin("Assets", show, 0);
565
566 if (ImGui::CollapsingHeader("Assets")) {
567 assetInspector(context);
568 }
569 if (ImGui::CollapsingHeader("Assets instances")) {
570 assetInstanceInspector(context);
571 }
572 ImGui::End();
573 }
574}
575
576void Cogs::Core::assetQueueInspector(Context* context, bool* show)
577{
578 if (*show) {
579 ImGui::SetNextWindowSize(ImVec2(600, 600), ImGuiCond_FirstUseEver);
580 ImGui::Begin("Asset Queue", show, 0);
581
582 auto pendingAssets = context->assetSystem->getPendingRequests();
583 auto inFlightAssets = context->assetSystem->getInFlightRequests();
584 auto buttonSize = ImVec2(70, 30);
585
586 if (!pendingAssets.empty()) {
587 assetsInQueueGraph.push_back(static_cast<float>(pendingAssets.size()));
588
589 std::vector<std::string> assetsInQueuePaths;
590 assetsInQueuePaths.reserve(pendingAssets.size());
591
592 for (auto& resource : pendingAssets) {
593 assetsInQueuePaths.emplace_back(resource->path);
594 }
595 assetsInQueueHistory.push_back(assetsInQueuePaths);
596 }
597 assetsInQueueTotal = pendingAssets.size();
598
599 if (!inFlightAssets.empty()) {
600 assetsProcessingGraph.push_back(static_cast<float>(inFlightAssets.size()));
601 std::vector<std::string> assetsProcessingPaths;
602 assetsProcessingPaths.reserve(inFlightAssets.size());
603
604 for (auto& resource : inFlightAssets) {
605 assetsProcessingPaths.emplace_back(resource->path);
606 }
607 assetsProcessingHistory.emplace_back(std::move(assetsProcessingPaths));
608 }
609 assetsProcessingTotal = inFlightAssets.size();
610
611 // Limit sizes to graph size:
612 while (assetsInQueueGraph.size() > static_cast<size_t>(assetsInQueueGraphScale)) {
613 assetsInQueueGraph.erase(assetsInQueueGraph.begin());
614 assetsInQueueHistory.erase(assetsInQueueHistory.begin());
615 }
616
617 while (assetsProcessingGraph.size() > static_cast<size_t>(assetsProcessingGraphScale)) {
618 assetsProcessingGraph.erase(assetsProcessingGraph.begin());
619 assetsProcessingHistory.erase(assetsProcessingHistory.begin());
620 }
621
622 assetsInQueueGraphHeight = std::max(assetsInQueueGraphHeight, static_cast<float>(pendingAssets.size()));
623 assetsProcessingGraphHeight = std::max(assetsProcessingGraphHeight, static_cast<float>(inFlightAssets.size()));
624 ImGui::PlotHistogram("", assetsInQueueGraph.data(), static_cast<int>(assetsInQueueGraph.size()), 0, nullptr, 0, assetsInQueueGraphHeight, ImVec2((ImGui::GetWindowContentRegionMax().x - ImGui::GetWindowContentRegionMin().x) / 2, 150.f));
625 ImGui::SameLine();
626 ImGui::PlotHistogram("", assetsProcessingGraph.data(), static_cast<int>(assetsProcessingGraph.size()), 0, nullptr, 0, assetsProcessingGraphHeight, ImVec2((ImGui::GetWindowContentRegionMax().x - ImGui::GetWindowContentRegionMin().x) / 2 - 8.f, 150.f));
627
628 ImGui::Text("Pending requests: %zu", assetsInQueueTotal);
629 ImGui::SameLine();
630 ImGui::SetCursorPosX((ImGui::GetWindowContentRegionMax().x - ImGui::GetWindowContentRegionMin().x) / 2 + 15.f);
631 ImGui::Text("In flight requests: %zu", assetsProcessingTotal);
632
633 ImGui::PushItemWidth((ImGui::GetWindowContentRegionMax().x - ImGui::GetWindowContentRegionMin().x) / 2 - 80.f);
634 ImGui::SliderInt("Pending scale", &assetsInQueueGraphScale, 10, 150);
635 ImGui::PopItemWidth();
636 ImGui::SameLine();
637 ImGui::PushItemWidth((ImGui::GetWindowContentRegionMax().x - ImGui::GetWindowContentRegionMin().x) / 2 - 90.f);
638 ImGui::SetCursorPosX((ImGui::GetWindowContentRegionMax().x - ImGui::GetWindowContentRegionMin().x) / 2 + 15.f);
639 ImGui::SliderInt("In flight scale", &assetsProcessingGraphScale, 10, 300);
640 ImGui::PopItemWidth();
641
642 if (ImGui::Button("Reset all", buttonSize)) {
643 assetsProcessingGraph.clear();
644 assetsProcessingHistory.clear();
645 assetsProcessingTotal = 0;
646 assetsInQueueGraph.clear();
647 assetsInQueueHistory.clear();
648 assetsInQueueTotal = 0;
649 }
650
651 ImGui::Separator();
652
653 for (size_t i = 0; i < std::max(assetsInQueueHistory.size(), assetsProcessingHistory.size()); i++) {
654 std::string header;
655 header.reserve(50);
656 header += std::to_string(i);
657 if (i < assetsInQueueHistory.size()) {
658 header += " Pending: ";
659 header += std::to_string(assetsInQueueHistory[i].size());
660 }
661 if (i < assetsProcessingHistory.size()) {
662 header += " In Flight: ";
663 header += std::to_string(assetsProcessingHistory[i].size());
664 }
665 if (ImGui::CollapsingHeader(header.c_str())) {
666 ImGui::Text("----------------Pending Requests----------------");
667 if (i < assetsInQueueHistory.size()) {
668 for (const std::string& assetName : assetsInQueueHistory[i]) {
669 ImGui::TextWrapped("%s", assetName.c_str());
670 }
671 }
672 ImGui::Text("----------------In Flight Requests-----------------");
673 if (i < assetsProcessingHistory.size()) {
674 for (const std::string& assetName : assetsProcessingHistory[i]) {
675 ImGui::TextWrapped("%s", assetName.c_str());
676 }
677 }
678 }
679 }
680
681 ImGui::End();
682 }
683}
Core renderer system.
Definition: Renderer.h:28
Contains the Engine, Renderer, resource managers and other systems needed to run Cogs....