139 lines
No EOL
3.1 KiB
C++
139 lines
No EOL
3.1 KiB
C++
#pragma once
|
|
|
|
#include <string>
|
|
#include <vector>
|
|
#include <map>
|
|
#include <typeindex>
|
|
#include <functional>
|
|
#include <eventdispatcher.hpp>
|
|
|
|
class Entity;
|
|
class Component;
|
|
class World;
|
|
|
|
struct ComponentInfo
|
|
{
|
|
std::type_index type = typeid(nullptr);
|
|
Entity* entity = nullptr;
|
|
|
|
ComponentInfo(const std::type_index& ti, Entity* ent)
|
|
{
|
|
type = ti;
|
|
entity = ent;
|
|
}
|
|
|
|
friend bool operator==(const ComponentInfo& a, const ComponentInfo& b)
|
|
{
|
|
if(a.entity == b.entity && a.type == b.type)
|
|
return true;
|
|
|
|
return false;
|
|
}
|
|
|
|
friend bool operator<(const ComponentInfo&, const ComponentInfo&)
|
|
{
|
|
return false;
|
|
}
|
|
};
|
|
|
|
namespace std
|
|
{
|
|
template<>
|
|
struct hash<ComponentInfo>
|
|
{
|
|
size_t operator()(ComponentInfo const& x) const noexcept
|
|
{
|
|
return (sizeof(x.entity) + sizeof(x.type));
|
|
}
|
|
};
|
|
}
|
|
|
|
/*
|
|
* This is where the entities are actually created/stored. This a replacement for the static functions in previous
|
|
* iterations of the entity class
|
|
* TODO: recycle our entity pointers
|
|
* TODO: don't make this a singleton (it can be set up as a regular object)
|
|
*/
|
|
class EntityPool
|
|
{
|
|
friend class Entity;
|
|
|
|
public:
|
|
Entity* CreateEntity(World* world, int id = -1);
|
|
Entity* CreateEntity(const std::string& name, World* world, int id = -1); //create an entity and attach it to a world
|
|
|
|
Entity* GetByID(int id);
|
|
|
|
std::multimap<ComponentInfo, Component*> GetComponents(Entity* entity);
|
|
|
|
template<class T>
|
|
std::vector<T*> GetOf()
|
|
{
|
|
std::vector<T*> tmp;
|
|
for(auto& itr : m_components)
|
|
{
|
|
if(itr.first.type == typeid(T))
|
|
tmp.push_back(static_cast<T*>(itr.second));
|
|
}
|
|
|
|
return tmp;
|
|
}
|
|
|
|
std::type_index GetType(Component* component);
|
|
|
|
std::vector<Entity*> GetAllEntities()
|
|
{
|
|
return m_entities;
|
|
}
|
|
|
|
std::multimap<ComponentInfo, Component*> GetAllComponents()
|
|
{
|
|
return m_components;
|
|
}
|
|
|
|
Entity* Duplicate(Entity* entity, World* world);
|
|
|
|
Entity* Duplicate(int id, World* world)
|
|
{
|
|
return Duplicate(GetByID(id), world);
|
|
}
|
|
|
|
void Delete(Entity* entity);
|
|
|
|
void Delete(int id)
|
|
{
|
|
m_deletionQueue.push_back(id);
|
|
}
|
|
|
|
void ProcessDeletions();
|
|
|
|
void Cleanup();
|
|
|
|
EventDispatcher<void()> onEntityListChange; //adding/deleting entities
|
|
EventDispatcher<void()> onEntityChange; //components being added/removed
|
|
|
|
protected:
|
|
//for internal use
|
|
void RegisterComponent(Entity* entity, Component* component);
|
|
|
|
void RemoveComponent(Entity* entity, std::type_index type);
|
|
void RemoveComponent(Entity* entity, Component* component);
|
|
void RemoveComponents(Entity* entity);
|
|
|
|
void DuplicateComponent(Entity* entity, Component* component);
|
|
|
|
private:
|
|
void DeleteInternal(Entity* entity);
|
|
|
|
std::vector<Entity*> m_entities;
|
|
std::multimap<ComponentInfo, Component*> m_components;
|
|
|
|
static std::vector<uint32_t> m_deletionQueue;
|
|
};
|
|
|
|
inline EntityPool& GetEntPool()
|
|
{
|
|
static EntityPool pool;
|
|
|
|
return pool;
|
|
} |