pub fn for_segments(&mut self, segments: &[Segment], method: TimingMethod) {
        let mut len = segments.len();

        self.all_weighted_segment_times
            .resize_with(len, Default::default);

        for ((i, segment), weighted_segment_times) in segments
            .iter()
            .enumerate()
            .zip(&mut self.all_weighted_segment_times)
        {
            weighted_segment_times.clear();

            // Collect initial weighted segments
            let mut current_weight = 1.0;
            for &(id, time) in segment.segment_history().iter_actual_runs().rev() {
                if let Some(time) = time[method] {
                    // Skip all the combined segments
                    let skip = catch! {
                        segments[i.checked_sub(1)?].segment_history().get(id)?[method].is_none()
                    }
                    .unwrap_or(false);

                    if !skip {
                        weighted_segment_times.push((current_weight, time));
                        current_weight *= WEIGHT;
                    }
                }
            }

            // End early if we don't have any segment times anymore
            if weighted_segment_times.is_empty() {
                len = i;
                break;
            }

            // Sort everything by the times
            weighted_segment_times
                .sort_unstable_by_key(|&(_, time)| OrderedFloat(time.total_milliseconds()));

            // Cumulative sum of the weights
            let mut sum = 0.0;
            for (weight, _) in weighted_segment_times.iter_mut() {
                sum += *weight;
                *weight = sum;
            }

            // Reweigh all of the weights to be in the range 0..1
            let min = weighted_segment_times
                .first()
                .map(|&(w, _)| w)
                .unwrap_or_default();

            let max = weighted_segment_times
                .last()
                .map(|&(w, _)| w)
                .unwrap_or_default();

            let diff = max - min;

            if diff != 0.0 {
                for (weight, _) in weighted_segment_times.iter_mut() {
                    *weight = (*weight - min) / diff;
                }
            }
        }

        // Limit the slice to only the segments that have segment times
        self.truncate(len);
    }
/// Calculate the skill curve for the segments and timing method provided.
/// All previous information available in the skill curve will be discarded.
/// The segment curve may not always contain information for all segments.
/// Once a segment with no segment history is encountered, the remainder of
/// the segments get discarded.
Calculate the skill curve for the segments and timing method provided.
All previous information available in the skill curve will be discarded.
The segment curve may not always contain information for all segments.
Once a segment with no segment history is encountered, the remainder of
the segments get discarded.
Calculate the skill curve for the segments and timing method provided . All previous information available in the skill curve will be discarded . The segment curve may not always contain information for all segments . Once a segment with no segment history is encountered the remainder of the segments get discarded .
pub fn for_segments(&mut self, segments: &[Segment], method: TimingMethod) {
        let mut len = segments.len();
        self.all_weighted_segment_times
            .resize_with(len, Default::default);
        for ((i, segment), weighted_segment_times) in segments
            .iter()
            .enumerate()
            .zip(&mut self.all_weighted_segment_times)
        {
            weighted_segment_times.clear();
            // Collect initial weighted segments
            let mut current_weight = 1.0;
            for &(id, time) in segment.segment_history().iter_actual_runs().rev() {
                if let Some(time) = time[method] {
                    // Skip all the combined segments
                    let skip = catch! {
                        segments[i.checked_sub(1)?].segment_history().get(id)?[method].is_none()
                    }
                    .unwrap_or(false);
                    if !skip {
                        weighted_segment_times.push((current_weight, time));
                        current_weight *= WEIGHT;
                    }
                }
            }
            // End early if we don't have any segment times anymore
            if weighted_segment_times.is_empty() {
                len = i;
                break;
            }
            // Sort everything by the times
            weighted_segment_times
                .sort_unstable_by_key(|&(_, time)| OrderedFloat(time.total_milliseconds()));
            // Cumulative sum of the weights
            let mut sum = 0.0;
            for (weight, _) in weighted_segment_times.iter_mut() {
                sum += *weight;
                *weight = sum;
            }
            // Reweigh all of the weights to be in the range 0..1
            let min = weighted_segment_times
                .first()
                .map(|&(w, _)| w)
                .unwrap_or_default();
            let max = weighted_segment_times
                .last()
                .map(|&(w, _)| w)
                .unwrap_or_default();
            let diff = max - min;
            if diff != 0.0 {
                for (weight, _) in weighted_segment_times.iter_mut() {
                    *weight = (*weight - min) / diff;
                }
            }
        }
        // Limit the slice to only the segments that have segment times
        self.truncate(len);
    }
pub fn for_segments ( & mut self , segments : & [ Segment ] , method : TimingMethod ) { let mut len = segments . len ( ) ; self . all_weighted_segment_times . resize_with ( len , Default :: default ) ; for ( ( i , segment ) , weighted_segment_times ) in segments . iter ( ) . enumerate ( ) . zip ( & mut self . all_weighted_segment_times ) { weighted_segment_times . clear ( ) ; // Collect initial weighted segments let mut current_weight = 1.0 ; for & ( id , time ) in segment . segment_history ( ) . iter_actual_runs ( ) . rev ( ) { if let Some ( time ) = time [ method ] { // Skip all the combined segments let skip = catch ! { segments [ i checked_sub ( 1 ) ] segment_history ( ) get ( id ) [ method ] is_none ( ) } . unwrap_or ( false ) ; if ! skip { weighted_segment_times . push ( ( current_weight , time ) ) ; current_weight *= WEIGHT ; } } } // End early if we don't have any segment times anymore if weighted_segment_times . is_empty ( ) { len = i ; break ; } // Sort everything by the times weighted_segment_times . sort_unstable_by_key ( | & ( _ , time ) | OrderedFloat ( time . total_milliseconds ( ) ) ) ; // Cumulative sum of the weights let mut sum = 0.0 ; for ( weight , _ ) in weighted_segment_times . iter_mut ( ) { sum += * weight ; * weight = sum ; } // Reweigh all of the weights to be in the range 0..1 let min = weighted_segment_times . first ( ) . map ( | & ( w , _ ) | w ) . unwrap_or_default ( ) ; let max = weighted_segment_times . last ( ) . map ( | & ( w , _ ) | w ) . unwrap_or_default ( ) ; let diff = max - min ; if diff != 0.0 { for ( weight , _ ) in weighted_segment_times . iter_mut ( ) { * weight = ( * weight - min ) / diff ; } } } // Limit the slice to only the segments that have segment times self . truncate ( len ) ; }
Calculate the skill curve for the segments and timing method provided.
Calculate the skill curve for the segments and timing method provided .
&mut self
segments
&[Segment]
method
TimingMethod
&mut self
segments
&[Segment]
method
TimingMethod