123 ERROR(
"Cannot get resource: world not initialized");
127 if (!resources->count(std::type_index(
typeid(R))))
129 ERROR(
"Resource not found: ", std::type_index(
typeid(R)).name());
133 auto ret = resources->at(std::type_index(
typeid(R)));
135 return static_cast<R *
>(ret.get());
154 template <
typename C>
159 ERROR(
"Cannot add component: world not initialized");
163 auto component = std::make_shared<C>(new_component);
165 component->entity = entity;
167 if (!components->count(std::type_index(
typeid(C))))
169 components->insert({std::type_index(
typeid(C)), {component}});
173 components->at(std::type_index(
typeid(C))).push_back(component);
176 INFO(
"Added component: ", std::type_index(
typeid(C)).name());
193 ERROR(
"Cannot add resource: world not initialized");
198 {std::type_index(
typeid(R)), std::make_shared<R>(resource)});
199 INFO(
"Added Resource: ", std::type_index(
typeid(R)).name());
233 ERROR(
"Cannot remove resource: world not initialized");
237 if (!resources->count(std::type_index(
typeid(R))))
239 ERROR(
"Resource not found: ", std::type_index(
typeid(R)).name());
243 resources->erase(std::type_index(
typeid(R)));
266 ERROR(
"Cannot get component: world not initialized");
270 if (!components->count(std::type_index(
typeid(C))))
272 ERROR(
"Component not found: ", std::type_index(
typeid(C)).name());
276 for (
auto component : components->at(std::type_index(
typeid(C))))
278 if (component->entity == entity)
280 return static_cast<C *
>(component.get());
295 static SetPtr<Entity> entities;
296 static UMapPtr<std::type_index, Resource> resources;
297 static UMapVecPtr<std::type_index, Component> components;
300 template <
typename Tuple, std::size_t... Is>
301 static void for_each_impl(Tuple &&tuple, std::index_sequence<Is...>)
303 (..., process(std::get<Is>(std::forward<Tuple>(tuple))));
305 template <
typename Tuple>
static void for_each(Tuple &&tuple)
307 for_each_impl(std::forward<Tuple>(tuple),
308 std::make_index_sequence<
309 std::tuple_size_v<std::remove_reference_t<Tuple>>>{});
311 template <
typename... T>
312 static std::vector<ECS::Entity> QueryComponentsTuple(std::tuple<T...>)
314 return QueryComponents<T...>();
316 template <
typename System>
static void process(
const System &system)
318 using Dependencies =
typename System::dependencies;
319 std::vector<ECS::Entity> matches = QueryComponentsTuple(Dependencies{});
323 template <
typename C,
typename... Components,
typename N = None>
324 static std::vector<Entity> QueryComponents()
326 if (!World::components)
328 ERROR(
"Cannot query: world not initialized");
332 std::vector<Entity> matched;
334 if (!components->count(std::type_index(
typeid(C))))
339 for (
auto component : components->at(std::type_index(typeid(C))))
341 matched.push_back(component->entity);
346 if (
sizeof...(Components) == 0)
349 QueryComponentsRec<Components..., None>(&matched);
354 template <
typename C,
typename... Components>
355 static void QueryComponentsRec(std::vector<Entity> *entities)
357 if (entities->empty())
359 std::vector<Entity> matched;
361 if (!components->count(std::type_index(
typeid(C))))
366 for (
auto component : components->at(std::type_index(typeid(C))))
368 if (std::find(entities->begin(), entities->end(),
369 (
int &) component->entity)
372 matched.push_back(component->entity);
377 if (
sizeof...(Components) == 0)
380 (QueryComponentsRec<Components>(entities), ...);