-
Notifications
You must be signed in to change notification settings - Fork 9
Action Queues
For the purposes of queuing actions to run sequentially, JISA provides the ActionQueue
class.
To create an action queue, you just need to instantiate an ActionQueue
object like so:
ActionQueue queue = new ActionQueue();
Adding actions to the queue is done by creating Action
objects and using the addAction(...)
method. Action
itself is an interface, so you cannot directly instantiate an Action
object. However, JISA
provides a few simple implementations of Action
. Before we cover that though, it's important to note that Action
also has a generic type, that is we should actually be writing Action<...>
. This is because Action
object can return an object as "data" by using the getData()
method. The type of object it returns is up to the implementation of Action<...>
that is used hence the need for a generic.
The simplest is SimpleAction
which just takes a runnable to define the action it should run. It returns no data, hence the generic type is Action<Void>
. For instance, if we wanted to add an action that just waits for 30 seconds we could write:
SimpleAction action1 = new SimpleAction("Wait 30s", () -> Thread.sleep(30000));
Alternatively, if we have a Measurement
object called measurement
to run and we want it to be run as part of our queue, we can wrap it in a MeasurementAction
object. These return ResultTable
objects as data hence their generic type is Action<ResultTable>
.
MeasurementAction action2 = new MeasurementAction(measurement);
After creating our Action
objects, we can add them to the queue like so:
// One at a time
queue.addAction(action1);
queue.addAction(action2);
// Or both together
queue.addActions(action1, action2);
Now, when we run the queue by calling start()
like so:
queue.start();
It will first wait 30 seconds then perform the measurement.
You can alter the queue in a number of different ways. The most straight-forward is removing actions. This can be done using the removeAction(...)
, removeActions(...)
and clear()
methods respectively:
// Remove one action
queue.removeAction(action);
// Remove multiple actions
queue.removeActions(action1, action2, action3);
// Remove all actions
queue.clear();
The other alteration that can be performed is changing the order of actions. This can be done by swapping the positions of two actions at a time by use of the swapActions(...)
method like so:
queue.swapActions(actionA, actionB);
where actionA
and actionB
are either the Action
objects to be swapped themselves, or their integer indices in the queue.
To run a queue we use the start()
method. This will not return until the queue has finished executing. The result of the execution is then returned as a ActionQueue.Result
object:
ActionQueue.Result result = queue.start();
swtich(result) {
case SUCCESS:
// All completed with no error
case INTERRUPTED:
// The queue ended early because stop() was called
case ERROR:
// One or more of the actions ended in error
}
To make a queue end early (from another thread) you can call stop()
on it:
queue.stop();
This functionality only really makes sense when using a GUI since the queue will be running on a separate thread to that which the user interacts with meaning user interaction and the running of the thread can happen simultaneously. For example:
Grid grid = new Grid("Experiment");
ActionQueue queue = new ActionQueue();
...
grid.addToolbarButton("Start Queue", () -> {
ActionQueue.Result result = queue.start();
switch(result) {
case SUCCESS:
GUI.infoAlert("Queue completed successfully");
break;
case INTERRUPTED:
GUI.warningAlert("Queue was ended early");
break;
case ERROR:
GUI.errorAlert("Queue completed with error(s)");
break;
}
});
grid.addToolbarButton("Stop Queue", queue::stop);
grid.show();
If a queue was previously interrupted, you can resume it from the last interrupted item by calling resume()
instead of start()
:
ActionQueue.Result result;
if (queue.isInterrupted()) {
result = queue.resume();
} else {
result = queue.start();
}
- Getting Started
- Object Orientation
- Choosing a Language
- Using JISA in Java
- Using JISA in Python
- Using JISA in Kotlin
- Exceptions
- Functions as Objects
- Instrument Basics
- SMUs
- Thermometers (and old TCs)
- PID and Temperature Controllers
- Lock-Ins
- Power Supplies
- Pre-Amplifiers
- Writing New Drivers