feat(plugin): emit SelectionChangedV4 to V4 plugins and add ocs_plugin_api architecture docs

- Add HostNotification::SelectionChangedV4 { tab_id, handles } with discriminant 7
- Broadcast active-tab selection changes at update() and automation_op boundaries
- Use stable order-independent signature to avoid spurious hover notifications
- Clear Scene selection in automation new/open to avoid stale handles
- Add crates/ocs_plugin_api/ARCHITECTURE.md and module-level rustdoc
- Cross-link README.md and docs/plugin-architecture.md
- Fix test env race with shared ENV_LOCK and EnvVarGuard helpers
This commit is contained in:
Sebastian committed 2026-08-25 23:31:27 +02:00
1 parent f4a292a6b2
commit f20bf93dfe
25 files changed
+592 -17

No files matched your search

+1 -3
View File
@@ -761,7 +761,6 @@ impl DocumentReader for EmptyDocumentReader {
#[cfg(all(test, feature = "host"))]
mod tests {
use std::sync::atomic::{AtomicU64, Ordering};
use std::sync::Mutex as StdMutex;
use std::thread;
use interprocess::local_socket::{
@@ -772,10 +771,9 @@ mod tests {
use super::*;
use crate::ipc::transport::recv;
use crate::ipc::v4::protocol::{HostToPluginV4, PluginToHostV4};
use crate::test_lock::ENV_LOCK;
use acadrust::entities::Point;
static ENV_LOCK: StdMutex<()> = StdMutex::new(());
fn unique_socket_name() -> String {
static COUNTER: AtomicU64 = AtomicU64::new(0);
let n = COUNTER.fetch_add(1, Ordering::Relaxed);
+9
View File
@@ -4,6 +4,15 @@
//! requests, responses, and best-effort notifications over a single local
//! socket. The V3 files (`src/ipc/{protocol,client,server}.rs`) are left
//! untouched; all V4 logic lives in this module.
//!
//! Submodules:
//!
//! - [`protocol`](crate::ipc::v4::protocol) — V4 wire frames, notification
//! envelopes, and correlation ids.
//! - [`client`](crate::ipc::v4::client) — plugin-side V4 client loop and
//! notification dispatch.
//! - [`server`](crate::ipc::v4::server) — host-side V4 connection and reader
//! thread.
pub mod client;
pub mod protocol;
@@ -1,4 +1,23 @@
//! V4 wire frames and envelope types.
//!
//! V4 replaces the simple request/response pipe with a multiplexed frame layer.
//! Every request and response carries a monotonically increasing correlation
//! `id` so a plugin can send/receive out of order. Notifications carry an
//! optional `command_id` so a plugin can associate a host notification with the
//! long-running command that caused it.
//!
//! The two frame enums are:
//!
//! - [`HostToPluginV4`] — host → runner requests, responses to runner requests,
//! and host notifications.
//! - [`PluginToHostV4`] — runner → host requests, responses to host requests,
//! and plugin notifications.
//!
//! Notifications are wrapped in [`NotificationEnvelope`] and are best-effort:
//! a process that fails to accept a notification is logged and skipped, but the
//! connection stays alive. Unknown host-notification discriminants deserialize
//! to [`crate::host::HostNotification::Unknown`] so newer host notifications do
//! not break older plugins.
use serde::{Deserialize, Serialize};