PrevNextUpHome SophiaFramework UNIVERSE 5.3

9.20. Optimize

In general, there are more than one method to program a function, but the performance or maintainability of the code will differ greatly depending on each method.

In this section, several methods to optimize your code will be described.

9.20.1. Setting Data from Resource File

If various data such as a text or an image used in a control or a dialog are saved in a resource file, it will be easy to provide multi-language support.

There is a method to set data to a responder by reading it from a resource file with the SFBShell::LoadResString function or SFBShell::LoadResImage function. However, in case of a responder such as a control or a dialog, you can set data to it directly and automatically from a resource file.

Example 9.149. Not optimized code

SFZTextButtonControlSmp button;
SFBShellSmp shell;
SFXWideString string;
SFCError error(SFERR_NO_ERROR);

...
// if text data are directly embedded into codes
// it will be troublesome to provide multi-language support
error = button->SetText("OK");

// below is to set text to text button control by reading it from the resource file
// error handling is not enough as it is
error = button->SetText(SFBShell::GetInstance()->LoadResString("usrapplication.bar", 128));

// it is troublesome to implement this with enough error handling since code becomes big
if ((shell = SFBShell::GetInstance()) != null) {

    error = string.Set(shell->LoadResString("usrapplication.bar", 128));
    if (error == SFERR_NO_ERROR) {

        error = button->SetText(string);
    }
}
else {

    error = SFERR_FAILED;
}
...

Example 9.150. Optimized code

SFZTextButtonControlSmp button;
SFCError error(SFERR_NO_ERROR);

...
// set the text to text button control directly from the resource file
// error handling is enough as it is
error = button->SetText("usrapplication.bar", 128);
...

The method to set an image to a responder directly from a resource file is the same with the above.

9.20.2. How to Use the Functions for Setting Various States

You can set various states with the functions such as SFYResponder::SetStateVisible or SFYResponder::SetStateFocus. However in case of setting all states together at a time, it will be recommended to use the SFYResponder::SetState function from performance point of view.

Example 9.151. Not optimized code

SFZTextButtonControlSmp button;

...

// set button control's visible state to "true"
button->SetStateVisible(true);

// set button control's active state to "true"
button->SetStateActive(true);

// set button control's enable state to "true"
button->SetStateEnable(true);

// set button control's focus state to "true"
button->SetStateFocus(true);

...

Example 9.152. Optimized code

SFZTextButtonControlSmp button;

...

// set button control's state to "visible" + "active" + "enable" + "focus" together 
button->SetState(true, true, true, true);

...

9.20.3. Setting the State of Backgound Responder to "Invisible"

In more than one window transition, drawing speed may improve by explicitly setting the visible state of a responder which is invisible behind foreground windows to "false".

Due to the renderer's algorithm of SophiaFramework UNIVERSE, the more child responders of the window such as controls, the greater the performance will improve.

Example 9.153. Non-optimized code

SFZWindowSmp window_a;
SFZWindowSmp window_b;

...
// perform initialization
// both window_a and window_b have the same size with their parent responder
window_a->SetRealBound(GetLocalBound());
window_b->SetRealBound(GetLocalBound());
// set window_a and window_b's states to "visible" + "active" + "enable" + "unfocus" together 
window_a->SetState(true, true, true, false); // window_a is visible
window_b->SetState(true, true, true, false); // window_b is visible
// move window_a foremost
window_a->ToFront(); // window_b is still visible

// next, move window_b foremost
window_b->ToFront(); // window_a is still visible
...

Example 9.154. Optimized code

SFZWindowSmp window_a;
SFZWindowSmp window_b;

...
// perform initialization
// both window_a and window_b have the same size with their parent responder
window_a->SetRealBound(GetLocalBound());
window_b->SetRealBound(GetLocalBound());
// set window_a's states to "visible" + "active" + "enable" + "unfocus" together 
window_a->SetState(true, true, true, false);
// set window_b's states to "invisible" + "active" + "enable" + "unfocus" together 
window_b->SetState(false, true, true, false);
// move window_a foremost
window_a->ToFront(); // window_b is invisible

// next, move window_b foremost
// set window_a's visible state to "false"
window_a->SetStateVisible(false);
window_b->ToFront(); // window_a is invisible
// set window_b's visible state to "true"
window_b->SetStateVisible(true);
...

9.20.4. Registering More Than One Dispatching Rule Together at a Time

In addition to registering more than one dispatching rule into a tracer one by one, there is a speed-optimized method to register them together at a time with an array structure.

To register multiple dispatching rules into a tracer together at a time, use an array of dispatching rules as follows:

Example 9.155. Not optimized code

SFCError error(SFERR_NO_ERROR);

