Skip to main content

LinkageView

Struct LinkageView 

Source
pub struct LinkageView<'a, const DOF: usize, const MARKS: usize> { /* private fields */ }
Expand description

A borrowed linkage used to evaluate, compose, and render a linkage.

It erases fixed step capacity while preserving the linkage-parameter and mark dimensions. Obtain one with LinkageFixed::view or LinkageBuf::view.

§Examples

const LINKAGE: LinkageFixed<1, 0, 8> = LinkageFixed::start()
    .define_param("distance", 0.5)
    .forward_param("distance", 1.0, 5.0);

let pose = view.final_pose(&[0.5])?;
assert!(pose.position().is_close_to(&Vec3::from([3.0, 0.0, 0.0]), 1e-5));

The API keeps LinkageFixed<DOF, MARKS, N> as the owned const-generic representation and uses this borrowed wrapper to erase N.

Implementations§

Source§

impl<'a, const DOF: usize, const MARKS: usize> LinkageView<'a, DOF, MARKS>

Source

pub const DOF: usize = DOF

The number of linkage parameters expected at evaluation time.

Source

pub const MARKS: usize = MARKS

The number of mark slots in this view.

Source

pub const fn dof(&self) -> usize

Return the number of linkage parameters expected at evaluation time.

Source

pub const fn len(&self) -> usize

Return the number of linkage steps, including the implicit start step.

Source

pub const fn is_empty(&self) -> bool

Return whether this linkage has no steps.

Source

pub const fn param(&self, index: usize) -> Param

Return a parameter definition by index.

§Panics

Panics if index >= dof().

§Examples
const LINKAGE: LinkageFixed<2, 0, 8> = LinkageFixed::start()
    .define_param("yaw", 0.5)
    .define_param("distance", 0.75);

let view = LINKAGE.view();
let param = view.param(0);
assert_eq!(param.name(), "yaw");
assert_eq!(param.default(), 0.5);
Source

pub const fn params(&self) -> &'a [Param; DOF]

Return a reference to the parameter array.

§Examples
const LINKAGE: LinkageFixed<2, 0, 8> = LinkageFixed::start()
    .define_param("x", 0.0)
    .define_param("y", 0.5);

let view = LINKAGE.view();
let params = view.params();
assert_eq!(params.len(), 2);
Source

pub const fn param_defaults(&self) -> [f32; DOF]

Return each parameter’s normalized default value.

§Examples
const LINKAGE: LinkageFixed<2, 0, 8> = LinkageFixed::start()
    .define_param("x", 0.25)
    .define_param("y", 0.75);

let defaults = LINKAGE.view().param_defaults();
assert_eq!(defaults, [0.25, 0.75]);
Source

pub const fn steps(&self) -> &'a [Step]

Return a reference to the step slice.

Source

pub const fn scan_param_range(&self, index: usize) -> (f32, f32)

Scan the steps for the (low, high) legal range of the parameter at index, as driven by the first step that uses it. Rotation ranges are in radians (convert with f32::to_degrees); translation/disk/sphere ranges are in linkage units.

This is an O(steps) linear scan, not a field read. The range is constant for a given linkage, so resolve it once — ideally in a const — and never per frame:

const HOURS_RANGE: (f32, f32) = LINKAGE.view().scan_param_range(1);
§Panics

Panics if no step drives the parameter at index.

Source

pub const fn mark_names(&self) -> &'a [&'static str; MARKS]

Return the active mark-name slots.

Source

pub const fn mark_len(&self) -> usize

Return the number of distinct mark slots used by this linkage.

Source

pub const fn mark_count(&self) -> usize

Return the number of marks currently used by this view.

Source

pub const fn marks(&self) -> usize

Return the view’s mark-slot capacity.

Source

pub const fn to_fixed<const N: usize>(self) -> LinkageFixed<DOF, MARKS, N>

Copy this view into fixed backing storage.

N must be large enough for the active steps.

See the fixed-storage example.

Source

pub fn to_lb_rs(&self) -> String

Serialize this linkage view as .lb.rs source using the linkage![ ... ] format.

The output is intended for editor interchange and generated linkage files. Color values are emitted as Rgb888::new(r, g, b) calls.

See the growable storage and serialization examples.

Source

pub const fn param_index(&self, name: &str, n: usize) -> usize

Return the index of the nth parameter (0-based) with the given name.

§Panics

Panics if the name is not found or if n exceeds the occurrence count.

§Examples
const LINKAGE: LinkageFixed<3, 0, 8> = LinkageFixed::start()
    .define_param("x", 0.0)
    .define_param("y", 0.5)
    .define_param("x", 0.8);

