Skip to main content

Document

Struct Document 

Source
pub struct Document {
    pub engine: EngineState,
    pub ecad: Editors,
    pub ecad_blocks: [BlockSync; 4],
    pub ecad_parts_revision: Option<u64>,
    pub ecad_parts_reported: Vec<String>,
    pub ecad_occurrences: Option<OccurrenceMark>,
    pub ecad_outdated: Vec<String>,
    pub ecad_update_requested: bool,
    /* private fields */
}
Expand description

ONE open model: the engine that owns it plus the identity the file lane needs — the store name it was opened from / saved to, and the clean baseline.

Fields§

§engine: EngineState

The windowing-agnostic brain for THIS document (scene, camera, history, settings, selection). Panels borrow it; it is never forked.

§ecad: Editors

This document’s eCAD editors — Diagram, PCB, Symbol and Pads — kept beside its engine, so each tab has its own and a tab switch keeps their pan, zoom and view: a switch rebuilds the PANELS (reset_document_scoped_state), never a document. Built with the document; all four measured 0.65 ms (release), so no document waits for its first eCAD workbench to have them.

§ecad_blocks: [BlockSync; 4]

Each editor’s standing with its block of this document’s history: what takes BREP’s undo and redo to the editor, and the editor’s edits into the document (ecad::BlockSync).

§ecad_parts_revision: Option<u64>§ecad_parts_reported: Vec<String>

The broken-reference lines crate::panels::ecad_parts::sync has already put in front of the user. A device whose part is missing is a STANDING state and the revision bumps on every edit, so without this it would toast on every keystroke — the same rule ecad::BlockSync::unreported keeps for an UNLINKED component.

§ecad_occurrences: Option<OccurrenceMark>

What crate::panels::ecad_parts::follow_occurrences last saw of the assembly’s occurrences; None until the first frame looks.

§ecad_outdated: Vec<String>

The parts-library entries whose saved part has moved on since this document took it — the shell’s UpdateComponents list for the active document, handed over each frame so the Diagram and PCB workbenches can mark the components placed from them and offer the update where the user is looking (viewport::ecad).

§ecad_update_requested: bool

Set by the eCAD host’s Update parts button; the shell runs the update (UpdateComponents::run, one undo step) on its next frame.

Implementations§

Source§

impl Document

Source

pub fn fresh(engine: EngineState, class: DocumentClass) -> Self

Create a fresh document. Part workbenches start with the same ordinary, schema-seeded datum a user adds from the palette. Existing content must use new instead: opening a file never changes its feature history.

Source

pub fn new(engine: EngineState) -> Self

Wrap engine as a document, taking its CURRENT model as the clean baseline — so a freshly loaded (or freshly emptied) document is clean and the first edit marks it dirty.

Source

pub fn recovered(engine: EngineState, name: Option<String>) -> Self

Wrap engine as a document RESTORED from the autosave blob (crate::recovery): it carries the store identity it had (None for an untitled one) and NO clean baseline, so it is dirty from its first frame — the work it holds is exactly what was never saved, and the close guard and the tab dot must say so until a Save writes it somewhere.

Source

pub fn access(&self) -> Access

Whether this document may be edited (Access).

Source

pub fn set_access(&mut self, access: Access)

Make the document editable or read-only. Read-only locks the engine’s history, so its saved bytes cannot change until it is editable again.

Source

pub fn save_access(&self) -> Access

Saving to the current PLM revision may be restricted while session editing remains available. A local Save As clears this restriction.

Source

pub fn set_plm_save_access(&mut self, access: Access)

Source

pub fn take_refused(&mut self) -> Option<String>

The sentence to show when an edit was refused since the last call — None when nothing was. Called once a frame by the shell, which toasts it.

Source

pub fn name(&self) -> Option<&str>

The raw store identity, or None for a never-saved document.

Source

pub fn set_name(&mut self, name: Option<String>)

Source

pub fn title(&self) -> String

The tab label: PLM part/revision, the bare file name, or untitled (untitled 2, … for the second and later untitled tabs).

Source

pub fn set_label(&mut self, label: Option<String>)

Give an untitled document a display label (see label).

Source

pub fn untitled_title(&self) -> String

What an untitled document is called, and what Save As offers for it.

Source

pub fn mark_clean(&mut self)

Snapshot the current model as the clean baseline (after New / Open / Save, or a ?loadModel= boot-load).

Source

pub fn settle_open_runs(&mut self)

A document’s first runs after it is opened write back into it: the first solve of a mate stored unsolved (the pose and the solve’s status), and the snapshots of embedded parts stored without one (the PLM import blanks them). None of that is the user’s change, so closing the document must not ask to save it.

Called once a frame. While the user has not edited the document since it was opened (its edit serial is unchanged), a run that has APPLIED moves the clean baseline to the document as that run left it. The rule is conservative where it cannot tell: the document changing while no run applied (a write that took no undo step, which could be the user’s) stops the settling for good, and the document stays as dirty as it is. The worst case is one needless save prompt, never an unsaved edit that reads saved.

Source

pub fn converge_runs(&mut self)

Called once a frame. After Self::arm_converge, once a run has applied and the user has not edited since: when the document equals its clean baseline to within CONVERGE_TOLERANCE in every number (mates re-solved the poses the discarded edit had moved, to ~1e-9), the solved document becomes the baseline, as a Save’s would. A real change is far outside the tolerance and leaves the tab changed.

Source

pub fn is_recovered(&self) -> bool

Restored from crash recovery and not saved since: it has no clean baseline, and what differs from its stored document is the user’s unsaved work, not an older copy to refresh.

Source

pub fn is_dirty(&self) -> bool

Dirty = the live model differs from the last saved/opened baseline. (Rolling the history does NOT change the request document, so navigating steps never marks dirty — only real edits/add/delete/reorder do.) The workbench the document is in is not part of it (signature).

HONEST but not free: it serializes the whole request document, which for an assembly carrying an embedded parts library is megabytes. Every place where being wrong would cost the user work — the close prompt, Save — calls THIS. The per-frame tab dot calls Self::dirty_marker instead.

Source

pub fn edit_key(&self) -> (u64, u64)

What moves when the saved document can have changed: the APPLIED RUN generation and the history’s revision.

Both, because each misses edits the other sees. An ordinary edit (a param change, add, delete, reorder, undo) re-runs the history, but a block write runs nothing — a drawing sheet, a PMI label move, an eCAD edit, a BOM part-attribute edit — and moves only the revision, which every write to the SAVED document moves, the partsLibrary block included (it is held in a field beside the document and both its setters tick the revision themselves). An object-metadata change (a workbench change is not an unsaved change at all, signature) moves neither and can leave the dot one edit behind: a marker briefly optimistic, never a lost edit, since Self::is_dirty is recomputed honestly at the close prompt.

Source

pub fn refresh_dirty_marker(&mut self)

The cached dirty flag the tab strip draws. Recomputing it serializes the whole document, so it is recomputed only when the Self::edit_key moved, and, once the tab is marked unsaved, only when a RUN moved it (an ordinary edit, an undo, a redo).

The second rule is for drags. Dragging a block (a PMI label, a view on a sheet) writes the document every frame and moves only the revision; recomputing there serialized the document on every frame, 2.6 ms in a release build on a 1.3 MB assembly. An unsaved tab stays unsaved while only the revision moves, so a drag pays one serialization, on the frame the dot lights. Param-slider drags re-run the history each frame and still recompute each frame, as they always did.

The residue is deliberate: a block edit that lands exactly back on the saved bytes keeps the dot on until the next run or Save. Showing unsaved when clean costs one needless Save; the opposite loses work, which is the bug the revision key fixed. Self::is_dirty stays honest at the close prompt either way.

Source

pub fn absorb_open_write( &mut self, before: &Value, after: &Value, key: (u64, u64), )

Take a write that OPENING the document made — before and after are the saved document either side of it, key the Self::edit_key before it — as though the file had been saved that way: every top-level block the write changed, and that was still as last saved, is moved in the clean baseline too, and a tab dot that was current stays as it was.

For an eCAD editor’s first sight of an older board (viewport::ecad’s store). Not Self::mark_clean: whatever else was unsaved before the open stays unsaved. So the open changes nothing a document that needed no bringing up would show — the honest Self::is_dirty and the dot alike.

Source

pub fn dirty_checks(&self) -> u64

How many times Self::refresh_dirty_marker has serialized the document.

Source

pub fn dirty_marker(&self) -> bool

Source

pub fn id(&self) -> u64

The document’s process-unique handle (identity across index shuffles).

Source

pub fn handle(&self) -> &str

The public handle (doc_<epoch>_<nonce>) automation names it by.

Source

pub fn committed_revision(&self) -> u64

The document’s committed revision: a per-document count that moves whenever its content_key has moved since the last observation — a history edit, undo and redo (they write the history), a run’s write-back (the applied generation), a block write and an object metadata change (the stamp). A view change (camera, selection, workbench, tab switch, an idle frame) moves none of the three.

Why observation is enough: all three components are monotonic process counters, so a content key never recurs, and any change between two observations reads as a different key at the second one. Two commits between observations count as one step — the value is an equality token for “nothing was written since”, never a count of writes.

Auto Trait Implementations§

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<ST, DT> CastableFrom<ST, Initialized, Initialized> for DT
where ST: ?Sized, DT: ?Sized,

Source§

impl<ST, DT> CastableFrom<ST, Uninit, Uninit> for DT
where ST: ?Sized, DT: ?Sized,

Source§

impl<T> Conv for T

Source§

fn conv<T>(self) -> T
where Self: Into<T>,

Converts self into T using Into<T>. Read more
Source§

impl<T> Downcast for T
where T: Any,

Source§

fn into_any(self: Box<T>) -> Box<dyn Any>

Convert Box<dyn Trait> (where Trait: Downcast) to Box<dyn Any>. Box<dyn Any> can then be further downcast into Box<ConcreteType> where ConcreteType implements Trait.
Source§

fn into_any_rc(self: Rc<T>) -> Rc<dyn Any>

Convert Rc<Trait> (where Trait: Downcast) to Rc<Any>. Rc<Any> can then be further downcast into Rc<ConcreteType> where ConcreteType implements Trait.
Source§

