-
-
Notifications
You must be signed in to change notification settings - Fork 3.6k
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
fix: added plugin registry #13400
base: main
Are you sure you want to change the base?
fix: added plugin registry #13400
Conversation
Co-authored-by: Alice Cecile <[email protected]>
use std::any::Any; | ||
|
||
/// Plugin state in the application |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'll try to add a full example, that maybe explains also what each state purpose is. I left this part out until there's a general agreement for the PR, if that makes sense.
Self::Building => Self::Configuring, | ||
Self::Configuring => Self::Finalizing, | ||
Self::Finalizing => Self::Done, | ||
s => unreachable!("Cannot handle {:?} state", s), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is one of those cases that should really not happen, or it would be a bug in the plugin registry management. Would still an option be a better choice?
@@ -67,6 +67,8 @@ impl DynamicPluginExt for App { | |||
// SAFETY: Follows the same safety requirements as `dynamically_load_plugin`. | |||
let (lib, plugin) = unsafe { dynamically_load_plugin(path).unwrap() }; | |||
std::mem::forget(lib); // Ensure that the library is not automatically unloaded | |||
println!("here"); | |||
plugin.init(self); | |||
plugin.build(self); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think we should not call build
here.
The main idea here is that we can add plugins and sub plugins, but some of these depend on sub apps, and they might not be added by other plugins. Generally speaking,
As in the previous comments, I can tackle some of these docs (but I'd love some help 😊 ). The general idea is:
Many constraints could be enforced, like:
but all this needs extra brain activity and could be postponed.
I added these only to simplify calls inside
see below
I'm not sure 100% about this one, not for
|
There are at least these parts that I'd like to solve, but not sure how for all:
Easily doable, I'll fix this. |
Definitely leave this for future work that solves #69.
Yeah, just private free functions is fine.
Yeah, this needs more brain power.
Good, I like that design! And yeah, now that I think about it most of the current plugin building should actually be done before the event loop starts. |
Desktop and mobile builds look fine here, but the web examples are failing with this error. |
I prefer going forward with the more minimal fix in Sophya#5 for 0.14 to reduce risk and rush, so I'm taking this out of the milestone. I still want to pursue this though, but it can have more time to bake. |
#[derive(Default)] | ||
pub struct PluginRegistry { | ||
plugins: Vec<Box<dyn Plugin>>, | ||
plugin_states: HashMap<String, PluginState>, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
How do you handle non unique plugins? You don't seem to handle the case where 2 plugins have the same name but different states.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I pushed a change and some new tests to show the behavior.
Adding the fancy new |
Objective
Rewrite the plugin handling for 2 main reasons:
init
state, in which plugins can be initialized (e.g. linked), before being builtThis is a requirement to allow winit to create windows before plugins are built, which is needed by #13366 (which will unbreak Android on the latest Rust version).
TODO:
Testing
Alternatives to be defined
app.update() requires app.update_and_clean_plugins() to run, or some added plugins won't be run correctly (specifically, they won't run the build step, but only the init one). One alternative would be to change the build step in many plugins as init, but I don't have a strong opinion. I think the pre-requisite on app.update() is valid and can be enforced. Another option could be to initialize plugins inside app.update() if they are not initialized.
the initial plugin step is now init instead of build: I choose this instead of keeping build as the initial one only for naming reasons (I found it hard to list 5 different step names). Another option, that enforces a migration, could be not to use
build
at all.add_plugins should be called only inside the
init
step: this could enforce consistency and ease the creation of a dependency graph. Ideally with an easier API to return the list of sub plugins.sub apps should be created only before the finalize phase, or even better in a well-defined plugin step, to enforce validation.
accessing sub_apps should be done only inside the finalize phase.
Changelog
Migration Guide