UserSelection

class UserSelection<T : Any>(callback: Consumer<T?>, opmodes: T) : BunyipsComponent, Runnable

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

You really should only be running one of these threads at a time, preferably using the Threads class to start and manage it to allow for logging and OpMode management.

Keep in mind this 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 is a WaitForTask. If you do not do this, the OpMode will assume it is ready to run regardless.

The result of this thread will be stored in the result property, 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.

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

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

@Override
protected void onInit() {
Threads.run(selector);
}

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

res will be null if the user did not make a selection.

Updated to use dynamic button mapping and generics 04/08/23. Updated to be async and removed time restriction 07/09/23.

Author

Lucas Bubner, 2023

Since

1.0.0-pre

Parameters

opmodes

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

Constructors

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

Properties

Link copied to clipboard

The result of the user selection. Will be null if the user did not make a selection. Passed into the callback.

Link copied to clipboard

The button that was selected by the user.

Inherited properties

Link copied to clipboard
protected val opMode: BunyipsOpMode?

Get a reference to the currently running BunyipsOpMode.

Functions

Link copied to clipboard
open override fun run()

Maps a set of operation modes to a set of buttons.

Inherited functions

Link copied to clipboard
protected fun opMode(@NonNull ifRunning: Consumer<BunyipsOpMode>)

Null check consumer for the opMode field which will no-op the given consumer if an active BunyipsOpMode is not present (i.e. the opMode field is null). This method is the same to the BunyipsOpMode.ifRunning method, and is supplied here for convenience.

Link copied to clipboard
protected fun require(@Nullable nullableOpMode: BunyipsOpMode?): BunyipsOpMode

Null assertion for the opMode field which throws a NullPointerException if an active BunyipsOpMode is not present (i.e. the supplied field is null). This method replicates Objects.requireNonNull but has a built-in message to alert the user of a non-active OpMode.