|
2 | 2 |
|
3 | 3 | namespace BT |
4 | 4 | { |
5 | | -void Blackboard::setPortInfo(const std::string& key, const PortInfo& info) |
6 | | -{ |
7 | | - std::unique_lock<std::mutex> lock(mutex_); |
8 | 5 |
|
9 | | - if (auto parent = parent_bb_.lock()) |
10 | | - { |
11 | | - auto remapping_it = internal_to_external_.find(key); |
12 | | - if (remapping_it != internal_to_external_.end()) |
13 | | - { |
14 | | - parent->setPortInfo(remapping_it->second, info); |
15 | | - return; |
16 | | - } |
17 | | - } |
| 6 | +void Blackboard::enableAutoRemapping(bool remapping) |
| 7 | +{ |
| 8 | + autoremapping_ = remapping; |
| 9 | +} |
18 | 10 |
|
| 11 | +const Blackboard::Entry *Blackboard::getEntry(const std::string &key) const |
| 12 | +{ |
| 13 | + std::unique_lock<std::mutex> lock(mutex_); |
19 | 14 | auto it = storage_.find(key); |
20 | | - if (it == storage_.end()) |
21 | | - { |
22 | | - storage_.emplace(key, std::make_unique<Entry>(info)); |
23 | | - } |
24 | | - else |
25 | | - { |
26 | | - auto old_type = it->second->port_info.type(); |
27 | | - if (old_type != info.type()) |
28 | | - { |
29 | | - throw LogicError("Blackboard::set() failed: once declared, the type of a port " |
30 | | - "shall not change. Declared type [", |
31 | | - BT::demangle(old_type), "] != current type [", |
32 | | - BT::demangle(info.type()), "]"); |
33 | | - } |
34 | | - } |
| 15 | + return (it == storage_.end()) ? nullptr : it->second.get(); |
35 | 16 | } |
36 | 17 |
|
37 | 18 | const PortInfo* Blackboard::portInfo(const std::string& key) |
38 | 19 | { |
39 | 20 | std::unique_lock<std::mutex> lock(mutex_); |
40 | 21 |
|
41 | | - if (auto parent = parent_bb_.lock()) |
42 | | - { |
43 | | - auto remapping_it = internal_to_external_.find(key); |
44 | | - if (remapping_it != internal_to_external_.end()) |
45 | | - { |
46 | | - return parent->portInfo(remapping_it->second); |
47 | | - } |
48 | | - } |
49 | | - |
50 | 22 | auto it = storage_.find(key); |
51 | | - if (it == storage_.end()) |
52 | | - { |
53 | | - return nullptr; |
54 | | - } |
55 | | - return &(it->second->port_info); |
| 23 | + return (it == storage_.end()) ? nullptr : &(it->second->port_info); |
56 | 24 | } |
57 | 25 |
|
58 | 26 | void Blackboard::addSubtreeRemapping(StringView internal, StringView external) |
@@ -82,27 +50,70 @@ void Blackboard::debugMessage() const |
82 | 50 | } |
83 | 51 | } |
84 | 52 |
|
85 | | -std::vector<StringView> Blackboard::getKeys(bool include_remapped) const |
| 53 | +std::vector<StringView> Blackboard::getKeys() const |
86 | 54 | { |
87 | | - const size_t N = storage_.size() + (include_remapped ? internal_to_external_.size() : 0 ); |
88 | | - if (N == 0) |
| 55 | + if (storage_.empty()) |
89 | 56 | { |
90 | 57 | return {}; |
91 | 58 | } |
92 | 59 | std::vector<StringView> out; |
93 | | - out.reserve(N); |
| 60 | + out.reserve(storage_.size()); |
94 | 61 | for (const auto& entry_it : storage_) |
95 | 62 | { |
96 | 63 | out.push_back(entry_it.first); |
97 | 64 | } |
98 | | - if(include_remapped) |
| 65 | + return out; |
| 66 | +} |
| 67 | + |
| 68 | +std::shared_ptr<Blackboard::Entry> |
| 69 | +Blackboard::createEntryImpl(const std::string& key, const PortInfo& info) |
| 70 | +{ |
| 71 | + std::unique_lock<std::mutex> lock(mutex_); |
| 72 | + // This function might be called recursively, when we do remapping, because we move |
| 73 | + // to the top scope to find already existing entries |
| 74 | + |
| 75 | + // search if exists already |
| 76 | + auto storage_it = storage_.find(key); |
| 77 | + if(storage_it != storage_.end()) |
99 | 78 | { |
100 | | - for (const auto& [key, remapped] : internal_to_external_) |
| 79 | + const auto old_type = storage_it->second->port_info.type(); |
| 80 | + if (old_type != info.type() && |
| 81 | + old_type != typeid(BT::PortInfo::AnyTypeAllowed) && |
| 82 | + info.type() != typeid(BT::PortInfo::AnyTypeAllowed)) |
101 | 83 | { |
102 | | - out.push_back(key); |
| 84 | + throw LogicError("Blackboard: once declared, the type of a port " |
| 85 | + "shall not change. Previously declared type [", |
| 86 | + BT::demangle(old_type), "] != new type [", |
| 87 | + BT::demangle(info.type()), "]"); |
103 | 88 | } |
| 89 | + return storage_it->second; |
104 | 90 | } |
105 | | - return out; |
| 91 | + |
| 92 | + std::shared_ptr<Entry> entry; |
| 93 | + |
| 94 | + // manual remapping first |
| 95 | + auto remapping_it = internal_to_external_.find(key); |
| 96 | + if (remapping_it != internal_to_external_.end()) |
| 97 | + { |
| 98 | + const auto& remapped_key = remapping_it->second; |
| 99 | + if (auto parent = parent_bb_.lock()) |
| 100 | + { |
| 101 | + entry = parent->createEntryImpl(remapped_key, info); |
| 102 | + } |
| 103 | + } |
| 104 | + else if(autoremapping_) |
| 105 | + { |
| 106 | + if (auto parent = parent_bb_.lock()) |
| 107 | + { |
| 108 | + entry = parent->createEntryImpl(key, info); |
| 109 | + } |
| 110 | + } |
| 111 | + else // not remapped, nor found. Create locally. |
| 112 | + { |
| 113 | + entry = std::make_shared<Entry>(info); |
| 114 | + } |
| 115 | + storage_.insert( {key, entry} ); |
| 116 | + return entry; |
106 | 117 | } |
107 | 118 |
|
108 | 119 | } // namespace BT |
0 commit comments