// register dispatching rule for SFEVT_APP_RESUME event into tracer
error = RegisterTracer(
    SFXEventRange(SFEVT_APP_RESUME, SFEVT_APP_RESUME, SFP16_BEGIN, SFP16_END),
    SFYTracer::ORDER_BACKWARD, SFYTracer::STATE_NONE, true
);
if (error == SFERR_NO_ERROR) {

    // register dispatching rule for SFEVT_APP_SUSPEND event into tracer
    error = RegisterTracer(
        SFXEventRange(SFEVT_APP_SUSPEND, SFEVT_APP_SUSPEND, SFP16_BEGIN, SFP16_END),
        SFYTracer::ORDER_FORWARD, SFYTracer::STATE_NONE, true
    );
    if (error == SFERR_NO_ERROR) {

        // register dispatching rule for SFEVT_KEY event into tracer
        error = RegisterTracer(
            SFXEventRange(SFEVT_KEY, SFEVT_KEY, SFP16_BEGIN, SFP16_END),
            SFYTracer::ORDER_FORWARD, SFYTracer::STATE_ALL, false
        );
    }
}

Example 9.156. Optimized code

// array of SFEVT_APP_RESUME / SFEVT_APP_SUSPEND / SFEVT_KEY events
static SFXEventRange::AtomRecConst range[] = {
    {         SFEVT_APP_RESUME,    SFEVT_APP_RESUME, SFP16_BEGIN, SFP16_END},
    {        SFEVT_APP_SUSPEND,   SFEVT_APP_SUSPEND, SFP16_BEGIN, SFP16_END},
    {                SFEVT_KEY,           SFEVT_KEY, SFP16_BEGIN, SFP16_END}
};

// array of dispatching rules for SFEVT_APP_RESUME / SFEVT_APP_SUSPEND / SFEVT_KEY events
static SFYTracer::RuleRecConst rule[lengthof(range)] = {
    {SFYTracer::ORDER_BACKWARD, SFYTracer::STATE_NONE,     true},
    { SFYTracer::ORDER_FORWARD, SFYTracer::STATE_NONE,     true},
    { SFYTracer::ORDER_FORWARD, SFYTracer::STATE_ALL,    false}
};

SFCError error(SFERR_NO_ERROR);

// register dispatching rules for SFEVT_APP_RESUME / SFEVT_APP_SUSPEND / SFEVT_KEY events into tracer together at a time with array structure
error = RegisterTracer(atomic_cast(range), rule, lengthof(range));

9.20.5. Registering More Than One Handler Together at a Time

In addition to registering more than one handler into a responder one by one, there is a speed-optimized method to register them together at a time with an array structure.

To register multiple handlers into a responder together at a time, use an array of handler rules from performance point of view as follows:

Example 9.157. Not optimized code

SFCError error(SFERR_NO_ERROR);

// register handler for SFEVT_APP_RESUME event into responder
error = RegisterHandler(
    SFXEventRange(SFEVT_APP_RESUME, SFEVT_APP_RESUME, SFP16_BEGIN, SFP16_END),
    XANDLER_INTERNAL(OnAppResume)
);
if (error == SFERR_NO_ERROR) {

    // register handler for SFEVT_APP_SUSPEND event into responder
    error = RegisterHandler(
        SFXEventRange(SFEVT_APP_SUSPEND, SFEVT_APP_SUSPEND, SFP16_BEGIN, SFP16_END),
        XANDLER_INTERNAL(OnAppSuspend)
    );
    if (error == SFERR_NO_ERROR) {

        // register handler for SFEVT_KEY event into responder
        error = RegisterHandler(
            SFXEventRange(SFEVT_KEY, SFEVT_KEY, SFP16_BEGIN, SFP16_END),
            XANDLER_INTERNAL(OnKey)
        );
    }
}

Example 9.158. Optimized code

// array of SFEVT_APP_RESUME / SFEVT_APP_SUSPEND / SFEVT_KEY events
static SFXEventRange::AtomRecConst range[] = {
    { SFEVT_APP_RESUME, SFEVT_APP_RESUME, SFP16_BEGIN, SFP16_END},
    {SFEVT_APP_SUSPEND, SFEVT_APP_SUSPEND, SFP16_BEGIN, SFP16_END},
    {        SFEVT_KEY,       SFEVT_KEY, SFP16_BEGIN, SFP16_END}
};

// array of handlers for SFEVT_APP_RESUME / SFEVT_APP_SUSPEND / SFEVT_KEY events
SFYHandler::RuleRec rule[lengthof(range)];

SFCError error(SFERR_NO_ERROR);

rule[0].spp = XANDLER_FUNCTION(OnAppResume);  // handler for SFEVT_APP_RESUME event
rule[0].reference = this;
rule[1].spp = XANDLER_FUNCTION(OnAppSuspend); // handler for SFEVT_APP_SUSPEND event
rule[1].reference = this;
rule[2].spp = XANDLER_FUNCTION(OnKey);        // handler for SFEVT_KEY event
rule[2].reference = this;

// register handlers for SFEVT_APP_RESUME / SFEVT_APP_SUSPEND / SFEVT_KEY events into responder together at a time with array structure
error = RegisterHandler(atomic_cast(range), rule, lengthof(range));