let view = LINKAGE.view();
assert_eq!(view.param_index("x", 0), 0);  // first "x"
assert_eq!(view.param_index("x", 1), 2);  // second "x"
Source

pub fn final_pose(&self, params: &[f32; DOF]) -> Result<Pose, Error>

Return the final pose after evaluating all steps.

This evaluates the linkage immediately. When rendering or looking up marked poses in the same pass, use the DrawItem3dIter returned by Self::draw_items_3d and inspect it after exhaustion instead.

§Examples
const LINKAGE: LinkageFixed<2, 0, 8> = LinkageFixed::start()
    .define_param("yaw", 0.5)
    .define_param("distance", 0.5)
    .yaw_param("yaw", -90.0, 90.0)
    .forward_param("distance", 1.0, 5.0);

let pose = view.final_pose(&[0.5, 0.6])?;
assert!(pose.position().is_close_to(&Vec3::from([3.4, 0.0, 0.0]), 1e-5));
Source

pub fn poses<'b>( &'b self, params: &'b [f32; DOF], ) -> Result<impl Iterator<Item = Pose> + 'b, Error>

Iterate over all intermediate poses produced by evaluating this linkage.

§Examples
const LINKAGE: LinkageFixed<1, 0, 8> = LinkageFixed::start()
    .define_param("distance", 0.5)
    .forward_param("distance", 1.0, 5.0);

let mut poses = view.poses(&[0.5])?;
let start = poses.next().expect("linkage always has start pose");
assert!(start.position().is_close_to(&Vec3::from([0.0, 0.0, 0.0]), 1e-5));
let end = poses.next().expect("forward step exists");
assert!(end.position().is_close_to(&Vec3::from([3.0, 0.0, 0.0]), 1e-5));
Source

pub fn styled_poses<'b>( &'b self, params: &'b [f32; DOF], ) -> Result<impl Iterator<Item = StyledPose> + 'b, Error>

Iterate over all styled poses with their pen state.

§Examples
const LINKAGE: LinkageFixed<0, 0, 8> = LinkageFixed::start()
    .forward(1.0)
    .forward(2.0);

let mut styled = view.styled_poses(&[])?;
let start = styled.next().expect("has start");
assert!(start.pose().position().is_close_to(&Vec3::from([0.0, 0.0, 0.0]), 1e-5));
assert_eq!(start.pen(), PenState::Down);
styled.next().expect("has first forward");
let end = styled.next().expect("has second forward");
assert!(end.pose().position()[0] > 2.9);
Source

pub fn draw_items_3d<'b>( &'b self, params: &'b [f32; DOF], ) -> Result<DrawItem3dIter<'b, DOF, MARKS>, Error>

Iterate over all draw items produced by this linkage.

§Examples
const LINKAGE: LinkageFixed<0, 0, 8> = LinkageFixed::start()
    .forward(1.0)
    .forward(2.0);

let has_stroke = view.draw_items_3d(&[])?
    .any(|item| matches!(item, Item3d::Stroke(_)));
assert!(has_stroke);
Source

pub const fn draw_item_3d_count(&self) -> usize

The number of Item3ds this linkage yields, evaluated at compile time.

Which steps emit a draw item depends only on the linkage’s steps and pen state (which moves draw, which shapes are emitted), never on the runtime parameter values, so the count is a const and can size a buffer.

§Examples
const LINKAGE: LinkageFixed<0, 0, 8> = LinkageFixed::start()
    .forward(1.0)
    .forward(2.0);

const COUNT: usize = LINKAGE.view().draw_item_3d_count();
assert_eq!(COUNT, 2);

Trait Implementations§

Source§

impl<'a, const DOF: usize, const MARKS: usize> Clone for LinkageView<'a, DOF, MARKS>

Source§

fn clone(&self) -> LinkageView<'a, DOF, MARKS>

Returns a duplicate of the value. Read more
1.0.0 (const: unstable) · Source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
Source§

impl<'a, const DOF: usize, const MARKS: usize> Copy for LinkageView<'a, DOF, MARKS>

Source§

impl<'a, const DOF: usize, const MARKS: usize> From<&'a LinkageBuf<DOF, MARKS>> for LinkageView<'a, DOF, MARKS>

Available on crate feature alloc only.
Source§

