forked from 1b-agent/opencadstudio-upstream
Add versioned scripting host model and entity coverage
This commit is contained in:
1 parent
ec2271fc9c
commit
11d5614991
22 files changed
+1015
-4
No files matched your search
@@ -444,6 +444,40 @@ impl HostApi for PluginHostApi {
|
||||
Err(error) => Err(error.to_string()),
|
||||
}
|
||||
}
|
||||
|
||||
fn update_entities_transaction(
|
||||
&mut self,
|
||||
label: &str,
|
||||
entities: Vec<EntityType>,
|
||||
) -> Result<(), String> {
|
||||
match self.client.request(PluginRequest::UpdateEntitiesTransaction {
|
||||
label: label.to_owned(), entities,
|
||||
}) {
|
||||
Ok(PluginResponse::EntityTransactionResult(result)) => {
|
||||
if result.is_ok() { self.document_cache = OnceCell::new(); }
|
||||
result
|
||||
}
|
||||
Ok(PluginResponse::Error(error)) => Err(error),
|
||||
Ok(other) => Err(format!("unexpected entity transaction response: {other:?}")),
|
||||
Err(error) => Err(error.to_string()),
|
||||
}
|
||||
}
|
||||
|
||||
fn selection(&self) -> Vec<Handle> {
|
||||
match self.client.request(PluginRequest::GetSelection) {
|
||||
Ok(PluginResponse::Selection(handles)) => handles,
|
||||
_ => Vec::new(),
|
||||
}
|
||||
}
|
||||
|
||||
fn set_selection(&mut self, handles: &[Handle]) -> Result<(), String> {
|
||||
match self.client.request(PluginRequest::SetSelection { handles: handles.to_vec() }) {
|
||||
Ok(PluginResponse::SelectionResult(result)) => result,
|
||||
Ok(PluginResponse::Error(error)) => Err(error),
|
||||
Ok(other) => Err(format!("unexpected selection response: {other:?}")),
|
||||
Err(error) => Err(error.to_string()),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Sentinel reader used when the shared-memory view could not be initialized.
|
||||
|
||||
@@ -76,6 +76,8 @@ pub enum HostRequest {
|
||||
code: String,
|
||||
tab_index: usize,
|
||||
},
|
||||
/// V7: release an interactive command after completion or cancellation.
|
||||
DropInteractive { command_id: u64 },
|
||||
}
|
||||
|
||||
/// Responses the plugin runner sends back for `HostRequest`.
|
||||
@@ -142,6 +144,11 @@ pub enum PluginRequest {
|
||||
GetSystemVariable { name: String },
|
||||
/// Change a host-managed setting without nested command dispatch.
|
||||
SetSystemVariable { name: String, value: HostSettingValue },
|
||||
/// V7: validate and replace existing entities in a single undo step.
|
||||
UpdateEntitiesTransaction { label: String, entities: Vec<EntityType> },
|
||||
/// V7: synchronous selection read/write for the dispatch tab.
|
||||
GetSelection,
|
||||
SetSelection { handles: Vec<Handle> },
|
||||
}
|
||||
|
||||
/// Responses the host sends back for `PluginRequest`.
|
||||
@@ -170,6 +177,9 @@ pub enum PluginResponse {
|
||||
DocumentPath(Option<std::ffi::OsString>),
|
||||
SystemVariable(Option<HostSettingValue>),
|
||||
SystemVariableResult(Result<HostSettingValue, String>),
|
||||
EntityTransactionResult(Result<(), String>),
|
||||
Selection(Vec<Handle>),
|
||||
SelectionResult(Result<(), String>),
|
||||
}
|
||||
|
||||
/// Messages sent from the host to the plugin runner.
|
||||
|
||||
@@ -83,5 +83,10 @@ pub fn handle_plugin_request(
|
||||
SetSystemVariable { name, value } => {
|
||||
PluginResponse::SystemVariableResult(host.set_system_variable(&name, value))
|
||||
}
|
||||
UpdateEntitiesTransaction { label, entities } => PluginResponse::EntityTransactionResult(
|
||||
host.update_entities_transaction(&label, entities),
|
||||
),
|
||||
GetSelection => PluginResponse::Selection(host.selection()),
|
||||
SetSelection { handles } => PluginResponse::SelectionResult(host.set_selection(&handles)),
|
||||
}
|
||||
}
|
||||
@@ -758,6 +758,40 @@ impl HostApi for V4PluginHostApi {
|
||||
Err(error) => Err(error.to_string()),
|
||||
}
|
||||
}
|
||||
|
||||
fn update_entities_transaction(
|
||||
&mut self,
|
||||
label: &str,
|
||||
entities: Vec<EntityType>,
|
||||
) -> Result<(), String> {
|
||||
match self.request(PluginRequest::UpdateEntitiesTransaction {
|
||||
label: label.to_owned(), entities,
|
||||
}) {
|
||||
Ok(PluginResponse::EntityTransactionResult(result)) => {
|
||||
if result.is_ok() { self.document_cache = OnceCell::new(); }
|
||||
result
|
||||
}
|
||||
Ok(PluginResponse::Error(error)) => Err(error),
|
||||
Ok(other) => Err(format!("unexpected entity transaction response: {other:?}")),
|
||||
Err(error) => Err(error.to_string()),
|
||||
}
|
||||
}
|
||||
|
||||
fn selection(&self) -> Vec<Handle> {
|
||||
match self.request(PluginRequest::GetSelection) {
|
||||
Ok(PluginResponse::Selection(handles)) => handles,
|
||||
_ => Vec::new(),
|
||||
}
|
||||
}
|
||||
|
||||
fn set_selection(&mut self, handles: &[Handle]) -> Result<(), String> {
|
||||
match self.request(PluginRequest::SetSelection { handles: handles.to_vec() }) {
|
||||
Ok(PluginResponse::SelectionResult(result)) => result,
|
||||
Ok(PluginResponse::Error(error)) => Err(error),
|
||||
Ok(other) => Err(format!("unexpected selection response: {other:?}")),
|
||||
Err(error) => Err(error.to_string()),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
|
||||
@@ -86,6 +86,37 @@ mod tests {
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn command_state_notification_roundtrips() {
|
||||
let notification = HostNotification::CommandStateChanged {
|
||||
tab_id: 42,
|
||||
command: Some("LINE".to_owned()),
|
||||
};
|
||||
let bytes = bincode::serialize(¬ification).unwrap();
|
||||
let decoded: HostNotification = bincode::deserialize(&bytes).unwrap();
|
||||
assert_eq!(decoded, notification);
|
||||
let stopped = HostNotification::CommandStateChanged { tab_id: 42, command: None };
|
||||
let bytes = bincode::serialize(&stopped).unwrap();
|
||||
let decoded: HostNotification = bincode::deserialize(&bytes).unwrap();
|
||||
assert_eq!(decoded, stopped);
|
||||
let changed = HostNotification::DrawingChanged { tab_id: 42, epoch: 7 };
|
||||
let bytes = bincode::serialize(&changed).unwrap();
|
||||
let decoded: HostNotification = bincode::deserialize(&bytes).unwrap();
|
||||
assert_eq!(decoded, changed);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn selection_request_and_response_roundtrip() {
|
||||
let request = PluginRequest::SetSelection { handles: vec![acadrust::Handle::new(9)] };
|
||||
let bytes = bincode::serialize(&request).unwrap();
|
||||
assert!(matches!(bincode::deserialize::<PluginRequest>(&bytes).unwrap(),
|
||||
PluginRequest::SetSelection { handles } if handles == vec![acadrust::Handle::new(9)]));
|
||||
let response = PluginResponse::Selection(vec![acadrust::Handle::new(9)]);
|
||||
let bytes = bincode::serialize(&response).unwrap();
|
||||
assert!(matches!(bincode::deserialize::<PluginResponse>(&bytes).unwrap(),
|
||||
PluginResponse::Selection(handles) if handles == vec![acadrust::Handle::new(9)]));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn plugin_notification_roundtrip() {
|
||||
let frame = PluginToHostV4::Notification(NotificationEnvelope {
|
||||
|
||||
Reference in new issue
Block a user