PrevNextUpHome SophiaFramework UNIVERSE 5.3

9.6. Application Class(Basic)

All BREW applets which use the responder system are required to to create one instance of the user-defined application class, which is defined and implemented by inheriting from SFYApplication.

Though SFYApplication is not the responder class, by default it contains the root[SFZRoot] bound with the distributer and the renderer.

The responder-related operation on SFYApplication is delegated to its default root[SFZRoot]. An application behaves like a responder regarding to some responder-related APIs that SFYApplication provides.

Table 9.5. Type of abstract application

Class name Description
SFYApplication Abstract class which represents an application class.

9.6.1. Abstract Class that Represents an Application Class [SFYApplication]

SFYApplication is the abstract base class to define and implement the user-defined application class which uses the SFY responder system.

This class contains by default the root[SFZRoot] bound with the distributer and the renderer, and implements virtual functions below.

Table 9.6. Virtual function name and its default behaviour

Virtual function name Default behaviour Override
SFYApplication::HandleEvent Boot up the distributer, and furthermore boot up the renderer if the event is handled *1 Optional
SFYApplication::HandleRender Redraw the device screen in white and the responder tree below the root. *1 Optional
SFCApplication::HandleError - Optional
[Note] NOTE

*1. Boot up the SFCApplication::HandleError function when the fatal error such as memory insufficiency during the distributer or renderer bootup occurs.

The minimum code necessary to make the user-defined application class is as follows:

Example 9.34. Declaration

SFMTYPEDEFCLASS(USRApplication)
class USRApplication: public SFYApplication {
    SFMSEALCOPY(USRApplication)
public:
    static SFCInvokerPtr Factory(Void);
private:
    explicit USRApplication(Void) static_throws;
    virtual ~USRApplication(Void);
};

Example 9.35. Implementation

// boot loader: function first executed in BREW applet
SFCApplet::FactorySPP SFCApplet::Boot(AEECLSID id, SFXAnsiStringPtr license)
{
    // here place the license code
    *license = "heap://";

    return (id == AEECLSID_USRAPPLICATION) ? (&USRApplication::Factory): (null);
}

// factory function to create the user-defined application instance
SFCInvokerPtr USRApplication::Factory(Void)
{
    return::new USRApplication;
}

// constructor
USRApplication::USRApplication(Void) static_throws
{
    if (static_try()) {

        // here describe the initialization
    }
}

// destructor
USRApplication::~USRApplication(Void)
{
    // here describe the finalization
}
[Caution] The return statement in the constructor or destructor

In general, the return statement should not be written in the constructor and destructor with C++.

The bug has been confirmed in GCC. It is that compiler will freeze if the return statement is written in the constructor or destructor under some particular inheritance relationship.

Implementation of the SFYApplication::HandleEvent virtual function is as follows:

Example 9.36. Implementation of the SFYApplication::HandleEvent function

// virtual function that will be called when the event dispatched from the BREW environment needs to be handled
/*protected virtual */Bool SFYApplication::HandleEvent(SFXEventConstRef event)
{
    // here describe the handling of the event dispatched from the BREW environment

    SFCError  error;
    Bool      result(false);

    // boot up the distributer to distribute the event using the tracer
    // first of all, the SFYDistributer instance bound with the root will receive the event
    // then, the event will be distributed to the responders in the responder tree according to the dispatching rules of the tracer
    // * _root is the root(SFZRoot)
    if ((error = _root->Distribute(event, &result)) == SFERR_NO_ERROR) {

        if (event.GetType() != SFEVT_APP_STOP && event.GetType() != SFEVT_APP_SUSPEND)) {  // if redrawing is necessary

            if (IsRenderable()) {  // if the screen can be redrawn (i.e., if no highest priority event handler is registered)

                 // boot up the renderer to redraw the responder tree below the root
                error = _root->Render();
            }
        }
    }
    if (error != SFERR_NO_ERROR) {

        // call HandleError() in case the fatal error such as insufficient memory during the initialization of the distributer or the renderer occurs
        if (HandleError(event, error)) {

            result = true;
        }
    }
    if ((event.GetType() == SFEVT_APP_SUSPEND) && IsRendererIntermissive()) {
        // if the back-up bitmap inside the renderer is released when an application suspends

        // terminate the renderer
        _renderer.Terminate();
    }
    return result;  // return "true" if the event has been handled, otherwise return "false"
}// SFYApplication::HandleEvent //

Reference: SFCApplication::HandleEvent | SFCApplication::IsRenderable | SFCApplication::HandleError | SFYApplication::IsRendererIntermissive | SFYResponder::Distribute | SFYResponder::Render | SFYRenderer::Initialize | SFYRenderer::Terminate | SFZRoot | Root | Tracer | Distributer | Renderer Drawing Event | Drawing Handler | Event Loop

[Note] Highest Priority Event Handler

For more details, see the description of the SFCApplication::RegisterBypass function.

Implementation of the SFYApplication::HandleRender virtual function is as follows:

Example 9.37. Implementation of the SFYApplication::HandleRender function

// virtual function that will be called when the full screen needs to be redrawn
/*protected virtual */Bool SFYApplication::HandleRender(SFXEventConstRef event)
{
    // here describe full screen redrawing
    SFCError  error;
    Bool      result(false);

    if (SFCApplication::HandleRender(event)) { // redraw the device screen

        // redraw the responder tree below the root
        // *1. if possible, redraw using the bitmap to restore the device screen
        // *2. start up the renderer by calling "Render(true)" if the bitmap to restore the device screen is not available in a timing such as receiving the SFEVT_APP_START event
        // *3. in case of "Render(true)", all visible responders' drawing handlers will be called
        error = _root->Render((event.GetType() == SFEVT_APP_START) || (_root->Recover() != SFERR_NO_ERROR));

        if (error == SFERR_NO_ERROR) {

            result = true;
        }
        else {
            // call HandleError() when fatal error such as insufficient memory during initialization of renderer
            HandleError(event, error);
        }
    }
    return result;
}// SFYApplication::HandleRender //

Reference: SFCApplication::HandleRender | SFCApplication::HandleError | SFCApplication::RenderDeviceScreen | SFYResponder::Render | SFYResponder::Recover | SFZRoot | Root | Renderer