364 m_last_time(std::chrono::high_resolution_clock::now()),
365 m_commands(std::make_unique<Commands>(*
this)) {
380 m_resources[
typeid(T)] = std::make_unique<
Resource<T>>(resource);
395 auto it = m_resources.find(
typeid(T));
397 assert(it != m_resources.end() &&
"Requested resource not found");
399 return *
static_cast<Resource<T>*
>(it->second.get());
417 template<
typename Func>
419 get_systems(label).emplace_back(
420 std::make_unique<System<std::decay_t<Func>>>(
421 std::forward<Func>(func),
442 template<
typename Func>
444 add_system(ScheduleLabel::Update, std::forward<Func>(func));
451 auto current_time = std::chrono::high_resolution_clock::now();
452 std::chrono::duration<float> delta = current_time - m_last_time;
453 m_time.delta = delta.count();
454 m_last_time = current_time;
464 m_time.delta = delta_time;
470 template<
typename... Components>
471 inline Query<Components...> query() {
472 return Query<Components...>(
this);
475 template<
typename... Components>
476 Observer<Components...>& observe() {
477 auto observer = std::make_unique<Observer<Components...>>();
478 auto new_observer = observer.
get();
479 m_observers.push_back(std::move(observer));
480 return *new_observer;
483 inline Commands& commands();
485 void despawn(Entity entity) {
486 auto entity_it = m_entity_archetype_map.find(entity);
487 if (entity_it == m_entity_archetype_map.end()) {
492 Archetype* archetype = entity_it->second;
493 archetype->remove_entity(entity);
494 m_entity_archetype_map.erase(entity_it);
495 notify_remove(archetype->m_mask, entity);
496 m_free_list.push_back(entity);
500 void log_archetypes() {
501 printf(
"--- Logging Archetypes ---\n");
502 for (
const auto& archetype : m_archetypes) {
504 "Archetype with mask: %s\n",
505 archetype->m_mask.to_string().c_str()
508 if (archetype->m_entity_to_index.empty()) {
509 printf(
"No entities in this archetype (empty)\n");
511 printf(
"Entities in this archetype: ");
512 for (
const auto& entity : archetype->m_entity_to_index) {
513 printf(
"Entity(%zu) ", entity.first);
515 printf(
"(total = %zu)\n", archetype->m_entity_to_index.size());
518 printf(
"--- End of Archetypes Log ---\n");
522 template<
typename... Components>
524 friend class EntityBuilder;
525 friend class EntityCommands;
528 struct TypeErasedSystem {
529 virtual ~TypeErasedSystem() =
default;
530 virtual void execute(World& world) = 0;
533 template<
typename Func>
534 struct System: TypeErasedSystem {
537 System(Func&& f, World& world) :
538 params(get_system_params<
539 typename _traits::function_traits<Func>::args_tuple>(world)),
540 func(std::forward<Func>(f)) {}
542 void execute(World& world)
override {
543 std::apply(func, params);
548 decltype(get_system_params<
549 typename _traits::function_traits<Func>::args_tuple>(
550 std::declval<World&>()
558 template<
typename... Components>
561 friend class EntityBuilder;
564 T* get_component(Entity entity) {
565 auto it = m_entity_to_index.find(entity);
566 if (it == m_entity_to_index.end()) {
569 return get_row<T>(it->second);
573 T* get_row(
size_t row) {
574 static const ComponentId
id = TypeIDGenerator::get_type_id<T>();
575 auto it = m_type_to_column.find(
id);
576 if (it == m_type_to_column.end()) {
582 static_cast<ComponentColumn<T>*
>(m_columns[it->second].get());
583 if (row >= column->data.size()) {
588 return &column->data[row];
591 template<
typename Component>
593 get_component_or_entity(Archetype* archetype,
const Entity& entity) {
594 if constexpr (std::is_same_v<Component, Entity>) {
596 }
else if constexpr (_traits::is_optional<Component>()) {
597 using UnderlyingType =
typename Component::value_type;
598 return Optional<UnderlyingType>(
599 archetype->template get_component<UnderlyingType>(entity)
602 return archetype->template get_component<Component>(entity);
606 template<
typename... Components>
608 make_component_tuple(Archetype* archetype,
const Entity& entity) {
609 return std::make_tuple(
610 get_component_or_entity<Components>(archetype, entity)...
614 Archetype(
const ComponentMask& mask) : m_mask(mask) {}
616 template<
typename... Components>
617 static std::unique_ptr<Archetype> from_columns() {
618 ComponentMask mask = compute_mask<Components...>();
619 auto archetype = std::make_unique<Archetype>(Archetype(mask));
620 (archetype->add_column<Components>(), ...);
621 return std::move(archetype);
624 template<
typename... NewComponents>
625 static std::unique_ptr<Archetype>
626 from_archetype(
const Archetype& old_archetype) {
627 ComponentMask new_components_mask =
628 compute_mask<NewComponents...>();
629 ComponentMask combined_mask =
630 old_archetype.m_mask | new_components_mask;
633 std::make_unique<Archetype>(Archetype(combined_mask));
635 for (
const auto& [component_id, column_index] :
636 old_archetype.m_type_to_column) {
637 auto& component = old_archetype.m_columns[column_index];
638 new_archetype->m_columns.emplace_back(component->clone_empty());
639 new_archetype->m_type_to_column[component_id] =
640 new_archetype->m_columns.size() - 1;
643 (new_archetype->add_column<NewComponents>(), ...);
645 return new_archetype;
650 ComponentId
id = TypeIDGenerator::get_type_id<T>();
651 m_columns.push_back(std::make_unique<ComponentColumn<T>>());
652 m_type_to_column[id] = m_columns.size() - 1;
656 void add_row(
size_t row, T&& component) {
657 static const ComponentId
id = TypeIDGenerator::get_type_id<T>();
659 auto it = m_type_to_column.find(
id);
660 if (it == m_type_to_column.end()) {
661 printf(
"Error: column does not exist in archetype\n");
665 auto* column =
static_cast<ComponentColumn<T>*
>(
666 m_columns[m_type_to_column[id]].get()
669 if (column->data.size() <= row) {
670 column->data.resize(row + 1);
673 column->data[row] = std::forward<T>(component);
676 template<
typename... Components>
677 void update_components(Entity entity, Components&&... components) {
678 (update_row<Components>(entity, components), ...);
682 void update_row(Entity entity, T&& component) {
683 static const ComponentId
id = TypeIDGenerator::get_type_id<T>();
685 auto it = m_type_to_column.find(
id);
686 if (it == m_type_to_column.end()) {
687 printf(
"error: coulmn does not exist in archetype\n");
691 auto* column =
static_cast<ComponentColumn<T>*
>(
692 m_columns[m_type_to_column[id]].get()
695 auto row_it = m_entity_to_index.find(entity);
697 if (row_it == m_entity_to_index.end()) {
698 printf(
"error: row does not exist in archetype\n");
702 column->data[row_it->second] = std::forward<T>(component);
705 template<
typename... Components>
706 bool has_components()
const {
707 auto mask = compute_mask<Components...>();
708 return has_components(mask);
711 bool has_components(ComponentMask mask)
const {
713 return m_mask.contains(mask);
716 template<
typename... Components>
717 void add_entity(Entity entity, Components&&... components) {
718 size_t row = m_next_available_row;
719 m_entity_to_index[entity] = row;
720 (add_row<Components>(row, std::forward<Components>(components)),
722 ++m_next_available_row;
725 void remove_entity(Entity entity) {
726 auto it = m_entity_to_index.find(entity);
727 if (it == m_entity_to_index.end()) {
730 size_t row = it->second;
731 size_t last_row = m_next_available_row - 1;
732 if (row != last_row) {
733 for (
auto& column : m_columns) {
734 column->swap(row, last_row);
736 for (
auto& pair : m_entity_to_index) {
737 if (pair.second == last_row) {
744 --m_next_available_row;
746 for (
auto& column : m_columns) {
750 m_entity_to_index.erase(it);
753 struct TypeErasedComponentColumn {
754 virtual ~TypeErasedComponentColumn() =
default;
755 virtual std::unique_ptr<TypeErasedComponentColumn>
756 clone_empty()
const = 0;
757 virtual void copy_component_to(
758 TypeErasedComponentColumn* target_column,
762 virtual void swap(
size_t index1,
size_t index2) = 0;
763 virtual void pop_back() = 0;
767 struct ComponentColumn: TypeErasedComponentColumn {
768 using StorageType =
typename std::decay<T>::type;
770 std::vector<StorageType> data;
772 std::unique_ptr<TypeErasedComponentColumn>
773 clone_empty()
const override {
774 return std::make_unique<ComponentColumn<T>>();
777 void copy_component_to(
778 TypeErasedComponentColumn* target_column,
782 auto* target =
static_cast<ComponentColumn<T>*
>(target_column);
783 if (target->data.size() <= to_index) {
784 target->data.resize(to_index + 1);
786 target->data[to_index] = this->data[from_index];
789 void swap(
size_t index1,
size_t index2)
override {
790 std::swap(data[index1], data[index2]);
793 void pop_back()
override {
798 template<
typename... NewComponents>
800 Archetype* target_archetype,
802 NewComponents&&... new_components
804 auto it = m_entity_to_index.find(entity);
805 if (it == m_entity_to_index.end()) {
806 printf(
"Error: Entity not found in archetype during move.\n");
809 size_t source_row = it->second;
810 size_t target_row = target_archetype->m_next_available_row;
811 target_archetype->m_entity_to_index[entity] = target_row;
813 for (
const auto& [component_id, column_index] : m_type_to_column) {
814 auto& src_column = m_columns[column_index];
816 target_archetype->m_type_to_column.find(component_id);
817 if (target_it != target_archetype->m_type_to_column.end()) {
818 size_t target_column_index = target_it->second;
819 auto& target_column =
820 target_archetype->m_columns[target_column_index];
823 src_column->copy_component_to(
832 (target_archetype->add_row<NewComponents>(
834 std::forward<NewComponents>(new_components)
839 ++target_archetype->m_next_available_row;
842 ComponentMask m_mask;
844 size_t m_next_available_row {0};
845 storage::dense_map<ComponentId, size_t> m_type_to_column;
846 storage::dense_map<Entity, size_t> m_entity_to_index;
847 std::vector<std::unique_ptr<TypeErasedComponentColumn>> m_columns;
850 void notify_add(
const ComponentMask& mask, Entity entity) {
851 for (
const auto& observer : m_observers) {
852 if (mask.contains(observer->mask())) {
853 observer->add(entity);
858 void notify_insert(
const ComponentMask& mask, Entity entity) {
859 for (
const auto& observer : m_observers) {
860 if (mask.contains(observer->mask())) {
861 observer->insert(entity);
866 void notify_remove(
const ComponentMask& mask, Entity entity) {
867 for (
const auto& observer : m_observers) {
868 if (mask.contains(observer->mask())) {
869 observer->remove(entity);
874 template<
typename... Components>
875 void add_components(Entity entity, Components&&... components) {
876 auto new_components_mask = compute_mask<Components...>();
877 ComponentMask combined_mask = new_components_mask;
879 Archetype* current_archetype =
nullptr;
880 auto entity_it = m_entity_archetype_map.find(entity);
881 if (entity_it != m_entity_archetype_map.end()) {
882 current_archetype = entity_it->second;
883 combined_mask = current_archetype->m_mask | new_components_mask;
886 if (current_archetype->m_mask.contains(new_components_mask)) {
887 current_archetype->update_components(entity, components...);
888 notify_insert(combined_mask, entity);
894 Archetype* target_archetype =
nullptr;
895 auto archetype_it = m_archetype_map.find(combined_mask);
896 if (archetype_it != m_archetype_map.end()) {
898 target_archetype = archetype_it->second;
901 if (current_archetype ==
nullptr) {
902 auto new_archetype = Archetype::from_columns<Components...>();
903 target_archetype = new_archetype.get();
904 m_archetypes.push_back(std::move(new_archetype));
905 m_archetype_map[combined_mask] = target_archetype;
908 Archetype::from_archetype<Components...>(*current_archetype
910 target_archetype = new_archetype.get();
911 m_archetypes.push_back(std::move(new_archetype));
912 m_archetype_map[combined_mask] = target_archetype;
916 if (current_archetype !=
nullptr) {
917 current_archetype->move_entity(
920 std::forward<Components>(components)...
922 notify_add(combined_mask, entity);
923 notify_insert(combined_mask, entity);
925 current_archetype->remove_entity(entity);
927 target_archetype->add_entity(
929 std::forward<Components>(components)...
931 notify_add(combined_mask, entity);
932 notify_insert(combined_mask, entity);
934 m_entity_archetype_map[entity] = target_archetype;
938 template<
typename Component>
939 void remove_component(Entity entity) {
940 auto entity_it = m_entity_archetype_map.find(entity);
941 if (entity_it == m_entity_archetype_map.end()) {
945 Archetype* current_archetype = entity_it->second;
947 ComponentMask new_mask = current_archetype->m_mask;
948 ComponentId component_id = TypeIDGenerator::get_type_id<Component>();
949 new_mask.reset(component_id);
952 Archetype* target_archetype =
nullptr;
953 auto archetype_it = m_archetype_map.find(new_mask);
954 if (archetype_it != m_archetype_map.end()) {
955 target_archetype = archetype_it->second;
959 Archetype::from_archetype<>(*current_archetype).release();
960 target_archetype->m_mask = new_mask;
962 m_archetypes.push_back(std::unique_ptr<Archetype>(target_archetype)
964 m_archetype_map[new_mask] = target_archetype;
967 current_archetype->move_entity(target_archetype, entity);
968 current_archetype->remove_entity(entity);
970 m_entity_archetype_map[entity] = target_archetype;
971 notify_remove(current_archetype->m_mask, entity);
976 inline void execute_schedule(ScheduleLabel label) {
977 for (
const auto& system : get_systems(label)) {
978 system->execute(*
this);
988 inline void execute_commands();
990 inline void execute_progress() {
991 execute_schedule(ScheduleLabel::Startup);
992 execute_schedule(ScheduleLabel::PreUpdate);
993 execute_schedule(ScheduleLabel::Update);
994 execute_schedule(ScheduleLabel::Validate);
995 execute_schedule(ScheduleLabel::PostUpdate);
996 execute_schedule(ScheduleLabel::PreStore);
997 execute_schedule(ScheduleLabel::Store);
999 for (
const auto& observer : m_observers) {
1005 get_systems(ScheduleLabel::Startup).clear();
1014 std::chrono::high_resolution_clock::time_point m_last_time;
1016 inline std::vector<std::unique_ptr<TypeErasedSystem>>&
1017 get_systems(ScheduleLabel label) {
1018 return m_systems[
static_cast<std::underlying_type_t<ScheduleLabel>
>(
1024 std::underlying_type_t<ScheduleLabel>,
1025 std::vector<std::unique_ptr<TypeErasedSystem>>>
1033 std::unordered_map<std::type_index, std::unique_ptr<TypeErasedResource>>
1036 Entity m_current_entity_id {0};
1037 unsigned int m_query_version {0};
1038 std::vector<std::unique_ptr<Archetype>> m_archetypes;
1039 std::unordered_map<ComponentMask, Archetype*> m_archetype_map;
1040 storage::dense_map<Entity, Archetype*> m_entity_archetype_map;
1041 std::vector<std::unique_ptr<TypeErasedObserver>> m_observers;
1042 std::unique_ptr<Commands> m_commands;
1043 std::vector<Entity> m_free_list;