Program Listing for File blackboard_pywrapper.hpp
↰ Return to documentation for file (include/yasmin/blackboard_pywrapper.hpp)
// Copyright (C) 2025 Miguel Ángel González Santamarta
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <https://www.gnu.org/licenses/>.
#ifndef YASMIN__BLACKBOARD_PYWRAPPER_HPP
#define YASMIN__BLACKBOARD_PYWRAPPER_HPP
#include <list>
#include <map>
#include <pybind11/cast.h>
#include <pybind11/pybind11.h>
#include <pybind11/stl.h>
#include <string>
#include <tuple>
#include <type_traits>
#include <typeinfo>
#include <vector>
#include "yasmin/blackboard.hpp"
namespace py = pybind11;
namespace yasmin {
// Forward declaration
class BlackboardPyWrapper;
class BlackboardPyWrapper {
private:
std::shared_ptr<Blackboard> blackboard;
public:
BlackboardPyWrapper() : blackboard(std::make_shared<Blackboard>()) {}
BlackboardPyWrapper(Blackboard &&other)
: blackboard(std::make_shared<Blackboard>(std::move(other))) {}
explicit BlackboardPyWrapper(std::shared_ptr<Blackboard> bb_ptr)
: blackboard(bb_ptr) {}
void set(const std::string &key, py::object value) {
if (py::isinstance<py::bool_>(value)) {
this->blackboard->set<bool>(key, value.cast<bool>());
} else if (py::isinstance<py::int_>(value)) {
try {
this->blackboard->set<int>(key, value.cast<int>());
} catch (...) {
this->blackboard->set<long>(key, value.cast<long>());
}
} else if (py::isinstance<py::float_>(value)) {
this->blackboard->set<double>(key, value.cast<double>());
} else if (py::isinstance<py::str>(value)) {
this->blackboard->set<std::string>(key, value.cast<std::string>());
} else if (py::isinstance<py::list>(value)) {
this->blackboard->set<py::object>(key, value);
} else if (py::isinstance<py::dict>(value)) {
this->blackboard->set<py::object>(key, value);
} else if (py::isinstance<py::tuple>(value)) {
this->blackboard->set<py::object>(key, value);
} else if (py::isinstance<py::set>(value)) {
this->blackboard->set<py::object>(key, value);
} else {
this->blackboard->set<py::object>(key, value);
}
}
py::object get(const std::string &key) {
// Get the type of the stored value
std::string type = this->blackboard->get_type(key);
// Check if it's a pybind11::object (Python object - includes all Python
// types)
if (type.find("pybind11::object") != std::string::npos ||
type.find("pybind11::int_") != std::string::npos ||
type.find("pybind11::float_") != std::string::npos ||
type.find("pybind11::str") != std::string::npos ||
type.find("pybind11::bool_") != std::string::npos ||
type.find("pybind11::list") != std::string::npos ||
type.find("pybind11::dict") != std::string::npos ||
type.find("pybind11::set") != std::string::npos ||
type.find("pybind11::tuple") != std::string::npos ||
type.find("pybind11::bytes") != std::string::npos ||
type.find("pybind11::none") != std::string::npos) {
return this->blackboard->get<py::object>(key);
}
// Check if it's a std::string (C++ string) - convert to Python str
else if (type.find("std::string") != std::string::npos ||
type.find("std::__cxx11::basic_string") != std::string::npos) {
std::string cpp_value = this->blackboard->get<std::string>(key);
return py::cast(cpp_value);
}
// Check if it's a std::vector (C++ vector) - convert to Python list
else if (type.find("std::vector") != std::string::npos) {
return this->blackboard->get<py::object>(key);
}
// Check if it's a std::map (C++ map) - convert to Python dict
else if (type.find("std::map") != std::string::npos ||
type.find("std::unordered_map") != std::string::npos) {
return this->blackboard->get<py::object>(key);
}
// Check if it's a std::set (C++ set) - convert to Python set
else if (type.find("std::set") != std::string::npos ||
type.find("std::unordered_set") != std::string::npos) {
return this->blackboard->get<py::object>(key);
}
// Check if it's a std::list (C++ list) - convert to Python list
else if (type.find("std::list") != std::string::npos) {
return this->blackboard->get<py::object>(key);
}
// Check if it's a std::tuple (C++ tuple) - convert to Python tuple
else if (type.find("std::tuple") != std::string::npos) {
return this->blackboard->get<py::object>(key);
}
// Check if it's an int (C++ int) - convert to Python int
else if (type.find("int") != std::string::npos) {
int cpp_value = this->blackboard->get<int>(key);
return py::cast(cpp_value);
}
// Check if it's a long (C++ long) - convert to Python int
else if (type.find("long") != std::string::npos) {
long cpp_value = this->blackboard->get<long>(key);
return py::cast(cpp_value);
}
// Check if it's a float or double (C++ float/double) - convert to Python
// float
else if (type.find("float") != std::string::npos ||
type.find("double") != std::string::npos) {
double cpp_value = this->blackboard->get<double>(key);
return py::cast(cpp_value);
}
// Check if it's a bool (C++ bool) - convert to Python bool
else if (type.find("bool") != std::string::npos) {
bool cpp_value = this->blackboard->get<bool>(key);
return py::cast(cpp_value);
}
// Default: try to get as py::object
else {
return this->blackboard->get<py::object>(key);
}
}
void remove(const std::string &key) { this->blackboard->remove(key); }
bool contains(const std::string &key) {
return this->blackboard->contains(key);
}
int size() { return this->blackboard->size(); }
std::string to_string() { return this->blackboard->to_string(); }
void set_remappings(const std::map<std::string, std::string> &remappings) {
this->blackboard->set_remappings(remappings);
}
std::map<std::string, std::string> get_remappings() {
return this->blackboard->get_remappings();
}
std::shared_ptr<Blackboard> get_cpp_blackboard() { return this->blackboard; }
};
} // namespace yasmin
#endif // YASMIN__BLACKBOARD_PYWRAPPER_HPP