Skip to content

Instantly share code, notes, and snippets.

@alecthomas
Created November 19, 2014 22:53
Show Gist options
  • Save alecthomas/500791d204531f6a6284 to your computer and use it in GitHub Desktop.
Save alecthomas/500791d204531f6a6284 to your computer and use it in GitHub Desktop.
EntityX system for replacing all builtin events
#pragma once
#include <vector>
#include <entityx/Entity.h>
#include <entityx/System.h>
namespace entityx {
struct Notification : public Component<Notification> {
EntityManager::ComponentMask components_added, components_removed;
bool created = false;
};
template <typename C>
struct MonitorComponentSystem : public System<MonitorComponentSystem<C>> {
void configure(EventManager &events) override {
events.subscribe<ComponentAddedEvent<C>>(*this);
events.subscribe<ComponentRemovedEvent<C>>(*this);
}
void update(EntityManager &entities, EventManager &events, TimeDelta dt) override {
Notification::Handle notification;
for (auto _ : entities.entities_with_components(notification)) {
notification->components_added.reset();
notification->components_removed.reset();
}
}
void receive(const ComponentAddedEvent<C> &event) {
Entity entity = event.entity;
Notification::Handle notification = entity.component<Notification>();
notification->components_added.set(C::family());
}
void receive(const ComponentRemovedEvent<C> &event) {
Entity entity = event.entity;
Notification::Handle notification = entity.component<Notification>();
notification->components_removed.set(C::family());
}
};
struct NotificationSystem : public System<NotificationSystem> {
template <typename ... Components>
explicit NotificationSystem(SystemManager &systems) {
register_component<Components...>(systems);
}
void configure(EventManager &events) override {
events.subscribe<EntityCreatedEvent>(*this);
events.subscribe<EntityDestroyedEvent>(*this);
for (auto reg : registrations_) reg(events);
}
void update(EntityManager &entities, EventManager &events, TimeDelta dt) override {
destroyed.clear();
Notification::Handle notification;
for (auto _ : entities.entities_with_components(notification)) {
notification->created = false;
}
}
void receive(const EntityCreatedEvent &event) {
Entity entity = event.entity;
auto notification = entity.assign<Notification>();
notification->created = true;
}
void receive(const EntityDestroyedEvent &event) {
destroyed.push_back(event.entity.id());
}
// Entities destroyed so far in this update.
std::vector<Entity::Id> destroyed;
private:
template <typename C>
void register_component(SystemManager &systems) {
registrations_.push_back([this, &systems](EventManager &events) {
systems.add<MonitorComponentSystem<C>>();
});
}
template <typename C, typename ... Components>
void register_component(SystemManager &systems) {
register_component<C>();
register_component<Components...>();
}
std::vector<void(EventManager&)> registrations_;
};
} // namespace entityx
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment