cmvr-es/cmvr-es/task/task_factory.h

103 lines
3.2 KiB
C++

#ifndef CMVR_ES_TASK_FACTORY_H
#define CMVR_ES_TASK_FACTORY_H
#include <memory>
#include <functional>
#include <mutex>
#include <string>
#include <unordered_map>
#include <utility>
#include "cmvr/config/task_manager_config/task_manager_config.pb.h"
#include "cmvr/config/touch_screen_task_config/touch_screen_task_config.pb.h"
#include "common/base/logging/logger.h"
#include "common/config/config_files.h"
#include "task/task.h"
#include "task/touch_screen_task/include/touch_screen_task.h"
namespace cmvr::task {
namespace task_factory_detail {
inline std::shared_ptr<Task> createTouchScreenTask(const config::TaskConfigEntry& entry)
{
if (entry.id().empty()) {
CMVR_LOG(ERROR) << "[TaskFactory] Empty TouchScreen task ID";
return nullptr;
}
if (entry.config_file().empty()) {
CMVR_LOG(ERROR) << "[TaskFactory] Empty TouchScreen config_file for task ID: " << entry.id();
return nullptr;
}
config::TouchScreenTaskRootConfig root_cfg;
if (!ConfigHelper::loadConfigFile(entry.config_file(), root_cfg)) {
CMVR_LOG(ERROR) << "[TaskFactory] Failed to load TouchScreen config: " << entry.config_file();
return nullptr;
}
CMVR_LOG(INFO) << "[TaskFactory] Load TouchScreenTask config_file=" << entry.config_file()
<< ", manager_id=" << entry.id();
const auto& cfg = root_cfg.touch_screen_task();
if (!cfg.has_id() || cfg.id().empty()) {
CMVR_LOG(ERROR) << "[TaskFactory] TouchScreen config missing id: " << entry.config_file();
return nullptr;
}
if (cfg.id() != entry.id()) {
CMVR_LOG(ERROR) << "[TaskFactory] TouchScreen task ID mismatch: manager id=" << entry.id()
<< ", config id=" << cfg.id();
return nullptr;
}
return std::make_shared<TouchScreenTask>(cfg);
}
} // namespace task_factory_detail
class TaskFactory {
public:
using Creator = std::function<std::shared_ptr<Task>(const config::TaskConfigEntry& entry)>;
static inline void registerCreator(const config::TaskConfigEntry::TaskType type,
Creator creator)
{
std::lock_guard lock(registryMutex());
registry()[type] = std::move(creator);
}
static inline std::shared_ptr<Task> create(const config::TaskConfigEntry& entry)
{
switch (entry.type()) {
case config::TaskConfigEntry::TASK_TYPE_TOUCH_SCREEN:
return task_factory_detail::createTouchScreenTask(entry);
default:
break;
}
std::lock_guard lock(registryMutex());
const auto it = registry().find(entry.type());
if (it != registry().end()) {
return it->second(entry);
}
CMVR_LOG(ERROR) << "[TaskFactory] Unsupported task type for config_file: " << entry.config_file();
return nullptr;
}
private:
static inline std::unordered_map<int, Creator>& registry()
{
static std::unordered_map<int, Creator> creators;
return creators;
}
static inline std::mutex& registryMutex()
{
static std::mutex mutex;
return mutex;
}
};
} // namespace cmvr::task
#endif // CMVR_ES_TASK_FACTORY_H