You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
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.
Every possible task has its own function in the trait
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.
The text was updated successfully, but these errors were encountered:
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.
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.
The text was updated successfully, but these errors were encountered: