2018-12-19 12:19:52 -05:00
|
|
|
#pragma once
|
|
|
|
|
|
|
|
#include <cstdint>
|
|
|
|
#include <map>
|
2019-01-08 22:27:42 -05:00
|
|
|
#include <vector>
|
2018-12-19 12:19:52 -05:00
|
|
|
#include <array>
|
2022-02-28 21:53:36 -05:00
|
|
|
#include <string>
|
2018-12-19 12:19:52 -05:00
|
|
|
#include <glm/glm.hpp>
|
|
|
|
#include <type_traits>
|
|
|
|
|
|
|
|
struct InfoComponent {
|
|
|
|
std::string name, tag;
|
|
|
|
};
|
|
|
|
|
|
|
|
struct TransformComponent {
|
|
|
|
glm::vec3 position = glm::vec3(0);
|
|
|
|
};
|
|
|
|
|
|
|
|
struct MeshAsset;
|
|
|
|
struct MaterialAsset;
|
|
|
|
|
|
|
|
struct MeshComponent {
|
|
|
|
MeshAsset* mesh = nullptr;
|
|
|
|
MaterialAsset* material = nullptr;
|
|
|
|
};
|
|
|
|
|
|
|
|
enum class LightType {
|
|
|
|
Point,
|
|
|
|
Directional
|
|
|
|
};
|
|
|
|
|
|
|
|
struct LightComponent {
|
|
|
|
LightType type = LightType::Point;
|
|
|
|
glm::vec3 color = glm::vec3(1);
|
2018-12-21 06:32:37 -05:00
|
|
|
|
2018-12-19 12:19:52 -05:00
|
|
|
glm::mat4 matrix = glm::mat4(1.0f);
|
|
|
|
};
|
|
|
|
|
|
|
|
struct CameraComponent {
|
|
|
|
float fov = 75.0f, near = 0.1f, far = 100.0f;
|
|
|
|
float focusDistance = 0.0f;
|
|
|
|
float aperture = 0.0f;
|
|
|
|
glm::vec3 target = glm::vec3(0);
|
|
|
|
};
|
|
|
|
|
2019-01-08 22:27:42 -05:00
|
|
|
struct ListenerComponent {
|
|
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
struct AudioAsset;
|
|
|
|
|
|
|
|
struct SpeakerComponent {
|
|
|
|
AudioAsset* audio = nullptr;
|
|
|
|
unsigned int source = 0;
|
|
|
|
bool playing = false;
|
|
|
|
};
|
|
|
|
|
2018-12-19 12:19:52 -05:00
|
|
|
using EntityID = uint64_t;
|
|
|
|
|
|
|
|
struct World;
|
|
|
|
|
2018-12-21 06:32:37 -05:00
|
|
|
namespace ECS {
|
2018-12-19 12:19:52 -05:00
|
|
|
// components
|
|
|
|
inline std::map<EntityID, InfoComponent*> infos;
|
|
|
|
inline std::map<EntityID, TransformComponent*> transforms;
|
|
|
|
inline std::map<EntityID, MeshComponent*> meshes;
|
|
|
|
inline std::map<EntityID, LightComponent*> lights;
|
|
|
|
inline std::map<EntityID, CameraComponent*> cameras;
|
2019-01-08 22:27:42 -05:00
|
|
|
inline std::map<EntityID, ListenerComponent*> listeners;
|
|
|
|
inline std::map<EntityID, SpeakerComponent*> speakers;
|
2018-12-21 06:32:37 -05:00
|
|
|
|
2018-12-19 12:19:52 -05:00
|
|
|
inline std::map<EntityID, ::World*> worlds;
|
|
|
|
inline EntityID lastID = 1;
|
2018-12-21 06:32:37 -05:00
|
|
|
|
2018-12-27 06:31:37 -05:00
|
|
|
static inline void destructResources() {
|
|
|
|
for(const auto& [id, info] : infos)
|
|
|
|
delete info;
|
|
|
|
|
|
|
|
for(const auto& [id, transform] : transforms)
|
|
|
|
delete transform;
|
|
|
|
|
|
|
|
for(const auto& [id, mesh] : meshes)
|
|
|
|
delete mesh;
|
|
|
|
|
|
|
|
for(const auto& [id, light] : lights)
|
|
|
|
delete light;
|
|
|
|
|
|
|
|
for(const auto& [id, camera] : cameras)
|
|
|
|
delete camera;
|
2019-01-08 22:27:42 -05:00
|
|
|
|
|
|
|
for(const auto& [id, listener] : listeners)
|
|
|
|
delete listener;
|
|
|
|
|
|
|
|
for(const auto& [id, speaker] : speakers)
|
|
|
|
delete speaker;
|
2018-12-27 06:31:37 -05:00
|
|
|
}
|
|
|
|
|
2018-12-19 12:19:52 -05:00
|
|
|
static inline EntityID createEntity(World* world) {
|
|
|
|
EntityID newID = lastID++;
|
|
|
|
worlds[newID] = world;
|
2018-12-21 06:32:37 -05:00
|
|
|
|
2018-12-19 12:19:52 -05:00
|
|
|
return newID;
|
|
|
|
}
|
2018-12-21 06:32:37 -05:00
|
|
|
|
2018-12-19 12:19:52 -05:00
|
|
|
static inline void destroyEntity(const EntityID id) {
|
2018-12-21 06:32:37 -05:00
|
|
|
|
2018-12-19 12:19:52 -05:00
|
|
|
}
|
2018-12-21 06:32:37 -05:00
|
|
|
|
2018-12-19 12:19:52 -05:00
|
|
|
template<class T>
|
|
|
|
static inline T* addComponent(const EntityID id) {
|
|
|
|
T* t = new T();
|
|
|
|
if constexpr(std::is_same<T, InfoComponent>::value) {
|
|
|
|
infos[id] = t;
|
|
|
|
} else if constexpr(std::is_same<T, TransformComponent>::value) {
|
|
|
|
transforms[id] = t;
|
|
|
|
} else if constexpr(std::is_same<T, MeshComponent>::value) {
|
|
|
|
meshes[id] = t;
|
|
|
|
} else if constexpr(std::is_same<T, LightComponent>::value) {
|
|
|
|
lights[id] = t;
|
|
|
|
} else if constexpr(std::is_same<T, CameraComponent>::value) {
|
|
|
|
cameras[id] = t;
|
2019-01-08 22:27:42 -05:00
|
|
|
} else if constexpr(std::is_same<T, ListenerComponent>::value) {
|
|
|
|
listeners[id] = t;
|
|
|
|
} else if constexpr(std::is_same<T, SpeakerComponent>::value) {
|
|
|
|
speakers[id] = t;
|
2018-12-19 12:19:52 -05:00
|
|
|
}
|
2018-12-21 06:32:37 -05:00
|
|
|
|
2018-12-19 12:19:52 -05:00
|
|
|
return t;
|
|
|
|
}
|
2018-12-21 06:32:37 -05:00
|
|
|
|
2018-12-19 12:19:52 -05:00
|
|
|
template<class T>
|
|
|
|
static inline T* getComponent(const EntityID id) {
|
|
|
|
if constexpr(std::is_same<T, InfoComponent>::value) {
|
|
|
|
return infos[id];
|
|
|
|
} else if constexpr(std::is_same<T, TransformComponent>::value) {
|
|
|
|
return transforms[id];
|
|
|
|
} else if constexpr(std::is_same<T, MeshComponent>::value) {
|
|
|
|
return meshes[id];
|
|
|
|
} else if constexpr(std::is_same<T, LightComponent>::value) {
|
|
|
|
return lights[id];
|
|
|
|
} else if constexpr(std::is_same<T, CameraComponent>::value) {
|
|
|
|
return cameras[id];
|
2019-01-08 22:27:42 -05:00
|
|
|
} else if constexpr(std::is_same<T, ListenerComponent>::value) {
|
|
|
|
return listeners[id];
|
|
|
|
} else if constexpr(std::is_same<T, SpeakerComponent>::value) {
|
|
|
|
return speakers[id];
|
2018-12-19 12:19:52 -05:00
|
|
|
}
|
|
|
|
}
|
2018-12-21 06:32:37 -05:00
|
|
|
|
2018-12-19 12:19:52 -05:00
|
|
|
template<class T>
|
2018-12-21 06:32:37 -05:00
|
|
|
static inline auto getWorldComponents(World* world) {
|
2018-12-19 12:19:52 -05:00
|
|
|
std::vector<EntityID> entities;
|
2018-12-21 06:32:37 -05:00
|
|
|
for (auto it = worlds.begin(); it != worlds.end(); ++it) {
|
2018-12-19 12:19:52 -05:00
|
|
|
if(it->second == world) {
|
|
|
|
entities.push_back(it->first);
|
|
|
|
}
|
|
|
|
}
|
2018-12-21 06:32:37 -05:00
|
|
|
|
2018-12-19 12:19:52 -05:00
|
|
|
std::vector<std::tuple<EntityID, T*>> components;
|
|
|
|
for(auto ent : entities) {
|
|
|
|
T* t = getComponent<T>(ent);
|
|
|
|
if(t != nullptr)
|
|
|
|
components.push_back(std::tuple(ent, t));
|
|
|
|
}
|
2018-12-21 06:32:37 -05:00
|
|
|
|
2018-12-19 12:19:52 -05:00
|
|
|
return components;
|
|
|
|
}
|
2018-12-21 06:32:37 -05:00
|
|
|
|
2018-12-19 12:19:52 -05:00
|
|
|
static inline std::vector<EntityID> getWorldEntities(World* world) {
|
|
|
|
std::vector<EntityID> entities;
|
|
|
|
for (auto it = worlds.begin(); it != worlds.end(); ++it) {
|
|
|
|
if(it->second == world)
|
|
|
|
entities.push_back(it->first);
|
|
|
|
}
|
2018-12-21 06:32:37 -05:00
|
|
|
|
2018-12-19 12:19:52 -05:00
|
|
|
return entities;
|
|
|
|
}
|
2018-12-21 06:32:37 -05:00
|
|
|
|
2018-12-19 12:19:52 -05:00
|
|
|
template<class T>
|
|
|
|
static inline void removeComponent(const EntityID id) {
|
2018-12-26 07:19:16 -05:00
|
|
|
if constexpr(std::is_same<T, InfoComponent>::value) {
|
|
|
|
infos.erase(infos.find(id), infos.end());
|
|
|
|
} else if constexpr(std::is_same<T, TransformComponent>::value) {
|
|
|
|
transforms.erase(transforms.find(id), transforms.end());
|
|
|
|
} else if constexpr(std::is_same<T, MeshComponent>::value) {
|
|
|
|
meshes.erase(meshes.find(id), meshes.end());
|
|
|
|
} else if constexpr(std::is_same<T, LightComponent>::value) {
|
|
|
|
lights.erase(lights.find(id), lights.end());
|
|
|
|
} else if constexpr(std::is_same<T, CameraComponent>::value) {
|
|
|
|
cameras.erase(cameras.find(id), cameras.end());
|
2019-01-08 22:27:42 -05:00
|
|
|
} else if constexpr(std::is_same<T, ListenerComponent>::value) {
|
|
|
|
listeners.erase(listeners.find(id), listeners.end());
|
|
|
|
} else if constexpr(std::is_same<T, SpeakerComponent>::value) {
|
|
|
|
speakers.erase(speakers.find(id), speakers.end());
|
2018-12-26 07:19:16 -05:00
|
|
|
}
|
2018-12-19 12:19:52 -05:00
|
|
|
}
|
|
|
|
};
|