pub struct App<AppData, O: FnPersist2<AppData, ScopeID<'static>, HashMap<Arc<SourceID>, Option<Window>>>> {
pub instance: Instance,
pub driver: Weak<Driver>,
pub state: StateManager,
/* private fields */
}
Expand description
Represents a feather application with a given AppData
and persistent outline function O
.
The outline function must always be a persistent function that takes two parameters, a copy
of the AppData, and a ScopeID. It must always return [OutlineReturn
].
An App creates all the top level structures needed for Feather to function. It stores all
wgpu, winit, and any other global state needed. See App::new
for examples.
Fields§
§instance: Instance
§driver: Weak<Driver>
§state: StateManager
Implementations§
Source§impl<AppData: Clone + PartialEq + 'static, O: FnPersist2<AppData, ScopeID<'static>, HashMap<Arc<SourceID>, Option<Window>>>> App<AppData, O>
impl<AppData: Clone + PartialEq + 'static, O: FnPersist2<AppData, ScopeID<'static>, HashMap<Arc<SourceID>, Option<Window>>>> App<AppData, O>
Sourcepub fn new<T: 'static>(
app_state: AppData,
inputs: Vec<AppEvent<AppData>>,
outline: O,
driver_init: impl FnOnce(Weak<Driver>) + 'static,
) -> Result<(Self, EventLoop<T>, Sender<EventPair<AppData>>, AtomicU64)>
pub fn new<T: 'static>( app_state: AppData, inputs: Vec<AppEvent<AppData>>, outline: O, driver_init: impl FnOnce(Weak<Driver>) + 'static, ) -> Result<(Self, EventLoop<T>, Sender<EventPair<AppData>>, AtomicU64)>
Creates a new feather application. app_state
represents the initial state of the application, and
will override any value returned by <O as FnPersist2>::init()
. inputs
must be an array of
AppEvent
, which can be acquired by boxing and wrapping lambdas using WrapEventEx
. The outline
must by a persistent function that takes two arguments (and implements FnPersist2
): a copy
of the AppData, and a ScopeID. It must always return [OutlineReturn
].
driver_init
is an optional hook used to enable hotloading of resources. For most basic applications,
it can be set to the empty lambda: |_| ()
.
This function returns 4 values - the App
object itself, the EventLoop
that you must call
EventLoop::run_app
on to actually start the application, a channel for sending dynamic AppEvent
handlers, and an atomic integer representing the current dynamic slot for any additional events. If
your handlers are not going to change after the app has been created, you can ignore the last 2 returns.
§Examples
use feather_ui::component::window::Window;
use feather_ui::persist::{ FnPersist2, FnPersistStore };
use feather_ui::{ SourceID, ScopeID, App };
use std::sync::Arc;
#[derive(Clone, PartialEq)]
struct MyState {
count: i32
}
struct MyApp {}
impl FnPersistStore for MyApp { type Store = (); }
impl FnPersist2<MyState, ScopeID<'_>, im::HashMap<Arc<SourceID>, Option<Window>>> for MyApp {
fn init(&self) -> Self::Store { () }
fn call(&mut self, _: Self::Store, _: MyState, _: ScopeID<'_>) -> (Self::Store, im::HashMap<Arc<SourceID>, Option<Window>>) {
((), im::HashMap::new())
}
}
let (mut app, event_loop, _, _) = App::<MyState, MyApp>::new::<()>(MyState { count: 0 }, Vec::new(), MyApp {}, |_| ()).unwrap();
// You would then run the app like so (commented out because docs can't test UIs)
// event_loop.run_app(&mut app).unwrap();
Examples found in repository?
More examples
178fn main() {
179 let (mut app, event_loop, _, _) = App::<Blocker, BasicApp>::new::<()>(
180 Blocker {
181 area: AbsRect::new(-1.0, -1.0, -1.0, -1.0),
182 },
183 vec![],
184 BasicApp {},
185 |_| (),
186 )
187 .unwrap();
188
189 event_loop.run_app(&mut app).unwrap();
190}
119fn main() {
120 let (mut app, event_loop, _, _) = App::<TextState, BasicApp>::new::<()>(
121 TextState {
122 text: EditBuffer::new("new text", (0, 0)).into(),
123 },
124 vec![],
125 BasicApp {},
126 |_| (),
127 )
128 .unwrap();
129
130 event_loop.run_app(&mut app).unwrap();
131}
236fn main() {
237 let onclick = Box::new(
238 |_: mouse_area::MouseAreaEvent,
239 mut appdata: feather_ui::AccessCell<CounterState>|
240 -> InputResult<()> {
241 {
242 appdata.count += 1;
243 InputResult::Consume(())
244 }
245 }
246 .wrap(),
247 );
248
249 let (mut app, event_loop, _, _) = App::<CounterState, BasicApp>::new::<()>(
250 CounterState { count: 0 },
251 vec![onclick],
252 BasicApp {},
253 |_| (),
254 )
255 .unwrap();
256
257 event_loop.run_app(&mut app).unwrap();
258}
308fn main() {
309 let onclick = Box::new(
310 |_: mouse_area::MouseAreaEvent,
311 mut appdata: feather_ui::AccessCell<CounterState>|
312 -> InputResult<()> {
313 {
314 appdata.count += 1;
315 InputResult::Consume(())
316 }
317 }
318 .wrap(),
319 );
320
321 let (mut app, event_loop, _, _) = App::<CounterState, BasicApp>::new::<()>(
322 CounterState { count: 0 },
323 vec![onclick],
324 BasicApp {},
325 |_| (),
326 )
327 .unwrap();
328
329 event_loop.run_app(&mut app).unwrap();
330}
185fn main() {
186 let onclick = Box::new(
187 |_: mouse_area::MouseAreaEvent,
188 mut appdata: feather_ui::AccessCell<CounterState>|
189 -> feather_ui::InputResult<()> {
190 {
191 appdata.count += 1;
192 feather_ui::InputResult::Consume(())
193 }
194 }
195 .wrap(),
196 );
197
198 let (mut app, event_loop, _, _) = App::<CounterState, BasicApp>::new::<()>(
199 CounterState { count: 0 },
200 vec![onclick],
201 BasicApp {},
202 |_| (),
203 )
204 .unwrap();
205
206 event_loop.run_app(&mut app).unwrap();
207}
Sourcepub fn new_any_thread<T: 'static>(
app_state: AppData,
inputs: Vec<AppEvent<AppData>>,
outline: O,
any_thread: bool,
driver_init: impl FnOnce(Weak<Driver>) + 'static,
) -> Result<(Self, EventLoop<T>, Sender<EventPair<AppData>>, AtomicU64)>
pub fn new_any_thread<T: 'static>( app_state: AppData, inputs: Vec<AppEvent<AppData>>, outline: O, any_thread: bool, driver_init: impl FnOnce(Weak<Driver>) + 'static, ) -> Result<(Self, EventLoop<T>, Sender<EventPair<AppData>>, AtomicU64)>
This is the same as App::new
, but it allows overriding the main thread detection that winit uses. This is necessary
for running tests, which don’t run on the main thread.
Trait Implementations§
Source§impl<AppData: Clone + PartialEq + 'static, T: 'static, O: FnPersist2<AppData, ScopeID<'static>, HashMap<Arc<SourceID>, Option<Window>>>> ApplicationHandler<T> for App<AppData, O>
impl<AppData: Clone + PartialEq + 'static, T: 'static, O: FnPersist2<AppData, ScopeID<'static>, HashMap<Arc<SourceID>, Option<Window>>>> ApplicationHandler<T> for App<AppData, O>
Source§fn resumed(&mut self, event_loop: &ActiveEventLoop)
fn resumed(&mut self, event_loop: &ActiveEventLoop)
Source§fn window_event(
&mut self,
event_loop: &ActiveEventLoop,
window_id: WindowId,
event: WindowEvent,
)
fn window_event( &mut self, event_loop: &ActiveEventLoop, window_id: WindowId, event: WindowEvent, )
Source§fn device_event(
&mut self,
event_loop: &ActiveEventLoop,
device_id: DeviceId,
event: DeviceEvent,
)
fn device_event( &mut self, event_loop: &ActiveEventLoop, device_id: DeviceId, event: DeviceEvent, )
Source§fn user_event(&mut self, event_loop: &ActiveEventLoop, _: T)
fn user_event(&mut self, event_loop: &ActiveEventLoop, _: T)
EventLoopProxy::send_event
.Source§fn suspended(&mut self, event_loop: &ActiveEventLoop)
fn suspended(&mut self, event_loop: &ActiveEventLoop)
Source§fn new_events(&mut self, event_loop: &ActiveEventLoop, cause: StartCause)
fn new_events(&mut self, event_loop: &ActiveEventLoop, cause: StartCause)
Source§fn about_to_wait(&mut self, event_loop: &ActiveEventLoop)
fn about_to_wait(&mut self, event_loop: &ActiveEventLoop)
Source§fn exiting(&mut self, event_loop: &ActiveEventLoop)
fn exiting(&mut self, event_loop: &ActiveEventLoop)
Source§fn memory_warning(&mut self, event_loop: &ActiveEventLoop)
fn memory_warning(&mut self, event_loop: &ActiveEventLoop)
Auto Trait Implementations§
impl<AppData, O> Freeze for App<AppData, O>
impl<AppData, O> !RefUnwindSafe for App<AppData, O>
impl<AppData, O> !Send for App<AppData, O>
impl<AppData, O> !Sync for App<AppData, O>
impl<AppData, O> Unpin for App<AppData, O>
impl<AppData, O> !UnwindSafe for App<AppData, O>
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
Source§impl<T> Downcast for Twhere
T: Any,
impl<T> Downcast for Twhere
T: Any,
Source§fn into_any(self: Box<T>) -> Box<dyn Any>
fn into_any(self: Box<T>) -> Box<dyn Any>
Box<dyn Trait>
(where Trait: Downcast
) to Box<dyn Any>
. Box<dyn Any>
can
then be further downcast
into Box<ConcreteType>
where ConcreteType
implements Trait
.Source§fn into_any_rc(self: Rc<T>) -> Rc<dyn Any>
fn into_any_rc(self: Rc<T>) -> Rc<dyn Any>
Rc<Trait>
(where Trait: Downcast
) to Rc<Any>
. Rc<Any>
can then be
further downcast
into Rc<ConcreteType>
where ConcreteType
implements Trait
.Source§fn as_any(&self) -> &(dyn Any + 'static)
fn as_any(&self) -> &(dyn Any + 'static)
&Trait
(where Trait: Downcast
) to &Any
. This is needed since Rust cannot
generate &Any
’s vtable from &Trait
’s.Source§fn as_any_mut(&mut self) -> &mut (dyn Any + 'static)
fn as_any_mut(&mut self) -> &mut (dyn Any + 'static)
&mut Trait
(where Trait: Downcast
) to &Any
. This is needed since Rust cannot
generate &mut Any
’s vtable from &mut Trait
’s.Source§impl<T> Instrument for T
impl<T> Instrument for T
Source§fn instrument(self, span: Span) -> Instrumented<Self>
fn instrument(self, span: Span) -> Instrumented<Self>
Source§fn in_current_span(self) -> Instrumented<Self>
fn in_current_span(self) -> Instrumented<Self>
Source§impl<T> IntoEither for T
impl<T> IntoEither for T
Source§fn into_either(self, into_left: bool) -> Either<Self, Self>
fn into_either(self, into_left: bool) -> Either<Self, Self>
self
into a Left
variant of Either<Self, Self>
if into_left
is true
.
Converts self
into a Right
variant of Either<Self, Self>
otherwise. Read moreSource§fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
self
into a Left
variant of Either<Self, Self>
if into_left(&self)
returns true
.
Converts self
into a Right
variant of Either<Self, Self>
otherwise. Read more