fn from(linkage: &'a LinkageBuf<DOF, MARKS>) -> Self

Converts to this type from the input type.
Source§

impl<'a, const DOF: usize, const MARKS: usize, const N: usize> From<&'a LinkageFixed<DOF, MARKS, N>> for LinkageView<'a, DOF, MARKS>

Source§

fn from(linkage: &'a LinkageFixed<DOF, MARKS, N>) -> Self

Converts to this type from the input type.

Auto Trait Implementations§

§

impl<'a, const DOF: usize, const MARKS: usize> Freeze for LinkageView<'a, DOF, MARKS>
where &'a [Param; DOF]: Freeze, &'a [&'static str; MARKS]: Freeze,

§

impl<'a, const DOF: usize, const MARKS: usize> RefUnwindSafe for LinkageView<'a, DOF, MARKS>
where &'a [Param; DOF]: RefUnwindSafe, &'a [&'static str; MARKS]: RefUnwindSafe,

§

impl<'a, const DOF: usize, const MARKS: usize> Send for LinkageView<'a, DOF, MARKS>
where &'a [Param; DOF]: Send, &'a [&'static str; MARKS]: Send,

§

impl<'a, const DOF: usize, const MARKS: usize> Sync for LinkageView<'a, DOF, MARKS>
where &'a [Param; DOF]: Sync, &'a [&'static str; MARKS]: Sync,

§

impl<'a, const DOF: usize, const MARKS: usize> Unpin for LinkageView<'a, DOF, MARKS>
where &'a [Param; DOF]: Unpin, &'a [&'static str; MARKS]: Unpin,

§

impl<'a, const DOF: usize, const MARKS: usize> UnsafeUnpin for LinkageView<'a, DOF, MARKS>
where &'a [Param; DOF]: UnsafeUnpin, &'a [&'static str; MARKS]: UnsafeUnpin,

§

impl<'a, const DOF: usize, const MARKS: usize> UnwindSafe for LinkageView<'a, DOF, MARKS>
where &'a [Param; DOF]: UnwindSafe, &'a [&'static str; MARKS]: UnwindSafe,

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> Az for T

Source§

fn az<Dst>(self) -> Dst
where T: Cast<Dst>,

Casts the value.
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<Src, Dst> CastFrom<Src> for Dst
where Src: Cast<Dst>,

Source§

fn cast_from(src: Src) -> Dst

Casts the value.
Source§

impl<T> CheckedAs for T

Source§

fn checked_as<Dst>(self) -> Option<Dst>
where T: CheckedCast<Dst>,

Casts the value.
Source§

impl<Src, Dst> CheckedCastFrom<Src> for Dst
where Src: CheckedCast<Dst>,

Source§

fn checked_cast_from(src: Src) -> Option<Dst>

Casts the value.
Source§

impl<T> CloneToUninit for T
where T: Clone,

Source§

unsafe fn clone_to_uninit(&self, dest: *mut u8)

🔬This is a nightly-only experimental API. (clone_to_uninit)
Performs copy-assignment from self to dest. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

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> OverflowingAs for T

Source§

fn overflowing_as<Dst>(self) -> (Dst, bool)
where T: OverflowingCast<Dst>,

Casts the value.
Source§

impl<Src, Dst> OverflowingCastFrom<Src> for Dst
where Src: OverflowingCast<Dst>,

Source§

fn overflowing_cast_from(src: Src) -> (Dst, bool)

Casts the value.
Source§

impl<T> SaturatingAs for T

Source§

fn saturating_as<Dst>(self) -> Dst
where T: SaturatingCast<Dst>,

Casts the value.
Source§

impl<Src, Dst> SaturatingCastFrom<Src> for Dst
where Src: SaturatingCast<Dst>,

Source§

fn saturating_cast_from(src: Src) -> Dst

Casts the value.
Source§

impl<T> ToOwned for T
where T: Clone,

Source§

type Owned = T

The resulting type after obtaining ownership.
Source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
Source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. 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<T> UnwrappedAs for T

Source§

fn unwrapped_as<Dst>(self) -> Dst
where T: UnwrappedCast<Dst>,

Casts the value.
Source§

impl<Src, Dst> UnwrappedCastFrom<Src> for Dst
where Src: UnwrappedCast<Dst>,

Source§

fn unwrapped_cast_from(src: Src) -> Dst

Casts the value.
Source§

impl<T> WrappingAs for T

Source§

fn wrapping_as<Dst>(self) -> Dst
where T: WrappingCast<Dst>,

Casts the value.
Source§

impl<Src, Dst> WrappingCastFrom<Src> for Dst
where Src: WrappingCast<Dst>,

Source§

fn wrapping_cast_from(src: Src) -> Dst

Casts the value.