Olympe Engine 2.0
2D Game Engine with ECS Architecture
Loading...
Searching...
No Matches
AtomicTaskUIRegistry.cpp
Go to the documentation of this file.
1/**
2 * @file AtomicTaskUIRegistry.cpp
3 * @brief Implementation of AtomicTaskUIRegistry with built-in task specs.
4 * @author Olympe Engine
5 * @date 2026-03-14
6 *
7 * C++14 compliant — no std::optional, structured bindings, std::filesystem.
8 */
9
11
12#include <algorithm>
13
14namespace Olympe {
15
16// ---------------------------------------------------------------------------
17// Singleton
18// ---------------------------------------------------------------------------
19
25
30
31// ---------------------------------------------------------------------------
32// Registration
33// ---------------------------------------------------------------------------
34
36{
37 if (!spec.id.empty())
38 m_specs[spec.id] = spec;
39}
40
41// ---------------------------------------------------------------------------
42// Queries
43// ---------------------------------------------------------------------------
44
45const TaskSpec* AtomicTaskUIRegistry::GetTaskSpec(const std::string& id) const
46{
47 auto it = m_specs.find(id);
48 return (it != m_specs.end()) ? &it->second : nullptr;
49}
50
51std::vector<std::string> AtomicTaskUIRegistry::GetAllTaskIds() const
52{
53 std::vector<std::string> ids;
54 ids.reserve(m_specs.size());
55 for (const auto& kv : m_specs)
56 ids.push_back(kv.first);
57 return ids;
58}
59
60std::vector<TaskSpec> AtomicTaskUIRegistry::GetTasksByCategory(const std::string& category) const
61{
62 std::vector<TaskSpec> result;
63 for (const auto& kv : m_specs)
64 {
65 if (kv.second.category == category)
66 result.push_back(kv.second);
67 }
68 std::sort(result.begin(), result.end(),
69 [](const TaskSpec& a, const TaskSpec& b) {
70 return a.displayName < b.displayName;
71 });
72 return result;
73}
74
75std::vector<std::string> AtomicTaskUIRegistry::GetAllCategories() const
76{
77 std::vector<std::string> cats;
78 for (const auto& kv : m_specs)
79 {
80 const std::string& cat = kv.second.category;
81 bool found = false;
82 for (size_t i = 0; i < cats.size(); ++i)
83 {
84 if (cats[i] == cat) { found = true; break; }
85 }
86 if (!found)
87 cats.push_back(cat);
88 }
89 std::sort(cats.begin(), cats.end());
90 return cats;
91}
92
93std::vector<TaskSpec> AtomicTaskUIRegistry::GetSortedForUI() const
94{
95 // Sort by category then by displayName
96 std::vector<TaskSpec> result;
97 result.reserve(m_specs.size());
98 for (const auto& kv : m_specs)
99 result.push_back(kv.second);
100
101 std::sort(result.begin(), result.end(),
102 [](const TaskSpec& a, const TaskSpec& b) {
103 if (a.category != b.category)
104 return a.category < b.category;
105 return a.displayName < b.displayName;
106 });
107 return result;
108}
109
110// ---------------------------------------------------------------------------
111// Built-in task specs
112// ---------------------------------------------------------------------------
113
115{
116 // ---- Movement ----
117 {
118 TaskSpec spec{"move_to_goal", "Move To Goal", "Movement",
119 "Move the agent toward its current goal position."};
120 spec.parameters = {
121 {"targetKey", "String", "TargetPosition", "Variable key for the target position"},
122 {"speed", "Float", "3.5", "Movement speed"}
123 };
124 Register(spec);
125 }
126
127 {
128 TaskSpec spec{"rotate_to_face", "Rotate To Face", "Movement",
129 "Rotate the agent to face a target entity or position."};
130 spec.parameters = {
131 {"targetKey", "String", "TargetActor", "Variable key for the target"},
132 {"rotationSpeed", "Float", "180.0", "Rotation speed in degrees per second"}
133 };
134 Register(spec);
135 }
136
137 {
138 TaskSpec spec{"patrol_path", "Patrol Path", "Movement",
139 "Walk along a predefined patrol waypoint path."};
140 spec.parameters = {
141 {"pathName", "String", "", "Name of the patrol path to follow"},
142 {"speed", "Float", "2.0", "Patrol movement speed"}
143 };
144 Register(spec);
145 }
146
147 // ---- Combat ----
148 {
149 TaskSpec spec{"attack_if_close", "Attack If Close", "Combat",
150 "Perform a melee or ranged attack if the target is within range."};
151 spec.parameters = {
152 {"targetKey", "String", "TargetActor", "Variable key for the target"},
153 {"range", "Float", "5.0", "Attack range"},
154 {"damage", "Float", "10.0", "Damage value"}
155 };
156 Register(spec);
157 }
158
159 {
160 TaskSpec spec{"perform_dodge", "Perform Dodge", "Combat",
161 "Execute an evasive dodge maneuver."};
162 spec.parameters = {
163 {"dodgeDistance", "Float", "2.0", "Distance to dodge"},
164 {"dodgeSpeed", "Float", "8.0", "Speed of dodge movement"}
165 };
166 Register(spec);
167 }
168
169 {
170 TaskSpec spec{"take_cover", "Take Cover", "Combat",
171 "Move the agent to the nearest available cover position."};
172 spec.parameters = {
173 {"searchRadius", "Float", "20.0", "Search radius for cover positions"},
174 {"moveSpeed", "Float", "5.0", "Speed to move to cover"}
175 };
176 Register(spec);
177 }
178
179 // ---- Animation ----
180 {
181 TaskSpec spec{"play_animation", "Play Animation", "Animation",
182 "Start playing a named animation clip."};
183 spec.parameters = {
184 {"animationName", "String", "", "Name of the animation to play"},
185 {"speed", "Float", "1.0", "Animation playback speed"},
186 {"loop", "Bool", "false", "Whether to loop the animation"}
187 };
188 Register(spec);
189 }
190
191 {
192 TaskSpec spec{"stop_animation", "Stop Animation", "Animation",
193 "Stop the currently playing animation."};
194 spec.parameters = {
195 {"fadeOutTime", "Float", "0.5", "Time to fade out the animation"}
196 };
197 Register(spec);
198 }
199
200 {
201 TaskSpec spec{"blend_animation", "Blend Animation", "Animation",
202 "Blend between two animation clips by a weight parameter."};
203 spec.parameters = {
204 {"animationNameA", "String", "", "First animation name"},
205 {"animationNameB", "String", "", "Second animation name"},
206 {"blendWeight", "Float", "0.5", "Blend weight (0.0 = A, 1.0 = B)"}
207 };
208 Register(spec);
209 }
210
211 // ---- Audio ----
212 {
213 TaskSpec spec{"play_sound", "Play Sound", "Audio",
214 "Play a sound effect or music track by name."};
215 spec.parameters = {
216 {"soundName", "String", "", "Name of the sound to play"},
217 {"volume", "Float", "1.0", "Volume (0.0 to 1.0)"},
218 {"loop", "Bool", "false", "Whether to loop the sound"}
219 };
220 Register(spec);
221 }
222
223 {
224 TaskSpec spec{"stop_sound", "Stop Sound", "Audio",
225 "Stop a currently playing sound."};
226 spec.parameters = {
227 {"soundName", "String", "", "Name of the sound to stop"},
228 {"fadeOutTime", "Float", "0.5", "Time to fade out"}
229 };
230 Register(spec);
231 }
232
233 {
234 TaskSpec spec{"set_volume", "Set Volume", "Audio",
235 "Set the volume for a sound channel."};
236 spec.parameters = {
237 {"channelName", "String", "", "Name of the audio channel"},
238 {"volume", "Float", "1.0", "Volume level (0.0 to 1.0)"}
239 };
240 Register(spec);
241 }
242
243 // ---- Misc ----
244 {
245 TaskSpec spec{"log_message", "Log Message", "Misc",
246 "Write a diagnostic message to the system log."};
247 spec.parameters = {
248 {"message", "String", "Debug message here", "The message to log"}
249 };
250 Register(spec);
251 }
252
253 {
254 TaskSpec spec{"set_state", "Set State", "Misc",
255 "Set a named state variable on the agent."};
256 spec.parameters = {
257 {"stateName", "String", "", "Name of the state variable"},
258 {"stateValue", "String", "", "Value to set"}
259 };
260 Register(spec);
261 }
262
263 {
264 TaskSpec spec{"clear_target", "Clear Target", "Misc",
265 "Clear the agent's current target reference."};
266 spec.parameters = {}; // No parameters
267 Register(spec);
268 }
269}
270
271} // namespace Olympe
UI-side registry of available atomic tasks with display metadata.
ComponentTypeID GetComponentTypeID_Static()
Definition ECS_Entity.h:56
Singleton registry mapping task IDs to TaskSpec metadata.
std::vector< TaskSpec > GetTasksByCategory(const std::string &category) const
Returns all tasks belonging to the given category.
static AtomicTaskUIRegistry & Get()
Returns the singleton instance.
std::vector< std::string > GetAllTaskIds() const
Returns all registered task IDs (unordered).
std::vector< TaskSpec > GetSortedForUI() const
Returns all tasks sorted by category then displayName, suitable for building a dropdown or combo box.
std::unordered_map< std::string, TaskSpec > m_specs
const TaskSpec * GetTaskSpec(const std::string &id) const
Returns the TaskSpec for the given id, or nullptr if not found.
void Register(const TaskSpec &spec)
Registers a TaskSpec for the given task ID.
std::vector< std::string > GetAllCategories() const
Returns all unique category names.
< Provides AssetID and INVALID_ASSET_ID
Display metadata for a single atomic task type.
std::vector< TaskParameter > parameters
Parameters this task accepts.