PrevNextUpHome SophiaFramework UNIVERSE 5.3

21.1. BREW Interface

SophiaFremwork provides the C++ wrapper classes for all the interfaces included in the BREW SDK.

21.1.1. Example: SFBHash

Example 21.1. Create the interface

// SFBHashSmp is smart pointer that manages SFBHash interface
// new interface is created by using SFBHash::NewInstance function
SFBHashSmp hash(SFBHash::NewInstance(AEECLSID_MD5));

Example 21.2. Call the interface

// call API
hash->Restart();

Example 21.3. Termination Processing after using the interface

// since interface will be automatically released, you need not to do anything

// if you want to release interface explicitly, use code below
// hash->Release(); 

21.1.2. Execution Speed of Wrapper

In a wrapper class, there are two types of functions: inline function that simply wraps the BREW API in C++, and function that takes the instances of SophiaFramework class as arguments.

Since the inline function is inline-expanded during compilation, the speed degradation will never occur at runtime.

Example 21.4. ISHELL_GetAppCopyright function of IShell interface

// BREW native API
int ISHELL_GetAppCopyright(IShell* pIShell, AECHAR* pBuff, int nSize);

// inline function that simply wraps BREW API function
SInt32 SFBShell::GetAppCopyright(WCharPtr buf, SInt32 size);

// function that takes instance of SophiaFramework class as argument
SInt32 SFBShell::GetAppCopyright(SFXWideStringPtr string);

The above function takes a pointer to the buffer where the WChar string is stored as an argument.

The inline function is one that wraps simply the BREW native API.

In the function that takes the instances of SophiaFramework class as arguments, the class such as SFXWideString is extended to be specified as an argument. Since overheads such as getting the size of SFXWideString instance are included, a bit slowdown occurs.

21.1.3. Smart Pointer

If using the smart pointer, you don't have to manage the reference counter, and also the interfaces that are no longer used will be automatically released.

Example 21.5. How to use the smart pointer

// SFBHashSmp is smart pointer for SFBHash interface
// create new interface using SFBHash::NewInstance function
SFBHashSmp hash(SFBHash::NewInstance(AEECLSID_MD5));

// call API
hash->Restart();

// interface that is no longer used will be automatically released

21.1.4. Callback function

The callback function that is used in the BREW Interface Wrapper need to be declared, implemented, and registered originally.

As in the following sample code, the actual callback function is called via the dummy callback function.

The callback function with regard to the C++ wrapper class for BREW API has limitation that it must be a static function. Therefore the acutual callback function must be called via dummy callback function defined as static member function or friend function as below.

[Note] Prototype of function that registers the callback function

The prototype of function that registers the callback function depends on the BREW Interface Wrapper.

Reference: "BREW API Reference"

Example 21.6. Declare, implement, and register the callback function as static member function.

SFMTYPEDEFCLASS(Camera)
class Camera {
SFMSEALCOPY(Camera)

private:
    SFBCameraSmp _camera;      // ICamera Interface Wrapper class 

public:
    SFCError Resume(Void);                      // resume processing
    friend Void OnCameraSHP(VoidPtr reference, AEECameraNotify* notify);    // dummy callback function 
    Void OnCamera(AEECameraNotify* notify);     // actual callback function
};

#endif

// resume processing: basic initialization for camera
SFCError Camera::Resume(Void)
{
    SFCError error(SFERR_NO_ERROR);
 
    // get camera interface
    if ((_camera = SFBCamera::NewInstance()) != null) {     
    
        // register dummy callback function
        error = _camera->RegisterNotify(OnCameraSHP, this); 
        
        if (error == SFERR_NO_ERROR) {

            ...

        }
        
    // when camera interface cannot be obtained
    } else {
    
        error = SFERR_NO_MEMORY;   
    }
    
    if (error != SFERR_NO_ERROR) {
       // error processing
    }
    return error;
}

// dummy callback function 
Void OnCameraSHP(VoidPtr reference, AEECameraNotify *notify)
{
    // call actual callback function
    static_case<CameraPtr>(reference)->OnCamera(notify); 
    return;
}

// actual callback function
Void Camera::OnCamera(AEECameraNotify* notify)
{
    switch (notify->nStatus) {
        case CAM_STATUS_START:  // when camera is started
            ...
            break;
        case CAM_STATUS_FRAME:  // when new frame is obtained
            ...
            break;
        case CAM_STATUS_DONE:   // when processing is finished
            ...
            break;
        case CAM_STATUS_FAIL:   // when processing is failed
            ...
            break;
        case CAM_STATUS_ABORT:  // when processing is stopped
            ...
            break;
    }
    return;
}
[Caution] SFBCameraSmp instance variable

The SFBCameraSmp instance variable "_camera" in which the dummy callback function is registered must be defined as variable of the Camera class.

If "_camera" is defined as local variable of member function "Camera::Resume()", the smart pointer "_camera" will be released since its scope comes off when member function "Camera::Resume()" ends. Therefore the dummy callback function "Camera::OnCameraSHP()" will be never called.

