diff --git a/ink/strokes/internal/brush_tip_modeler.cc b/ink/strokes/internal/brush_tip_modeler.cc index 613f536c..fac698a7 100644 --- a/ink/strokes/internal/brush_tip_modeler.cc +++ b/ink/strokes/internal/brush_tip_modeler.cc @@ -184,9 +184,8 @@ bool SourceDependsOnNextModeledInput(BrushBehavior::Source source) { } Duration32 TimeSinceLastInput(const InputModelerState& input_modeler_state) { - // TODO: b/287041801 - Do we need to consider predicted inputs here too? return input_modeler_state.complete_elapsed_time - - input_modeler_state.total_real_elapsed_time; + input_modeler_state.full_input_metrics.elapsed_time; } } // namespace @@ -536,9 +535,10 @@ InputMetrics BrushTipModeler::CalculateMaxFixedInputMetrics( return { .traveled_distance = last_stable_input.traveled_distance - - std::max(distance_remaining_behavior_upper_bound_, - distance_fraction_behavior_upper_bound_ * - input_modeler_state.complete_traveled_distance), + std::max( + distance_remaining_behavior_upper_bound_, + distance_fraction_behavior_upper_bound_ * + input_modeler_state.full_input_metrics.traveled_distance), .elapsed_time = last_stable_input.elapsed_time - time_since_input_behavior_upper_bound_, }; diff --git a/ink/strokes/internal/brush_tip_modeler_helpers.cc b/ink/strokes/internal/brush_tip_modeler_helpers.cc index 177467a0..32a4cb31 100644 --- a/ink/strokes/internal/brush_tip_modeler_helpers.cc +++ b/ink/strokes/internal/brush_tip_modeler_helpers.cc @@ -80,15 +80,16 @@ std::optional GetTiltY(Angle tilt, Angle orientation) { float GetPredictedDistanceTraveledInStrokeUnits( const InputModelerState& input_modeler_state, const ModeledStrokeInput& input) { - return std::max( - 0.f, input.traveled_distance - input_modeler_state.total_real_distance); + return std::max(0.f, + input.traveled_distance - + input_modeler_state.real_input_metrics.traveled_distance); } Duration32 GetPredictedTimeElapsed(const InputModelerState& input_modeler_state, const ModeledStrokeInput& input) { return std::max( Duration32::Zero(), - input.elapsed_time - input_modeler_state.total_real_elapsed_time); + input.elapsed_time - input_modeler_state.real_input_metrics.elapsed_time); } // Returns the value of the given `Source` at the given modeled input, or @@ -154,7 +155,7 @@ std::optional GetSourceValue( case BrushBehavior::Source::kPredictedTimeElapsedInSeconds: return GetPredictedTimeElapsed(input_modeler_state, input).ToSeconds(); case BrushBehavior::Source::kDistanceRemainingInMultiplesOfBrushSize: - return (input_modeler_state.complete_traveled_distance - + return (input_modeler_state.full_input_metrics.traveled_distance - input.traveled_distance) / brush_size; case BrushBehavior::Source::kTimeSinceInputInSeconds: @@ -163,7 +164,7 @@ std::optional GetSourceValue( case BrushBehavior::Source::kTimeSinceStrokeEndInSeconds: if (!input_modeler_state.inputs_are_finished) return 0.0f; return (input_modeler_state.complete_elapsed_time - - input_modeler_state.total_real_elapsed_time) + input_modeler_state.full_input_metrics.elapsed_time) .ToSeconds(); case BrushBehavior::Source:: kAccelerationInMultiplesOfBrushSizePerSecondSquared: @@ -229,11 +230,13 @@ std::optional GetSourceValue( return Vec::DotProduct(input.acceleration, input.velocity.AsUnitVec().Orthogonal()) * input_modeler_state.stroke_unit_length->ToCentimeters(); - case BrushBehavior::Source::kDistanceRemainingAsFractionOfStrokeLength: - return input_modeler_state.complete_traveled_distance == 0.0f + case BrushBehavior::Source::kDistanceRemainingAsFractionOfStrokeLength: { + float stroke_length = + input_modeler_state.full_input_metrics.traveled_distance; + return stroke_length == 0.0f ? 0.0f - : 1.0f - input.traveled_distance / - input_modeler_state.complete_traveled_distance; + : 1.0f - input.traveled_distance / stroke_length; + } } return std::nullopt; } diff --git a/ink/strokes/internal/brush_tip_modeler_helpers_test.cc b/ink/strokes/internal/brush_tip_modeler_helpers_test.cc index bf810cb2..b16352db 100644 --- a/ink/strokes/internal/brush_tip_modeler_helpers_test.cc +++ b/ink/strokes/internal/brush_tip_modeler_helpers_test.cc @@ -369,7 +369,7 @@ TEST_F(ProcessBehaviorNodeTest, }; context_.brush_size = 3; current_input_.traveled_distance = 15; - input_modeler_state_.total_real_distance = 9; + input_modeler_state_.real_input_metrics.traveled_distance = 9; ProcessBehaviorNode(source_node, context_); EXPECT_THAT(stack_, ElementsAre(0.2f)); } @@ -380,7 +380,7 @@ TEST_F(ProcessBehaviorNodeTest, SourceNodePredictedTimeElapsedInSeconds) { .source_value_range = {0, 10}, }; current_input_.elapsed_time = Duration32::Seconds(15); - input_modeler_state_.total_real_elapsed_time = Duration32::Seconds(9); + input_modeler_state_.real_input_metrics.elapsed_time = Duration32::Seconds(9); ProcessBehaviorNode(source_node, context_); EXPECT_THAT(stack_, ElementsAre(0.6f)); } @@ -393,7 +393,7 @@ TEST_F(ProcessBehaviorNodeTest, }; context_.brush_size = 3; current_input_.traveled_distance = 9; - input_modeler_state_.complete_traveled_distance = 15; + input_modeler_state_.full_input_metrics.traveled_distance = 15; ProcessBehaviorNode(source_node, context_); EXPECT_THAT(stack_, ElementsAre(0.2f)); } @@ -416,7 +416,7 @@ TEST_F(ProcessBehaviorNodeTest, SourceNodeTimeSinceStrokeEndInSeconds) { }; // If `inputs_are_finished` is still `false`, the source node emits zero. - input_modeler_state_.total_real_elapsed_time = Duration32::Seconds(3); + input_modeler_state_.full_input_metrics.elapsed_time = Duration32::Seconds(3); input_modeler_state_.complete_elapsed_time = Duration32::Seconds(5); input_modeler_state_.inputs_are_finished = false; ProcessBehaviorNode(source_node, context_); @@ -628,7 +628,7 @@ TEST_F(ProcessBehaviorNodeTest, input_modeler_state_.stroke_unit_length = PhysicalDistance::Centimeters(0.1f); current_input_.traveled_distance = 50; - input_modeler_state_.total_real_distance = 46; + input_modeler_state_.real_input_metrics.traveled_distance = 46; ProcessBehaviorNode(source_node, context_); EXPECT_THAT(stack_, ElementsAre(FloatNear(0.4f, 1e-5))); @@ -776,7 +776,7 @@ TEST_F(ProcessBehaviorNodeTest, }; current_input_.traveled_distance = 3.0f; - input_modeler_state_.complete_traveled_distance = 12.0f; + input_modeler_state_.full_input_metrics.traveled_distance = 12.0f; ProcessBehaviorNode(source_node, context_); EXPECT_THAT(stack_, ElementsAre(0.75f)); } @@ -793,7 +793,7 @@ TEST_F(ProcessBehaviorNodeTest, // then the fraction of distance remaining isn't well-defined (0/0), so we // arbitrarily define that as 0% distance remaining. current_input_.traveled_distance = 0.0f; - input_modeler_state_.complete_traveled_distance = 0.0f; + input_modeler_state_.full_input_metrics.traveled_distance = 0.0f; ProcessBehaviorNode(source_node, context_); EXPECT_THAT(stack_, ElementsAre(0.0f)); } diff --git a/ink/strokes/internal/modeled_stroke_input.h b/ink/strokes/internal/modeled_stroke_input.h index 818cc8c8..1289c20b 100644 --- a/ink/strokes/internal/modeled_stroke_input.h +++ b/ink/strokes/internal/modeled_stroke_input.h @@ -77,21 +77,19 @@ struct InputModelerState { // space and physical space is unknown (possibly because the current stroke // has no inputs yet) or ill-defined. std::optional stroke_unit_length; + // The total modeled distance/time from the start of the stroke until the last + // "real" (i.e. non-predicted) modeled input so far. + InputMetrics real_input_metrics; + // The total modeled distance/time from the start of the stroke until the last + // modeled input so far (including unstable/predicted modeled inputs). + InputMetrics full_input_metrics; // The modeled time elapsed from the start of the stroke until either "now" or // the last modeled input, whichever comes later. // // This value may be different from the `current_elapsed_time` value passed to - // `ExtendStroke()` due to modeling and prediction. If `GetModeledInputs()` is - // not empty, this value will always be greater than or equal to - // `GetModeledInputs().back().elapsed_time`. + // `ExtendStroke()` due to modeling and prediction. This value will always be + // greater than or equal to `full_input_metrics.elapsed_time`. Duration32 complete_elapsed_time = Duration32::Zero(); - // The modeled distance traveled from the start of the stroke to the last - // modeled input (including unstable/predicted modeled inputs). - float complete_traveled_distance = 0; - // The total elapsed time for "real" (i.e. non-predicted) inputs only. - Duration32 total_real_elapsed_time = Duration32::Zero(); - // The total traveled distance for "real" (i.e. non-predicted) inputs only. - float total_real_distance = 0; // The number of "stable" elements at the start of `GetModeledInputs()`. // // These will not be removed or modified by subsequent calls to diff --git a/ink/strokes/internal/stroke_input_modeler.cc b/ink/strokes/internal/stroke_input_modeler.cc index 11f461ec..1c504f5a 100644 --- a/ink/strokes/internal/stroke_input_modeler.cc +++ b/ink/strokes/internal/stroke_input_modeler.cc @@ -15,6 +15,7 @@ #include "ink/strokes/internal/stroke_input_modeler.h" #include +#include #include #include @@ -22,6 +23,7 @@ #include "absl/log/absl_check.h" #include "ink/brush/brush_family.h" #include "ink/strokes/input/stroke_input_batch.h" +#include "ink/strokes/internal/modeled_stroke_input.h" #include "ink/strokes/internal/stroke_input_modeler/input_model_impl.h" #include "ink/strokes/internal/stroke_input_modeler/naive_input_modeler.h" #include "ink/strokes/internal/stroke_input_modeler/sliding_window_input_modeler.h" @@ -78,15 +80,17 @@ void StrokeInputModeler::ExtendStroke(const StrokeInputBatch& real_inputs, input_model_impl_->ExtendStroke(state_, modeled_inputs_, real_inputs, predicted_inputs); ABSL_DCHECK_LE(state_.stable_input_count, state_.real_input_count); - ABSL_DCHECK_LE(state_.real_input_count, modeled_inputs_.size()); + + SetMetricsFromInputCount(state_.real_input_count, state_.real_input_metrics); + SetMetricsFromInputCount(modeled_inputs_.size(), state_.full_input_metrics); state_.complete_elapsed_time = - std::max(state_.complete_elapsed_time, current_elapsed_time); + std::max(state_.full_input_metrics.elapsed_time, current_elapsed_time); } void StrokeInputModeler::ErasePredictedModeledInputs() { modeled_inputs_.resize(state_.real_input_count); - state_.complete_elapsed_time = state_.total_real_elapsed_time; - state_.complete_traveled_distance = state_.total_real_distance; + state_.full_input_metrics = state_.real_input_metrics; + state_.complete_elapsed_time = state_.real_input_metrics.elapsed_time; } void StrokeInputModeler::SetToolTypeAndStrokeUnitLength( @@ -101,4 +105,17 @@ void StrokeInputModeler::SetToolTypeAndStrokeUnitLength( } } +void StrokeInputModeler::SetMetricsFromInputCount(size_t modeled_input_count, + InputMetrics& metrics) { + ABSL_DCHECK_LE(modeled_input_count, modeled_inputs_.size()); + if (modeled_input_count == 0) { + metrics.elapsed_time = Duration32::Zero(); + metrics.traveled_distance = 0; + } else { + const ModeledStrokeInput& input = modeled_inputs_[modeled_input_count - 1]; + metrics.elapsed_time = input.elapsed_time; + metrics.traveled_distance = input.traveled_distance; + } +} + } // namespace ink::strokes_internal diff --git a/ink/strokes/internal/stroke_input_modeler.h b/ink/strokes/internal/stroke_input_modeler.h index 77304fc9..f12b9605 100644 --- a/ink/strokes/internal/stroke_input_modeler.h +++ b/ink/strokes/internal/stroke_input_modeler.h @@ -101,6 +101,11 @@ class StrokeInputModeler { void SetToolTypeAndStrokeUnitLength(const StrokeInputBatch& real_inputs, const StrokeInputBatch& predicted_inputs); + // Helper method for `ExtendStroke()`. Sets `metrics` based on the first + // `modeled_input_count` inputs in `modeled_inputs_`. + void SetMetricsFromInputCount(size_t modeled_input_count, + InputMetrics& metrics); + InputModelerState state_; std::vector modeled_inputs_; absl_nullable std::unique_ptr input_model_impl_; diff --git a/ink/strokes/internal/stroke_input_modeler/BUILD.bazel b/ink/strokes/internal/stroke_input_modeler/BUILD.bazel index 7ec7c257..2b39f583 100644 --- a/ink/strokes/internal/stroke_input_modeler/BUILD.bazel +++ b/ink/strokes/internal/stroke_input_modeler/BUILD.bazel @@ -125,7 +125,6 @@ cc_library( "//ink/types:duration", "//ink/types:numbers", "//ink/types:physical_distance", - "@com_google_absl//absl/cleanup", "@com_google_absl//absl/log:absl_check", "@com_google_absl//absl/types:span", "@ink_stroke_modeler//ink_stroke_modeler:params", diff --git a/ink/strokes/internal/stroke_input_modeler/input_model_impl.h b/ink/strokes/internal/stroke_input_modeler/input_model_impl.h index de1bb6e6..546c23a4 100644 --- a/ink/strokes/internal/stroke_input_modeler/input_model_impl.h +++ b/ink/strokes/internal/stroke_input_modeler/input_model_impl.h @@ -35,10 +35,10 @@ class InputModelImpl { // // When this is called, `modeled_inputs` will already have been trimmed down // to just its real inputs, and `state.complete_elapsed_time` and - // `state.complete_traveled_distance` will have been updated accordingly. This - // method is responsible for updating any previously-unstable real modeled - // inputs, modeling the new `real_inputs` and `predicted_inputs`, and updating - // `state` accordingly. + // `state.full_input_metrics` will have been updated accordingly. This method + // is responsible for updating any previously-unstable real modeled inputs, + // modeling the new `real_inputs` and `predicted_inputs`, and updating `state` + // accordingly. virtual void ExtendStroke(InputModelerState& state, std::vector& modeled_inputs, const StrokeInputBatch& real_inputs, diff --git a/ink/strokes/internal/stroke_input_modeler/naive_input_modeler.cc b/ink/strokes/internal/stroke_input_modeler/naive_input_modeler.cc index 5b275236..7748e55c 100644 --- a/ink/strokes/internal/stroke_input_modeler/naive_input_modeler.cc +++ b/ink/strokes/internal/stroke_input_modeler/naive_input_modeler.cc @@ -31,11 +31,6 @@ void NaiveInputModeler::ExtendStroke( const StrokeInputBatch& real_inputs, const StrokeInputBatch& predicted_inputs) { AppendInputs(state, modeled_inputs, real_inputs); - if (!modeled_inputs.empty()) { - const ModeledStrokeInput& last_real_input = modeled_inputs.back(); - state.total_real_elapsed_time = last_real_input.elapsed_time; - state.total_real_distance = last_real_input.traveled_distance; - } state.real_input_count = modeled_inputs.size(); state.stable_input_count = state.real_input_count; AppendInputs(state, modeled_inputs, predicted_inputs); @@ -60,8 +55,6 @@ void NaiveInputModeler::AppendInputs( acceleration = (velocity - last_input.velocity) / delta_seconds; } } - state.complete_elapsed_time = input.elapsed_time; - state.complete_traveled_distance = traveled_distance; modeled_inputs.push_back(ModeledStrokeInput{ .position = input.position, .velocity = velocity, diff --git a/ink/strokes/internal/stroke_input_modeler/naive_input_modeler_test.cc b/ink/strokes/internal/stroke_input_modeler/naive_input_modeler_test.cc index dd39e47f..50c9a589 100644 --- a/ink/strokes/internal/stroke_input_modeler/naive_input_modeler_test.cc +++ b/ink/strokes/internal/stroke_input_modeler/naive_input_modeler_test.cc @@ -122,8 +122,10 @@ TEST(NaiveInputModelerTest, RealAndCompleteElapsedTime) { /*brush_epsilon=*/0.001); modeler.ExtendStroke(input_batches[1], input_batches[2], Duration32::Zero()); - EXPECT_THAT(modeler.GetState().total_real_elapsed_time, + EXPECT_THAT(modeler.GetState().real_input_metrics.elapsed_time, Duration32Eq(Duration32::Seconds(1))); + EXPECT_THAT(modeler.GetState().full_input_metrics.elapsed_time, + Duration32Eq(Duration32::Seconds(2))); EXPECT_THAT(modeler.GetState().complete_elapsed_time, Duration32Eq(Duration32::Seconds(2))); } diff --git a/ink/strokes/internal/stroke_input_modeler/sliding_window_input_modeler.cc b/ink/strokes/internal/stroke_input_modeler/sliding_window_input_modeler.cc index 45c607f4..d1ac1a59 100644 --- a/ink/strokes/internal/stroke_input_modeler/sliding_window_input_modeler.cc +++ b/ink/strokes/internal/stroke_input_modeler/sliding_window_input_modeler.cc @@ -228,7 +228,6 @@ void SlidingWindowInputModeler::ExtendStroke( int raw_input_queue_real_input_count = raw_input_queue_.Size(); AppendRawInputsToQueue(state, predicted_inputs); ModelUnstableInputs(state, modeled_inputs, raw_input_queue_real_input_count); - UpdateRealAndCompleteDistanceAndTime(state, modeled_inputs); MarkStableModeledInputs(state, modeled_inputs); TrimRawInputQueue(state, modeled_inputs, raw_input_queue_real_input_count); } @@ -465,29 +464,19 @@ void SlidingWindowInputModeler::ModelUnstableInputs( modeled_inputs, state.stable_input_count, half_window_size_); } -void SlidingWindowInputModeler::UpdateRealAndCompleteDistanceAndTime( - InputModelerState& state, std::vector& modeled_inputs) { - if (state.real_input_count > 0) { - const ModeledStrokeInput& last_real_input = - modeled_inputs[state.real_input_count - 1]; - state.total_real_elapsed_time = last_real_input.elapsed_time; - state.total_real_distance = last_real_input.traveled_distance; - } - if (!modeled_inputs.empty()) { - const ModeledStrokeInput& last_input = modeled_inputs.back(); - state.complete_traveled_distance = last_input.traveled_distance; - state.complete_elapsed_time = last_input.elapsed_time; - } -} - void SlidingWindowInputModeler::MarkStableModeledInputs( InputModelerState& state, std::vector& modeled_inputs) { ABSL_DCHECK_LE(state.stable_input_count, state.real_input_count); ABSL_DCHECK_LE(state.real_input_count, modeled_inputs.size()); + + if (state.real_input_count == 0) return; + const ModeledStrokeInput& last_real_input = + modeled_inputs[state.real_input_count - 1]; + while (state.stable_input_count < state.real_input_count && modeled_inputs[state.stable_input_count].elapsed_time + half_window_size_ < - state.total_real_elapsed_time) { + last_real_input.elapsed_time) { ++state.stable_input_count; } } diff --git a/ink/strokes/internal/stroke_input_modeler/sliding_window_input_modeler.h b/ink/strokes/internal/stroke_input_modeler/sliding_window_input_modeler.h index 3fa6f4c9..45c36d00 100644 --- a/ink/strokes/internal/stroke_input_modeler/sliding_window_input_modeler.h +++ b/ink/strokes/internal/stroke_input_modeler/sliding_window_input_modeler.h @@ -92,17 +92,10 @@ class SlidingWindowInputModeler : public InputModelImpl { std::vector& modeled_inputs, Duration32 elapsed_time, int& start_index, int& end_index); - // Helper method for `ExtendStroke()`. Updates `state` fields for `total_real` - // and `complete` distance and time, based on current `modeled_inputs` and - // `state.real_input_count`. - void UpdateRealAndCompleteDistanceAndTime( - InputModelerState& state, - std::vector& modeled_inputs); - // Helper method for `ExtendStroke()`. Marks stable all real modeled inputs - // that are at least `half_window_size_` before - // `state.total_real_elapsed_time` (and which will therefore not change - // further when further real raw inputs are added later). + // that are at least `half_window_size_` before the `elapsed_time` of the last + // real input (and which will therefore not change further when further real + // raw inputs are added later). void MarkStableModeledInputs(InputModelerState& state, std::vector& modeled_inputs); diff --git a/ink/strokes/internal/stroke_input_modeler/spring_based_input_modeler.cc b/ink/strokes/internal/stroke_input_modeler/spring_based_input_modeler.cc index e8dd6b07..39192187 100644 --- a/ink/strokes/internal/stroke_input_modeler/spring_based_input_modeler.cc +++ b/ink/strokes/internal/stroke_input_modeler/spring_based_input_modeler.cc @@ -18,7 +18,6 @@ #include #include -#include "absl/cleanup/cleanup.h" #include "absl/log/absl_check.h" #include "ink/brush/brush_family.h" #include "ink/geometry/angle.h" @@ -149,10 +148,6 @@ void SpringBasedInputModeler::ExtendStroke( InputModelerState& state, std::vector& modeled_inputs, const StrokeInputBatch& real_inputs, const StrokeInputBatch& predicted_inputs) { - absl::Cleanup update_time_and_distance = [&]() { - UpdateStateTimeAndDistance(state, modeled_inputs); - }; - if (!last_real_stroke_input_.has_value()) { ResetStrokeModeler(stroke_modeler_, version_, brush_epsilon_, state.stroke_unit_length); @@ -278,22 +273,4 @@ void SpringBasedInputModeler::ModelInput( } } -void SpringBasedInputModeler::UpdateStateTimeAndDistance( - InputModelerState& state, std::vector& modeled_inputs) { - if (modeled_inputs.empty()) { - return; - } - - const ModeledStrokeInput& last_input = modeled_inputs.back(); - state.complete_elapsed_time = last_input.elapsed_time; - state.complete_traveled_distance = last_input.traveled_distance; - - if (state.real_input_count == 0) return; - - const ModeledStrokeInput& last_real_input = - modeled_inputs[state.real_input_count - 1]; - state.total_real_distance = last_real_input.traveled_distance; - state.total_real_elapsed_time = last_real_input.elapsed_time; -} - } // namespace ink::strokes_internal diff --git a/ink/strokes/internal/stroke_input_modeler/spring_based_input_modeler.h b/ink/strokes/internal/stroke_input_modeler/spring_based_input_modeler.h index ebc75252..fc33b200 100644 --- a/ink/strokes/internal/stroke_input_modeler/spring_based_input_modeler.h +++ b/ink/strokes/internal/stroke_input_modeler/spring_based_input_modeler.h @@ -51,11 +51,6 @@ class SpringBasedInputModeler : public InputModelImpl { void ModelInput(std::vector& modeled_inputs, const StrokeInput& input, bool last_input_in_update); - // Updates `state` elapsed time and distance properties. - void UpdateStateTimeAndDistance( - InputModelerState& state, - std::vector& modeled_inputs); - Version version_; // We use `brush_epsilon` to set up the parameters for `stroke_modeler_`, and // to determine the minimum distance that a new `stroke_model::Result` must diff --git a/ink/strokes/internal/stroke_input_modeler_test.cc b/ink/strokes/internal/stroke_input_modeler_test.cc index 58277150..58022e74 100644 --- a/ink/strokes/internal/stroke_input_modeler_test.cc +++ b/ink/strokes/internal/stroke_input_modeler_test.cc @@ -364,12 +364,13 @@ TEST_P(StrokeInputModelerTest, CumulativeDistanceTraveled) { // on the order of *around* 200 stroke units. Exactly how close the distance // is will depend on the modeler implementation, but it shouldn't be *too* far // off. - EXPECT_THAT(modeler.GetState().complete_traveled_distance, + EXPECT_THAT(modeler.GetState().full_input_metrics.traveled_distance, FloatNear(200, 25)); // Only the first 100ms of inputs were real, so the total real distance should // be *around* 100 stroke units (again, we'll leave a generous margin to allow // for different modeling strategies). - EXPECT_THAT(modeler.GetState().total_real_distance, FloatNear(100, 25)); + EXPECT_THAT(modeler.GetState().real_input_metrics.traveled_distance, + FloatNear(100, 25)); // Intermediate elapsed times/distances should also be reasonable. Different // modeling implementations may have different upsampling strategies, but // given the regularity of these test inputs, it is reasonable to assume that @@ -396,16 +397,24 @@ TEST_P(StrokeInputModelerTest, EraseInitialPredictionWithNoRealInputs) { StrokeInputBatch synthetic_predicted_inputs = input_batches[0]; ASSERT_THAT(synthetic_predicted_inputs.Append(input_batches[1]), IsOk()); modeler.ExtendStroke({}, synthetic_predicted_inputs, Duration32::Zero()); + EXPECT_EQ(modeler.GetState().real_input_count, 0); + EXPECT_EQ(modeler.GetState().real_input_metrics.elapsed_time, + Duration32::Zero()); + EXPECT_EQ(modeler.GetState().real_input_metrics.traveled_distance, 0); EXPECT_THAT(modeler.GetModeledInputs(), Not(IsEmpty())); EXPECT_GT(modeler.GetState().complete_elapsed_time, Duration32::Zero()); - EXPECT_GT(modeler.GetState().complete_traveled_distance, 0); + EXPECT_GT(modeler.GetState().full_input_metrics.elapsed_time, + Duration32::Zero()); + EXPECT_GT(modeler.GetState().full_input_metrics.traveled_distance, 0); // Now erase the prediction, still with no real inputs. Elapsed time and // distance traveled should go back to zero. modeler.ExtendStroke({}, {}, Duration32::Zero()); EXPECT_THAT(modeler.GetModeledInputs(), IsEmpty()); EXPECT_EQ(modeler.GetState().complete_elapsed_time, Duration32::Zero()); - EXPECT_EQ(modeler.GetState().complete_traveled_distance, 0); + EXPECT_EQ(modeler.GetState().full_input_metrics.elapsed_time, + Duration32::Zero()); + EXPECT_EQ(modeler.GetState().full_input_metrics.traveled_distance, 0); } TEST_P(StrokeInputModelerTest, ExtendWithoutStart) {