UserSelection

class UserSelection<T : Any> @SafeVarargs constructor(callback: Consumer<T?>, selections: T) : Callable<T>

Callable thread-friendly operation to ask for user input from a controller in order to determine a pre-determined set of instructions before a BunyipsOpMode starts (during dynamic_init).

You really should only be running one of these at a time, preferably using the Threads class to start and manage it to allow for logging, OpMode management, and parallelization. AutonomousBunyipsOpMode handles the propagation of a user selection fully automatically and re-exposes it through onReady. Note you area ble to call this UserSelection manually via call, but be warned as this will block your thread until completion. During init, this may not matter, so pick whichever method you wish.

Keep in mind a thread runs in the background so it is not guaranteed to be ready during any specific phase of your init-cycle. It is recommended to check if this thread is running using Threads.isRunning(selector) in your onInitLoop() to ensure BOM knows it has to wait for the user to make a selection. Alternatively, you can set an init-task that simply waits for the thread to die or similar (e.g. Task.waitFor(() -> !Threads.isRunning(...))). You can also alternatively use the init branch of this task to initialise the user selection. onReady of AutonomousBunyipsOpMode handles this. If you do not implement a waiting action, the OpMode will assume it is ready to run regardless.

The result of this thread will be stored in the Future getter, which you can access yourself, or you can attach a callback to the callback property to be run once the thread is complete. This callback will still be run if the OpMode moves to a running state without a selection. In the event a user does not make a selection, the callback result and result property will be null or an array of nulls if chaining is used.

// In Kotlin using a lambda function, String can be replaced with any type
private val selector: UserSelection<String> = UserSelection({ if (it == "POV") initPOVDrive() else initFCDrive() }, "POV", "FIELD-CENTRIC")

override fun onInit() {
Threads.start("drive selector", selector)
}
// In Java using a callback, String can be replaced with any type
private UserSelection<String> selector = new UserSelection<>(this::callback, "POV", "FIELD-CENTRIC");

@Override
protected void onInit() {
Threads.start("drive selector", selector);
}

private void callback(@Nullable String res) {
// Do something with res
}

New feature as of BunyipsLib v7.0.0: Passing in multiple Array or Collection instances, effectively passing in a type T of Array<*>/Collection<*> will activate chaining mode. Chaining mode will prompt the user to select sequentially given the options in each sub-array, allowing you to compose and piece together separate selections. The callback, which will be of Array<*> or Collection<*> will return the selections made for each section. Null values will fill the array at the point the selection is terminated early, hence the return type is still T?. Chaining Array with Collection instances will not trigger chaining. All elements of T must conform with either a vararg of arrays (primitive arrays will be autoboxed), or vararg of collections (including List and Set). You can choose to disable chaining behaviour by calling disableChaining.

This class is currently only supported for use in a BunyipsOpMode context as it references several of its internal components.

Author

Lucas Bubner, 2023

Since

1.0.0-pre

Parameters

selections

Modes to map to buttons. Will be cast to strings for display and return back in type T.

Constructors

Link copied to clipboard
constructor(callback: Consumer<T?>, vararg selections: T)

Types

Link copied to clipboard
object Companion

Properties

Link copied to clipboard

The captions used which are appended after the text "ACTION REQUIRED: " on the DS.

Functions

Link copied to clipboard
open override fun call(): T?

Maps a set of operation modes to a set of buttons, then blocks until the user inputs an option via gamepad1.

Link copied to clipboard
fun captionLayer(layer: Int, caption: String): UserSelection<T>

Chaining utility to add a layering caption to captionLayers, which will display the given caption on the desired selection layer. Since this string will be added to telemetry, if HTML is available for telemetry you can use HTML here for formatting.

Link copied to clipboard

Disables user selection chaining when passing in sets of Array or Collection instances.