#pragma once #include #include class IBlackboardField { public: virtual ~IBlackboardField() = default; }; //BlackboardField does not take ownership of pointers whatsoever! template class BlackboardField final : public IBlackboardField { public: explicit BlackboardField(T data) : m_Data(data) { } T GetData() { return m_Data; }; void SetData(T data) { m_Data = data; } private: T m_Data; }; class Blackboard final { public: Blackboard() = default; ~Blackboard() { for (const auto& el : m_BlackboardData) delete el.second; m_BlackboardData.clear(); } Blackboard(const Blackboard& other) = delete; Blackboard& operator=(const Blackboard& other) = delete; Blackboard(Blackboard&& other) = delete; Blackboard& operator=(Blackboard&& other) = delete; //Add data to the blackboard template bool AddData(const std::string& name, T data) { auto it = m_BlackboardData.find(name); if (it == m_BlackboardData.end()) { m_BlackboardData[name] = new BlackboardField(data); return true; } printf("WARNING: Data '%s' of type '%s' already in Blackboard \n", name.c_str(), typeid(T).name()); return false; } //Change the data of the blackboard template bool ChangeData(const std::string& name, T data) { auto it = m_BlackboardData.find(name); if (it != m_BlackboardData.end()) { BlackboardField* p = dynamic_cast*>(m_BlackboardData[name]); if (p) { p->SetData(data); return true; } } printf("WARNING: Data '%s' of type '%s' not found in Blackboard \n", name.c_str(), typeid(T).name()); return false; } //Get the data from the blackboard template bool GetData(const std::string& name, T& data) { BlackboardField* p = dynamic_cast*>(m_BlackboardData[name]); if (p != nullptr) { data = p->GetData(); return true; } printf("WARNING: Data '%s' of type '%s' not found in Blackboard \n", name.c_str(), typeid(T).name()); return false; } private: std::unordered_map m_BlackboardData; };