#pragma once
#include <kooling/json/json.h>
#include <exception>
#include <plog/Log.h>
#include <functional>
#include <string>
namespace kooling::component {
template<typename I>
class factory
{
public:
using pointer_type = std::unique_ptr<I>;
using creator_type = std::function<pointer_type(const json_t&)>;
using map_type = std::unordered_map<std::string, creator_type>;
static factory& instance()
{
static factory f;
return f;
}
template<typename C>
bool register_component()
{
std::string name{ C::name() };
creator_type creator{ C::create };
const auto ret{ d_map.try_emplace(std::move(name), std::move(creator)) };<--- Calling std::move(name)
if (!ret.second)
{
PLOG_ERROR << "Sensor component already registered: \"" << name << "\"";<--- Access of moved variable 'name'.
}
return ret.second;
}
template<typename... Args>
pointer_type create(const json_t& config, Args&&... args)
{
const std::string type{ config["type"] };
if (const auto it{ d_map.find(type) }; it != d_map.end())
{
try
{
return it->second(config, std::forward<Args>(args)...);
}
catch (std::exception& e)
{
PLOG_ERROR
<< "Could not build component \"" << type << "\": "
<< e.what();
return {};
}
}
else
{
PLOG_ERROR << "Component \"" << type << "\" not found";
return {};
}
}
private:
factory()
{}
map_type d_map;
};
} // namespace kooling::component