forked from 1b-agent/opencadstudio-upstream
feat(plugin): name-addressed XRecord CRUD on the HostApi (API v8)
Add create/read/update/delete/list for XRecord objects under named-object-dictionary paths to the plugin HostApi, with five additive PluginRequest/PluginResponse variants, dispatch through the shared handler, in-process HostSession methods and both out-of-process proxies. - dictionary paths walk from the NOD root; create seeds missing dictionaries (ensure_image_dictionary bootstrap) and refuses existing names; update refuses missing ones; refusals precede the undo step - entry group codes validated (1..=369, never 5/105); payload content is the plugin's own - each mutating call is one undo step: the pending history snapshot restores the objects map byte-exactly, auto-created dictionaries included (tested) - typed entries survive DWG and DXF write/reload round-trips (tested); update drops verbatim raw bytes so saves emit the new content - bump API_VERSION 7 -> 8 with the build.rs version_info in lockstep, mirroring the v7 addition; MIN_SUPPORTED stays 3
This commit is contained in:
1 parent
6cde0e02d8
commit
ca2f0c9857
11 files changed
+1212
-3
No files matched your search
@@ -339,3 +339,21 @@ plugin gate (60 real-IPC host tests, 115 plugin API, 20 plugin crate, 16 Python
|
||||
`--no-fail-fast` (1,805 passed, 1 failed: `fonts_parse_and_resolve`, which fails on pristine `main` on this Mac too; `arc_grips_drive_center_start_and_end_but_not_midpoint`
|
||||
now passes, fixed upstream). The change is 72 files, +30,705 / -178 against current `main` (fork-only workflow excluded).
|
||||
|
||||
### 2026-10-11: XRecord objects (API v8, no Python surface yet)
|
||||
|
||||
New additive v8 requests `CreateXRecord` / `ReadXRecord` / `UpdateXRecord` / `DeleteXRecord` / `ListXRecords`
|
||||
give plugins a non-graphical record carrier: name-addressed typed `XRecordEntry` pairs under the drawing's
|
||||
named-object dictionary, with no carrier entity. `dictionary_path` is walked from the NOD root (an empty path
|
||||
is the root), creating missing dictionaries on create only — the `ensure_image_dictionary` bootstrap — so the
|
||||
first call seeds a namespace; `create` refuses an existing name and `update` refuses a missing one, so neither
|
||||
can silently overwrite or create. Names and path fragments are symbol-validated, entry group codes are checked
|
||||
(1..=369, never the handle codes 5/105), and every refusal is decided before the undo step is recorded. Update
|
||||
replaces the entries atomically (handle, owner and name stay, the record's verbatim raw payloads are dropped, so
|
||||
saves emit the new content); delete returns the removed record; list reports only the keys that address
|
||||
XRecords, in dictionary order. Undo: objects-map mutations are captured by the pending history's full structure
|
||||
snapshot, so each mutating call is one undo step whose undo restores the objects map byte-exactly, the
|
||||
auto-created dictionaries included. Evidence: `xrecord_crud_round_trips_refusals_and_list`,
|
||||
`xrecord_mutations_are_single_undo_steps_that_restore_objects` (four steps, refusal paths record none),
|
||||
`xrecords_survive_dxf_and_dwg_round_trips` (typed entries reload from both writers), the IPC round-trips
|
||||
`xrecord_request_and_response_roundtrip` and `xrecord_requests_await_their_typed_responses`. The API is
|
||||
host-level and stands on its own; a Python mapping (`doc.xrecords`-style) is future work.
|
||||
@@ -26,6 +26,7 @@ without it keeps working, and the default `HostApi` methods refuse.
|
||||
| Selection | `selection`, `set_selection` | Ordered, tab-scoped, exact (missing or duplicate handles reject the request). |
|
||||
| Solids | `solid_operation` | Kernel-backed create, transform, booleans, extrude, region and surface from a profile, picture embedding. Every result is verified to lift back from its ACIS payload without loss; a refusal leaves the operands untouched. |
|
||||
| Tables | `table_operation` | Layers, text and dimension styles, blocks and their contents, linetypes, layouts (see below). |
|
||||
| Objects | `create_xrecord`, `read_xrecord`, `update_xrecord`, `delete_xrecord`, `list_xrecords` | Name-addressed XRecords under the drawing's named-object dictionary (API v8, see below): a non-graphical record carrier with strict create-vs-update semantics and one undo step per change. |
|
||||
| Commands | `run_command` | Drives the real OCS command one step at a time (see below). |
|
||||
| Settings | `system_variable`, `set_system_variable` | `CLAYER`, `SNAPANG`, and a read-only `CTAB` (the current layout). |
|
||||
|
||||
@@ -85,6 +86,22 @@ recorded, so a failure changes nothing and leaves the history alone.
|
||||
Style and layout operations act on the active document, because they use the
|
||||
application's shared style and view machinery.
|
||||
|
||||
## XRecords (API v8)
|
||||
|
||||
`create_xrecord`, `read_xrecord`, `update_xrecord`, `delete_xrecord` and
|
||||
`list_xrecords` address XRecords by name under a dictionary path walked from the
|
||||
named-object dictionary root (an empty path is the root itself); missing
|
||||
dictionaries are created on create only, so the first call seeds a plugin's
|
||||
namespace. The payload is the codec's typed `XRecordEntry` pairs — the host puts
|
||||
no opinion on the content. Names and path fragments are symbol-validated, and
|
||||
dictionary addressing follows the codec's case-insensitive lookup. Create never
|
||||
overwrites and update never creates; each refusal is decided before the undo step
|
||||
is recorded, so a failure changes nothing, and each change is one undo step whose
|
||||
undo restores the objects map byte-exactly, the auto-created dictionaries
|
||||
included. `list_xrecords` reports only the keys that address XRecords, in the
|
||||
dictionary's own order, so audits need no prior knowledge. Not yet mapped to
|
||||
Python.
|
||||
|
||||
## Commands
|
||||
|
||||
`run_command` takes a `CommandRequest` (`Run`, `Start`, `Point`, `Text`, `Token`,
|
||||
|
||||
Reference in new issue
Block a user