forked from 1b-agent/opencadstudio-upstream
feat(plugin-api): entity-class display declarations on the manifest (API v10)
Plugins can now declare the entity classes they identify via XDATA, and the
host resolves them to display-only type labels while the declaring plugin is
loaded.
- Append `BuiltinPlugin::entity_classes()` (a guarded trailing vtable slot,
the same additive pattern as `on_load` in v5) returning a &'static
`EntityClasses { app_id, class_prefix, labels }`. The static
`PluginManifest` struct is deliberately untouched: older cdylibs share it
by pointer and its layout is frozen ABI since v1, so adding a field would
read past their allocation.
- `OwnedEntityClasses` travels on the registered manifest as
`OwnedPluginManifest.entity_classes` with `#[serde(default)]`, so manifests
serialized before the field keep decoding (older runners tolerate it
both ways).
- The runner folds the declaration into the GetManifest registration only
when the loaded cdylib's exported `ocs_plugin_api_version` symbol reports
>= 10 — an older binary's vtable predates the slot, so it is never called;
its entities simply keep their native type names.
- `PluginManager::entity_class_declarations` exposes the live set, filtered
to alive, non-disabled plugins in load order. The registered manifests are
the only source and nothing is cached: not installed, disabled,
cap-excluded (`OCS_PLUGIN_MAX_API_VERSION`), failed at load, removed, or a
dead process all contribute nothing.
- Embedded version info `api_version` follows the bump to 10;
`API_VERSION_MIN_SUPPORTED` stays 3.
Tests: runner fold (v10 folds, pre-v10 skipped, `entity_classes()` panic is
contained and reported), manager filtering (disabled / dead / undeclaring
skipped; declarations disappear once the process dies — verified with a real
killed child), bincode registration round-trip, and older-manifest serde
default.
This commit is contained in:
1 parent
859070403c
commit
60eb7b086e
9 files changed
+502
-13
No files matched your search
@@ -123,6 +123,18 @@ fn collect_item_command_ids(item: &OwnedRibbonItem, out: &mut Vec<String>) {
|
||||
}
|
||||
}
|
||||
|
||||
/// Owned mirror of [`crate::manifest::EntityClasses`]: the entity-class
|
||||
/// declaration as it travels on the registered manifest across the IPC wire.
|
||||
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
|
||||
pub struct OwnedEntityClasses {
|
||||
/// XDATA application name whose records carry the class-identity keys.
|
||||
pub app_id: String,
|
||||
/// Prefix that marks a string XDATA value as a class-identity key.
|
||||
pub class_prefix: String,
|
||||
/// Class key → display label.
|
||||
pub labels: std::collections::BTreeMap<String, String>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||
pub struct OwnedPluginManifest {
|
||||
pub id: String,
|
||||
@@ -133,6 +145,11 @@ pub struct OwnedPluginManifest {
|
||||
pub ribbon_order: i32,
|
||||
pub xdata_apps: Vec<String>,
|
||||
pub command_prefixes: Vec<String>,
|
||||
/// Entity-class display declarations (API v10), folded in by the runner
|
||||
/// for plugins that declare them. `#[serde(default)]` keeps manifests
|
||||
/// serialized before the field existed decoding as `None`.
|
||||
#[serde(default)]
|
||||
pub entity_classes: Option<OwnedEntityClasses>,
|
||||
}
|
||||
|
||||
impl From<IconKind> for OwnedIconKind {
|
||||
|
||||
Reference in new issue
Block a user