Skip to content

Instantly share code, notes, and snippets.

@Kromey
Forked from jaynus/system_chain.rs
Created March 20, 2019 21:35
Show Gist options
  • Select an option

  • Save Kromey/acef217d907b4e1edcde66f9ee9bbb9f to your computer and use it in GitHub Desktop.

Select an option

Save Kromey/acef217d907b4e1edcde66f9ee9bbb9f to your computer and use it in GitHub Desktop.
pretty triangles
use crate::components;
use amethyst::ecs::{self, prelude::*, shred::ResourceId};
pub trait EventSystem<'a> {
type SystemData: ecs::SystemData<'a>;
type Event: Sized;
fn run(data: &Self::SystemData, event: &mut Self::Event) -> bool;
fn invalidate(data: &Self::SystemData, event: &mut Self::Event) {}
}
impl<'a, E, A, B> EventSystem<'a> for (A, B)
where
A: EventSystem<'a, Event = E>,
B: EventSystem<'a, Event = E>,
{
type SystemData = (A::SystemData, B::SystemData);
type Event = E;
fn run(data: &Self::SystemData, event: &mut Self::Event) -> bool {
if A::run(&data.0, event) {
if B::run(&data.1, event) {
return true;
} else {
A::invalidate(&data.0, event);
}
}
false
}
}
impl<'a, E, A, B, C> EventSystem<'a> for (A, B, C)
where
A: EventSystem<'a, Event = E>,
B: EventSystem<'a, Event = E>,
C: EventSystem<'a, Event = E>,
{
type SystemData = (A::SystemData, B::SystemData, C::SystemData);
type Event = E;
fn run(data: &Self::SystemData, event: &mut Self::Event) -> bool {
if A::run(&data.0, event) {
if B::run(&data.1, event) {
if C::run(&data.2, event) {
return true;
} else {
B::invalidate(&data.1, event);
A::invalidate(&data.0, event);
}
} else {
A::invalidate(&data.0, event);
}
}
false
}
}
impl<'a, E, A, B, C, D> EventSystem<'a> for (A, B, C, D)
where
A: EventSystem<'a, Event = E>,
B: EventSystem<'a, Event = E>,
C: EventSystem<'a, Event = E>,
D: EventSystem<'a, Event = E>,
{
type SystemData = (A::SystemData, B::SystemData, C::SystemData, D::SystemData);
type Event = E;
fn run(data: &Self::SystemData, event: &mut Self::Event) -> bool {
if A::run(&data.0, event) {
if B::run(&data.1, event) {
if C::run(&data.2, event) {
if D::run(&data.3, event) {
return true;
} else {
C::invalidate(&data.2, event);
B::invalidate(&data.1, event);
A::invalidate(&data.0, event);
}
} else {
B::invalidate(&data.1, event);
A::invalidate(&data.0, event);
}
} else {
A::invalidate(&data.0, event);
}
}
false
}
}
pub struct ReifiedEventSystem<'a, T>
where
T: EventSystem<'a>,
{
data: T::SystemData,
}
impl<'a, T> ReifiedEventSystem<'a, T>
where
T: EventSystem<'a>,
{
pub fn run(&self, event: &mut T::Event) -> bool {
T::run(&self.data, event)
}
}
impl<'a, T> SystemData<'a> for ReifiedEventSystem<'a, T>
where
T: EventSystem<'a>,
{
fn setup(res: &mut Resources) {
T::SystemData::setup(&mut *res);
}
fn fetch(res: &'a Resources) -> Self {
ReifiedEventSystem {
data: T::SystemData::fetch(res),
}
}
fn reads() -> Vec<ResourceId> {
T::SystemData::reads()
}
fn writes() -> Vec<ResourceId> {
T::SystemData::writes()
}
}
@Kromey

Kromey commented Mar 20, 2019

Copy link
Copy Markdown
Author

Static dispatch for mutable events, with cancellation notifying previous event systems.
See usage example here: https://github.com/JaniM/amethyst-rogue-thing/blob/ecb4ee72150fc35d971161e60f615d50db4c6782/src/systems/apply_attacks.rs#L26-L41

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment