fn fill_buffer<M, F>(
        &mut self,
        model: &mut M,
        render: F,
        buffer: &mut Buffer,
        state: &State,
    )
    where
        F: RenderFn<M>,
    {
        // If the frame rate is `0`, leave the buffer empty.
        if state.frame_hz == 0 {
            return;
        }

        // If the buffer has no points, there's nothing to fill.
        if buffer.is_empty() {
            return;
        }

        // The number of points to generate per frame.
        let point_hz = buffer.point_hz();
        let latency_points = buffer.latency_points();

        // The starting index of the buffer we'll write to.
        let mut start = 0;

        // If there are still un-read points, use those first.
        if !self.raw_points.is_empty() {
            // If the pending range would not fill the buffer, write what we can.
            if self.raw_points.len() < buffer.len() {
                start = self.raw_points.len();
                buffer[..start].copy_from_slice(&self.raw_points);
                self.raw_points.clear();

            // If we have the exact number of frames as output, write them and return.
            } else if self.raw_points.len() == buffer.len() {
                buffer.copy_from_slice(&self.raw_points);
                self.raw_points.clear();
                return;

            // If we have too many points, write what we can and leave the rest.
            } else {
                let end = buffer.len();
                buffer.copy_from_slice(&self.raw_points[..end]);
                self.raw_points.drain(0..end);
                return;
            }
        }

        // The number of points to fill for each frame.
        let points_per_frame = point_hz / state.frame_hz;

        // If we reached this point, `self.raw_points` is empty so we should fill buffer with
        // frames until it is full.
        loop {
            // See how many points are left to fill.
            let num_points_remaining = buffer.len() - start;

            // Determine how many points to fill this pass.
            let num_points_to_fill = std::cmp::min(points_per_frame as usize, num_points_remaining);

            // Render a frame of points.
            let mut frame = Frame {
                point_hz,
                latency_points,
                frame_hz: state.frame_hz,
                points: vec![], // TODO: Reuse this buffer rather than allocating every loop.
            };
            render(model, &mut frame);

            // If we were given no points, the user must be expecting an empty frame.
            if frame.points.is_empty() {
                let blank_point = self.last_frame_point.map(|p| p.blanked())
                    .unwrap_or_else(RawPoint::centered_blank);
                self.raw_points.extend((0..points_per_frame).map(|_| blank_point));

            // Otherwise, we'll optimise and interpolate the given points.
            } else {
                // Optimisation passes.
                let segs = opt::points_to_segments(frame.iter().cloned());
                let pg = opt::segments_to_point_graph(segs);
                let eg = opt::point_graph_to_euler_graph(&pg);
                let ec = opt::euler_graph_to_euler_circuit(&eg);

                // Blank from last point of the previous frame to first point of this one.
                let last_frame_point = self.last_frame_point.take();
                let inter_frame_blank_points = match last_frame_point {
                    Some(last) => {
                        match eg.node_indices().next() {
                            None => vec![],
                            Some(next_id) => {
                                let next = eg[next_id];
                                if last.position != next.position {
                                    let a = last.blanked().with_weight(0);
                                    let b = next.to_raw().blanked();
                                    let blank_delay_points =
                                        state.interpolation_conf.blank_delay_points;
                                    opt::blank_segment_points(a, b, blank_delay_points).collect()
                                } else {
                                    vec![]
                                }
                            }
                        }
                    }
                    None => vec![],
                };

                // Subtract the inter-frame blank points from points per frame to maintain frame_hz.
                let inter_frame_point_count = inter_frame_blank_points.len() as u32;
                let target_points = if points_per_frame > inter_frame_point_count {
                    points_per_frame - inter_frame_point_count
                } else {
                    0
                };

                // Join the inter-frame points with the interpolated frame.
                let interp_conf = &state.interpolation_conf;
                let mut interpolated =
                    opt::interpolate_euler_circuit(&ec, &eg, target_points, interp_conf);

                // If the interpolated frame is empty there were no lit points or lines.
                // In this case, we'll produce an empty frame.
                if interpolated.is_empty() {
                    let blank_point = inter_frame_blank_points.last()
                        .map(|&p| p)
                        .or_else(|| last_frame_point.map(|p| p.blanked()))
                        .unwrap_or_else(RawPoint::centered_blank);
                    interpolated.extend((0..target_points).map(|_| blank_point));
                }

                self.raw_points.extend(inter_frame_blank_points);
                self.raw_points.extend(interpolated);
            }

            // Update the last frame point.
            self.last_frame_point = self.raw_points.last().map(|&p| p);

            // Write the points to buffer.
            let end = start + num_points_to_fill;
            let range = start..end;
            buffer[range.clone()].copy_from_slice(&self.raw_points[..range.len()]);
            self.raw_points.drain(..range.len());

            // If this output filled the buffer, break.
            if end == buffer.len() {
                break;
            }

            // Continue looping through the next frames.
            start = end;
        }
    }
