C++ YASMIN (Yet Another State MachINe)
Loading...
Searching...
No Matches
blackboard.hpp
Go to the documentation of this file.
1// Copyright (C) 2023 Miguel Ángel González Santamarta
2//
3// This program is free software: you can redistribute it and/or modify
4// it under the terms of the GNU General Public License as published by
5// the Free Software Foundation, either version 3 of the License, or
6// (at your option) any later version.
7//
8// This program is distributed in the hope that it will be useful,
9// but WITHOUT ANY WARRANTY; without even the implied warranty of
10// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11// GNU General Public License for more details.
12//
13// You should have received a copy of the GNU General Public License
14// along with this program. If not, see <https://www.gnu.org/licenses/>.
15
16#ifndef YASMIN__BLACKBOARD_HPP_
17#define YASMIN__BLACKBOARD_HPP_
18
19#include <cxxabi.h>
20
21#include <exception>
22#include <map>
23#include <memory>
24#include <mutex>
25#include <stdexcept>
26#include <string>
27#include <unordered_map>
28#include <utility>
29#include <vector>
30
31#include "yasmin/logs.hpp"
32#include "yasmin/types.hpp"
33
34namespace yasmin {
35
41inline std::string demangle_type(const std::string &mangled_name) {
42
43 std::string name = mangled_name;
44
45#ifdef __GNUG__ // If using GCC/G++
46 int status;
47 // Demangle the name using GCC's demangling function
48 char *demangled =
49 abi::__cxa_demangle(name.c_str(), nullptr, nullptr, &status);
50 if (status == 0) {
51 name = demangled;
52 }
53 free(demangled);
54#endif
55
56 return name; // Return the demangled type name
57}
58
68private:
78 mutable std::recursive_mutex mutex;
80 std::unordered_map<std::string, std::shared_ptr<void>> values;
83 };
84
86 std::shared_ptr<SharedStorage> storage;
89
94 const std::string &remap(const std::string &key) const;
95
96public:
101
102
105 Blackboard();
106
114 Blackboard(const Blackboard &other);
115
122 template <class T> void set(const std::string &name, T value) {
123
124 YASMIN_LOG_DEBUG("Setting '%s' in the blackboard", name.c_str());
125
126 std::lock_guard<std::recursive_mutex> lk(this->storage->mutex);
127
128 // Apply remapping if exists
129 const std::string &key = this->remap(name);
130 const std::string type_name = demangle_type(typeid(T).name());
131
132 auto type_it = this->storage->type_registry.find(key);
133 if (type_it != this->storage->type_registry.end() &&
134 type_it->second == type_name) {
135 // Same type: update existing value in-place (avoids allocation)
136 *(std::static_pointer_cast<T>(this->storage->values.at(key))) = value;
137 } else {
138 // New key or different type: (re)create entry
139 this->storage->values[key] = std::make_shared<T>(value);
140 this->storage->type_registry[key] = type_name;
141 }
142 }
143
151 template <class T> T get(const std::string &key) const {
152
153 YASMIN_LOG_DEBUG("Getting '%s' from the blackboard", key.c_str());
154
155 std::lock_guard<std::recursive_mutex> lk(this->storage->mutex);
156
157 // Check if the key exists
158 if (!this->contains(key)) {
159 throw std::runtime_error("Element '" + key +
160 "' does not exist in the blackboard");
161 }
162
163 // Return the value casted to the requested type
164 return *(std::static_pointer_cast<T>(
165 this->storage->values.at(this->remap(key))));
166 }
167
172 void remove(const std::string &key);
173
179 bool contains(const std::string &key) const;
180
190 void copy_value_from(const Blackboard &other, const std::string &source_key,
191 const std::string &target_key);
192
197 int size() const;
198
207 std::vector<std::string> keys() const;
208
215 std::string get_type(const std::string &key) const;
216
221 std::string to_string() const;
222
228
233 const Remappings &get_remappings() const noexcept;
234};
235
236} // namespace yasmin
237
238#endif // YASMIN__BLACKBOARD_HPP_
A thread-safe storage for key-value pairs of varying types.
Definition blackboard.hpp:67
Remappings remappings
Storage for key remappings local to this blackboard handle.
Definition blackboard.hpp:88
std::string to_string() const
Convert the contents of the blackboard to a string.
Definition blackboard.cpp:154
void set(const std::string &name, T value)
Set a value in the blackboard.
Definition blackboard.hpp:122
void copy_value_from(const Blackboard &other, const std::string &source_key, const std::string &target_key)
Copy a value from another blackboard.
Definition blackboard.cpp:53
Blackboard()
Default constructor for Blackboard.
Definition blackboard.cpp:30
std::vector< std::string > keys() const
Get the keys visible in the current remapping scope.
Definition blackboard.cpp:99
const Remappings & get_remappings() const noexcept
Get the remappings of the blackboard.
Definition blackboard.cpp:182
bool contains(const std::string &key) const
Check if a key exists in the blackboard.
Definition blackboard.cpp:44
std::string get_type(const std::string &key) const
Get the type of a value stored in the blackboard.
Definition blackboard.cpp:139
void set_remappings(const Remappings &remappings)
Set the remappings of the blackboard.
Definition blackboard.cpp:178
const std::string & remap(const std::string &key) const
Internal method that acquires the maped key. In the case the key is not remaped, retruns the arg key.
Definition blackboard.cpp:168
void remove(const std::string &key)
Remove a value from the blackboard.
Definition blackboard.cpp:35
std::shared_ptr< SharedStorage > storage
Shared storage for key-value pairs and type information.
Definition blackboard.hpp:86
int size() const
Get the number of key-value pairs in the blackboard.
Definition blackboard.cpp:94
T get(const std::string &key) const
Retrieve a value from the blackboard.
Definition blackboard.hpp:151
#define YASMIN_LOG_DEBUG(text,...)
Definition logs.hpp:174
Definition blackboard.hpp:34
std::string demangle_type(const std::string &mangled_name)
Demangle a C++ type name to a human-readable format.
Definition blackboard.hpp:41
StringMap Remappings
Map of remappings (string to string).
Definition types.hpp:88
StringMap TypeRegistry
Registry for type information.
Definition types.hpp:96
Shared storage used by blackboard copies.
Definition blackboard.hpp:76
std::recursive_mutex mutex
Mutex for thread safety of the shared storage.
Definition blackboard.hpp:78
TypeRegistry type_registry
Storage for type information for each key.
Definition blackboard.hpp:82
std::unordered_map< std::string, std::shared_ptr< void > > values
Storage for key-value pairs.
Definition blackboard.hpp:80
#define YASMIN_PTR_ALIASES(ClassName)
Macro to define all pointer aliases for a class.
Definition types.hpp:52