Skip to content
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

GUI-Core Interface Proposal #14

Open
jaredoconnell opened this issue Mar 4, 2023 · 0 comments
Open

GUI-Core Interface Proposal #14

jaredoconnell opened this issue Mar 4, 2023 · 0 comments
Labels
enhancement New feature or request

Comments

@jaredoconnell
Copy link
Contributor

About

We need an interface to make the GUI and Core modular. This will be done in the form of a struct and a trait, or two traits.

Details about the traits

In either case, the traits will be implemented by structs, but a trait is technically only required one way because there is no need to make the core interface generic, assuming the GUI depends on the core. But the other way around must be generic because it will also be declared by the core, with the GUI implementing it, and passing its implementation over to the core at runtime.

The run function

It may make sense for there to be a blocking async run function. This function would be run by the GUI, and it would pass in its implementation of the GUI trait. It would be responsible for running everything. It would start some stuff automatically, including the IPC sockets.
Async because I've ran into issues caused by us mixing async and non-async code before.

Theoretically, an alternative would be a non-blocking async function, and a blocking join() or shutdown() function for when the core is shutting down.

Design choices

Enum vs Many functions

There are two ways to define the interface between the core and GUI.

  1. Every possible task has its own function in the trait
  2. Tasks are made generic with an enum. Enums in Rust can store different data for each value, so they take the place of parameters.

The interface is much simpler with the enum format because instead of a function for every task, it's just one, or one for every category of tasks. Compile time validation can be bypassed more easily with this method, by just having a default method in the match (switch). To retain compile time validation, you would just exclude the default case.

An advantage of the lack of compile time validation with the enum method is it makes it so out of date GUIs can still operate, even with reduced functionality. It's possible for the function in the trait to have a return value that states whether or not it was handled, or to return an error result. This would allow the core to know whether the GUI properly handled the task.

Callbacks vs a pair of functions

It's possible to use callbacks, but Rust is not well setup for them due to the shared ownership issues. Therefore, it's probably most beneficial to have pairs of functions/tasks. If one requests, and the other responds to that request, there will be enum values or functions for it, as opposed to passing in a callback in the original request.

About this proposal

Nothing in this is final. It's up for debate and trial and error.

@jaredoconnell jaredoconnell added the enhancement New feature or request label Mar 4, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

No branches or pull requests

1 participant