// Fill the given buffer by requesting frames from the given user `render` function as
// required.
Fill the given buffer by requesting frames from the given user `render` function as
required.
Fill the given buffer by requesting frames from the given user ` render ` function as required .
fn fill_buffer<M, F>(
        &mut self,
        model: &mut M,
        render: F,
        buffer: &mut Buffer,
        state: &State,
    )
    where
        F: RenderFn<M>,
    {
        // If the frame rate is `0`, leave the buffer empty.
        if state.frame_hz == 0 {
            return;
        }
        // If the buffer has no points, there's nothing to fill.
        if buffer.is_empty() {
            return;
        }
        // The number of points to generate per frame.
        let point_hz = buffer.point_hz();
        let latency_points = buffer.latency_points();
        // The starting index of the buffer we'll write to.
        let mut start = 0;
        // If there are still un-read points, use those first.
        if !self.raw_points.is_empty() {
            // If the pending range would not fill the buffer, write what we can.
            if self.raw_points.len() < buffer.len() {
                start = self.raw_points.len();
                buffer[..start].copy_from_slice(&self.raw_points);
                self.raw_points.clear();
            // If we have the exact number of frames as output, write them and return.
            } else if self.raw_points.len() == buffer.len() {
                buffer.copy_from_slice(&self.raw_points);
                self.raw_points.clear();
                return;
            // If we have too many points, write what we can and leave the rest.
            } else {
                let end = buffer.len();
                buffer.copy_from_slice(&self.raw_points[..end]);
                self.raw_points.drain(0..end);
                return;
            }
        }
        // The number of points to fill for each frame.
        let points_per_frame = point_hz / state.frame_hz;
        // If we reached this point, `self.raw_points` is empty so we should fill buffer with
        // frames until it is full.
        loop {
            // See how many points are left to fill.
            let num_points_remaining = buffer.len() - start;
            // Determine how many points to fill this pass.
            let num_points_to_fill = std::cmp::min(points_per_frame as usize, num_points_remaining);
            // Render a frame of points.
            let mut frame = Frame {
                point_hz,
                latency_points,
                frame_hz: state.frame_hz,
                points: vec![], // TODO: Reuse this buffer rather than allocating every loop.
            };
            render(model, &mut frame);
            // If we were given no points, the user must be expecting an empty frame.
            if frame.points.is_empty() {
                let blank_point = self.last_frame_point.map(|p| p.blanked())
                    .unwrap_or_else(RawPoint::centered_blank);
                self.raw_points.extend((0..points_per_frame).map(|_| blank_point));
            // Otherwise, we'll optimise and interpolate the given points.
            } else {
                // Optimisation passes.
                let segs = opt::points_to_segments(frame.iter().cloned());
                let pg = opt::segments_to_point_graph(segs);
                let eg = opt::point_graph_to_euler_graph(&pg);
                let ec = opt::euler_graph_to_euler_circuit(&eg);
                // Blank from last point of the previous frame to first point of this one.
                let last_frame_point = self.last_frame_point.take();
                let inter_frame_blank_points = match last_frame_point {
                    Some(last) => {
                        match eg.node_indices().next() {
                            None => vec![],
                            Some(next_id) => {
                                let next = eg[next_id];
                                if last.position != next.position {
                                    let a = last.blanked().with_weight(0);
                                    let b = next.to_raw().blanked();
                                    let blank_delay_points =
                                        state.interpolation_conf.blank_delay_points;
                                    opt::blank_segment_points(a, b, blank_delay_points).collect()
                                } else {
                                    vec![]
                                }
                            }
                        }
                    }
                    None => vec![],
                };
                // Subtract the inter-frame blank points from points per frame to maintain frame_hz.
                let inter_frame_point_count = inter_frame_blank_points.len() as u32;
                let target_points = if points_per_frame > inter_frame_point_count {
                    points_per_frame - inter_frame_point_count
                } else {
                    0
                };
                // Join the inter-frame points with the interpolated frame.
                let interp_conf = &state.interpolation_conf;
                let mut interpolated =
                    opt::interpolate_euler_circuit(&ec, &eg, target_points, interp_conf);
                // If the interpolated frame is empty there were no lit points or lines.
                // In this case, we'll produce an empty frame.
                if interpolated.is_empty() {
                    let blank_point = inter_frame_blank_points.last()
                        .map(|&p| p)
                        .or_else(|| last_frame_point.map(|p| p.blanked()))
                        .unwrap_or_else(RawPoint::centered_blank);
                    interpolated.extend((0..target_points).map(|_| blank_point));
                }
                self.raw_points.extend(inter_frame_blank_points);
                self.raw_points.extend(interpolated);
            }
            // Update the last frame point.
            self.last_frame_point = self.raw_points.last().map(|&p| p);
            // Write the points to buffer.
            let end = start + num_points_to_fill;
            let range = start..end;
            buffer[range.clone()].copy_from_slice(&self.raw_points[..range.len()]);
            self.raw_points.drain(..range.len());
            // If this output filled the buffer, break.
            if end == buffer.len() {
                break;
            }
            // Continue looping through the next frames.
            start = end;
        }
    }
