@@ -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,55 @@ 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 ();
139
-
108
+ entry = it->second ;
109
+ }
110
+ else
111
+ {
140
112
Any new_value (value);
113
+ lock.unlock ();
114
+ entry = createEntryImpl (key, PortInfo (PortDirection::INOUT, new_value.type (), {}));
115
+ entry->value = new_value;
116
+ return ;
117
+ }
118
+
119
+ const PortInfo& port_info = entry->port_info ;
120
+ auto & previous_any = entry->value ;
121
+ const auto previous_type = port_info.type ();
122
+
123
+ Any new_value (value);
141
124
142
- if (previous_type && *previous_type != typeid (T) &&
143
- *previous_type != new_value.type ())
125
+ if (previous_type && *previous_type != typeid (T) &&
126
+ *previous_type != new_value.type ())
127
+ {
128
+ bool mismatching = true ;
129
+ if (std::is_constructible<StringView, T>::value)
144
130
{
145
- bool mismatching = true ;
146
- if (std::is_constructible<StringView, T>::value )
131
+ Any any_from_string = port_info. parseString (value) ;
132
+ if (any_from_string. empty () == false )
147
133
{
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
- }
134
+ mismatching = false ;
135
+ new_value = std::move (any_from_string);
154
136
}
137
+ }
155
138
156
- if (mismatching)
157
- {
158
- debugMessage ();
139
+ if (mismatching)
140
+ {
141
+ debugMessage ();
159
142
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
- }
143
+ throw LogicError (" Blackboard::set() failed: once declared, the type of a port "
144
+ " shall not change. Declared type [" ,
145
+ BT::demangle (previous_type), " ] != current type [" ,
146
+ BT::demangle (typeid (T)), " ]" );
166
147
}
167
- previous_any = std::move (new_value);
168
- }
169
- else
170
- { // create for the first time without any info
171
- storage_.emplace (key, Entry (Any (value), PortInfo ()));
172
148
}
173
- return ;
149
+ previous_any = std::move (new_value) ;
174
150
}
175
151
176
- void setPortInfo (std::string key, const PortInfo& info);
177
-
178
152
const PortInfo* portInfo (const std::string& key);
179
153
180
154
void addSubtreeRemapping (StringView internal, StringView external);
@@ -197,6 +171,11 @@ class Blackboard
197
171
return entry_mutex_;
198
172
}
199
173
174
+ void createEntry (const std::string& key, const PortInfo& info)
175
+ {
176
+ createEntryImpl (key, info);
177
+ }
178
+
200
179
private:
201
180
struct Entry
202
181
{
@@ -211,11 +190,15 @@ class Blackboard
211
190
{}
212
191
};
213
192
193
+ std::shared_ptr<Entry> createEntryImpl (const std::string& key, const PortInfo& info);
194
+
214
195
mutable std::mutex mutex_;
215
196
mutable std::mutex entry_mutex_;
216
- std::unordered_map<std::string, Entry> storage_;
197
+ std::unordered_map<std::string, std::shared_ptr< Entry> > storage_;
217
198
std::weak_ptr<Blackboard> parent_bb_;
218
199
std::unordered_map<std::string, std::string> internal_to_external_;
200
+
201
+ bool autoremapping_ = false ;
219
202
};
220
203
221
204
} // namespace BT
0 commit comments