chrono_batch_render/
Coverage:
low: ≥ 0%
medium: ≥ 75.0%
high: ≥ 90.0%
Lines:
152 / 156
97.4%
Branches:
112 / 125
89.6%
Functions:
22 / 22
100.0%

scene/prim.cpp
Line Branch Exec Source
1 // SPDX-License-Identifier: BSD-3-Clause
2 #include "chrono_batch_render/scene/prim.h"
3
4 #include <algorithm>
5
6 #include "chrono_batch_render/scene/scene.h"
7 #include "chrono_batch_render/scene/scene_impl.h"
8 #include "chrono_batch_render/util/error.h"
9 #include "chrono_batch_render/util/log.h"
10
11 namespace chrono::batch_render {
12
13 71364 Scene& Prim::GetScene() const {
14
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 71364 times.
71364 if (m_scene == nullptr) {
15
0/2
✗ Branch 2 not taken.
✗ Branch 5 not taken.
✗ throw Error("An empty prim belongs to no scene");
16 }
17 71364 return *m_scene;
18 }
19
20 119699 bool Prim::Valid() const {
21 119699 const auto lock = LockScene(m_scene);
22
1/2
✓ Branch 0 taken 119699 times.
✗ Branch 1 not taken.
119699 if (m_scene == nullptr) {
23 return false;
24 }
25
1/1
✓ Branch 1 taken 119699 times.
119699 const Prims& prims = SceneImpl::Get(*m_scene).GetStructure().GetPrims();
26
6/6
✓ Branch 1 taken 119699 times.
✓ Branch 3 taken 119697 times.
✓ Branch 4 taken 2 times.
✓ Branch 6 taken 119697 times.
✓ Branch 8 taken 2 times.
✓ Branch 9 taken 119695 times.
119699 return prims.Alive(m_index) && prims.Generation(m_index) == m_generation;
27 119699 }
28
29 63735 void Prim::Check() const {
30 63735 const auto lock = LockScene(m_scene);
31
2/3
✓ Branch 1 taken 63735 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 63735 times.
63735 if (!Valid()) {
32
0/1
✗ Branch 2 not taken.
✗ throw Error("Prim {} was removed", m_index);
33 }
34 63735 }
35
36 61420 SchemaId Prim::Schema() const {
37 61420 const auto lock = LockScene(m_scene);
38
1/1
✓ Branch 1 taken 61420 times.
61420 Check();
39
1/1
✓ Branch 1 taken 61420 times.
122840 return SceneImpl::Get(*m_scene).GetStructure().GetPrims().Record(m_index).schema;
40 61420 }
41
42 5 bool Prim::IsSession() const {
43 5 const auto lock = LockScene(m_scene);
44
1/1
✓ Branch 1 taken 5 times.
5 Check();
45
1/1
✓ Branch 1 taken 5 times.
10 return SceneImpl::Get(*m_scene).GetStructure().GetPrims().Session(m_index);
46 5 }
47
48 11 uint32_t Prim::World() const {
49 11 const auto lock = LockScene(m_scene);
50
1/1
✓ Branch 1 taken 11 times.
11 Check();
51
1/1
✓ Branch 1 taken 11 times.
22 return SceneImpl::Get(*m_scene).GetStructure().GetPrims().Record(m_index).world;
52 11 }
53
54 2123 std::string Prim::Path() const {
55 2123 const auto lock = LockScene(m_scene);
56
1/1
✓ Branch 1 taken 2123 times.
2123 Check();
57
1/1
✓ Branch 1 taken 2123 times.
4246 return SceneImpl::Get(*m_scene).GetStructure().GetPaths().Path(m_index);
58 2123 }
59
60 2 std::string_view Prim::Name() const {
61 2 const auto lock = LockScene(m_scene);
62
1/1
✓ Branch 1 taken 2 times.
2 Check();
63
1/1
✓ Branch 1 taken 2 times.
4 return SceneImpl::Get(*m_scene).GetStructure().GetPaths().Name(m_index);
64 2 }
65
66 6 std::optional<Prim> Prim::Parent() const {
67 6 const auto lock = LockScene(m_scene);
68
1/1
✓ Branch 1 taken 6 times.
6 Check();
69 6 const uint32_t parent =
70
1/1
✓ Branch 1 taken 6 times.
6 SceneImpl::Get(*m_scene).GetStructure().GetPrims().Record(m_index).parent;
71
2/2
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 4 times.
6 if (parent == kNoPrim) {
72 2 return std::nullopt;
73 }
74
1/1
✓ Branch 1 taken 4 times.
4 return SceneImpl::Get(*m_scene).Handle(parent);
75 6 }
76
77 147 std::vector<Prim> Prim::Children() const {
78 147 const auto lock = LockScene(m_scene);
79
1/1
✓ Branch 1 taken 147 times.
147 Check();
80 147 std::vector<Prim> children;
81 147 for (const uint32_t child :
82
3/3
✓ Branch 1 taken 147 times.
✓ Branch 3 taken 257 times.
✓ Branch 4 taken 147 times.
404 SceneImpl::Get(*m_scene).GetStructure().GetPaths().Children(m_index)) {
83
1/1
✓ Branch 1 taken 257 times.
514 children.push_back(SceneImpl::Get(*m_scene).Handle(child));
84 147 }
85 147 return children;
86 147 }
87
88 300 std::vector<Connection> Prim::Connections() const {
89 300 const auto lock = LockScene(m_scene);
90
1/1
✓ Branch 1 taken 300 times.
300 CheckSchema(SchemaId::Connectable);
91
1/1
✓ Branch 1 taken 300 times.
300 const std::vector<std::string> sources = Get(Connectable::kConnectionsSources);
92
1/1
✓ Branch 1 taken 300 times.
300 const std::vector<std::string> inputs = Get(Connectable::kConnectionsInputs);
93
1/1
✓ Branch 1 taken 300 times.
300 const std::vector<std::string> outputs = Get(Connectable::kConnectionsOutputs);
94
1/1
✓ Branch 1 taken 300 times.
300 const size_t count = std::min({sources.size(), inputs.size(), outputs.size()});
95 300 std::vector<Connection> connections;
96
1/1
✓ Branch 1 taken 300 times.
300 connections.reserve(count);
97
2/2
✓ Branch 0 taken 66 times.
✓ Branch 1 taken 300 times.
366 for (size_t i = 0; i < count; ++i) {
98
3/3
✓ Branch 1 taken 66 times.
✓ Branch 4 taken 66 times.
✓ Branch 7 taken 66 times.
132 connections.push_back({inputs[i], sources[i], outputs[i]});
99 }
100 300 return connections;
101 366 }
102
103 namespace {
104
105 254 void WriteConnections(const Prim& prim, const std::vector<Connection>& connections) {
106 254 std::vector<std::string> sources;
107 254 std::vector<std::string> inputs;
108 254 std::vector<std::string> outputs;
109
2/2
✓ Branch 0 taken 259 times.
✓ Branch 1 taken 254 times.
513 for (const Connection& connection : connections) {
110
1/1
✓ Branch 1 taken 259 times.
259 sources.push_back(connection.source);
111
1/1
✓ Branch 1 taken 259 times.
259 inputs.push_back(connection.input);
112
1/1
✓ Branch 1 taken 259 times.
259 outputs.push_back(connection.output);
113 }
114
1/1
✓ Branch 1 taken 254 times.
254 prim.Set(Connectable::kConnectionsSources, sources);
115
1/1
✓ Branch 1 taken 254 times.
254 prim.Set(Connectable::kConnectionsInputs, inputs);
116
1/1
✓ Branch 1 taken 254 times.
254 prim.Set(Connectable::kConnectionsOutputs, outputs);
117 254 }
118
119 }
120
121 250 void Prim::Connect(std::string_view input, const Prim& source, std::string_view output) const {
122 250 const auto lock = LockScene(m_scene);
123
1/1
✓ Branch 1 taken 248 times.
250 CheckSchema(SchemaId::Connectable);
124
1/1
✓ Branch 1 taken 247 times.
248 source.CheckSchema(SchemaId::Connectable);
125
3/4
✓ Branch 1 taken 247 times.
✓ Branch 4 taken 247 times.
✗ Branch 6 not taken.
✓ Branch 7 taken 247 times.
247 if (&source.GetScene() != &GetScene()) {
126
0/1
✗ Branch 1 not taken.
✗ throw Error("{} can't connect {} to {}, which is in another scene", Path(), input,
127
0/2
✗ Branch 2 not taken.
✗ Branch 5 not taken.
✗ source.Path());
128 }
129
3/4
✓ Branch 0 taken 246 times.
✓ Branch 1 taken 1 time.
✗ Branch 2 not taken.
✓ Branch 3 taken 246 times.
247 if (input.empty() || output.empty()) {
130
1/1
✓ Branch 1 taken 1 time.
2 throw Error("Connecting {} to {} needs both an input and an output name", Path(),
131
2/2
✓ Branch 2 taken 1 time.
✓ Branch 5 taken 1 time.
3 source.Path());
132 }
133
1/1
✓ Branch 1 taken 246 times.
246 std::vector<Connection> connections = Connections();
134 246 const auto found = std::ranges::find(connections, input, &Connection::input);
135
2/2
✓ Branch 0 taken 9 times.
✓ Branch 1 taken 237 times.
246 if (found != connections.end()) {
136
1/1
✓ Branch 1 taken 9 times.
18 Log(LogLevel::Debug, "{}'s {} reconnects from {}.{} to {}.{}", Path(), input, found->source,
137
2/2
✓ Branch 1 taken 9 times.
✓ Branch 4 taken 9 times.
9 found->output, source.Path(), output);
138
1/1
✓ Branch 1 taken 9 times.
9 found->source = source.Path();
139
1/1
✓ Branch 1 taken 9 times.
9 found->output = std::string(output);
140 } else {
141
3/3
✓ Branch 1 taken 237 times.
✓ Branch 4 taken 237 times.
✓ Branch 7 taken 237 times.
474 Log(LogLevel::Debug, "{}'s {} connects to {}.{}", Path(), input, source.Path(), output);
142
2/2
✓ Branch 1 taken 237 times.
✓ Branch 4 taken 237 times.
711 connections.push_back({std::string(input), source.Path(), std::string(output)});
143 }
144
1/1
✓ Branch 1 taken 246 times.
246 WriteConnections(*this, connections);
145 724 }
146
147 10 void Prim::Disconnect(std::string_view input) const {
148 10 const auto lock = LockScene(m_scene);
149
1/1
✓ Branch 1 taken 10 times.
10 std::vector<Connection> connections = Connections();
150 10 const auto found = std::ranges::find(connections, input, &Connection::input);
151
2/2
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 8 times.
10 if (found == connections.end()) {
152 2 return;
153 }
154
1/1
✓ Branch 1 taken 8 times.
8 Log(LogLevel::Debug, "{}'s {} disconnects from {}.{}", Path(), input, found->source,
155
1/1
✓ Branch 1 taken 8 times.
8 found->output);
156 8 connections.erase(found);
157
1/1
✓ Branch 1 taken 8 times.
8 WriteConnections(*this, connections);
158 18 }
159
160 14348 View Prim::Single() const {
161 14348 const auto lock = LockScene(m_scene);
162
2/2
✓ Branch 1 taken 14348 times.
✓ Branch 4 taken 14347 times.
28695 return GetScene().Select(*this);
163 14348 }
164
165 6 View Prim::Single(SchemaId api, std::string_view instance) const {
166 6 const auto lock = LockScene(m_scene);
167
2/2
✓ Branch 1 taken 6 times.
✓ Branch 4 taken 6 times.
12 return GetScene().Select(*this, api, instance);
168 6 }
169
170 1 std::vector<std::string> Prim::Instances(SchemaId api) const {
171 1 const auto lock = LockScene(m_scene);
172
1/1
✓ Branch 1 taken 1 time.
1 Check();
173
1/1
✓ Branch 1 taken 1 time.
1 const Structure& structure = SceneImpl::Get(*m_scene).GetStructure();
174 1 std::vector<std::string> names;
175
3/3
✓ Branch 1 taken 1 time.
✓ Branch 3 taken 1 time.
✓ Branch 4 taken 1 time.
2 for (const ApiInstance& entry : structure.GetPrims().Instances(m_index, api)) {
176
2/2
✓ Branch 1 taken 1 time.
✓ Branch 4 taken 1 time.
1 names.emplace_back(structure.GetTokens().Text(Token{entry.instance}));
177 }
178 1 std::ranges::sort(names);
179 1 return names;
180 1 }
181
182 2568 bool Prim::IsA(SchemaId schema) const {
183 2568 const auto lock = LockScene(m_scene);
184
2/2
✓ Branch 1 taken 2568 times.
✓ Branch 4 taken 2568 times.
5136 return chrono::batch_render::IsA(Schema(), schema);
185 2568 }
186
187 20 bool Prim::HasApi(SchemaId api) const {
188 20 const auto lock = LockScene(m_scene);
189
1/1
✓ Branch 1 taken 20 times.
20 Check();
190
1/1
✓ Branch 1 taken 20 times.
40 return SceneImpl::Get(*m_scene).GetStructure().GetPrims().HasApi(m_index, api);
191 20 }
192
193 3127 void Prim::CheckSchema(SchemaId schema) const {
194 3127 const auto lock = LockScene(m_scene);
195
7/7
✓ Branch 1 taken 3127 times.
✓ Branch 4 taken 3127 times.
✓ Branch 6 taken 5 times.
✓ Branch 7 taken 3122 times.
✓ Branch 9 taken 5 times.
✓ Branch 11 taken 4 times.
✓ Branch 12 taken 1 time.
3127 if (!chrono::batch_render::IsA(Schema(), schema) && !HasApi(schema)) {
196
5/7
✗ Branch 1 not taken.
✓ Branch 2 taken 4 times.
✓ Branch 4 taken 4 times.
✗ Branch 6 not taken.
✓ Branch 7 taken 4 times.
✓ Branch 9 taken 4 times.
✓ Branch 12 taken 4 times.
16 throw Error("{} is a {}, not a {}", Path(), Info(Schema()).name, Info(schema).name);
197 }
198 3127 }
199
200 35 Token Prim::Intern(std::string_view text) const {
201 35 const auto lock = LockScene(m_scene);
202
2/2
✓ Branch 1 taken 35 times.
✓ Branch 4 taken 35 times.
70 return GetScene().Token(text);
203 35 }
204
205 509 std::string_view Prim::Text(Token token) const {
206 509 const auto lock = LockScene(m_scene);
207
2/2
✓ Branch 1 taken 509 times.
✓ Branch 4 taken 509 times.
1018 return GetScene().Text(token);
208 509 }
209
210 }
211