WIP: Open and save assemblies #165

Draft
Vectornaut wants to merge 13 commits from Vectornaut/dyna3:open-save into main
Member

Summary

This pull request enables dyna3 to open assemblies from and save assemblies to files, resolving to-do issue #164.

Changes

Primary

  • Add the following actions:
    • Open an assembly from a local file.
    • Open an assembly from a URL.
    • Create a new assembly.
  • Add an open/save interface component that affords the following capabilities:
    • Save an assembly to a local file.
    • Open an assembly from a local file.
    • Open an example assembly.
    • Create a new assembly.
  • Open the example assemblies from files on the server instead of using hard-coded loading scripts. Keep the example assembly files in sync when packaging dyna3 for deployment.

Supporting

  • Encapsulate the code that clears the workspace in the new clear method of AppState.
  • Automatically generate loading scripts using the new export method of Assembly.
    • Enable elements and regulators to generate their own loading script statements using the new declaration methods of Element and Regulator and the new representation_assignment method of Element. These methods' blanket implementations work for all the elements and regulators we have so far.
  • Upgrade js-sys to a version where js_sys::Promise implements IntoFuture, allowing the JavaScript promise system to be more seamlessly reflected in Rust code.
  • Revamp the sidebar
    • Make the sidebar styling code simpler and more consistent, facilitating the addition of the open/save component.
    • Take the hover highlighting from the new example chooser component and apply it to the existing outline component.

Notes

  • For readability, the example assembly files are hand-written rather than automatically generated. As a result, many of them don't match the files you get when you open and then save the example assemblies.
  • Since we're upgrading js-sys anyway, we might as well go to the latest version.
## Summary This pull request enables dyna3 to open assemblies from and save assemblies to files, resolving to-do issue #164. ## Changes ### Primary - Add the following actions: - Open an assembly from a local file. - Open an assembly from a URL. - Create a new assembly. - Add an open/save interface component that affords the following capabilities: - Save an assembly to a local file. - Open an assembly from a local file. - Open an example assembly. - Create a new assembly. - Open the example assemblies from files on the server instead of using hard-coded loading scripts. Keep the example assembly files in sync when packaging dyna3 for deployment. ### Supporting - Encapsulate the code that clears the workspace in the new `clear` method of `AppState`. - Automatically generate loading scripts using the new `export` method of `Assembly`. - Enable elements and regulators to generate their own loading script statements using the new `declaration` methods of `Element` and `Regulator` and the new `representation_assignment` method of `Element`. These methods' blanket implementations work for all the elements and regulators we have so far. - Upgrade `js-sys` to a version where `js_sys::Promise` implements `IntoFuture`, allowing the JavaScript promise system to be [more seamlessly reflected](https://wasm-bindgen.github.io/wasm-bindgen/reference/js-promises-and-rust-futures.html#awaiting-a-promise-directly) in Rust code. - Revamp the sidebar - Make the sidebar styling code simpler and more consistent, facilitating the addition of the open/save component. - Take the hover highlighting from the new example chooser component and apply it to the existing outline component. ## Notes - For readability, the example assembly files are hand-written rather than automatically generated. As a result, many of them don't match the files you get when you open and then save the example assemblies. - Since we're upgrading `js-sys` anyway, we might as well go to the latest version.
To show that the action works, connect it to a file input on a new
open/save toolbar.
We should be able to get similar behavior more easily by using the
file input as the drop area.
To show that the action works, connect it to an example chooser in the
open/save component.
We should eventually turn this into an action, but that will take some
creative thinking about where to stash the download link. Giving the
save button ownership of the download link feels natural for now.
Sync the examples when packaging for deployment
All checks were successful
/ test (pull_request) Successful in 4m26s
112777fca7
In the process, make the tests for the presence of old hash-named files
more robust. These tests should now work when the filename patterns
match multiple files.

Also, tell `git` to ignore the packaged examples.
Bump js-sys to the latest version
All checks were successful
/ test (pull_request) Successful in 4m23s
97f9685d8d
A few new releases of `js-sys` have come out since we started working on
opening and saving assemblies!
Author
Member

This pull request is ready for @glen to review! I've marked it as a work in progress because it needs one last change before merging: removing the old example chooser. This component has been left in during review so we can more easily spot differences in behavior with the new example chooser, which opens the example assemblies from files on the server instead of from hard-coded loading scripts.

This pull request is ready for @glen to review! I've marked it as a work in progress because it needs one last change before merging: removing the old example chooser. This component has been left in during review so we can more easily spot differences in behavior with the new example chooser, which opens the example assemblies from files on the server instead of from hard-coded loading scripts.
@ -23,4 +22,3 @@
# the derive macro for the `Named` trait is defined in this internal crate
derive-named = { path = "derive-named" }
# We use Charming to help display engine diagnostics
Owner

I personally don't think it's worth an additional line of diff just to chase the first letter of a comment from uppercase to lowercase, especially when uppercase looks perfectly normal in the existing comment.

I personally don't think it's worth an additional line of diff just to chase the first letter of a comment from uppercase to lowercase, especially when uppercase looks perfectly normal in the existing comment.
@ -80,0 +83,4 @@
fn clear(&self) {
// clear the assembly
let assembly = &self.assembly;
Owner

Isn't this code mis-modularized? In other words, shouldn't either (a) the assembly know how to clear itself, or (b) the state discard the current assembly and replace it with a fresh empty one? I would not expect to see code implementing how an assembly would clear itself in the implementation of a structure that contains an assembly...

Isn't this code mis-modularized? In other words, shouldn't either (a) the assembly know how to clear itself, or (b) the state discard the current assembly and replace it with a fresh empty one? I would not expect to see code implementing how an assembly would clear itself in the implementation of a structure that _contains_ an assembly...
Author
Member

Good call: refactored in commit 1a004ce. Right now, discarding and replacing the assembly would require mutating the app state, which is why I'm clearing the assembly instead. We should revisit the idea of discarding and replacing, though, If we ever redesign the app state to give the assembly field interior mutability—for example, by making it an assembly-valued signal.

Good call: refactored in commit 1a004ce. Right now, discarding and replacing the assembly would require mutating the app state, which is why I'm clearing the assembly instead. We should revisit the idea of discarding and replacing, though, If we ever redesign the app state to give the assembly field interior mutability—for example, by making it an assembly-valued signal.
Owner

Feel free to also go ahead with finalizing the PR for merging. Thanks.

Feel free to also go ahead with finalizing the PR for merging. Thanks.
Owner

It is also helpful (going forward) to put notations like

Resolves #164.

in the PR description, one issue that the PR will (purportedly) resolve per line. Then they show up in the suggested commit message when one does a squash commit; and if they are in the commit message, then Gitea autocloses the corresponding issue upon merge to main.

It is also helpful (going forward) to put notations like Resolves #164. in the PR description, one issue that the PR will (purportedly) resolve per line. Then they show up in the suggested commit message when one does a squash commit; and if they are in the commit message, then Gitea autocloses the corresponding issue upon merge to main.
Let the assembly clear itself
All checks were successful
/ test (pull_request) Successful in 4m28s
1a004cebd0
All checks were successful
/ test (pull_request) Successful in 4m28s
Required
Details
This pull request is marked as a work in progress.
View command line instructions

Checkout

From your project repository, check out a new branch and test the changes.
git fetch -u open-save:Vectornaut-open-save
git switch Vectornaut-open-save
Sign in to join this conversation.
No description provided.