This example is part of OpenSceneGraph cross-platform examples.
In this example we create a sequence of asynchronous commands to combine animations with other operations.
Note: this example requires 05.NodeSelection example knowledge.
Previous examples used Reporter
class, which was not explained before.
Reporter
is at the core of asynchronous operations. Reporter
is a simple
implementation of powerful publish-subscribe pattern.
To make a class be able to report changes to any number of
listeners, the class has to have an instance of Reporter
. Whenever the class
wants to report changes, the class should call Reporter
's report()
function.
The listening parties should subscribe to the instance
of Reporter
with its addCallback()
function.
Here's how we subscribe to be notified of each frame event (source code):
this->app->frameReporter.addCallback(
[&] {
this->rotateBox();
},
this->boxRotationCallbackName
);
And here's how the "main loop" drives frameReporter
instance of Reporter
(source code):
void frame()
{
this->viewer->frame();
this->frameReporter.report();
}
In order to have a sequence of asynchronous operations, we need to combine asynchronous functions.
From the point of view of Sequence
, an asynchronous function is a function
that returns pointer to Reporter
instance (source code):
core::Reporter *waitForBoxSelection()
{
return &this->boxSelected;
}
If you need to have a normal function call as part of Sequence
, you should
use instant asynchronous functions, i.e., functions that return zero
Reporter
instance (source code):
core::Reporter *setBoxSelectionEnabled(bool state)
{
- - - -
return 0;
}
Let's perform the following upon the box selection:
- disable selection
- dim background
- rotate the box
- restore background
- enable selection
Here's how it translates into code (source code):
this->sequence.setActions({
CORE_SEQUENCE_ACTION(
"enableBoxSelection",
this->setBoxSelectionEnabled(true)
),
CORE_SEQUENCE_ACTION(
"waitForBoxSelection",
this->waitForBoxSelection()
),
CORE_SEQUENCE_ACTION(
"disableBoxSelection",
this->setBoxSelectionEnabled(false)
),
CORE_SEQUENCE_ACTION(
"dimBackground",
this->changeBackground(true)
),
CORE_SEQUENCE_ACTION(
"startBoxRotation",
this->setBoxRotationEnabled(true)
),
CORE_SEQUENCE_ACTION(
"simulateLoading",
this->simulateLoading()
),
CORE_SEQUENCE_ACTION(
"stopBoxRotation",
this->setBoxRotationEnabled(false)
),
CORE_SEQUENCE_ACTION(
"lightBackground",
this->changeBackground(false)
),
});
// Enable sequence.
this->sequence.isRepeatable = true;
this->sequence.setEnabled(true);
Here's a web build of the example.