#pragma once
#include <concepts>
#include <memory>
#include <stdexcept>
#include <string>
#include <string_view>
#include <utility>
#include <networktables/NetworkTable.h>
#include <wpi/StringMap.h>
#include "frc/Errors.h"
namespace frc {
class MechanismObject2d {
friend class Mechanism2d;
protected:
explicit MechanismObject2d(std::string_view name);
virtual void UpdateEntries(std::shared_ptr<nt::NetworkTable> table) = 0;
mutable wpi::mutex m_mutex;
public:
virtual ~MechanismObject2d() = default;
const std::string& GetName() const;
template <typename T, typename... Args>
requires std::convertible_to<T*, MechanismObject2d*>
T* Append(std::string_view name, Args&&... args) {
std::scoped_lock lock(m_mutex);
auto& obj = m_objects[name];
if (obj) {
throw FRC_MakeError(
err::Error,
"MechanismObject names must be unique! `{}` was inserted twice!",
name);
}
obj = std::make_unique<T>(name, std::forward<Args>(args)...);
T* ex = static_cast<T*>(obj.get());
if (m_table) {
ex->Update(m_table->GetSubTable(name));
}
return ex;
}
private:
std::string m_name;
wpi::StringMap<std::unique_ptr<MechanismObject2d>> m_objects;
std::shared_ptr<nt::NetworkTable> m_table;
void Update(std::shared_ptr<nt::NetworkTable> table);
};
}