Skip to content

Instantly share code, notes, and snippets.

@eyelash
Last active June 5, 2018 20:15
Show Gist options
  • Select an option

  • Save eyelash/3495436f90fed9e3c562c4c06e3b09f9 to your computer and use it in GitHub Desktop.

Select an option

Save eyelash/3495436f90fed9e3c562c4c06e3b09f9 to your computer and use it in GitHub Desktop.
// library code
enum SystemEvent {
Draw,
Mouse
}
enum Event<E> {
SystemEvent(SystemEvent),
UserEvent(E)
}
struct Context<E> {
events: std::collections::VecDeque<Event<E>>
}
impl<E> Context<E> {
fn new() -> Self {
Context {
events: std::collections::VecDeque::new()
}
}
fn push_event(&mut self, e: E) {
self.events.push_back(Event::UserEvent(e));
}
}
trait SystemComponent<E> {
fn handle_system_event(&mut self, e: &SystemEvent, c: &mut Context<E>);
}
trait UserComponent<E>: SystemComponent<E> {
fn handle_user_event(&mut self, e: &E, c: &mut Context<E>);
}
fn run<E, C: UserComponent<E>>(mut component: C) {
let mut context: Context<E> = Context::new();
context.events.push_back(Event::SystemEvent(SystemEvent::Mouse));
context.events.push_back(Event::SystemEvent(SystemEvent::Draw));
while let Some(e) = context.events.pop_front() {
match e {
Event::SystemEvent(e) => {
component.handle_system_event(&e, &mut context);
},
Event::UserEvent(e) => {
component.handle_user_event(&e, &mut context);
}
}
}
}
struct Button<E> {
clicked_event: E
}
impl<E> Button<E> {
fn new(e: E) -> Self {
Button {
clicked_event: e
}
}
}
impl<E: Clone> SystemComponent<E> for Button<E> {
fn handle_system_event(&mut self, e: &SystemEvent, c: &mut Context<E>) {
match e {
SystemEvent::Draw => {
println!("drawing a button");
},
SystemEvent::Mouse => {
c.push_event(self.clicked_event.clone());
}
}
}
}
struct SplitView {
}
impl SplitView {
fn new() -> Self {
SplitView {}
}
fn handle_system_event<E, C1: SystemComponent<E>, C2: SystemComponent<E>>(&self, c1: &mut C1, c2: &mut C2, e: &SystemEvent, c: &mut Context<E>) {
c1.handle_system_event(e, c);
c2.handle_system_event(e, c);
}
}
// user code
#[derive(Copy, Clone)]
enum UserEvent {
ButtonClicked(i32),
}
struct App {
sv: SplitView,
button1: Button<UserEvent>,
button2: Button<UserEvent>,
}
impl App {
fn new() -> Self {
App {
sv: SplitView::new(),
button1: Button::new(UserEvent::ButtonClicked(1)),
button2: Button::new(UserEvent::ButtonClicked(2))
}
}
}
impl SystemComponent<UserEvent> for App {
fn handle_system_event(&mut self, e: &SystemEvent, c: &mut Context<UserEvent>) {
self.sv.handle_system_event(&mut self.button1, &mut self.button2, e, c);
}
}
impl UserComponent<UserEvent> for App {
fn handle_user_event(&mut self, e: &UserEvent, _c: &mut Context<UserEvent>) {
match e {
UserEvent::ButtonClicked(n) => {
println!("button {} clicked", n);
}
}
}
}
fn main() {
let app = App::new();
run(app);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment