Skip to content

Instantly share code, notes, and snippets.

@apathyboy
Created May 11, 2014 21:56
Show Gist options
  • Select an option

  • Save apathyboy/eb9433a1550f8a702412 to your computer and use it in GitHub Desktop.

Select an option

Save apathyboy/eb9433a1550f8a702412 to your computer and use it in GitHub Desktop.
#pragma once
#include "TypeId.hpp"
#include <boost/noncopyable.hpp>
#include <map>
#include <memory>
#include <set>
#include <type_traits>
#include <vector>
#include <cstdint>
namespace iggy
{
typedef uint64_t EntityId;
typedef type_id_t ComponentTypeId;
class Component
{
public:
template<typename T>
Component(const T& data)
: impl_(std::make_shared<Model<T>>(data))
{}
private:
friend class EntityComponentCoordinator;
struct Concept
{
virtual ~Concept() {}
};
template<typename T>
struct Model : Concept
{
Model(T value)
: data(value)
{}
T data;
};
std::shared_ptr<const Concept> impl_;
};
class EntityComponentCoordinator : boost::noncopyable
{
public:
EntityComponentCoordinator();
EntityId createEntity();
void destroyEntity(EntityId entity_id);
template<typename ComponentT>
ComponentT get(EntityId e)
{
auto component_type = type_id<ComponentT>();
auto& components = entity_components_.at(e);
auto& component = components.at(component_type);
return std::static_pointer_cast<const Component::Model<ComponentT>>(component.impl_)->data;
}
template<typename ComponentT>
void set(EntityId e, const ComponentT& c)
{
auto& components = entity_components_.at(e);
auto find_iter = components.find(type_id<ComponentT>());
if (find_iter != components.end())
{
find_iter->second = c;
}
else
{
components.insert(std::make_pair(type_id<ComponentT>(), std::move(c)));
}
}
template<typename ComponentT>
void unset(EntityId e)
{
auto& components = entity_components_.at(e);
components.erase(type_id<ComponentT>());
}
private:
uint64_t next_id_;
typedef std::map<ComponentTypeId, Component> ComponentMap;
std::map<EntityId, ComponentMap> entity_components_;
std::set<EntityId> entities_;
};
} // namespace iggy
#include "Entity.hpp"
using EntityComponentCoordinator;
struct Position
{
Position(int x, int y) : x {x}, y {y} {}
int x;
int y;
};
int main()
{
EntityComponentCoordinator ec {};
auto entity = ec.createEntity();
ec.set(entity, Position {100, 100});
auto p = ec.get<Position>(entity);
ec.unset<Position>(entity);
ec.destroy(entity);
}
#pragma once
#include "TypeId.hpp"
#include <boost/noncopyable.hpp>
#include <map>
#include <memory>
#include <set>
#include <type_traits>
#include <vector>
#include <cstdint>
namespace iggy
{
typedef uint64_t EntityId;
typedef type_id_t ComponentTypeId;
class Component
{
public:
template<typename T>
Component(const T& data)
: impl_(std::make_shared<Model<T>>(data))
{}
private:
friend class EntityComponentCoordinator;
struct Concept
{
virtual ~Concept() {}
};
template<typename T>
struct Model : Concept
{
Model(T value)
: data(value)
{}
T data;
};
std::shared_ptr<const Concept> impl_;
};
class EntityComponentCoordinator : boost::noncopyable
{
public:
EntityComponentCoordinator();
EntityId createEntity();
void destroyEntity(EntityId entity_id);
template<typename ComponentT>
ComponentT get(EntityId e)
{
auto component_type = type_id<ComponentT>();
auto& components = entity_components_.at(e);
auto& component = components.at(component_type);
return std::static_pointer_cast<const Component::Model<ComponentT>>(component.impl_)->data;
}
template<typename ComponentT>
void set(EntityId e, const ComponentT& c)
{
auto& components = entity_components_.at(e);
auto find_iter = components.find(type_id<ComponentT>());
if (find_iter != components.end())
{
find_iter->second = c;
}
else
{
components.insert(std::make_pair(type_id<ComponentT>(), std::move(c)));
}
}
template<typename ComponentT>
void unset(EntityId e)
{
auto& components = entity_components_.at(e);
components.erase(type_id<ComponentT>());
}
private:
uint64_t next_id_;
typedef std::map<ComponentTypeId, Component> ComponentMap;
std::map<EntityId, ComponentMap> entity_components_;
std::set<EntityId> entities_;
};
} // namespace iggy
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment