Olympe Engine 2.0
2D Game Engine with ECS Architecture
Loading...
Searching...
No Matches
AtomicTaskRegistry.h
Go to the documentation of this file.
1/**
2 * @file AtomicTaskRegistry.h
3 * @brief Singleton registry for atomic task factories.
4 * @author Olympe Engine
5 * @date 2026-02-22
6 *
7 * @details
8 * AtomicTaskRegistry stores factory functions keyed by a string task ID.
9 * Call Register() to associate a factory with an ID, and Create() to
10 * instantiate a task by ID.
11 *
12 * The REGISTER_ATOMIC_TASK(ClassName, Id) macro registers a factory at
13 * static initialization time so that every translation unit that includes
14 * the concrete task's .cpp file automatically populates the registry.
15 *
16 * C++14 compliant - no C++17/20 features.
17 */
18
19#pragma once
20
21#include <string>
22#include <unordered_map>
23#include <functional>
24#include <memory>
25
26#include "IAtomicTask.h"
27
28namespace Olympe {
29
30/**
31 * @class AtomicTaskRegistry
32 * @brief Singleton registry mapping task IDs to factory functions.
33 *
34 * @details
35 * Usage:
36 * @code
37 * // Register (done automatically via REGISTER_ATOMIC_TASK macro):
38 * AtomicTaskRegistry::Get().Register("Task_LogMessage",
39 * []() { return std::unique_ptr<IAtomicTask>(new Task_LogMessage()); });
40 *
41 * // Create:
42 * auto task = AtomicTaskRegistry::Get().Create("Task_LogMessage");
43 * if (task) { task->Execute(params); }
44 * @endcode
45 */
47public:
48
49 /// Factory function type: returns a heap-allocated IAtomicTask.
50 using FactoryFn = std::function<std::unique_ptr<IAtomicTask>()>;
51
52 /**
53 * @brief Returns the singleton instance.
54 */
55 static AtomicTaskRegistry& Get();
56
57 /**
58 * @brief Registers a factory function under the given task ID.
59 *
60 * If a factory is already registered for @p id, it is replaced.
61 *
62 * @param id Unique string identifier for the task type.
63 * @param factory Callable that produces a new IAtomicTask instance.
64 */
65 void Register(const std::string& id, FactoryFn factory);
66
67 /**
68 * @brief Creates a new instance of the task identified by @p id.
69 *
70 * @param id Task type identifier (as registered via Register()).
71 * @return A unique_ptr to the new task, or nullptr if @p id is unknown.
72 */
73 std::unique_ptr<IAtomicTask> Create(const std::string& id) const;
74
75 /**
76 * @brief Returns true if a factory is registered for @p id.
77 * @param id Task type identifier.
78 */
79 bool IsRegistered(const std::string& id) const;
80
81 /**
82 * @brief Returns a vector of all registered task IDs.
83 *
84 * The order of IDs in the returned vector is unspecified.
85 * Useful for editor enumeration (e.g. context menus, palette panels).
86 *
87 * @return Vector of every ID that has been passed to Register().
88 */
89 std::vector<std::string> GetAllTaskIDs() const;
90
91private:
92
93 AtomicTaskRegistry() = default;
94
95 std::unordered_map<std::string, FactoryFn> m_factories;
96};
97
98} // namespace Olympe
99
100// ---------------------------------------------------------------------------
101// REGISTER_ATOMIC_TASK macro
102// ---------------------------------------------------------------------------
103
104/**
105 * @def REGISTER_ATOMIC_TASK(ClassName, Id)
106 * @brief Registers a factory for ClassName under Id at static init time.
107 *
108 * Place this macro in the .cpp file of your concrete task class (outside any
109 * namespace or function):
110 *
111 * @code
112 * REGISTER_ATOMIC_TASK(Task_LogMessage, "Task_LogMessage")
113 * @endcode
114 *
115 * The macro creates a file-scope object whose constructor calls
116 * AtomicTaskRegistry::Get().Register(), ensuring registration happens
117 * before main() is entered.
118 */
119#define REGISTER_ATOMIC_TASK(ClassName, Id) \
120 namespace { \
121 struct ClassName##_Registrar { \
122 ClassName##_Registrar() { \
123 ::Olympe::AtomicTaskRegistry::Get().Register( \
124 Id, \
125 []() -> std::unique_ptr<::Olympe::IAtomicTask> { \
126 return std::unique_ptr<::Olympe::IAtomicTask>( \
127 new ClassName()); \
128 }); \
129 } \
130 }; \
131 static ClassName##_Registrar s_##ClassName##_registrar; \
132 }
ComponentTypeID GetComponentTypeID_Static()
Definition ECS_Entity.h:56
Interface for atomic tasks in the Atomic Task System.
Singleton registry mapping task IDs to factory functions.
std::vector< std::string > GetAllTaskIDs() const
Returns a vector of all registered task IDs.
bool IsRegistered(const std::string &id) const
Returns true if a factory is registered for id.
std::unique_ptr< IAtomicTask > Create(const std::string &id) const
Creates a new instance of the task identified by id.
static AtomicTaskRegistry & Get()
Returns the singleton instance.
std::unordered_map< std::string, FactoryFn > m_factories
void Register(const std::string &id, FactoryFn factory)
Registers a factory function under the given task ID.
std::function< std::unique_ptr< IAtomicTask >()> FactoryFn
Factory function type: returns a heap-allocated IAtomicTask.
< Provides AssetID and INVALID_ASSET_ID