InProgressStroke


class InProgressStroke


Use an InProgressStroke to efficiently build a stroke over multiple rendering frames with incremental inputs.

To use an InProgressStroke, you would typically:

  1. Begin a stroke by calling start with a chosen Brush.

  2. Repeatedly update the stroke:

    1. Call enqueueInputs with any new real and predicted stroke inputs.

    2. Call updateShape when isUpdateNeeded is true and new geometry is needed for rendering.

    3. Render the current stroke mesh or outlines, either via a provided renderer that accepts an InProgressStroke or by using the various getters on this type with a custom renderer.

  3. Call finishInput once there are no more inputs for this stroke (e.g. the user lifts the stylus from the screen).

  4. Continue to call updateShape and render after finishInput until isUpdateNeeded returns false (to allow any lingering brush shape animations to complete).

  5. Extract the completed stroke by calling toImmutable.

  6. For best performance, reuse this object and go back to step 1 rather than allocating a new instance.

Summary

Public constructors

Public functions

Unit
enqueueInputs(
    realInputs: StrokeInputBatch,
    predictedInputs: StrokeInputBatch
)

Enqueues the incremental realInputs and sets the prediction to predictedInputs, overwriting any previous prediction.

Unit

Indicates that the inputs for the current stroke are finished.

@IntRange(from = 0) Int

Returns the number of BrushCoats for the current brush, or zero if start has not been called.

@IntRange(from = 0) Int

Returns the number of StrokeInputs in the stroke so far.

@IntRange(from = 0) Int
getOutlineCount(coatIndex: @IntRange(from = 0) Int)

Returns the number of outlines for the specified brush coat.

@IntRange(from = 0) Int
getOutlineVertexCount(
    coatIndex: @IntRange(from = 0) Int,
    outlineIndex: @IntRange(from = 0) Int
)

Returns the number of outline points for the specified outline and brush coat.

@IntRange(from = 0) Int

Returns the number of inputs in the current stroke prediction.

@IntRange(from = 0) Int
Boolean

Returns true if finishInput has been called since the last call to start, or if start hasn't been called yet.

Boolean

Returns true if calling updateShape would have any effect on the stroke (and should thus be called before the next render), or false if no calls to updateShape are currently needed.

StrokeInput
populateInput(out: StrokeInput, index: @IntRange(from = 0) Int)

Gets the value of the i-th input and overwrites out.

MutableStrokeInputBatch
populateInputs(
    out: MutableStrokeInputBatch,
    from: @IntRange(from = 0) Int,
    to: @IntRange(from = 0) Int
)

Replace the contents of the MutableStrokeInputBatch with the specified range of inputs from the this InProgressStroke.

BoxAccumulator
populateMeshBounds(
    coatIndex: @IntRange(from = 0) Int,
    outMeshBounds: BoxAccumulator
)

Writes to outBoxAccumulator the bounding box of the vertex positions of the mesh for brush coat coatIndex.

MutableVec
populateOutlinePosition(
    coatIndex: @IntRange(from = 0) Int,
    outlineIndex: @IntRange(from = 0) Int,
    outlineVertexIndex: @IntRange(from = 0) Int,
    outPosition: MutableVec
)

Fills outPosition with the x and y coordinates of the specified outline vertex.

BoxAccumulator

Returns the bounding rectangle of mesh positions added, modified, or removed by calls to updateShape since the most recent call to start or resetUpdatedRegion.

Unit

Call after making use of a value from populateUpdatedRegion to reset the accumulation.

Unit
start(brush: Brush)

Clears and starts a new stroke with the given brush.

Stroke

Copies the current input, brush, and geometry as of the last call to start or updateShape to a new Stroke.

Unit
updateShape(currentElapsedTimeMillis: Long)

Updates the stroke geometry up to the given duration since the start of the stroke.

Protected functions

Unit

Public properties

Brush?

The Brush currently being used to generate the stroke content.

Public constructors

InProgressStroke

Added in 1.0.0-alpha05
InProgressStroke()

Public functions

enqueueInputs

Added in 1.0.0-alpha05
fun enqueueInputs(
    realInputs: StrokeInputBatch,
    predictedInputs: StrokeInputBatch
): Unit

Enqueues the incremental realInputs and sets the prediction to predictedInputs, overwriting any previous prediction. Queued inputs will be processed on the next call to updateShape.

