Go to the documentation of this file.
5 #include <unordered_map>
35 using Ptr = std::shared_ptr<Blackboard>;
52 std::chrono::nanoseconds
stamp = std::chrono::nanoseconds{ 0 };
72 [[nodiscard]]
const std::shared_ptr<Entry>
getEntry(
const std::string& key)
const;
74 [[nodiscard]] std::shared_ptr<Blackboard::Entry>
getEntry(
const std::string& key);
80 [[deprecated(
"Use getAnyLocked instead")]]
const Any*
81 getAny(
const std::string& key)
const;
83 [[deprecated(
"Use getAnyLocked instead")]] Any*
getAny(
const std::string& key);
89 [[nodiscard]]
bool get(
const std::string& key, T& value)
const;
92 [[nodiscard]] Expected<Timestamp>
getStamped(
const std::string& key, T& value)
const;
98 [[nodiscard]] T
get(
const std::string& key)
const;
100 template <
typename T>
101 [[nodiscard]] Expected<StampedValue<T>>
getStamped(
const std::string& key)
const;
104 template <
typename T>
105 void set(
const std::string& key,
const T& value);
107 void unset(
const std::string& key);
109 [[nodiscard]]
const TypeInfo*
entryInfo(
const std::string& key);
115 [[nodiscard]] std::vector<StringView>
getKeys()
const;
117 [[deprecated(
"This command is unsafe. Consider using Backup/Restore instead")]]
void
120 [[deprecated(
"Use getAnyLocked to access safely an Entry")]] std::recursive_mutex&
123 void createEntry(
const std::string& key,
const TypeInfo& info);
146 std::unordered_map<std::string, std::shared_ptr<Entry>>
storage_;
171 template <
typename T>
179 throw RuntimeError(
"Blackboard::get() error. Entry [", key,
180 "] hasn't been initialized, yet");
184 throw RuntimeError(
"Blackboard::get() error. Missing key [", key,
"]");
189 std::unique_lock lock(
mutex_);
202 template <
typename T>
210 std::unique_lock lock(
mutex_);
217 Any new_value(value);
219 std::shared_ptr<Blackboard::Entry> entry;
221 if constexpr(std::is_same_v<std::string, T>)
228 GetAnyFromStringFunctor<T>());
233 entry->value = new_value;
234 entry->sequence_id++;
235 entry->stamp = std::chrono::steady_clock::now().time_since_epoch();
241 Entry& entry = *it->second;
245 Any new_value(value);
251 entry.
info = TypeInfo::Create<T>();
253 entry.
stamp = std::chrono::steady_clock::now().time_since_epoch();
254 previous_any = std::move(new_value);
258 std::type_index previous_type = entry.
info.
type();
261 if(previous_type != std::type_index(
typeid(T)) && previous_type != new_value.
type())
263 bool mismatching =
true;
267 if(any_from_string.
empty() ==
false)
270 new_value = std::move(any_from_string);
276 if constexpr(std::is_arithmetic_v<T>)
288 auto msg =
StrCat(
"Blackboard::set(", key,
290 "the type of a port shall not change. "
291 "Previously declared type [",
298 if constexpr(std::is_same_v<Any, T>)
300 previous_any = new_value;
308 entry.
stamp = std::chrono::steady_clock::now().time_since_epoch();
312 template <
typename T>
327 template <
typename T>
332 std::unique_lock lk(entry->entry_mutex);
333 if(entry->value.empty())
335 return nonstd::make_unexpected(
StrCat(
"Blackboard::getStamped() error. Entry [",
336 key,
"] hasn't been initialized, yet"));
338 value = entry->value.cast<T>();
339 return Timestamp{ entry->sequence_id, entry->stamp };
341 return nonstd::make_unexpected(
342 StrCat(
"Blackboard::getStamped() error. Missing key [", key,
"]"));
345 template <
typename T>
349 if(
auto res = getStamped<T>(key, out.
value))
356 return nonstd::make_unexpected(res.error());
void set(const std::string &key, const T &value)
Update the entry with the given key.
std::weak_ptr< Blackboard > parent_bb_
std::string demangle(char const *name)
std::recursive_mutex entry_mutex_
std::shared_ptr< Entry > createEntryImpl(const std::string &key, const TypeInfo &info)
void unset(const std::string &key)
bool get(const std::string &key, T &value) const
nonstd::expected< T, std::string > Expected
std::string_view StringView
void ImportBlackboardFromJSON(const nlohmann::json &json, Blackboard &blackboard)
ImportBlackboardFromJSON will append elements to the blackboard, using the values parsed from the JSO...
void createEntry(const std::string &key, const TypeInfo &info)
Entry & operator=(const Entry &other)
std::unordered_map< std::string, std::shared_ptr< Entry > > storage_
const std::shared_ptr< Entry > getEntry(const std::string &key) const
bool isCastingSafe(const std::type_index &type, const T &val)
namespace for Niels Lohmann
const std::type_index & type() const noexcept
std::vector< StringView > getKeys() const
constexpr E value(std::size_t i) noexcept
const Any * getAny(const std::string &key) const
Blackboard(Blackboard::Ptr parent)
nlohmann::json ExportBlackboardToJSON(const Blackboard &blackboard)
ExportBlackboardToJSON will create a JSON that contains the current values of the blackboard....
void debugMessage() const
static pthread_mutex_t mutex
std::shared_ptr< Blackboard > Ptr
const TypeInfo * entryInfo(const std::string &key)
void enableAutoRemapping(bool remapping)
std::function< Any(StringView)> StringConverter
virtual ~Blackboard()=default
LockedPtr< Any > AnyPtrLocked
std::recursive_mutex & entryMutex() const
bool empty() const noexcept
void cloneInto(Blackboard &dst) const
cloneInto copies the values of the entries into another blackboard. Known limitations:
Blackboard * rootBlackboard()
void addSubtreeRemapping(StringView internal, StringView external)
The Blackboard is the mechanism used by BehaviorTrees to exchange typed data.
const std::type_index & type() const
The LockedPtr class is used to share a pointer to an object and a mutex that protects the read/write ...
static Blackboard::Ptr create(Blackboard::Ptr parent={})
bool StartWith(StringView str, StringView prefix)
basic_json<> json
default specialization
StringConverter string_converter
std::unordered_map< std::string, std::string > internal_to_external_
std::chrono::nanoseconds stamp
Any parseString(const char *str) const
Expected< Timestamp > getStamped(const std::string &key, T &value) const
constexpr auto any
Matches anything and consumes all remaining characters.
constexpr T & get() noexcept
bool isStronglyTyped() const
Entry(const TypeInfo &_info)
AnyPtrLocked getAnyLocked(const std::string &key)