Publish built-in document edits to V4 plugins

This commit is contained in:
Felix Riestra committed 2026-09-18 12:13:43 +02:00
1 parent 79028bcee4
commit 93afe91afc
4 files changed
+63 -1

No files matched your search

+32
View File
@@ -283,6 +283,8 @@ impl OpenCADStudio {
// selection check has to run on this path too.
#[cfg(not(target_arch = "wasm32"))]
self.notify_plugins_selection_changed();
#[cfg(not(target_arch = "wasm32"))]
self.notify_plugins_document_changed();
res
}
@@ -737,6 +739,36 @@ impl OpenCADStudio {
#[cfg(test)]
mod tests {
#[cfg(not(target_arch = "wasm32"))]
#[test]
fn built_in_edits_advance_plugin_document_fingerprint_once() {
let mut app = super::OpenCADStudio::new_for_test();
app.automation_op(r#"{"op":"new"}"#);
let before = app.last_plugin_document.expect("new drawing published");
app.automation_op(r#"{"op":"run","cmd":"LINE 0,0 10,0"}"#);
let after = app.last_plugin_document.expect("line edit published");
assert_eq!(after.0, app.tabs[app.active_tab].id);
assert_ne!(after, before);
assert_eq!(after.1, app.tabs[app.active_tab].scene.geometry_epoch);
app.automation_op(r#"{"op":"query","type":"Line"}"#);
assert_eq!(app.last_plugin_document, Some(after));
}
#[cfg(not(target_arch = "wasm32"))]
#[test]
fn plugin_edit_publication_is_not_repeated_at_message_boundary() {
use acadrust::entities::Point;
use acadrust::EntityType;
let mut app = super::OpenCADStudio::new_for_test();
app.automation_op(r#"{"op":"new"}"#);
let tab = app.active_tab;
let mut host = super::super::plugin_host::HostSession::new(&mut app, tab);
host.add_entity(EntityType::Point(Point::new()));
let published = app.last_plugin_document.expect("plugin write published");
app.notify_plugins_document_changed();
assert_eq!(app.last_plugin_document, Some(published));
}
use crate::app::OpenCADStudio;
#[test]
+7
View File
@@ -802,6 +802,11 @@ pub(super) struct OpenCADStudio {
/// `SelectionChangedV4` fires once per real change rather than per message.
#[cfg(not(target_arch = "wasm32"))]
last_plugin_selection: Option<(u64, u64)>,
/// `(tab id, geometry epoch)` last published to the V4 document view.
/// Built-in edits bypass HostSession, so this is checked at message
/// boundaries as well as after plugin-initiated writes.
#[cfg(not(target_arch = "wasm32"))]
last_plugin_document: Option<(u64, u64)>,
/// External add-on packages found in the plugins folder, refreshed when the
/// Plugin Manager opens.
external_plugins: Vec<crate::plugin::external::ExternalPlugin>,
@@ -3750,6 +3755,8 @@ impl OpenCADStudio {
disabled_plugins: rustc_hash::FxHashSet::default(),
#[cfg(not(target_arch = "wasm32"))]
last_plugin_selection: None,
#[cfg(not(target_arch = "wasm32"))]
last_plugin_document: None,
external_plugins: Vec::new(),
loaded_plugin_ids: rustc_hash::FxHashSet::default(),
plugin_load_errors: rustc_hash::FxHashMap::default(),
+5 -1
View File
@@ -92,7 +92,11 @@ impl<'a> HostSession<'a> {
}
}
#[cfg(not(target_arch = "wasm32"))]
v4_support::publish_document_view_v4(self.tab_id(), doc);
{
v4_support::publish_document_view_v4(self.tab_id(), doc);
self.app.last_plugin_document =
Some((self.tab_id(), self.app.tabs[self.tab].scene.geometry_epoch));
}
}
pub fn add_entity(&mut self, entity: EntityType) -> Handle {
+19
View File
@@ -262,6 +262,23 @@ impl OpenCADStudio {
crate::plugin::v4_support::publish_selection_changed_v4(tab_id, handles);
}
/// Refresh the shared V4 document after built-in geometry edits. Plugin
/// writes publish through HostSession immediately; the fingerprint avoids
/// sending a duplicate notification at this message boundary.
#[cfg(not(target_arch = "wasm32"))]
pub(super) fn notify_plugins_document_changed(&mut self) {
if self.active_tab >= self.tabs.len() {
return;
}
let tab = &self.tabs[self.active_tab];
let key = (tab.id, tab.scene.geometry_epoch);
if self.last_plugin_document == Some(key) {
return;
}
self.last_plugin_document = Some(key);
crate::plugin::v4_support::publish_document_view_v4(tab.id, &tab.scene.document);
}
pub fn update(&mut self, msg: Message) -> Task<Message> {
self.control_observe_user_message(&msg);
let perf_started = crate::perf::enabled().then(Instant::now);
@@ -319,6 +336,8 @@ impl OpenCADStudio {
// and plugin request draining).
#[cfg(not(target_arch = "wasm32"))]
self.notify_plugins_selection_changed();
#[cfg(not(target_arch = "wasm32"))]
self.notify_plugins_document_changed();
// OTRACK acquires tracking points only while a command or grip drag is
// running; drop them once neither is active so the temporary tracking
// points / vectors disappear when the command ends (issue #64).