diff options
| author | nsfisis <nsfisis@gmail.com> | 2026-08-04 04:07:41 +0900 |
|---|---|---|
| committer | nsfisis <nsfisis@gmail.com> | 2026-08-04 05:43:24 +0900 |
| commit | 695365a0ad68e4534425c64b7a6a4b6598b68ef7 (patch) | |
| tree | a906972618f08e31012f721c717321bd08164cde /crates/shirabe/src/plugin/plugin_manager.rs | |
| parent | 261516d5ce6f8b0d69cf9e3da7dd2f0ef1cdc36a (diff) | |
| download | php-shirabe-695365a0ad68e4534425c64b7a6a4b6598b68ef7.tar.gz php-shirabe-695365a0ad68e4534425c64b7a6a4b6598b68ef7.tar.zst php-shirabe-695365a0ad68e4534425c64b7a6a4b6598b68ef7.zip | |
feat(plugin): dispatch plugin event subscribers through the RPC worker
Wires the addPlugin subscriber branch end to end: EventSubscriberInterface
and Capable become fallible and dyn-compatible (their sole implementor is
the PHP plugin proxy, which answers getSubscribedEvents over RPC), listeners
register as Callable::PhpMethod and are invoked with a per-call event handle,
and the R table now drops entries when a child-side stub destructs. The R
table keeps its IndexMap with monotonically increasing handles, so released
handles are never reused and no generation counter is needed.
Upstream has no subscriber-plugin test, so the path is covered by a
Shirabe-owned fixture exercising all three getSubscribedEvents shapes.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Diffstat (limited to 'crates/shirabe/src/plugin/plugin_manager.rs')
| -rw-r--r-- | crates/shirabe/src/plugin/plugin_manager.rs | 32 |
1 files changed, 17 insertions, 15 deletions
diff --git a/crates/shirabe/src/plugin/plugin_manager.rs b/crates/shirabe/src/plugin/plugin_manager.rs index 65c4b03f..a3810d0c 100644 --- a/crates/shirabe/src/plugin/plugin_manager.rs +++ b/crates/shirabe/src/plugin/plugin_manager.rs @@ -485,9 +485,12 @@ impl PluginManager { .into()); } let handle = self.php_runtime_new_object(&class)?; - let plugin: std::rc::Rc<std::cell::RefCell<dyn PluginInterface>> = std::rc::Rc::new( - std::cell::RefCell::new(PhpPluginProxy::new(handle.phandle, handle.class)), - ); + let plugin: std::rc::Rc<std::cell::RefCell<dyn PluginInterface>> = + std::rc::Rc::new(std::cell::RefCell::new(PhpPluginProxy::new( + handle.phandle, + handle.class, + handle.implements, + ))); self.add_plugin(plugin.clone(), is_global_plugin, Some(package.clone()))?; self.registered_plugins .entry(package.get_name().to_string()) @@ -513,7 +516,7 @@ impl PluginManager { let value = unwrap_php_result(call_function_with_dispatcher( function, args, - Some(&mut PluginRpcDispatcher), + Some(&mut PluginRpcDispatcher::default()), ))?; match value { PluginValue::Bool(value) => Ok(value), @@ -545,7 +548,7 @@ impl PluginManager { unwrap_php_result(call_function_with_dispatcher( "__shirabe_eval", vec![PluginValue::string(code)], - Some(&mut PluginRpcDispatcher), + Some(&mut PluginRpcDispatcher::default()), ))?; Ok(()) } @@ -561,7 +564,7 @@ impl PluginManager { PluginValue::string(file_identifier), PluginValue::string(file), ], - Some(&mut PluginRpcDispatcher), + Some(&mut PluginRpcDispatcher::default()), ))?; Ok(()) } @@ -571,7 +574,7 @@ impl PluginManager { let value = unwrap_php_result(shirabe_php_rpc::new_object( class, vec![], - Some(&mut PluginRpcDispatcher), + Some(&mut PluginRpcDispatcher::default()), ))?; match value { PluginValue::PhpHandle(handle) => Ok(handle), @@ -735,12 +738,12 @@ impl PluginManager { .borrow_mut() .activate(self.composer_full(), self.io.clone())?; - // TODO(plugin): if plugin is EventSubscriberInterface, hook into the event dispatcher - // The PHP code calls $this->composer->getEventDispatcher()->addSubscriber($plugin); - // — add_subscriber here is generic over `S: EventSubscriberInterface` and cannot - // accept a `&dyn EventSubscriberInterface`. Skipped until subscriber dispatch is - // implemented dynamically. - let _ = plugin.borrow().is_event_subscriber_interface(); + let plugin_ref = plugin.borrow(); + if let Some(subscriber) = plugin_ref.as_event_subscriber() { + let event_dispatcher = self.composer_full().borrow().get_event_dispatcher(); + let result = event_dispatcher.borrow_mut().add_subscriber(subscriber); + result?; + } Ok(()) } @@ -949,13 +952,12 @@ impl PluginManager { plugin: &dyn PluginInterface, capability: &str, ) -> anyhow::Result<Option<String>> { - // TODO(plugin): capability lookup let capable = match plugin.as_capable() { Some(c) => c, None => return Ok(None), }; - let capabilities = capable.get_capabilities(); + let capabilities = capable.get_capabilities()?; // PHP: !empty($capabilities[$capability]) && is_string($capabilities[$capability]) && trim($capabilities[$capability]) if let Some(s) = capabilities.get(capability) { |
