PrevNextUpHome SophiaFramework UNIVERSE 5.3

20.3. Callback Class

For dealing with a callback, there are the SFXCallback, SFXTimer and SFXTask classes.

Both of the SFXTimer class and the SFXTask class are implemented using the SFXCallback class internally.

20.3.1. SFXCallback Class: for dealing with a callback

The SFXCallback class is the kernel class to deal with a callback. This calss internally contains the BREW API AEECallback structure to be passed to the BREW environment as the callback information, through which the callback parameters can be set, and the registered callback can be confirmed or canceled.

In the implementation of the SFXCallback::Set function, a callback function and data passed to the callback function is set to the BREW API AEECallback structure that the SFXCallback class contains internally by calling the BREW API CALLBACK_Init function as follows:

Example 20.8. Implementation of the SFXCallback::Set function

class SFXCallback {

    ...

    private:
        The SFXCallback class contains the AEECallback structure internally
        AEECallback _callback;

    ...

}

/*public */Void SFXCallback::Set(CallbackSPP spp, VoidPtr reference)
{
    cancel the callback registered into _callback
    Cancel();

    clear data of _callback
    SFXHelper::memset(&_callback, 0, sizeof(_callback));

    initialize _callback with a callback function and data passed to the callback function
    CALLBACK_Init(&_callback, spp, reference);
    return;
}// SFXCallback::Set //

With the interface_cast operator, the SFXCallback class can be casted into the BREW API AEECallback structure, and vice versa.

In general, the BREW API AEECallback structure is passed between BREW API and SophiaFramework UNIVERSE by using this operator.

The below is the code to pass the BREW API AEECallback structure converted from the SFXCallback class by using the interface_cast operator to the BREW API ISHELL_SetTimerEx function.

Example 20.9. Method to pass the SFXCallback class to BREW API by converting it into the AEECallback structure

/*public */inline SFCError SFBShell::SetTimerEx(SInt32 mSecs, SFXCallbackPtr callback)
{
    return ISHELL_SetTimerEx(interface_cast(this), mSecs, interface_cast(callback));
}// SFBShell::SetTimerEx //
[Note] SFXCallback class

The SFXCallback class is used to implement callbacks in reading or writing data from or into the storage classes, a timer (SFXTimer), and a timer (SFXTask).

20.3.2. SFXTimer Class: for dealing with a timer

The SFXTimer class is used to deal with a timer, that is, callback that will be called and executed after a specified time elapses.

The method to use the SFXTimer class is as follows:

  1. Set the timer information(callback function and data passed to the callback function) with the SFXTimer::Set function.
  2. Schedule the timer with the SFXTimer::Schedule function, that is, register the callback into the AEE shell. In the argument of this function, the elapsed time until the callback is called should be specified in milliseconds.
  3. When the time specified in the argument of the SFXTimer::Schedule function elapses, the callback will be called.
  4. If the SFXTimer::Cancel function is called before the callback is called, the scheduled timer, the registered callback, will be canceled.
[Note] Internal implementation

The SFXTimer class is implemented by using the SFXCallback class. In the internal implementaion, the BREW API ISHELL_SetTimerEx function is used to schedule a timer, i.e., register a callback,

Example 20.10. Method to use the SFXTimer class

// define _timer as the class member variable
class MyClass {
private:
    SFXTimer _timer;
public:
    Void Start(Void);
    
    // callback function
    XALLBACK_DECLARE_SFXTIMER(OnTimer)
};

Void MyClass::Start(Void)
{
    SFCError error;

    // set information necessary to schedule the timer
    // * set the OnTimer function and data passed to the OnTimer function
    _timer.Set(XALLBACK_INTERNAL(OnTimer));

    // schedule the timer
    // * the OnTimer function will be called after the 1000 milliseconds elapses
    error = _timer.Schedule(1000);

    if (error != SFERR_NO_ERROR) {

        // if an error occurs (the OnTimer function will not be called)
    }
}

/// callback function called by BREW environment after the specified time elapses
XALLBACK_IMPLEMENT_SFXTIMER(MyClass, OnTimer)
{
    TRACE("timer");
    
    // with the code below, this timer will be called after the 1000 milliseconds elapses
    // _timer.Schedule(1000);
}
[Caution] Containing the SFXTimer instance

When a timer is used, the SFXTimer instance must not be released.

Example 20.11. Cancelling the timer

// cancel the timer
// this function may be called anywhere
_timer.Cancel();

The SFXTimer::Cancel function is called in the SFXTimer::~SFXTimer destructor or the SFXTimer::Schedule / SFXTimer::Set function.

20.3.3. SFXTask Class: for dealing with a task

The SFXTask class is used to deal with a task, that is, callback that will be called in the next event loop. This class used mainly to implement cooperative multi-task processing.

The method to use the SFXTask class is as follows:

  1. Set the timer information(callback function and data passed to the callback function) with the SFXTask::Set function.
  2. Schedule the timer with the SFXTask::Schedule function, that is, register the callback into the AEE shell.
  3. The callback will be called in the next event loop.
  4. If the SFXTask::Cancel function is called before the callback is called, the scheduled task, the registered callback, will be canceled.
[Note] Internal implementation

The SFXTask class is implemented by using the SFXCallback class. In the internal implementaion, the BREW API ISHELL_Resume function is used to schedule a task, i.e., register a callback,

In the BREW environment, one processing must be finished within about 1 second. Therefore, the processing that takes more than 1 second must be divided into segments that take less than 1 second, and then execute each segment sequentially by using the SFXTask class.

The below is the code to divide one processing into several seguments each of which will be executed sequentially.

Example 20.12. Task Division

// define SFXTask instance as class member variable
class MyClass {
private:
    SFXTask _task;
    SInt32 _index;
    SInt32 _sum;
public:
    Void Start(Void);
    SInt32 Calculate(SInt32 index);

    // callback function
    XALLBACK_DECLARE_SFXTIMER(OnTask)
};

Void MyClass::Start(Void)
{
    SFCError error;

    _index = 1;
    _sum = 0;

    // set information necessary to schedule the task
    // * set the OnTask function and data passed to the OnTask function
    _task.Set(XALLBACK_INTERNAL(OnTask));

    // schedule task
    error = _task.Schedule();

    if (error != SFERR_NO_ERROR) {

        // if an error occurs: the OnTask function will not be called
    }
    
    // control is returned to BREW environment after this code ended,
    // the Ontask function will be called by BREW environment in the next event loop
}

// time consuming calculation
SInt32 MyClass::Calculate(SInt32 index)
{
    SInt32 i;
    for (i = 0; i < 5000000; ++i) {
        ;
    }
    return index;
}

/// callback function called by BREW environment in the next event loop
XALLBACK_IMPLEMENT_SFXTIMER(MyClass, OnTask)
{
    SFCError error;

    if (_index <= 100) { // divide calculation into 100 segments

        // calculate with _index
        _sum += Calculate(_index);
        ++_index;
        // schedule task agian: the OnTask function will be called again by BREW environment
        error = _task.Schedule();

        if (error != SFERR_NO_ERROR) {
            // if an error occurs: the OnTask function will not be called
        }
    }
    else {
        // display result
        TRACE("%d", _sum);
    }
}

The above code is equivalent with the following.

SInt32 i;
SInt32 sum = 0;
for (i = 1; i <= 100; ++i) {
    sum += Calculate(i);
}

Example 20.13. Cancelling the task

// cancel the task
// this function may be called anywhere
_task.Cancel();

The SFXTask::Cancel function is called in the SFXTask::~SFXTask destructor or the SFXTask::Schedule / SFXTask::Set function.