Skip to content

Commit bc457e0

Browse files
committed
making default functions a closures
1 parent 8744412 commit bc457e0

File tree

2 files changed

+67
-17
lines changed

2 files changed

+67
-17
lines changed

nannou/src/app.rs

Lines changed: 65 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -31,22 +31,74 @@ use winit;
3131
use winit::event_loop::ControlFlow;
3232

3333
/// The user function type for initialising their model.
34-
pub type ModelFn<Model> = fn(&App) -> Model;
34+
pub type ModelFn<Model> = Arc<dyn Fn(&App) -> Model>;
35+
#[macro_export]
36+
macro_rules! model {
37+
($e:expr) => {
38+
{ std::sync::Arc::new($e) }
39+
}
40+
}
41+
3542

3643
/// The user function type for updating their model in accordance with some event.
37-
pub type EventFn<Model, Event> = fn(&App, &mut Model, Event);
44+
pub type EventFn<Model, Event> = Arc<dyn Fn(&App, &mut Model, Event)>;
45+
#[macro_export]
46+
macro_rules! event {
47+
($e:expr) => {
48+
{
49+
use std::sync::Arc;
50+
Arc::new($e)
51+
}
52+
}
53+
}
3854

3955
/// The user function type for updating the user model within the application loop.
40-
pub type UpdateFn<Model> = fn(&App, &mut Model, Update);
56+
pub type UpdateFn<Model> = Arc<dyn Fn(&App, &mut Model, Update)>;
57+
#[macro_export]
58+
macro_rules! update {
59+
($e:expr) => {
60+
{
61+
use std::sync::Arc;
62+
Arc::new($e)
63+
}
64+
}
65+
}
4166

4267
/// The user function type for drawing their model to the surface of a single window.
43-
pub type ViewFn<Model> = fn(&App, &Model, Frame);
68+
pub type ViewFn<Model> = Arc<dyn Fn(&App, &Model, Frame)>;
69+
#[macro_export]
70+
macro_rules! view {
71+
($e:expr) => {
72+
{
73+
use std::sync::Arc;
74+
Arc::new($e)
75+
}
76+
}
77+
}
4478

4579
/// A shorthand version of `ViewFn` for sketches where the user does not need a model.
46-
pub type SketchViewFn = fn(&App, Frame);
80+
pub type SketchViewFn = Arc<dyn Fn(&App, Frame)>;
81+
#[macro_export]
82+
macro_rules! sketch_view {
83+
($e:expr) => {
84+
{
85+
use std::sync::Arc;
86+
Arc::new($e)
87+
}
88+
}
89+
}
4790

4891
/// The user function type allowing them to consume the `model` when the application exits.
49-
pub type ExitFn<Model> = fn(&App, Model);
92+
pub type ExitFn<Model> = Arc<dyn Fn(&App, Model)>;
93+
#[macro_export]
94+
macro_rules! exit {
95+
($e:expr) => {
96+
{
97+
use std::sync::Arc;
98+
Arc::new($e)
99+
}
100+
}
101+
}
50102

51103
/// The **App**'s view function.
52104
enum View<Model = ()> {
@@ -548,7 +600,7 @@ impl Builder<(), Event> {
548600
/// This is useful for late night hack sessions where you just don't care about all that other
549601
/// stuff, you just want to play around with some ideas or make something pretty.
550602
pub fn sketch(view: SketchViewFn) -> SketchBuilder<Event> {
551-
let mut builder = Builder::new(default_model);
603+
let mut builder = Builder::new(model!(default_model));
552604
builder.default_view = Some(View::Sketch(view));
553605
builder.create_default_window = true;
554606
SketchBuilder { builder }
@@ -1028,7 +1080,7 @@ impl EventLoopWindowTarget {
10281080
// This method is solely used during `window::Builder::build` to allow for
10291081
pub(crate) fn as_ref(&self) -> &winit::event_loop::EventLoopWindowTarget<()> {
10301082
match *self {
1031-
EventLoopWindowTarget::Owned(ref event_loop) => (&**event_loop),
1083+
EventLoopWindowTarget::Owned(ref event_loop) => &**event_loop,
10321084
EventLoopWindowTarget::Pointer(ptr) => {
10331085
// This cast is safe, assuming that the `App`'s `EventLoopWindowTarget` will only
10341086
// ever be in the `Pointer` state while the pointer is valid - that is, during the
@@ -1100,9 +1152,6 @@ fn run_loop<M, E>(
11001152
if let Some(model) = model.as_mut() {
11011153
let loop_mode = app.loop_mode();
11021154
let now = Instant::now();
1103-
let mut do_update = |loop_state: &mut LoopState| {
1104-
apply_update(&mut app, model, event_fn, update_fn, loop_state, now);
1105-
};
11061155
match loop_mode {
11071156
LoopMode::NTimes { number_of_updates }
11081157
if loop_state.total_updates >= number_of_updates as u64 => {}
@@ -1114,7 +1163,7 @@ fn run_loop<M, E>(
11141163
// LoopMode::Wait { updates_before_waiting } =>
11151164
// if loop_state.updates_since_event > updates_before_waiting as u64 => {}
11161165
_ => {
1117-
do_update(&mut loop_state);
1166+
apply_update(&mut app, model, event_fn.clone(), update_fn.clone(), &mut loop_state, now);
11181167
},
11191168
}
11201169
}
@@ -1231,13 +1280,13 @@ fn run_loop<M, E>(
12311280
(*raw_view)(&app, &model, raw_frame);
12321281
}
12331282
None => match default_view {
1234-
Some(View::Sketch(view)) => {
1283+
Some(View::Sketch(ref view)) => {
12351284
let data = frame_data.as_ref().expect("missing `frame_data`");
12361285
let frame =
12371286
Frame::new_empty(raw_frame, &data.render, &data.capture);
12381287
view(&app, frame);
12391288
}
1240-
Some(View::WithModel(view)) => {
1289+
Some(View::WithModel(ref view)) => {
12411290
let data = frame_data.as_ref().expect("missing `frame_data`");
12421291
let frame =
12431292
Frame::new_empty(raw_frame, &data.render, &data.capture);
@@ -1330,7 +1379,7 @@ fn run_loop<M, E>(
13301379

13311380
// Process the event with the user's functions and see if we need to exit.
13321381
if let Some(model) = model.as_mut() {
1333-
exit |= process_and_emit_winit_event::<M, E>(&mut app, model, event_fn, &event);
1382+
exit |= process_and_emit_winit_event::<M, E>(&mut app, model, event_fn.clone(), &event);
13341383
}
13351384

13361385
// Set the control flow based on the loop mode.
@@ -1348,7 +1397,7 @@ fn run_loop<M, E>(
13481397
// If we need to exit, call the user's function and update control flow.
13491398
if exit {
13501399
if let Some(model) = model.take() {
1351-
if let Some(exit_fn) = exit_fn {
1400+
if let Some(exit_fn) = exit_fn.clone() {
13521401
exit_fn(&app, model);
13531402
}
13541403
}

nannou_egui_demo_app/src/main.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,9 @@
11
use nannou::prelude::*;
2+
use nannou::{model, update};
23
use nannou_egui::{egui_wgpu_backend::epi::App as EguiApp, Egui};
34

45
fn main() {
5-
nannou::app(model).update(update).run();
6+
nannou::app(model!(model)).update(update!(update)).run();
67
}
78

89
struct Model {

0 commit comments

Comments
 (0)