fn as_any(&self) -> &(dyn Any + 'static)

Convert &Trait (where Trait: Downcast) to &Any. This is needed since Rust cannot generate &Any’s vtable from &Trait’s.
Source§

fn as_any_mut(&mut self) -> &mut (dyn Any + 'static)

Convert &mut Trait (where Trait: Downcast) to &Any. This is needed since Rust cannot generate &mut Any’s vtable from &mut Trait’s.
Source§

impl<T> Downcast<T> for T

Source§

fn downcast(&self) -> &T

Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T> Instrument for T

Source§

fn instrument(self, span: Span) -> Instrumented<Self> ⓘ

Instruments this type with the provided Span, returning an Instrumented wrapper. Read more
Source§

fn in_current_span(self) -> Instrumented<Self> ⓘ

Instruments this type with the current Span, returning an Instrumented wrapper. Read more
Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> IntoEither for T

Source§

fn into_either(self, into_left: bool) -> Either<Self, Self> ⓘ

Converts self into a Left variant of Either<Self, Self> if into_left is true. Converts self into a Right variant of Either<Self, Self> otherwise. Read more
Source§

fn into_either_with<F>(self, into_left: F) -> Either<Self, Self> ⓘ
where F: FnOnce(&Self) -> bool,

Converts self into a Left variant of Either<Self, Self> if into_left(&self) returns true. Converts self into a Right variant of Either<Self, Self> otherwise. Read more
Source§

impl<T> Pipe for T
where T: ?Sized,

Source§

fn pipe<R>(self, func: impl FnOnce(Self) -> R) -> R
where Self: Sized,

Pipes by value. This is generally the method you want to use. Read more
Source§

fn pipe_ref<'a, R>(&'a self, func: impl FnOnce(&'a Self) -> R) -> R
where R: 'a,

Borrows self and passes that borrow into the pipe function. Read more
Source§

fn pipe_ref_mut<'a, R>(&'a mut self, func: impl FnOnce(&'a mut Self) -> R) -> R
where R: 'a,

Mutably borrows self and passes that borrow into the pipe function. Read more
Source§

fn pipe_borrow<'a, B, R>(&'a self, func: impl FnOnce(&'a B) -> R) -> R
where Self: Borrow<B>, B: 'a + ?Sized, R: 'a,

Borrows self, then passes self.borrow() into the pipe function. Read more
Source§

fn pipe_borrow_mut<'a, B, R>( &'a mut self, func: impl FnOnce(&'a mut B) -> R, ) -> R
where Self: BorrowMut<B>, B: 'a + ?Sized, R: 'a,

Mutably borrows self, then passes self.borrow_mut() into the pipe function. Read more
Source§

fn pipe_as_ref<'a, U, R>(&'a self, func: impl FnOnce(&'a U) -> R) -> R
where Self: AsRef<U>, U: 'a + ?Sized, R: 'a,

Borrows self, then passes self.as_ref() into the pipe function.
Source§

fn pipe_as_mut<'a, U, R>(&'a mut self, func: impl FnOnce(&'a mut U) -> R) -> R
where Self: AsMut<U>, U: 'a + ?Sized, R: 'a,

Mutably borrows self, then passes self.as_mut() into the pipe function.
Source§

fn pipe_deref<'a, T, R>(&'a self, func: impl FnOnce(&'a T) -> R) -> R
where Self: Deref<Target = T>, T: 'a + ?Sized, R: 'a,

Borrows self, then passes self.deref() into the pipe function.
Source§

fn pipe_deref_mut<'a, T, R>( &'a mut self, func: impl FnOnce(&'a mut T) -> R, ) -> R
where Self: DerefMut<Target = T> + Deref, T: 'a + ?Sized, R: 'a,

Mutably borrows self, then passes self.deref_mut() into the pipe function.
Source§

impl<T> Pointable for T

Source§

const ALIGN: usize

The alignment of pointer.
Source§

type Init = T

The type for initializers.
Source§

unsafe fn init(init: <T as Pointable>::Init) -> usize

Initializes a with the given initializer. Read more
Source§

unsafe fn deref<'a>(ptr: usize) -> &'a T

Dereferences the given pointer. Read more
Source§

unsafe fn deref_mut<'a>(ptr: usize) -> &'a mut T

Mutably dereferences the given pointer. Read more
Source§

unsafe fn drop(ptr: usize)

Drops the object pointed to by the given pointer. Read more
Source§

impl<T> Read<Exclusive, BecauseExclusive> for T
where T: ?Sized,

Source§

impl<T> Same for T

Source§

type Output = T

Should always be Self
Source§

impl<T, S> SimdFrom<T, S> for T
where S: Simd,

Source§

fn simd_from(_simd: S, value: T) -> T

Source§

impl<F, T, S> SimdInto<T, S> for F
where T: SimdFrom<F, S>, S: Simd,

Source§

fn simd_into(self, simd: S) -> T

Source§

impl<T> Tap for T

Source§

fn tap(self, func: impl FnOnce(&Self)) -> Self

Immutable access to a value. Read more
Source§

fn tap_mut(self, func: impl FnOnce(&mut Self)) -> Self

Mutable access to a value. Read more
Source§

fn tap_borrow<B>(self, func: impl FnOnce(&B)) -> Self
where Self: Borrow<B>, B: ?Sized,

Immutable access to the Borrow<B> of a value. Read more
Source§

fn tap_borrow_mut<B>(self, func: impl FnOnce(&mut B)) -> Self
where Self: BorrowMut<B>, B: ?Sized,

Mutable access to the BorrowMut<B> of a value. Read more
Source§

fn tap_ref<R>(self, func: impl FnOnce(&R)) -> Self
where Self: AsRef<R>, R: ?Sized,

Immutable access to the AsRef<R> view of a value. Read more
Source§

fn tap_ref_mut<R>(self, func: impl FnOnce(&mut R)) -> Self
where Self: AsMut<R>, R: ?Sized,

Mutable access to the AsMut<R> view of a value. Read more
Source§

fn tap_deref<T>(self, func: impl FnOnce(&T)) -> Self
where Self: Deref<Target = T>, T: ?Sized,

Immutable access to the Deref::Target of a value. Read more
Source§

fn tap_deref_mut<T>(self, func: impl FnOnce(&mut T)) -> Self
where Self: DerefMut<Target = T> + Deref, T: ?Sized,

Mutable access to the Deref::Target of a value. Read more
Source§

fn tap_dbg(self, func: impl FnOnce(&Self)) -> Self

Calls .tap() only in debug builds, and is erased in release builds.
Source§

fn tap_mut_dbg(self, func: impl FnOnce(&mut Self)) -> Self

Calls .tap_mut() only in debug builds, and is erased in release builds.
Source§

fn tap_borrow_dbg<B>(self, func: impl FnOnce(&B)) -> Self
where Self: Borrow<B>, B: ?Sized,

Calls .tap_borrow() only in debug builds, and is erased in release builds.
Source§

fn tap_borrow_mut_dbg<B>(self, func: impl FnOnce(&mut B)) -> Self
where Self: BorrowMut<B>, B: ?Sized,

Calls .tap_borrow_mut() only in debug builds, and is erased in release builds.
Source§

fn tap_ref_dbg<R>(self, func: impl FnOnce(&R)) -> Self
where Self: AsRef<R>, R: ?Sized,

Calls .tap_ref() only in debug builds, and is erased in release builds.
Source§

fn tap_ref_mut_dbg<R>(self, func: impl FnOnce(&mut R)) -> Self
where Self: AsMut<R>, R: ?Sized,

Calls .tap_ref_mut() only in debug builds, and is erased in release builds.
Source§

fn tap_deref_dbg<T>(self, func: impl FnOnce(&T)) -> Self
where Self: Deref<Target = T>, T: ?Sized,

Calls .tap_deref() only in debug builds, and is erased in release builds.
Source§

fn tap_deref_mut_dbg<T>(self, func: impl FnOnce(&mut T)) -> Self
where Self: DerefMut<Target = T> + Deref, T: ?Sized,

Calls .tap_deref_mut() only in debug builds, and is erased in release builds.
Source§

impl<T> TryConv for T

Source§

fn try_conv<T>(self) -> Result<T, Self::Error>
where Self: TryInto<T>,

Attempts to convert self into T using TryInto<T>. Read more
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = !

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, !>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
Source§

impl<S, T> Upcast<T> for S
where T: UpcastFrom<S> + ?Sized, S: ?Sized,

Source§

fn upcast(&self) -> &T
where Self: ErasableGeneric, T: Sized + ErasableGeneric<Repr = Self::Repr>,

Perform a zero-cost type-safe upcast to a wider ref type within the Wasm bindgen generics type system. Read more
Source§

fn upcast_into(self) -> T
where Self: Sized + ErasableGeneric, T: Sized + ErasableGeneric<Repr = Self::Repr>,

Perform a zero-cost type-safe upcast to a wider type within the Wasm bindgen generics type system. Read more
Source§

impl<T> Upcast<T> for T

Source§

fn upcast(&self) -> Option<&T>

Source§

impl<T> WithSubscriber for T

Source§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self> ⓘ
where S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a WithDispatch wrapper. Read more
Source§

fn with_current_subscriber(self) -> WithDispatch<Self> ⓘ

Attaches the current default Subscriber to this type, returning a WithDispatch wrapper. Read more