This method requires that:

Either one or both of realInputs and predictedInputs may be empty.

Throws
kotlin.IllegalStateException

If start has not been called since construction or the last call to finishInput.

kotlin.IllegalArgumentException

If the input is not valid. Note that this can be a common occurrence with real user input on certain devices, in particular due to duplicate or out-of-order inputs. Therefore, users should either catch and handle this exception or sanitize the input to avoid ensure validity before passing it to this function.

finishInput

Added in 1.0.0-alpha05
fun finishInput(): Unit

Indicates that the inputs for the current stroke are finished. After calling this, it is an error to call enqueueInputs until start is called again to start a new stroke. This method is idempotent; it has no effect if start was never called, or if this method has already been called since the last call to start. This method is synchronous, but the stroke may not be fully finished changing shape due to brush shape animations until isUpdateNeeded returns false. Until that condition is met, keep calling updateShape periodically and rendering the result.

getBrushCoatCount

Added in 1.0.0-alpha05
fun getBrushCoatCount(): @IntRange(from = 0) Int

Returns the number of BrushCoats for the current brush, or zero if start has not been called.

getInputCount

Added in 1.0.0-alpha05
fun getInputCount(): @IntRange(from = 0) Int

Returns the number of StrokeInputs in the stroke so far. This counts all of the real inputs and the most-recently-processed sequence of predicted inputs.

getOutlineCount

Added in 1.0.0-alpha05
fun getOutlineCount(coatIndex: @IntRange(from = 0) Int): @IntRange(from = 0) Int

Returns the number of outlines for the specified brush coat.

Calls to functions that accept an outlineIndex must treat the result of this function as an upper bound. Coats with discontinuous geometry will always have multiple outlines, but even continuous geometry may be drawn with multiple overlapping outlines when this improves rendering quality or performance.

Parameters
coatIndex: @IntRange(from = 0) Int

Must be between 0 (inclusive) and the result of getBrushCoatCount (exclusive).

getOutlineVertexCount

Added in 1.0.0-alpha05
fun getOutlineVertexCount(
    coatIndex: @IntRange(from = 0) Int,
    outlineIndex: @IntRange(from = 0) Int
): @IntRange(from = 0) Int

Returns the number of outline points for the specified outline and brush coat. populateOutlinePosition must treat the result of this as the upper bound of its outlineVertexIndex parameter.

Parameters
coatIndex: @IntRange(from = 0) Int

Must be between 0 (inclusive) and the result of getBrushCoatCount (exclusive).

outlineIndex: @IntRange(from = 0) Int

Must be between 0 (inclusive) and the result of getOutlineCount for the same coatIndex (exclusive).

getPredictedInputCount

Added in 1.0.0-alpha05
fun getPredictedInputCount(): @IntRange(from = 0) Int

Returns the number of inputs in the current stroke prediction.

getRealInputCount

Added in 1.0.0-alpha05
fun getRealInputCount(): @IntRange(from = 0) Int

isInputFinished

Added in 1.0.0-alpha05
fun isInputFinished(): Boolean

Returns true if finishInput has been called since the last call to start, or if start hasn't been called yet. If this returns true, it is an error to call enqueueInputs.

isUpdateNeeded

Added in 1.0.0-alpha05
fun isUpdateNeeded(): Boolean

Returns true if calling updateShape would have any effect on the stroke (and should thus be called before the next render), or false if no calls to updateShape are currently needed. Specifically:

  • If the brush has one or more timed shape animation behavior that are still active (which can be true even after inputs are finished), returns true.

  • If there are no active shape animation behaviors, but there are pending inputs from an enqueueInputs call that have not yet been consumed by a call to updateShape, returns true.

  • Otherwise, returns false.

Once isInputFinished returns true and this method returns false, the stroke is considered "dry", and will not change any further until the next call to start.

populateInput

Added in 1.0.0-alpha05
fun populateInput(out: StrokeInput, index: @IntRange(from = 0) Int): StrokeInput

Gets the value of the i-th input and overwrites out. Requires that index is positive and less than getInputCount.

Returns the passed-in StrokeInput to make it easier to chain calls.

Returns
StrokeInput

out

populateInputs

