forked from 1b-agent/opencadstudio-upstream
fix: close the review findings on the issue wave
Two reviewers over the #1345/#1348/#1349 wave; no blockers, two majors, several minors — all fixed. - La16 was still billed at 4 B/px: the no-conversion special case keyed on native_bpp == 4, which La16 also is — but only Rgba8 is a real move in into_rgba8, so La16's decode peak is 8. The case now keys on the color type, and a table test pins every layout's peak (plus GIF's screen+frame 8) so the accounting can't silently drift. - A control-routed open of a damaged-but-recoverable drawing parked the operation behind the RecoveryPrompt modal (hang until the JS timeout, silent drop if another op arrived, or false success when a human declined). The open op now settles as failed with recovery_required and the parse error; the prompt stays for humans, automation can retry through the recovery flow. - json_values_match: integers beyond f64 precision compared by value (a u64 could round-trip-match a float); integral pairs now compare exactly and mixed integer/float matches only when the float is whole and equals the integer. - A queued web open settles with the explicit queued marker whenever the open slot was busy (the old name check made same-named in-flight opens look completed with an empty result). - ocs-control.js resolves with the API object reference, not window.ocsControl (undefined if the bridge already existed when the script ran); DATALINK on web says the typed path is superseded by the picker instead of silently discarding it; the wipeout depth test probes past the page background's rectangle; and the plot-path doc comment names the function it actually mirrors.
This commit is contained in:
1 parent
2c38de53e2
commit
d719fb7778
30 files changed
+143
-18
No files matched your search
@@ -1601,7 +1601,16 @@ impl OpenCADStudio {
|
||||
// then runs from `DataLinkCsvPicked`.
|
||||
#[cfg(target_arch = "wasm32")]
|
||||
{
|
||||
let _ = path;
|
||||
// Say the typed argument is superseded — a silent
|
||||
// redirect looks like the input was lost.
|
||||
if !path.trim().is_empty() {
|
||||
self.command_line.push_info(
|
||||
crate::t!(
|
||||
"The browser cannot open a typed path; pick the file instead."
|
||||
)
|
||||
.as_ref(),
|
||||
);
|
||||
}
|
||||
return Some(Task::perform(
|
||||
crate::io::pick_datalink_csv_web(),
|
||||
Message::DataLinkCsvPicked,
|
||||
|
||||
@@ -755,9 +755,13 @@ impl OpenCADStudio {
|
||||
// stays pending until the open settles instead of
|
||||
// completing before the drawing exists.
|
||||
let task = self.update(Message::PollWebControl);
|
||||
if self.opening.as_ref().is_none_or(|opening| opening.name != name) {
|
||||
// Another open holds the slot; the poll opens this
|
||||
// entry once it frees, after this operation settles.
|
||||
// Another open holds the slot; the poll opens this entry
|
||||
// once it frees, after this operation settles. Report
|
||||
// `queued` whenever the slot was busy at submit — the
|
||||
// name check skipped same-named in-flight opens, making
|
||||
// the op look completed with an empty result before the
|
||||
// queued entry had opened.
|
||||
if self.opening.is_some() {
|
||||
self.set_control_result(json!({"queued": true, "name": name}));
|
||||
}
|
||||
return Ok(task);
|
||||
|
||||
+21
-5
@@ -1111,11 +1111,27 @@ fn requested_handle(request: &Value) -> Result<acadrust::Handle, String> {
|
||||
/// bools and null stay exact; objects and arrays recurse.
|
||||
fn json_values_match(stored: &Value, expected: &Value) -> bool {
|
||||
match (stored, expected) {
|
||||
(Value::Number(stored), Value::Number(expected)) => match (stored.as_f64(), expected.as_f64()) {
|
||||
(Some(stored), Some(expected)) => stored == expected,
|
||||
// Out-of-range or arbitrary-precision numbers keep exact equality.
|
||||
_ => stored == expected,
|
||||
},
|
||||
(Value::Number(stored), Value::Number(expected)) => {
|
||||
// Integers compare exactly (a u64 beyond f64 precision must not
|
||||
// round-trip-match a float); mixed integer/float matches only
|
||||
// when the float is whole and equals the integer.
|
||||
match (stored.as_u64(), expected.as_u64()) {
|
||||
(Some(stored), Some(expected)) => stored == expected,
|
||||
(Some(stored), None) => match expected.as_f64() {
|
||||
Some(expected) => expected.fract() == 0.0 && expected >= 0.0 && stored as f64 == expected,
|
||||
None => false,
|
||||
},
|
||||
(None, Some(expected)) => match stored.as_f64() {
|
||||
Some(stored) => stored.fract() == 0.0 && stored >= 0.0 && expected as f64 == stored,
|
||||
None => false,
|
||||
},
|
||||
_ => match (stored.as_i64(), expected.as_i64(), stored.as_f64(), expected.as_f64()) {
|
||||
(Some(stored), Some(expected), _, _) => stored == expected,
|
||||
(_, _, Some(stored), Some(expected)) => stored == expected,
|
||||
_ => stored == expected,
|
||||
},
|
||||
}
|
||||
}
|
||||
(Value::Object(stored), Value::Object(expected)) => {
|
||||
stored.len() == expected.len()
|
||||
&& stored.iter().all(|(key, value)| {
|
||||
|
||||
+25
-1
@@ -1059,9 +1059,33 @@ impl OpenCADStudio {
|
||||
}
|
||||
if e.recovery_available {
|
||||
if let Some(opening) = self.opening.as_mut() {
|
||||
opening.recovery_error = Some(e.message);
|
||||
let recovery_message = e.message.clone();
|
||||
opening.recovery_error = Some(recovery_message.clone());
|
||||
opening.recovery_read_stats = e.read_stats;
|
||||
self.active_modal = Some(super::ModalKind::RecoveryPrompt);
|
||||
// A control-routed open (automation) must not park
|
||||
// behind a modal nobody may answer: settle the
|
||||
// operation as failed with the parse error. The
|
||||
// prompt stays for a human; automation retries with
|
||||
// the recovery op if it wants the content.
|
||||
// A control-routed open (automation) must not park
|
||||
// behind a modal nobody may answer: settle the
|
||||
// operation as failed with the parse error. The
|
||||
// prompt stays for a human; automation can retry
|
||||
// through the recovery flow if it wants the content.
|
||||
#[cfg(target_arch = "wasm32")]
|
||||
{
|
||||
let settled = serde_json::json!({
|
||||
"ok": false,
|
||||
"status": "failed",
|
||||
"code": "recovery_required",
|
||||
"error": format!(
|
||||
"the drawing is damaged and needs a recovery decision: {}",
|
||||
recovery_message
|
||||
),
|
||||
});
|
||||
self.set_control_result(settled);
|
||||
}
|
||||
return Task::none();
|
||||
}
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user