-
-
Notifications
You must be signed in to change notification settings - Fork 306
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Make nannou::app
receive a closure.
#793
Comments
Hi Alex, I had a similar problem to you. What I did is I used the I think your suggestion is probably the right thing to do. I had a similar problem with the |
Ooh, I haven't thought of that, I will try it out, thank you! |
Hi, has there been any updates on this issue? I think i stumbled over a similar problem, but please correct me if I'm wrong. I'd like to use some data inside the impl Renderer {
pub fn preview(&mut self) {
nannou::app(self.model())
.update(Renderer::update)
.simple_window(Renderer::view)
.run();
}
fn model(&self) -> fn(app: &nannou::App) -> Animation {
move |app: &nannou::App| self.animation
}
} But as |
use my fork until then https://github.com/i-think-rapido/nannou/tree/feature/tr/functions-as-closures |
+1 - it's really a pity that one has to use global state when closures would have been enough. This is the relevant type they're using: https://github.com/nannou-org/nannou/blob/c8ac92d6c59b6dbd78bb903207a9c20013f7b7d1/nannou/src/app.rs#L35C1-L35C45 In case this helps anyone, I think there's another (somewhat hacky) way of dealing with this that doesn't without require a lazy static or other global workarounds. While impl Model {
fn new(python_file: PathBuf, some_dir: PathBuf) -> Self {
Self {
primitives: Vec::with_capacity(100),
files_checksums: HashMap::new(),
python_code: String::new(),
python_file,
some_dir,
}
}
}
fn main() -> color_eyre::Result<()> {
// This will block until args are parsed
// This is an 'hack' to go around a limitation of the nannou API,
// which require function pointers instead of closures
Cli::parse();
let model = move |_app: &App| {
// Here we actually get the CLI args and we return the model
let cli = Cli::parse();
let (sketch_file, some_dir) = match cli.command {
cli::SubCommands::Run {
sketch_file,
some_dir,
} => (sketch_file, some_dir),
};
let cwd = std::env::current_dir().expect("Failed to get current working directory");
let sketch_file = cwd.join(
sketch_file
.canonicalize()
.expect("Failed to canonicalize path"),
);
let some_dir = cwd.join(
some_dir
.canonicalize()
.expect("Failed to canonicalize path"),
);
Model::new(sketch_file, some_dir)
};
// App loop
nannou::app(model).update(update).simple_window(view).run();
Ok(())
} That's because closures that don't actually capture anything from the environment can be coerced to function pointers: https://rust-lang.github.io/rfcs/1558-closure-to-fn-coercion.html EDIT: That being said, this^ hack only works for people that require parsing CLI args. fn main() -> color_eyre::Result<()> {
// This will block until args are parsed
// This is an 'hack' to go around a limitation of the nannou API,
// which require function pointers instead of closures
crate::cli::Cli::parse();
// App loop
nannou::app(model).update(update).simple_window(view).run();
Ok(())
}
fn model(_app: &App) -> Model {
// Get the cli args and create the nannou Model
let cli = Cli::parse();
let (sketch_file, improvviso_dir) = match cli.command {
cli::SubCommands::Run {
sketch_file,
some_dir,
} => (sketch_file, some_dir),
};
// same stuff..
Model::new(sketch_file, some_dir)
} |
Currently,
nannou::app
and, in general, theapp::Builder
API expect an argument of typefn
, but it would be nice to be able to pass a closure instead.My use case is that I'm writing a CLI wrapper to speed up my workflow, and I need to close over the environment in
model
,update
, andview
, but I can't because they have to be of typefn
.I think this wouldn't be a breaking change because you can pass a function in a place where a closure is expected, but not the other way around. However, there may be some nuance I am not aware of.
The text was updated successfully, but these errors were encountered: