-
-
Notifications
You must be signed in to change notification settings - Fork 14
Description
Issue: Overhaul universal_plugin_system to Enable App-Specific Event/Plugin Architectures
Goal
Transform the universal_plugin_system crate into a truly generic, reusable foundation that allows any application to implement its own event-driven plugin system—matching the power, flexibility, and ergonomics of Horizon’s current event and plugin architecture, but without any Horizon-specific logic or types.
Requirements
-
No App-Specific Logic:
The crate must not contain any event types, handler signatures, or plugin logic specific to Horizon or any other app. -
Extensible Event Domains:
Support for registering and emitting events in arbitrary domains (e.g., core, client, plugin, custom), with ergonomic APIs for each, but without hardcoding any domain names. -
Type-Safe, Async Handlers:
Allow host apps to define their own event types and register async handlers with full type safety and minimal boilerplate. -
Custom Propagators:
Allow host apps to define and plug in their own event propagation strategies (e.g., local, networked, distributed), with the universal crate providing only the interfaces and hooks. -
Plugin Lifecycle & Context:
Provide a generic plugin trait (e.g.,SimplePlugin) with async handler registration and context injection, but leave the context type open for the host app to define. -
Minimal Boilerplate for Host Apps:
Host apps should only need to define their event types, propagators, and context, and wire them up using the universal system’s traits and APIs. -
Replaceability:
The universal crate should be able to replace the generic functionality in Horizon’s event and plugin system, allowing Horizon to focus only on its domain logic.
Example Usage
Host App: Defining Events, Context, and Propagators
// In the host app
use universal_plugin_system::*;
#[derive(Debug, Clone)]
pub struct MyEvent { /* ... */ }
pub struct MyContext { /* ... */ }
impl ServerContext for MyContext {}
pub struct MyPropagator;
impl<E: Event> EventPropagator<E> for MyPropagator {
fn propagate(&self, event: &E) { /* ... */ }
}Host App: Setting Up the System
let context = Arc::new(MyContext { /* ... */ });
let event_system = UniversalEventSystem::new(context.clone(), MyPropagator);
event_system.on("core", "user_login", |event: MyEvent| async move {
println!("User logged in: {:?}", event);
Ok(())
}).await?;Plugin Implementation
pub struct MyPlugin;
#[async_trait::async_trait]
impl SimplePlugin for MyPlugin {
fn name(&self) -> &str { "my_plugin" }
async fn register_handlers(
&mut self,
events: Arc<UniversalEventSystem>,
context: Arc<dyn ServerContext>
) -> Result<(), PluginError> {
events.on("client", "chat", |event: ChatEvent| async move {
context.log(LogLevel::Info, &format!("Chat: {:?}", event));
Ok(())
}).await?;
Ok(())
}
}Emitting Events
event_system.emit("core", "user_login", &MyEvent { /* ... */ }).await?;Acceptance Criteria
- Host apps can define all event types, domains, and propagators.
- Plugins can register handlers for any event type/domain.
- Plugin loading, lifecycle, and context are generic.
- No app-specific logic or types in the universal crate.
- Documentation and examples for host app and plugin authors.
- This needs to be fully capable to the point where we can implement horizons system on top of it to eliminate the built in logic in horizon for all these tasks that art not horizon specific.
Metadata
Metadata
Assignees
Labels
Type
Projects
Status