docs(plugins): entity-class label convention; demo in template v2

- plugin-architecture.md: new "Entity class display labels (API v10)"
  section documenting the split (stable identity keys in XDATA, display
  labels in the plugin declaration), the live-loaded-plugin gating (missing,
  disabled, cap-excluded, failed, removed, or dead → bare native type), the
  "<Label> (<Native>)" display rule, that raw schema fields (`type`,
  `dxf_name`, `record_type`) and LIST are unchanged, and that the label is
  display-only. `plugin.toml` deliberately does not carry the table: it is
  the pre-load discovery file and labels must activate on live manifests.
- Template v2 demonstrates the whole convention: declares
  `SURVEY-CLASS:POINT -> "Survey Point"` and stamps the identity key in
  MARK_FIRST_SURVEY_POINT, so marked points show as "Survey Point (Point)"
  while the plugin is loaded. plugin.toml's api_version is bumped to 10 (keep
  in sync with ApiVersion::CURRENT) with a NOTE on where the class table
  lives. DESIGN.md documents the flow.
- Template v2's stale `acadrust` pin (8a28c21, predating the host's codec
  bump to 278c49a) is realigned with the host's pin: without it the template
  no longer compiles on main — its `acadrust::EntityType` and the host
  re-exports are distinct types when the revisions disagree (verified the
  same four type errors occur before and after this feature's template edit).
- changelogs/unreleased.md entry (Plugins section).
This commit is contained in:
Sebastian committed 2026-10-15 22:39:09 +02:00
1 parent ab3e0723fd
commit be675f2824
6 files changed
+110 -4

No files matched your search

+24 -1
View File
@@ -8,7 +8,7 @@ use acadrust::xdata::{ExtendedDataRecord, XDataValue};
use acadrust::{EntityType, Handle};
use ocs_plugin_api::export_plugin;
use ocs_plugin_api::host::{BuiltinPlugin, HostApi, ReaderEntityKind};
use ocs_plugin_api::manifest::{ApiVersion, PluginManifest};
use ocs_plugin_api::manifest::{ApiVersion, EntityClasses, PluginManifest};
use ocs_plugin_api::ribbon::{CadModule, IconKind, ModuleEvent, RibbonGroup, RibbonItem, ToolDef};
static MANIFEST: PluginManifest = PluginManifest {
@@ -27,6 +27,18 @@ static MANIFEST: PluginManifest = PluginManifest {
],
};
/// Entity-class display labels (API v10): entities carrying a
/// `SURVEY-CLASS:<key>` string in their SURVEYMARK XDATA display the mapped
/// label (e.g. "Survey Point (Point)") in the host's Properties panel and
/// `display_type` — *while this plugin is loaded*. The key is the only thing
/// stored in the drawing; the label text lives here, so it can be reworded or
/// localized without rewriting drawings.
static ENTITY_CLASSES: EntityClasses = EntityClasses {
app_id: "SURVEYMARK",
class_prefix: "SURVEY-CLASS:",
labels: &[("POINT", "Survey Point")],
};
struct PluginTemplateV2;
impl BuiltinPlugin for PluginTemplateV2 {
@@ -34,6 +46,12 @@ impl BuiltinPlugin for PluginTemplateV2 {
&MANIFEST
}
// API v10: expose the entity-class labels declared above. The default
// (not overriding this) declares none.
fn entity_classes(&self) -> Option<&'static EntityClasses> {
Some(&ENTITY_CLASSES)
}
fn ribbon(&self) -> Box<dyn CadModule> {
Box::new(TemplateModule)
}
@@ -106,6 +124,11 @@ fn first_survey_point_handle(host: &mut dyn HostApi) -> Option<Handle> {
fn mark_point(host: &mut dyn HostApi, handle: Handle) {
let mut record = ExtendedDataRecord::new("SURVEYMARK");
record.add_value(XDataValue::Integer32(1));
// Class-identity key for the entity-class labels declared above: the
// host shows marked points as "Survey Point (Point)" while this plugin is
// loaded, and as plain "Point" when it is not. Keys are stable identity —
// display text never goes into the drawing.
record.add_value(XDataValue::String("SURVEY-CLASS:POINT".to_string()));
if host.write_record(handle, record) {
host.push_info(&format!("Marked SURVEY point {handle}"));
} else {