MilkEvaluator

Struct MilkEvaluator 

Source
pub struct MilkEvaluator {
    pub(crate) context: MilkContext,
    compiled_cache: Vec<(String, Node)>,
}
Expand description

Evaluator for Milkdrop expressions.

Fields§

§context: MilkContext

Execution context

§compiled_cache: Vec<(String, Node)>

Compiled expressions cache

Implementations§

Source§

impl MilkEvaluator

Source

pub fn eval_equation_list(&mut self, eqs: &[String]) -> EvaluationStats

Evaluate a flat list of equations, joining consecutive paren-unbalanced lines (MD2 loop(...) idiom). Returns aggregate stats; the evaluator’s context retains every variable touched by the run.

Source

pub(super) fn eval_processed_with_loops( &mut self, expr: &str, original: &str, ) -> Result<f64>

Evaluate expr (already preprocessed), intercepting top-level loop(N, body), exec2(a, b), exec3(a, b, c) and while(body) calls. original is kept for error reporting.

Source§

impl MilkEvaluator

Source

pub(super) fn preprocess_expression(&mut self, expression: &str) -> String

Pre-process expression to handle auto-initialization and type conversion.

Source§

impl MilkEvaluator

Source

pub fn new() -> Self

Create a new evaluator.

Source

pub fn context(&self) -> &MilkContext

Get a reference to the context.

Source

pub fn context_mut(&mut self) -> &mut MilkContext

Get a mutable reference to the context.

Source

pub fn compile(&mut self, expression: &str) -> Result<Node>

Pre-compile an expression into an evalexpr Node that can be evaluated repeatedly without re-parsing.

Pre-processing (auto-init of undefined variables, integer→float promotion in assignments, if(milkif( rewrite) runs as part of compilation, so any variable referenced in expression is also registered in self.context as a side effect — exactly like a normal eval call. This means a context cloned out of this evaluator after a compile call already contains every var the compiled Node will look up at evaluation time.

Source

pub fn eval(&mut self, expression: &str) -> Result<f64>

Evaluate a single expression.

Source

pub fn eval_per_frame(&mut self, equations: &[String]) -> Result<()>

Evaluate multiple expressions (per-frame equations).

Source

pub fn eval_per_pixel( &mut self, x: f64, y: f64, rad: f64, ang: f64, equations: &[String], ) -> Result<()>

Evaluate per-pixel equations for a single pixel.

Source

pub fn compile_batch(&mut self, equations: &[String]) -> Result<Vec<Node>>

Compile a batch of source strings into reusable Nodes. Use this on load_preset for custom wave/shape equations, which run hundreds of times per frame — avoiding per-eval reparse is a 10×+ speedup.

Source

pub fn eval_compiled(&mut self, node: &Node) -> Result<f64>

Evaluate a pre-compiled Node against this evaluator’s context. Skips the regex preprocess that eval() runs every call — variables referenced in the source string were already auto-initialized at compile() time.

Source

pub fn eval_per_shape_instance( &mut self, instance: ShapeInstance, compiled: &[Node], ) -> Result<ShapeInstance>

Evaluate per-frame equations for one instance of a custom shape (shapecode_N). Seeds the loop variables (instance, sides, num_inst) plus the full geometry/colour state, runs the compiled per-frame Nodes, reads everything back into a fresh ShapeInstance.

Unlike eval_per_point (which threads state across iterations within a frame), each shape instance is independent: callers pass the shape’s scalar block seed every time and instance changes per call. Persistent state across instances lives in q* / t* channels, which the context carries.

Source

pub fn run_per_shape_instance( &mut self, instance: ShapeInstance, block: &CompiledBlock, ) -> Result<ShapeInstance>

Bytecode-aware companion of [eval_per_shape_instance]. Runs the bytecode VM when [CompiledBlock::bytecode] is Some, otherwise walks the evalexpr Node list.

Source

fn seed_shape_instance(ctx: &mut MilkContext, instance: ShapeInstance)

Push the 23 hot-var seed values from instance into ctx.

Source

fn read_shape_instance( c: &MilkContext, instance: ShapeInstance, ) -> ShapeInstance

Companion to [seed_shape_instance] — read every per-instance var back, falling back to instance.* when a slot is missing.

Source

pub fn run_per_point_bc( &mut self, point: WavePoint, compiled: &CompiledBytecode, ) -> WavePoint

Bytecode counterpart of [eval_per_point]. Skips both the String → Value::Float wrapping and the recursive operator-tree walk that evalexpr does for each child node — the bytecode VM just reads/writes hot slots by index and runs a flat opcode stream.

Source

pub fn eval_per_point( &mut self, point: WavePoint, compiled: &[Node], ) -> Result<WavePoint>

Evaluate per-point equations for one sample inside a custom wave or shape loop. point carries the input vars (sample, value1, value2) and the carry-over geometry/colour (x, y, r, g, b, a). The output echoes the same fields back, read from the context after the equations ran.

The caller is responsible for seeding the loop on point 0 with the wave’s base colour and any saved x/y, then threading the previous point’s output into the next call — this matches MD2’s “trail across samples within a frame” semantics.

Source

pub fn eval_assignment(&mut self, expression: &str) -> Result<f64>

Parse an assignment expression and update context. Returns the assigned value.

Source

pub fn reset(&mut self)

Reset the evaluator to initial state.

Trait Implementations§

Source§

impl Clone for MilkEvaluator

Custom Clone impl that skips compiled_cache. The cache is per-call memoisation for the regex-preprocess path; worker threads (the wave and warp parallel passes) never re-enter that path — they’re given pre-compiled Nodes by the caller — so cloning the cache is pure overhead. The cache can grow into the hundreds of entries on a long-running engine, so this matters: cloning a 100-entry Vec<(String, Node)> is ~30 µs that goes away for free.

Source§

fn clone(&self) -> Self

Returns a duplicate of the value. Read more
1.0.0 · Source§

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

Performs copy-assignment from source. Read more
Source§

impl Default for MilkEvaluator

Source§

fn default() -> Self

Returns the “default value” for a type. Read more

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<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> 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 = Infallible

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

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

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.