Skip to content

Commit fdfc5d6

Browse files
Ink Open Sourcecopybara-github
authored andcommitted
Introduce a range-based Append function in StrokeInputBatch
This allows appending a specific sub-range of `StrokeInput`s from one batch to another. PiperOrigin-RevId: 826053613
1 parent 9c47104 commit fdfc5d6

File tree

3 files changed

+158
-0
lines changed

3 files changed

+158
-0
lines changed

ink/strokes/input/stroke_input_batch.cc

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -357,6 +357,35 @@ absl::Status StrokeInputBatch::Append(const StrokeInputBatch& inputs) {
357357
return absl::OkStatus();
358358
}
359359

360+
absl::Status StrokeInputBatch::Append(const StrokeInputBatch& inputs,
361+
int start_index, int end_index) {
362+
ABSL_CHECK_GE(start_index, 0);
363+
ABSL_CHECK_LE(end_index, inputs.Size());
364+
ABSL_CHECK_LE(start_index, end_index);
365+
366+
if (start_index == end_index) return absl::OkStatus();
367+
368+
if (!IsEmpty()) {
369+
if (absl::Status status =
370+
ValidateConsecutiveInputs(Last(), inputs.Get(start_index));
371+
!status.ok()) {
372+
return status;
373+
}
374+
} else {
375+
if (!data_.HasValue()) data_.Emplace();
376+
SetInlineFormatMetadata(inputs.Get(start_index));
377+
}
378+
379+
std::vector<float>& data = data_.MutableValue();
380+
const std::vector<float>& append_data = inputs.data_.Value();
381+
int stride = inputs.FloatsPerInput();
382+
data.insert(data.end(), append_data.begin() + start_index * stride,
383+
append_data.begin() + end_index * stride);
384+
size_ += end_index - start_index;
385+
386+
return absl::OkStatus();
387+
}
388+
360389
void StrokeInputBatch::Erase(int start, int count) {
361390
ABSL_DCHECK_GE(start, 0);
362391
ABSL_CHECK_LE(start, Size());

ink/strokes/input/stroke_input_batch.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -144,6 +144,11 @@ class StrokeInputBatch {
144144
absl::Status Append(absl::Span<const StrokeInput> inputs);
145145
absl::Status Append(const StrokeInputBatch& inputs);
146146

147+
// Validates and appends the range of `inputs` from `start_index` (inclusive)
148+
// to `end_index` (exclusive).
149+
absl::Status Append(const StrokeInputBatch& inputs, int start_index,
150+
int end_index);
151+
147152
// Erases `count` elements beginning at `start`.
148153
//
149154
// If `start` + `count` is greater than `Size()`, then all elements from

ink/strokes/input/stroke_input_batch_test.cc

Lines changed: 124 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1582,5 +1582,129 @@ TEST(StrokeInputBatchDeathTest, EraseWithStartOutOfBounds) {
15821582
EXPECT_DEATH_IF_SUPPORTED(batch->Erase(batch->Size() + 1, 1), "");
15831583
}
15841584

1585+
TEST(StrokeInputBatchTest, AppendRangeToEmptyBatch) {
1586+
std::vector<StrokeInput> input_vector = MakeValidTestInputSequence();
1587+
absl::StatusOr<StrokeInputBatch> source_batch =
1588+
StrokeInputBatch::Create(input_vector);
1589+
ASSERT_EQ(source_batch.status(), absl::OkStatus());
1590+
1591+
StrokeInputBatch batch;
1592+
EXPECT_EQ(absl::OkStatus(), batch.Append(*source_batch, 1, 4));
1593+
EXPECT_THAT(batch,
1594+
StrokeInputBatchIsArray(absl::MakeSpan(&input_vector[1], 3)));
1595+
}
1596+
1597+
TEST(StrokeInputBatchTest, AppendRangeToNonEmptyBatch) {
1598+
std::vector<StrokeInput> input_vector = MakeValidTestInputSequence();
1599+
absl::StatusOr<StrokeInputBatch> source_batch =
1600+
StrokeInputBatch::Create(input_vector);
1601+
ASSERT_EQ(source_batch.status(), absl::OkStatus());
1602+
1603+
absl::StatusOr<StrokeInputBatch> batch =
1604+
StrokeInputBatch::Create({input_vector[0]});
1605+
ASSERT_EQ(batch.status(), absl::OkStatus());
1606+
EXPECT_EQ(absl::OkStatus(), batch->Append(*source_batch, 1, 3));
1607+
EXPECT_THAT(*batch,
1608+
StrokeInputBatchIsArray(absl::MakeSpan(&input_vector[0], 3)));
1609+
}
1610+
1611+
TEST(StrokeInputBatchTest, AppendEmptyRange) {
1612+
std::vector<StrokeInput> input_vector = MakeValidTestInputSequence();
1613+
absl::StatusOr<StrokeInputBatch> source_batch =
1614+
StrokeInputBatch::Create(input_vector);
1615+
ASSERT_EQ(source_batch.status(), absl::OkStatus());
1616+
1617+
absl::StatusOr<StrokeInputBatch> batch =
1618+
StrokeInputBatch::Create({input_vector[0]});
1619+
ASSERT_EQ(batch.status(), absl::OkStatus());
1620+
EXPECT_EQ(absl::OkStatus(), batch->Append(*source_batch, 2, 2));
1621+
EXPECT_THAT(*batch, StrokeInputBatchIsArray({input_vector[0]}));
1622+
}
1623+
1624+
TEST(StrokeInputBatchTest, AppendFullRange) {
1625+
std::vector<StrokeInput> input_vector = MakeValidTestInputSequence();
1626+
absl::StatusOr<StrokeInputBatch> source_batch =
1627+
StrokeInputBatch::Create(input_vector);
1628+
ASSERT_EQ(source_batch.status(), absl::OkStatus());
1629+
1630+
StrokeInputBatch batch;
1631+
EXPECT_EQ(absl::OkStatus(),
1632+
batch.Append(*source_batch, 0, source_batch->Size()));
1633+
EXPECT_THAT(batch, StrokeInputBatchEq(*source_batch));
1634+
}
1635+
1636+
TEST(StrokeInputBatchTest, AppendRangeWithoutOptionalAttributes) {
1637+
StrokeInputBatch batch;
1638+
absl::StatusOr<StrokeInputBatch> source_batch =
1639+
StrokeInputBatch::Create({{.tool_type = StrokeInput::ToolType::kStylus,
1640+
.position = {10, 20},
1641+
.elapsed_time = Duration32::Seconds(5)},
1642+
{.tool_type = StrokeInput::ToolType::kStylus,
1643+
.position = {20, 30},
1644+
.elapsed_time = Duration32::Seconds(5)},
1645+
{.tool_type = StrokeInput::ToolType::kStylus,
1646+
.position = {30, 40},
1647+
.elapsed_time = Duration32::Seconds(5)}});
1648+
ASSERT_EQ(source_batch.status(), absl::OkStatus());
1649+
EXPECT_EQ(absl::OkStatus(), batch.Append(*source_batch, 1, 2));
1650+
EXPECT_THAT(batch, StrokeInputBatchIsArray({source_batch->Get(1)}));
1651+
}
1652+
1653+
TEST(StrokeInputBatchTest, AppendRangeWithDecreasingTime) {
1654+
std::vector<StrokeInput> input_vector = MakeValidTestInputSequence();
1655+
absl::StatusOr<StrokeInputBatch> source_batch =
1656+
StrokeInputBatch::Create(input_vector);
1657+
ASSERT_EQ(source_batch.status(), absl::OkStatus());
1658+
1659+
// Attempt to append a range that fails validation due to non-decreasing
1660+
// `elapsed_time`.
1661+
absl::StatusOr<StrokeInputBatch> batch =
1662+
StrokeInputBatch::Create({input_vector[3]});
1663+
ASSERT_EQ(batch.status(), absl::OkStatus());
1664+
absl::Status status = batch->Append(*source_batch, 1, 3);
1665+
EXPECT_EQ(status.code(), absl::StatusCode::kInvalidArgument);
1666+
EXPECT_THAT(status.message(), HasSubstr("non-decreasing `elapsed_time`"));
1667+
EXPECT_THAT(*batch, StrokeInputBatchIsArray({input_vector[3]}));
1668+
}
1669+
1670+
TEST(StrokeInputBatchTest, AppendRangeWithIncompatibleFormat) {
1671+
std::vector<StrokeInput> input_vector = MakeValidTestInputSequence();
1672+
absl::StatusOr<StrokeInputBatch> source_batch =
1673+
StrokeInputBatch::Create(input_vector);
1674+
ASSERT_EQ(source_batch.status(), absl::OkStatus());
1675+
1676+
// Append a range with an incompatible format.
1677+
absl::StatusOr<StrokeInputBatch> batch =
1678+
StrokeInputBatch::Create({input_vector[0]});
1679+
ASSERT_EQ(batch.status(), absl::OkStatus());
1680+
1681+
std::vector<StrokeInput> different_format_vector =
1682+
MakeValidTestInputSequence(StrokeInput::ToolType::kMouse);
1683+
absl::StatusOr<StrokeInputBatch> different_format_batch =
1684+
StrokeInputBatch::Create(different_format_vector);
1685+
ASSERT_EQ(different_format_batch.status(), absl::OkStatus());
1686+
1687+
absl::Status status = batch->Append(*different_format_batch, 1, 3);
1688+
EXPECT_EQ(status.code(), absl::StatusCode::kInvalidArgument);
1689+
EXPECT_THAT(status.message(), HasSubstr("tool_type"));
1690+
EXPECT_THAT(*batch, StrokeInputBatchIsArray({input_vector[0]}));
1691+
}
1692+
1693+
TEST(StrokeInputBatchTest, AppendRangeWithIndexOutOfBounds) {
1694+
std::vector<StrokeInput> input_vector = MakeValidTestInputSequence();
1695+
absl::StatusOr<StrokeInputBatch> source_batch =
1696+
StrokeInputBatch::Create(input_vector);
1697+
ASSERT_EQ(source_batch.status(), absl::OkStatus());
1698+
1699+
StrokeInputBatch batch;
1700+
EXPECT_DEATH_IF_SUPPORTED(auto status = batch.Append(*source_batch, -1, 1),
1701+
"");
1702+
EXPECT_DEATH_IF_SUPPORTED(
1703+
auto status = batch.Append(*source_batch, 0, source_batch->Size() + 1),
1704+
"");
1705+
EXPECT_DEATH_IF_SUPPORTED(auto status = batch.Append(*source_batch, 5, 0),
1706+
"");
1707+
}
1708+
15851709
} // namespace
15861710
} // namespace ink

0 commit comments

Comments
 (0)