separate state from rsc
This commit is contained in:
@@ -1,7 +1,10 @@
|
||||
use crate::prelude::*;
|
||||
use arboard::Clipboard;
|
||||
use iris_core::util::forget_mut;
|
||||
use std::{marker::Sized, sync::Arc, time::Instant};
|
||||
use std::{
|
||||
marker::{PhantomData, Sized},
|
||||
sync::Arc,
|
||||
time::Instant,
|
||||
};
|
||||
use winit::{
|
||||
event::{Ime, WindowEvent},
|
||||
event_loop::{ActiveEventLoop, EventLoopProxy},
|
||||
@@ -49,53 +52,97 @@ impl DefaultUiState {
|
||||
}
|
||||
}
|
||||
|
||||
pub trait HasDefaultUiState: Sized + 'static + HasUi {
|
||||
fn get(&self) -> &DefaultUiState;
|
||||
fn get_mut(&mut self) -> &mut DefaultUiState;
|
||||
fn ui_state(&self) -> &DefaultUiState {
|
||||
HasDefaultUiState::get(self)
|
||||
}
|
||||
fn ui_state_mut(&mut self) -> &mut DefaultUiState {
|
||||
HasDefaultUiState::get_mut(self)
|
||||
}
|
||||
fn ui_with_state(&mut self) -> (&mut Ui, &mut DefaultUiState) {
|
||||
// as long as you're not doing anything actually unhinged this should always work safely
|
||||
(
|
||||
unsafe { forget_mut(self.ui_mut()) },
|
||||
HasDefaultUiState::get_mut(self),
|
||||
)
|
||||
}
|
||||
pub trait HasAppEvent {
|
||||
type Event: 'static;
|
||||
}
|
||||
|
||||
pub trait DefaultAppState: RunEvents + HasDefaultUiState {
|
||||
type Event: 'static = ();
|
||||
fn new(ui_state: DefaultUiState, proxy: Proxy<Self::Event>) -> Self;
|
||||
impl<T> HasAppEvent for T {
|
||||
type Event = ();
|
||||
}
|
||||
|
||||
pub trait HasDefaultUiState: Sized + 'static + HasAppEvent {
|
||||
fn default_state(&self) -> &DefaultUiState;
|
||||
fn default_state_mut(&mut self) -> &mut DefaultUiState;
|
||||
}
|
||||
|
||||
pub trait DefaultAppState: HasDefaultUiState {
|
||||
fn new(ui_state: DefaultUiState, rsc: &mut DefaultRsc<Self>, proxy: Proxy<Self::Event>)
|
||||
-> Self;
|
||||
#[allow(unused_variables)]
|
||||
fn event(&mut self, event: Self::Event) {}
|
||||
fn event(&mut self, event: Self::Event, rsc: &mut DefaultRsc<Self>) {}
|
||||
#[allow(unused_variables)]
|
||||
fn exit(&mut self) {}
|
||||
fn exit(&mut self, rsc: &mut DefaultRsc<Self>) {}
|
||||
#[allow(unused_variables)]
|
||||
fn window_event(&mut self, event: WindowEvent) {}
|
||||
fn window_event(&mut self, event: WindowEvent, rsc: &mut DefaultRsc<Self>) {}
|
||||
fn window_attributes() -> WindowAttributes {
|
||||
Default::default()
|
||||
}
|
||||
}
|
||||
|
||||
impl<State: DefaultAppState> AppState for State {
|
||||
pub struct DefaultRsc<State> {
|
||||
pub ui: Ui,
|
||||
pub events: EventManager<Self>,
|
||||
_state: PhantomData<State>,
|
||||
}
|
||||
|
||||
impl<State> Default for DefaultRsc<State> {
|
||||
fn default() -> Self {
|
||||
Self {
|
||||
ui: Default::default(),
|
||||
events: Default::default(),
|
||||
_state: Default::default(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<State> HasUi for DefaultRsc<State> {
|
||||
fn ui(&self) -> &Ui {
|
||||
&self.ui
|
||||
}
|
||||
|
||||
fn ui_mut(&mut self) -> &mut Ui {
|
||||
&mut self.ui
|
||||
}
|
||||
}
|
||||
|
||||
impl<State: 'static> HasEvents for DefaultRsc<State> {
|
||||
type State = State;
|
||||
|
||||
fn events(&self) -> &EventManager<Self> {
|
||||
&self.events
|
||||
}
|
||||
|
||||
fn events_mut(&mut self) -> &mut EventManager<Self> {
|
||||
&mut self.events
|
||||
}
|
||||
}
|
||||
|
||||
pub struct DefaultApp<State: DefaultAppState> {
|
||||
rsc: DefaultRsc<State>,
|
||||
state: State,
|
||||
}
|
||||
|
||||
// impl StateLike for DefaultRsc<State> {
|
||||
// }
|
||||
//
|
||||
impl<State: DefaultAppState> AppState for DefaultApp<State> {
|
||||
type Event = State::Event;
|
||||
|
||||
fn new(event_loop: &ActiveEventLoop, proxy: EventLoopProxy<Self::Event>) -> Self {
|
||||
let window = event_loop.create_window(Self::window_attributes()).unwrap();
|
||||
Self::new(DefaultUiState::new(window), proxy)
|
||||
let window = event_loop
|
||||
.create_window(State::window_attributes())
|
||||
.unwrap();
|
||||
let mut rsc = DefaultRsc::default();
|
||||
let state = State::new(DefaultUiState::new(window), &mut rsc, proxy);
|
||||
Self { rsc, state }
|
||||
}
|
||||
|
||||
fn event(&mut self, event: Self::Event, _: &ActiveEventLoop) {
|
||||
self.event(event);
|
||||
self.state.event(event, &mut self.rsc);
|
||||
}
|
||||
|
||||
fn window_event(&mut self, event: WindowEvent, event_loop: &ActiveEventLoop) {
|
||||
let events = unsafe { forget_mut(self.events_mut()) };
|
||||
let ui_state = HasDefaultUiState::get_mut(self);
|
||||
let ui_state = self.state.default_state_mut();
|
||||
let input_changed = ui_state.input.event(&event);
|
||||
let cursor_state = ui_state.cursor_state().clone();
|
||||
let old = ui_state.focus;
|
||||
@@ -104,9 +151,11 @@ impl<State: DefaultAppState> AppState for State {
|
||||
}
|
||||
if input_changed {
|
||||
let window_size = ui_state.window_size();
|
||||
self.run_sensors(&cursor_state, window_size);
|
||||
self.rsc
|
||||
.run_sensors(&mut self.state, &cursor_state, window_size);
|
||||
}
|
||||
let (mut ui, mut ui_state) = self.ui_with_state();
|
||||
let ui = &mut self.rsc.ui;
|
||||
let ui_state = self.state.default_state_mut();
|
||||
if old != ui_state.focus
|
||||
&& let Some(old) = old
|
||||
{
|
||||
@@ -115,7 +164,7 @@ impl<State: DefaultAppState> AppState for State {
|
||||
match &event {
|
||||
WindowEvent::CloseRequested => event_loop.exit(),
|
||||
WindowEvent::RedrawRequested => {
|
||||
ui.update(events);
|
||||
ui.update(&mut self.rsc.events);
|
||||
ui_state.renderer.update(ui);
|
||||
ui_state.renderer.draw();
|
||||
}
|
||||
@@ -134,13 +183,13 @@ impl<State: DefaultAppState> AppState for State {
|
||||
ui_state.window.set_ime_allowed(false);
|
||||
}
|
||||
TextInputResult::Submit => {
|
||||
self.run_event::<Submit>(sel, &mut ());
|
||||
self.rsc.run_event::<Submit>(sel, &mut (), &mut self.state);
|
||||
}
|
||||
TextInputResult::Paste => {
|
||||
if let Ok(t) = ui_state.clipboard.get_text() {
|
||||
text.insert(&t);
|
||||
}
|
||||
self.run_event::<Edited>(sel, &mut ());
|
||||
self.rsc.run_event::<Edited>(sel, &mut (), &mut self.state);
|
||||
}
|
||||
TextInputResult::Copy(text) => {
|
||||
if let Err(err) = ui_state.clipboard.set_text(text) {
|
||||
@@ -148,7 +197,7 @@ impl<State: DefaultAppState> AppState for State {
|
||||
}
|
||||
}
|
||||
TextInputResult::Used => {
|
||||
self.run_event::<Edited>(sel, &mut ());
|
||||
self.rsc.run_event::<Edited>(sel, &mut (), &mut self.state);
|
||||
}
|
||||
TextInputResult::Unused => {}
|
||||
}
|
||||
@@ -172,15 +221,15 @@ impl<State: DefaultAppState> AppState for State {
|
||||
}
|
||||
_ => (),
|
||||
}
|
||||
self.window_event(event);
|
||||
(ui, ui_state) = self.ui_with_state();
|
||||
if ui.needs_redraw() {
|
||||
self.state.window_event(event, &mut self.rsc);
|
||||
let ui_state = self.state.default_state_mut();
|
||||
if self.rsc.ui.needs_redraw() {
|
||||
ui_state.renderer.window().request_redraw();
|
||||
}
|
||||
ui_state.input.end_frame();
|
||||
}
|
||||
|
||||
fn exit(&mut self) {
|
||||
self.exit();
|
||||
self.state.exit(&mut self.rsc);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user