void add_component(Handle<Component>);
void remove_component(Handle<Component>);
+ const std::vector<Handle<Component>> &get_components() const { return components; }
template<typename T>
Handle<T> get_component();
{ std::erase_if(handlers, [obs](auto &h){ return h.observer==obs; }); }
void dispatch(const T &) const;
+ void dispatch_to(EventObserver &, const T &) const;
};
template<typename T>
void dispatch(const T &) const;
+
+ template<typename T>
+ void dispatch_to(EventObserver &, const T &) const;
};
h.callback(event);
}
+template<typename T>
+void EventDispatcher<T>::dispatch_to(EventObserver &obs, const T &event) const
+{
+ for(const Handler &h: handlers)
+ if(h.observer==&obs)
+ h.callback(event);
+}
+
template<typename T>
inline unsigned EventBus::get_event_id()
static_cast<EventDispatcher<T> *>(dispatchers[id].dispatcher)->dispatch(event);
}
+template<typename T>
+inline void EventBus::dispatch_to(EventObserver &obs, const T &event) const
+{
+ unsigned id = get_event_id<T>();
+ if(id<dispatchers.size() && dispatchers[id].dispatcher)
+ static_cast<EventDispatcher<T> *>(dispatchers[id].dispatcher)->dispatch_to(obs, event);
+}
+
} // namespace Msp::Game
#endif
public:
template<typename T, typename... Args>
void emit(Args &&...) const;
+
+ template<typename T, typename... Args>
+ void emit_to(EventObserver &, Args &&...) const;
};
bus.dispatch(event);
}
+template<typename... E>
+template<typename T, typename... Args>
+inline void EventSource<E...>::emit_to(EventObserver &obs, Args &&... args) const
+{
+ T event(std::forward<Args>(args)...);
+ static_cast<const EventDispatcher<T> &>(*this).dispatch_to(obs, event);
+ bus.dispatch_to(obs, event);
+}
+
} // namespace Msp::Game
#endif
event_source.emit<Events::CameraChanged>(active_camera);
}
+void Stage::synthesize_initial_events(EventObserver &target_observer)
+{
+ synthesize_initial_events(Handle<Entity>::from_object(root.get()), target_observer);
+ if(active_camera)
+ event_source.emit_to<Events::CameraChanged>(target_observer, active_camera);
+}
+
+void Stage::synthesize_initial_events(Handle<Entity> entity, EventObserver &target_observer)
+{
+ for(Handle<Component> c: entity->get_components())
+ event_source.emit_to<Events::ComponentCreated>(target_observer, c);
+ for(Handle<Entity> e: entity->get_children())
+ synthesize_initial_events(e, target_observer);
+ event_source.emit_to<Events::EntityCreated>(target_observer, entity);
+}
+
void Stage::tick(Time::TimeDelta dt)
{
for(const auto &s: systems)
void set_active_camera(Handle<Camera>);
Handle<Camera> get_active_camera() const { return active_camera; }
+ void synthesize_initial_events(EventObserver &);
+private:
+ void synthesize_initial_events(Handle<Entity>, EventObserver &);
+
+public:
void tick(Time::TimeDelta);
};
event_observer.observe<Game::Events::EntityDestroyed>([this](auto &e){ entity_destroyed(e); });
event_observer.observe<Game::Events::CameraChanged>([this](auto &e){ camera_changed(e); });
- stage.iterate_objects<Game::Entity>([this](auto &e){ entity_created({ Game::Handle<Game::Entity>::from_object(&e) }); });
- if(Game::Handle<Game::Camera> ac = stage.get_active_camera())
- camera_changed({ ac });
+ stage.synthesize_initial_events(event_observer);
view.set_camera(&gl_camera);
}