Example 21.7. Declare, implement, and register the callback function as friend function.

SFMTYPEDEFCLASS(jpegreader)
class jpegreader : public SFYApplication {
    SFMSEALCOPY(jpegreader)

private:
    SFBImageSmp _image;  // IIMage Interface Wrapper class

public:
    static SFCInvokerPtr Factory(Void);

private:
    explicit jpegreader(Void) static_throws;
    virtual ~jpegreader(Void);
    SFCError LoadImage(SFXPathConstRef path);
    SFCError ExampleDirectFile(SFXFilePtr file);  // read image via file storage
    SFCError ExampleThroughMemory(SFXFilePtr file, UInt32 size);  // read image via memory storage
    XANDLER_DECLARE_BOOLEVENT(OnKey)
    Void OnImage(Void);  // actual callback function
    static Void read_finished(VoidPtr, IImage*, AEEImageInfo*, SIntN);  // dummy callback function: defined as static memberfunction
};


// Constructor
jpegreader::jpegreader(Void) static_throws
{
    if (static_try()) {
        static_throw(RegisterHandler(
            SFXEventRange(SFEVT_KEY, SFEVT_KEY, SFP16_BEGIN, SFP16_END),
            XANDLER_INTERNAL(OnKey)
        ));
    }
    if (static_try()) {
        static_throw(LoadImage(SFXPath("version.jpg")));
    }
}

// Destructor
jpegreader::~jpegreader(Void)
{
}


// Read JPEG image via path
SFCError jpegreader::LoadImage(SFXPathConstRef path)
{
    SFXFile   file;
    UInt32    size;
    SFCError  error(SFERR_NO_ERROR);

    // get SFBImage instance
    if ((_image = SFBImage::NewInstance(AEECLSID_JPEG, &error)) != null) {

        if ((error = file.OpenReadOnly(path)) == SFERR_NO_ERROR) {

            if ((error = file.GetSize(path, &size)) == SFERR_NO_ERROR) {

                // read image via file storage
                // ExampleDirectFile(&file);

                // read image via memory storage
                ExampleThroughMemory(&file, size); 
            }
        }
    }
    return error;
}

// read image via file storage
SFCError jpegreader::ExampleDirectFile(SFXFilePtr file)
{
    // register dummy callback function
    _image->Notify((PFNIMAGEINFO)read_finished, this);

    // set stream for file storage
    return _image->SetStream(*file);
}

// read image via memory storage
SFCError jpegreader::ExampleThroughMemory(SFXFilePtr file, UInt32 size)
{
    SFXBuffer  buffer;
    VoidPtr    ptr;
    SFXMemory  memory;
    SFCError   error(SFERR_NO_ERROR);

    if (size > 0) {

        if ((error = buffer.SetSize(size)) == SFERR_NO_ERROR) {

            ptr = buffer.Detach();

            if ((error = file->Read(ptr, &size)) == SFERR_NO_ERROR) {

                if ((error = buffer.Attach(ptr, size)) ==SFERR_NO_ERROR) {

                    if ((error = memory.Open(buffer)) == SFERR_NO_ERROR) {

                        // register dummy callback function
                        _image->Notify((PFNIMAGEINFO)read_finished, this);

                        // set stream for memory storage
                        error = _image->SetStream(memory);
                    }
                }
            }
        }
    }
    else {
        error = SFERR_FAILED;
    }
    return error;
}

// actual callback function(draw image)
Void jpegreader::OnImage(Void)
{
    SFXRectangle  rx;
    AEEImageInfo  info;

    rx.Set(GetLocalBound());

    _image->GetInfo(&info);

    // draw image
    _image->Draw((rx.GetWidth() - info.cx) / 2, (rx.GetHeight() - info.cy) / 2);

    return;
}

// dummy callback function(PFNIMAGEINFO type)
Void read_finished(VoidPtr reference, IImage* /* image*/, AEEImageInfo* /* info*/, SIntN /* error*/)
{
    // call actual callback function
    static_cast<jpegreaderPtr>(reference)->OnImage();

    return;
}

// key handler
XANDLER_IMPLEMENT_BOOLEVENT(jpegreader, OnKey, invoker, event)
{
    unused(invoker);
    switch (event.GetP16()) {
        case AVK_SELECT:
            Terminate();
            return true;
    }
    return false;
}

[Caution] SFBImageSmp instance variable

The SFBImageSmp instance variable "_image" in which the dummy callback function is registered must be defined as variable of the jpegreader class.

If "_image" is defined as local variable of member function "jpegreader::LoadImage()", the smart pointer "_image" will be released since its scope comes off when member function "jpegreader::LoadImage()" ends. Therefore the dummy callback function "read_finished()" will be never called.

[Note] Callback function

In the above example, the dummy callback function "read_finished()" is defined as friend function. And the procedure to draw the JPEG image(actual callback processing) is described in the "jpegreader::OnImage()" function which is called in the dummy callback function "read_finished()".

This sample code is available at this site(jpegreader-en.zip : 100kb).