forked from 1b-agent/opencadstudio-upstream
Merge pull request #1423 from felixriestra:pr/python-host-model
The bundled `opencad.python` plugin drives OCS through plugin API v7: all 43 canvas entity kinds, the drawing tables, and OCS's own commands run step by step. RustPython stays in the plugin process — the plugin crate is outside the workspace with its own lock file, so the application's own dependencies are unchanged. Reconciled with the plugin command work that landed as #1425, which the branch was written before: - Both added `impl Drop for PluginProcessInteractiveAdapter`, which git merges silently into two impls that do not compile. One body now cancels the command and then drops it from the runner, in that order: a plugin waiting on a step has to be released before the runner forgets the command. - `execute_command` (#1425) and `run_command` (#1423) are both routes from a script to the command line, and only the second was guarded. The SCRIPTCOMMANDS switch and the denylist are shared now, so neither route is the unguarded one. - `run_command` dispatched with plugin dispatch still enabled, so a script naming a plugin command re-entered the plugin that was blocked waiting for it. It sets the suppression flag for the length of the dispatch, as `execute_command` does. The denylist read the command as typed, while the dispatcher resolves aliases: a user-defined `Q` for `QUIT` (ALIASEDIT writes those) walked past it. It resolves the alias first. Also: the active-command comparison ran on every message, a mouse move included, allocating two strings for names that are already `&'static str`; SCRIPTCOMMANDS' own messages go through the translation macros; and `docs/.DS_Store` (now ignored) and an unrelated RTF note about constraint commands are out of the tree. Co-Authored-By: Claude Opus 5 <[email protected]>
This commit is contained in:
commit
41ecc0c458
72 files changed
+30614
-91
No files matched your search
@@ -619,6 +619,7 @@ impl OpenCADStudio {
|
||||
constraint_bar_display: self.constraint_bar_display,
|
||||
constraint_bar_mode: self.constraint_bar_mode,
|
||||
savetime_min: self.savetime_min,
|
||||
script_commands: self.script_commands,
|
||||
default_save_format: self.default_save_format.clone(),
|
||||
pick_add: self.pick_add,
|
||||
pick_drag_rect: self.pick_drag_rect,
|
||||
@@ -723,6 +724,7 @@ impl OpenCADStudio {
|
||||
self.constraint_bar_display = s.constraint_bar_display.clamp(0, 3);
|
||||
self.constraint_bar_mode = s.constraint_bar_mode.clamp(0, 4095);
|
||||
self.savetime_min = s.savetime_min;
|
||||
self.script_commands = s.script_commands;
|
||||
self.default_save_format =
|
||||
crate::io::canonical_save_format(&s.default_save_format).to_string();
|
||||
self.pick_add = s.pick_add;
|
||||
|
||||
@@ -284,6 +284,24 @@ 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_drawing_changed(tab.id, tab.scene.geometry_epoch);
|
||||
crate::plugin::v4_support::publish_document_view_v4(tab.id, &tab.scene.document);
|
||||
}
|
||||
|
||||
pub fn update(&mut self, msg: Message) -> Task<Message> {
|
||||
if let Some(tab) = self.tabs.get(self.active_tab) {
|
||||
crate::entities::common::set_unit_context(
|
||||
@@ -355,7 +373,29 @@ impl OpenCADStudio {
|
||||
return task;
|
||||
}
|
||||
}
|
||||
// A command's name is `&'static str`, so this runs on every message —
|
||||
// a mouse move included — without allocating.
|
||||
#[cfg(not(target_arch = "wasm32"))]
|
||||
let active_command = |app: &Self| -> Option<(u64, Option<&'static str>)> {
|
||||
app.tabs
|
||||
.get(app.active_tab)
|
||||
.map(|tab| (tab.id, tab.active_cmd.as_ref().map(|command| command.name())))
|
||||
};
|
||||
#[cfg(not(target_arch = "wasm32"))]
|
||||
let command_before = active_command(self);
|
||||
let task = self.update_inner(msg);
|
||||
#[cfg(not(target_arch = "wasm32"))]
|
||||
{
|
||||
let command_after = active_command(self);
|
||||
if command_before != command_after {
|
||||
if let Some((tab_id, command)) = command_after {
|
||||
crate::plugin::v4_support::publish_command_state_changed(
|
||||
tab_id,
|
||||
command.map(str::to_owned),
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
self.refresh_gpu_status();
|
||||
self.show_next_startup_modal();
|
||||
self.sync_open_command_history();
|
||||
@@ -389,6 +429,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).
|
||||
|
||||
Reference in new issue
Block a user