material/node.cpp
| Line | Branch | Exec | Source |
|---|---|---|---|
| 1 | // SPDX-License-Identifier: BSD-3-Clause | ||
| 2 | #include "chrono_batch_render/material/node.h" | ||
| 3 | |||
| 4 | #include <algorithm> | ||
| 5 | #include <map> | ||
| 6 | #include <string> | ||
| 7 | #include <vector> | ||
| 8 | |||
| 9 | #include "chrono_batch_render/graph/library.h" | ||
| 10 | #include "chrono_batch_render/util/error.h" | ||
| 11 | |||
| 12 | namespace chrono::batch_render::material { | ||
| 13 | |||
| 14 | namespace { | ||
| 15 | |||
| 16 | 6 | struct Nodes { | |
| 17 | std::map<std::string, std::shared_ptr<const MaterialNodeDefinition>, std::less<>> byName; | ||
| 18 | ClosurePrimitiveList primitives; | ||
| 19 | uint64_t version = 0; | ||
| 20 | }; | ||
| 21 | |||
| 22 | 9854 | graph::Published<Nodes>& Registry() { | |
| 23 | 9854 | static graph::Published<Nodes> nodes; | |
| 24 | 9854 | return nodes; | |
| 25 | } | ||
| 26 | |||
| 27 | } | ||
| 28 | |||
| 29 | 20 | void RegisterMaterialNode(MaterialNodeDefinition node) { | |
| 30 | 20 | Registry().Update([&](Nodes& nodes) { | |
| 31 | 20 | const auto found = nodes.byName.find(node.name); | |
| 32 | 20 | if (found != nodes.byName.end() && found->second->file != node.file) { | |
| 33 | ✗ | throw Error("A material node called {} is already loaded from {}", node.name, | |
| 34 | ✗ | found->second->file); | |
| 35 | } | ||
| 36 | 20 | if (found != nodes.byName.end() && found->second->source == node.source && | |
| 37 | ✗ | found->second->schema == node.schema) { | |
| 38 | ✗ | return; | |
| 39 | } | ||
| 40 | 20 | nodes.version += found != nodes.byName.end() ? 1 : 0; | |
| 41 | 20 | const std::string name = node.name; | |
| 42 | 20 | nodes.byName[name] = std::make_shared<const MaterialNodeDefinition>(std::move(node)); | |
| 43 | 20 | }); | |
| 44 | 20 | } | |
| 45 | |||
| 46 | ✗ | std::vector<std::shared_ptr<const MaterialNodeDefinition>> MaterialNodes() { | |
| 47 | ✗ | const std::shared_ptr<const Nodes> nodes = Registry().Get(); | |
| 48 | ✗ | std::vector<std::shared_ptr<const MaterialNodeDefinition>> listed; | |
| 49 | ✗ | for (const auto& [name, node] : nodes->byName) { | |
| 50 | ✗ | listed.push_back(node); | |
| 51 | } | ||
| 52 | ✗ | return listed; | |
| 53 | ✗ | } | |
| 54 | |||
| 55 | 39 | std::shared_ptr<const MaterialNodeDefinition> FindMaterialNode(std::string_view name) { | |
| 56 | 39 | const std::shared_ptr<const Nodes> nodes = Registry().Get(); | |
| 57 | 39 | const auto found = nodes->byName.find(name); | |
| 58 | 61 | return found == nodes->byName.end() ? nullptr : found->second; | |
| 59 | 39 | } | |
| 60 | |||
| 61 | 3 | ClosurePrimitiveList WithClosurePrimitive(ClosurePrimitiveList primitives, | |
| 62 | ClosurePrimitive primitive) { | ||
| 63 | 3 | const auto known = std::ranges::find(primitives, primitive.name, | |
| 64 | 1 | [](const auto& entry) { return entry->name; }); | |
| 65 | 3 | if (known == primitives.end()) { | |
| 66 | 3 | primitive.kind = kFirstPrimitiveLobe + uint32_t(primitives.size()); | |
| 67 | 3 | primitives.push_back(std::make_shared<const ClosurePrimitive>(std::move(primitive))); | |
| 68 | 3 | return primitives; | |
| 69 | } | ||
| 70 | ✗ | if ((*known)->file != primitive.file) { | |
| 71 | ✗ | throw Error("A closure primitive called {} is already loaded from {}", primitive.name, | |
| 72 | ✗ | (*known)->file); | |
| 73 | } | ||
| 74 | ✗ | if ((*known)->source != primitive.source) { | |
| 75 | ✗ | primitive.kind = (*known)->kind; | |
| 76 | ✗ | *known = std::make_shared<const ClosurePrimitive>(std::move(primitive)); | |
| 77 | } | ||
| 78 | ✗ | return primitives; | |
| 79 | } | ||
| 80 | |||
| 81 | 1 | void RegisterClosurePrimitive(ClosurePrimitive primitive) { | |
| 82 | 1 | Registry().Update([&](Nodes& nodes) { | |
| 83 | 1 | ClosurePrimitiveList primitives = | |
| 84 | 1 | WithClosurePrimitive(nodes.primitives, std::move(primitive)); | |
| 85 | 1 | if (primitives != nodes.primitives) { | |
| 86 | 1 | nodes.primitives = std::move(primitives); | |
| 87 | 1 | ++nodes.version; | |
| 88 | } | ||
| 89 | 1 | }); | |
| 90 | 1 | } | |
| 91 | |||
| 92 | 351 | ClosurePrimitiveList ClosurePrimitives() { | |
| 93 | 702 | return Registry().Get()->primitives; | |
| 94 | } | ||
| 95 | |||
| 96 | 9443 | uint64_t MaterialNodeVersion() { | |
| 97 | 9443 | return Registry().Get()->version; | |
| 98 | } | ||
| 99 | |||
| 100 | } | ||
| 101 |