@@ -40,6 +40,8 @@ class Blackboard
40
40
41
41
virtual ~Blackboard () = default ;
42
42
43
+ void enableAutoRemapping (bool remapping);
44
+
43
45
/* *
44
46
* @brief The method getAny allow the user to access directly the type
45
47
* erased value.
@@ -49,33 +51,15 @@ class Blackboard
49
51
const Any* getAny (const std::string& key) const
50
52
{
51
53
std::unique_lock<std::mutex> lock (mutex_);
52
- // search first if this port was remapped
53
- if (auto parent = parent_bb_.lock ())
54
- {
55
- auto remapping_it = internal_to_external_.find (key);
56
- if (remapping_it != internal_to_external_.end ())
57
- {
58
- return parent->getAny (remapping_it->second );
59
- }
60
- }
61
54
auto it = storage_.find (key);
62
- return (it == storage_.end ()) ? nullptr : &(it->second . value );
55
+ return (it != storage_.end ()) ? &(it->second -> value ) : nullptr ;
63
56
}
64
57
65
58
Any* getAny (const std::string& key)
66
59
{
67
- std::unique_lock<std::mutex> lock (mutex_);
68
- // search first if this port was remapped
69
- if (auto parent = parent_bb_.lock ())
70
- {
71
- auto remapping_it = internal_to_external_.find (key);
72
- if (remapping_it != internal_to_external_.end ())
73
- {
74
- return parent->getAny (remapping_it->second );
75
- }
76
- }
77
- auto it = storage_.find (key);
78
- return (it == storage_.end ()) ? nullptr : &(it->second .value );
60
+ // "Avoid Duplication in const and Non-const Member Function,"
61
+ // on p. 23, in Item 3 "Use const whenever possible," in Effective C++, 3d ed
62
+ return const_cast <Any*>(static_cast <const Blackboard&>(*this ).getAny (key));
79
63
}
80
64
81
65
/* * Return true if the entry with the given key was found.
@@ -116,65 +100,54 @@ class Blackboard
116
100
std::unique_lock<std::mutex> lock_entry (entry_mutex_);
117
101
std::unique_lock<std::mutex> lock (mutex_);
118
102
119
- // search first if this port was remapped.
120
- // Change the parent_bb_ in that case
121
- auto remapping_it = internal_to_external_.find (key);
122
- if (remapping_it != internal_to_external_.end ())
123
- {
124
- const auto & remapped_key = remapping_it->second ;
125
- if (auto parent = parent_bb_.lock ())
126
- {
127
- parent->set (remapped_key, value);
128
- return ;
129
- }
130
- }
131
-
132
103
// check local storage
133
104
auto it = storage_.find (key);
105
+ std::shared_ptr<Entry> entry;
134
106
if (it != storage_.end ())
135
107
{
136
- const PortInfo& port_info = it->second .port_info ;
137
- auto & previous_any = it->second .value ;
138
- const auto previous_type = port_info.type ();
108
+ entry = it->second ;
109
+ }
110
+ else
111
+ {
112
+ lock.unlock ();
113
+ entry = createEntryImpl (key, PortInfo ());
114
+ entry->value = Any (value);
115
+ return ;
116
+ }
139
117
140
- Any new_value (value);
118
+ const PortInfo& port_info = entry->port_info ;
119
+ auto & previous_any = entry->value ;
120
+ const auto previous_type = port_info.type ();
141
121
142
- if (previous_type && *previous_type != typeid (T) &&
143
- *previous_type != new_value.type ())
122
+ Any new_value (value);
123
+
124
+ if (previous_type && *previous_type != typeid (T) &&
125
+ *previous_type != new_value.type ())
126
+ {
127
+ bool mismatching = true ;
128
+ if (std::is_constructible<StringView, T>::value)
144
129
{
145
- bool mismatching = true ;
146
- if (std::is_constructible<StringView, T>::value )
130
+ Any any_from_string = port_info. parseString (value) ;
131
+ if (any_from_string. empty () == false )
147
132
{
148
- Any any_from_string = port_info.parseString (value);
149
- if (any_from_string.empty () == false )
150
- {
151
- mismatching = false ;
152
- new_value = std::move (any_from_string);
153
- }
133
+ mismatching = false ;
134
+ new_value = std::move (any_from_string);
154
135
}
136
+ }
155
137
156
- if (mismatching)
157
- {
158
- debugMessage ();
138
+ if (mismatching)
139
+ {
140
+ debugMessage ();
159
141
160
- throw LogicError (" Blackboard::set() failed: once declared, the type of a port "
161
- " shall not change. "
162
- " Declared type [" ,
163
- BT::demangle (previous_type), " ] != current type [" ,
164
- BT::demangle (typeid (T)), " ]" );
165
- }
142
+ throw LogicError (" Blackboard::set() failed: once declared, the type of a port "
143
+ " shall not change. Declared type [" ,
144
+ BT::demangle (previous_type), " ] != current type [" ,
145
+ BT::demangle (typeid (T)), " ]" );
166
146
}
167
- previous_any = std::move (new_value);
168
147
}
169
- else
170
- { // create for the first time without any info
171
- storage_.emplace (key, Entry (Any (value), PortInfo ()));
172
- }
173
- return ;
148
+ previous_any = std::move (new_value);
174
149
}
175
150
176
- void setPortInfo (std::string key, const PortInfo& info);
177
-
178
151
const PortInfo* portInfo (const std::string& key);
179
152
180
153
void addSubtreeRemapping (StringView internal, StringView external);
@@ -197,6 +170,11 @@ class Blackboard
197
170
return entry_mutex_;
198
171
}
199
172
173
+ void createEntry (const std::string& key, const PortInfo& info)
174
+ {
175
+ createEntryImpl (key, info);
176
+ }
177
+
200
178
private:
201
179
struct Entry
202
180
{
@@ -211,11 +189,15 @@ class Blackboard
211
189
{}
212
190
};
213
191
192
+ std::shared_ptr<Entry> createEntryImpl (const std::string& key, const PortInfo& info);
193
+
214
194
mutable std::mutex mutex_;
215
195
mutable std::mutex entry_mutex_;
216
- std::unordered_map<std::string, Entry> storage_;
196
+ std::unordered_map<std::string, std::shared_ptr< Entry> > storage_;
217
197
std::weak_ptr<Blackboard> parent_bb_;
218
198
std::unordered_map<std::string, std::string> internal_to_external_;
199
+
200
+ bool autoremapping_ = false ;
219
201
};
220
202
221
203
} // namespace BT
0 commit comments