refactor(scene): reference-only designation becomes a scene-scoped set (API v9)

Per the upstream review of the XDATA-based storage: the host no longer writes
its own state into the saved file. The marker record under the host-owned OCS
APPID, the on-first-use APPID registration and the verbatim-EED rewrite
handling are removed; the single source of truth is a scene-scoped in-memory
set of entity handles (Scene::reference_only) that dies with the drawing tab,
so a reopened file starts undesignated and the owning plugin re-marks on the
document-opened notification.

All behaviour sites are unchanged, driven by the set: the wire stamp moves
from an XDATA read to a set lookup threaded through the tessellation
pipelines (tessellate_entity and the dimension text path take the handle set
as a plain parameter), and the pick filters, selection retains and
update/erase refusals read Scene::is_reference_only.

Undo keeps the entity-write contract: set mutations are recorded as explicit
first-touch before/after values on each history delta (the parametric-
constraints channel pattern). A designation inside a plugin push_undo scope
joins it, a scope-less change is one step of its own, an idempotent re-mark
records nothing, erasing a designated entity drops the set entry with the
entity, and undo/redo restores entity and designation together.

The round-trip test is inverted: reference_only_designation_is_not_written_
to_dwg_or_dxf now asserts the marker appears in neither format's bytes, that
no OCS APPID or marker record survives a reload, and that the designation
stays live in memory.
This commit is contained in:
Sebastian committed 2026-10-14 21:12:17 +02:00
1 parent 06ee0798a8
commit 50db12b169
17 files changed
+623 -232

No files matched your search

+12 -3
View File
@@ -1189,12 +1189,21 @@ pub trait HostApi {
/// plugin keeps full write access through this API: `update_entity`,
/// [`update_entities_transaction`](HostApi::update_entities_transaction),
/// `remove_entity` and the XDATA record methods keep working, so derived
/// display geometry can be refreshed in place. The designation survives
/// DWG/DXF save and reload.
/// display geometry can be refreshed in place.
///
/// The designation is a scene-scoped, in-memory set keyed by entity
/// handle: it is not written to the saved DWG/DXF (the host stores no
/// state of its own in the file), it lives and dies with the drawing tab,
/// and a reloaded drawing starts undesignated — the owning plugin
/// re-marks its entities when the document opens, which makes the
/// in-memory designation fully equivalent to a persisted one for its use
/// case.
///
/// Fails when the entity does not exist or is on a locked layer (the same
/// policy as the XDATA record methods). A call that would not change the
/// current designation succeeds without recording an undo step.
/// current designation succeeds without recording an undo step — and
/// without publishing a document change, so idempotent re-marks cannot
/// loop with the notification dispatch.
///
/// Undo composition — the entity-write contract: a change performed
/// inside a plugin-opened [`HostApi::push_undo`] scope joins that scope,