fn fill_buffer < M , F > ( & mut self , model : & mut M , render : F , buffer : & mut Buffer , state : & State , ) where F : RenderFn < M > , { // If the frame rate is `0`, leave the buffer empty. if state . frame_hz == 0 { return ; } // If the buffer has no points, there's nothing to fill. if buffer . is_empty ( ) { return ; } // The number of points to generate per frame. let point_hz = buffer . point_hz ( ) ; let latency_points = buffer . latency_points ( ) ; // The starting index of the buffer we'll write to. let mut start = 0 ; // If there are still un-read points, use those first. if ! self . raw_points . is_empty ( ) { // If the pending range would not fill the buffer, write what we can. if self . raw_points . len ( ) < buffer . len ( ) { start = self . raw_points . len ( ) ; buffer [ .. start ] . copy_from_slice ( & self . raw_points ) ; self . raw_points . clear ( ) ; // If we have the exact number of frames as output, write them and return. } else if self . raw_points . len ( ) == buffer . len ( ) { buffer . copy_from_slice ( & self . raw_points ) ; self . raw_points . clear ( ) ; return ; // If we have too many points, write what we can and leave the rest. } else { let end = buffer . len ( ) ; buffer . copy_from_slice ( & self . raw_points [ .. end ] ) ; self . raw_points . drain ( 0 .. end ) ; return ; } } // The number of points to fill for each frame. let points_per_frame = point_hz / state . frame_hz ; // If we reached this point, `self.raw_points` is empty so we should fill buffer with // frames until it is full. loop { // See how many points are left to fill. let num_points_remaining = buffer . len ( ) - start ; // Determine how many points to fill this pass. let num_points_to_fill = std :: cmp :: min ( points_per_frame as usize , num_points_remaining ) ; // Render a frame of points. let mut frame = Frame { point_hz , latency_points , frame_hz : state . frame_hz , points : vec ! [ ] , // TODO: Reuse this buffer rather than allocating every loop. } ; render ( model , & mut frame ) ; // If we were given no points, the user must be expecting an empty frame. if frame . points . is_empty ( ) { let blank_point = self . last_frame_point . map ( | p | p . blanked ( ) ) . unwrap_or_else ( RawPoint :: centered_blank ) ; self . raw_points . extend ( ( 0 .. points_per_frame ) . map ( | _ | blank_point ) ) ; // Otherwise, we'll optimise and interpolate the given points. } else { // Optimisation passes. let segs = opt :: points_to_segments ( frame . iter ( ) . cloned ( ) ) ; let pg = opt :: segments_to_point_graph ( segs ) ; let eg = opt :: point_graph_to_euler_graph ( & pg ) ; let ec = opt :: euler_graph_to_euler_circuit ( & eg ) ; // Blank from last point of the previous frame to first point of this one. let last_frame_point = self . last_frame_point . take ( ) ; let inter_frame_blank_points = match last_frame_point { Some ( last ) => { match eg . node_indices ( ) . next ( ) { None => vec ! [ ] , Some ( next_id ) => { let next = eg [ next_id ] ; if last . position != next . position { let a = last . blanked ( ) . with_weight ( 0 ) ; let b = next . to_raw ( ) . blanked ( ) ; let blank_delay_points = state . interpolation_conf . blank_delay_points ; opt :: blank_segment_points ( a , b , blank_delay_points ) . collect ( ) } else { vec ! [ ] } } } } None => vec ! [ ] , } ; // Subtract the inter-frame blank points from points per frame to maintain frame_hz. let inter_frame_point_count = inter_frame_blank_points . len ( ) as u32 ; let target_points = if points_per_frame > inter_frame_point_count { points_per_frame - inter_frame_point_count } else { 0 } ; // Join the inter-frame points with the interpolated frame. let interp_conf = & state . interpolation_conf ; let mut interpolated = opt :: interpolate_euler_circuit ( & ec , & eg , target_points , interp_conf ) ; // If the interpolated frame is empty there were no lit points or lines. // In this case, we'll produce an empty frame. if interpolated . is_empty ( ) { let blank_point = inter_frame_blank_points . last ( ) . map ( | & p | p ) . or_else ( | | last_frame_point . map ( | p | p . blanked ( ) ) ) . unwrap_or_else ( RawPoint :: centered_blank ) ; interpolated . extend ( ( 0 .. target_points ) . map ( | _ | blank_point ) ) ; } self . raw_points . extend ( inter_frame_blank_points ) ; self . raw_points . extend ( interpolated ) ; } // Update the last frame point. self . last_frame_point = self . raw_points . last ( ) . map ( | & p | p ) ; // Write the points to buffer. let end = start + num_points_to_fill ; let range = start .. end ; buffer [ range . clone ( ) ] . copy_from_slice ( & self . raw_points [ .. range . len ( ) ] ) ; self . raw_points . drain ( .. range . len ( ) ) ; // If this output filled the buffer, break. if end == buffer . len ( ) { break ; } // Continue looping through the next frames. start = end ; } }
Fill the given buffer by requesting frames from the given user `render` function as
required.
Fill the given buffer by requesting frames from the given user ` render ` function as required .
&mut self
model
&mut M
render
F
buffer
&mut Buffer
state
&State
&mut self
model
&mut M
render
F
buffer
&mut Buffer
state
&State