Added in 1.0.0-alpha05
fun populateInputs(
    out: MutableStrokeInputBatch,
    from: @IntRange(from = 0) Int = 0,
    to: @IntRange(from = 0) Int = getInputCount()
): MutableStrokeInputBatch

Replace the contents of the MutableStrokeInputBatch with the specified range of inputs from the this InProgressStroke. By default, all inputs are copied.

Returns the passed-in MutableStrokeInputBatch to make it easier to chain calls.

populateMeshBounds

Added in 1.0.0-alpha05
fun populateMeshBounds(
    coatIndex: @IntRange(from = 0) Int,
    outMeshBounds: BoxAccumulator
): BoxAccumulator

Writes to outBoxAccumulator the bounding box of the vertex positions of the mesh for brush coat coatIndex.

Returns the passed in BoxAccumulator to make it easier to chain calls.

Parameters
coatIndex: @IntRange(from = 0) Int

The index of the coat to obtain the bounding box from.

outMeshBounds: BoxAccumulator

The pre-allocated BoxAccumulator to be filled with the result.

populateOutlinePosition

Added in 1.0.0-alpha05
fun populateOutlinePosition(
    coatIndex: @IntRange(from = 0) Int,
    outlineIndex: @IntRange(from = 0) Int,
    outlineVertexIndex: @IntRange(from = 0) Int,
    outPosition: MutableVec
): MutableVec

Fills outPosition with the x and y coordinates of the specified outline vertex.

Returns the passed-in MutableVec to make it easier to chain calls.

Parameters
coatIndex: @IntRange(from = 0) Int

Must be between 0 (inclusive) and the result of getBrushCoatCount (exclusive).

outlineIndex: @IntRange(from = 0) Int

Must be between 0 (inclusive) and the result of getOutlineCount (exclusive) for the same coatIndex.

outlineVertexIndex: @IntRange(from = 0) Int

Must be between 0 (inclusive) and the result of getOutlineVertexCount (exclusive) for the same coatIndex and outlineIndex.

outPosition: MutableVec

the pre-allocated MutableVec to be filled with the result.

populateUpdatedRegion

Added in 1.0.0-alpha05
fun populateUpdatedRegion(outUpdatedRegion: BoxAccumulator): BoxAccumulator

Returns the bounding rectangle of mesh positions added, modified, or removed by calls to updateShape since the most recent call to start or resetUpdatedRegion.

Returns the passed in BoxAccumulator to make it easier to chain calls.

Parameters
outUpdatedRegion: BoxAccumulator

The pre-allocated BoxAccumulator to be filled with the result.

resetUpdatedRegion

Added in 1.0.0-alpha05
fun resetUpdatedRegion(): Unit

Call after making use of a value from populateUpdatedRegion to reset the accumulation.

start

Added in 1.0.0-alpha05
fun start(brush: Brush): Unit

Clears and starts a new stroke with the given brush.

This includes clearing or resetting any existing inputs, mesh data, and updated region. This method must be called at least once after construction before making any calls to enqueueInputs or updateShape.

toImmutable

Added in 1.0.0-alpha05
fun toImmutable(): Stroke

Copies the current input, brush, and geometry as of the last call to start or updateShape to a new Stroke.

The resulting Stroke will not be modified if further inputs are added to this InProgressStroke, and a Stroke created by another call to this method will not modify or be connected in any way to the prior Stroke.

updateShape

Added in 1.0.0-alpha05
fun updateShape(currentElapsedTimeMillis: Long = Long.MAX_VALUE): Unit

Updates the stroke geometry up to the given duration since the start of the stroke. This will consume any inputs queued up by calls to enqueueInputs, and cause brush shape animations (if any) to progress up to the specified time. Any stroke geometry resulting from previously-predicted input from before the previous call to this method will be cleared.

This method requires that:

Clients that do not use brushes with shape animation behaviors can omit currentElapsedTimeMillis. Doing so when using brushes with shape animation beaviors will cause the animation to be completed immediately.

Throws
kotlin.IllegalStateException

If start has not been called.

kotlin.IllegalArgumentException

If currentElapsedTimeMillis is negative or decreased from a previous call to this method for the same in-progress stroke.

Protected functions

finalize

Added in 1.0.0-alpha05
protected fun finalize(): Unit

Public properties

brush

Added in 1.0.0-alpha05
val brushBrush?

The Brush currently being used to generate the stroke content. To set this, call start.