Last active
June 5, 2018 20:15
-
-
Save eyelash/3495436f90fed9e3c562c4c06e3b09f9 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| // 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