| Line |
Branch |
Exec |
Source |
| 1 |
|
|
// SPDX-License-Identifier: BSD-3-Clause |
| 2 |
|
|
/// @file blackboard.h |
| 3 |
|
|
/// @brief A per-graph store where passes leave structs of handles for later passes to find by |
| 4 |
|
|
/// type, rather than in renderer members. |
| 5 |
|
|
/// |
| 6 |
|
|
/// struct Hits { graph::Image ids, depth; }; |
| 7 |
|
|
/// graph.Board().Put(Hits{ids, depth}); |
| 8 |
|
|
/// // Later, in another feature's setup: |
| 9 |
|
|
/// const Hits& hits = graph.Board().Get<Hits>(); |
| 10 |
|
|
/// |
| 11 |
|
|
/// References: |
| 12 |
|
|
/// - Google, Filament's FrameGraph Blackboard. https://github.com/google/filament |
| 13 |
|
|
#pragma once |
| 14 |
|
|
|
| 15 |
|
|
#include <any> |
| 16 |
|
|
#include <stdexcept> |
| 17 |
|
|
#include <string> |
| 18 |
|
|
#include <typeindex> |
| 19 |
|
|
#include <typeinfo> |
| 20 |
|
|
#include <unordered_map> |
| 21 |
|
|
|
| 22 |
|
|
namespace ernie::graph { |
| 23 |
|
|
|
| 24 |
|
|
/// @brief One value of each type, such as a feature's handles. |
| 25 |
|
96 |
class Blackboard { |
| 26 |
|
|
public: |
| 27 |
|
|
/// @brief Stores a value, replacing one of the same type. |
| 28 |
|
|
/// @return The stored value. |
| 29 |
|
30 |
template <typename T> T& Put(T value) { |
| 30 |
|
30 |
std::any& slot = values_[typeid(T)]; |
| 31 |
|
30 |
slot = std::move(value); |
| 32 |
|
30 |
return std::any_cast<T&>(slot); |
| 33 |
|
|
} |
| 34 |
|
|
/// @return The value of type `T`, or null. |
| 35 |
|
30 |
template <typename T> T* Find() { |
| 36 |
|
30 |
const auto found = values_.find(typeid(T)); |
| 37 |
7/12
ernie::TraceScene* ernie::graph::Blackboard::Find<ernie::TraceScene>():
✓ Branch 0 taken 25 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 25 times.
✗ Branch 3 not taken.
ernie::graph::(anonymous namespace)::Blackboard_FindsValuesByType_Test::TestBody()::Hits* ernie::graph::Blackboard::Find<ernie::graph::(anonymous namespace)::Blackboard_FindsValuesByType_Test::TestBody()::Hits>():
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 2 times.
✓ Branch 2 taken 2 times.
✗ Branch 3 not taken.
ernie::graph::(anonymous namespace)::Blackboard_FindsValuesByType_Test::TestBody()::Sky* ernie::graph::Blackboard::Find<ernie::graph::(anonymous namespace)::Blackboard_FindsValuesByType_Test::TestBody()::Sky>():
✓ Branch 0 taken 1 time.
✗ Branch 1 not taken.
✓ Branch 2 taken 1 time.
✗ Branch 3 not taken.
|
58 |
return found == values_.end() ? nullptr : std::any_cast<T>(&found->second); |
| 38 |
|
|
} |
| 39 |
|
|
template <typename T> const T* Find() const { |
| 40 |
|
|
const auto found = values_.find(typeid(T)); |
| 41 |
|
|
return found == values_.end() ? nullptr : std::any_cast<T>(&found->second); |
| 42 |
|
|
} |
| 43 |
|
|
/// @return The value of type `T`. |
| 44 |
|
|
/// @throws std::out_of_range if none was put. |
| 45 |
|
13 |
template <typename T> T& Get() { |
| 46 |
4/6
ernie::TraceScene& ernie::graph::Blackboard::Get<ernie::TraceScene>():
✓ Branch 1 taken 9 times.
✗ Branch 2 not taken.
ernie::graph::(anonymous namespace)::Blackboard_FindsValuesByType_Test::TestBody()::Hits& ernie::graph::Blackboard::Get<ernie::graph::(anonymous namespace)::Blackboard_FindsValuesByType_Test::TestBody()::Hits>():
✓ Branch 1 taken 2 times.
✓ Branch 2 taken 1 time.
ernie::graph::(anonymous namespace)::Blackboard_FindsValuesByType_Test::TestBody()::Sky& ernie::graph::Blackboard::Get<ernie::graph::(anonymous namespace)::Blackboard_FindsValuesByType_Test::TestBody()::Sky>():
✓ Branch 1 taken 1 time.
✗ Branch 2 not taken.
|
13 |
if (T* value = Find<T>()) { |
| 47 |
|
12 |
return *value; |
| 48 |
|
|
} |
| 49 |
2/12
ernie::TraceScene& ernie::graph::Blackboard::Get<ernie::TraceScene>():
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
ernie::graph::(anonymous namespace)::Blackboard_FindsValuesByType_Test::TestBody()::Hits& ernie::graph::Blackboard::Get<ernie::graph::(anonymous namespace)::Blackboard_FindsValuesByType_Test::TestBody()::Hits>():
✓ Branch 2 taken 1 time.
✗ Branch 3 not taken.
✓ Branch 5 taken 1 time.
✗ Branch 6 not taken.
ernie::graph::(anonymous namespace)::Blackboard_FindsValuesByType_Test::TestBody()::Sky& ernie::graph::Blackboard::Get<ernie::graph::(anonymous namespace)::Blackboard_FindsValuesByType_Test::TestBody()::Sky>():
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
|
3 |
throw std::out_of_range(std::string("The blackboard has no ") + typeid(T).name()); |
| 50 |
|
|
} |
| 51 |
|
1 |
template <typename T> bool Has() const { |
| 52 |
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 1 time.
|
1 |
return values_.contains(typeid(T)); |
| 53 |
|
|
} |
| 54 |
|
1 |
void Clear() { |
| 55 |
|
1 |
values_.clear(); |
| 56 |
|
|
} |
| 57 |
|
|
|
| 58 |
|
|
private: |
| 59 |
|
|
std::unordered_map<std::type_index, std::any> values_; |
| 60 |
|
|
}; |
| 61 |
|
|
|
| 62 |
|
|
} // namespace ernie::graph |
| 63 |
|
|
|