SophiaFramework UNIVERSE 5.3 |
This chapter outlines the processing steps from start up to termination of SophiaFramework UNIVERSE application
The HelloWorld source code is used as an example to explain the basic structure and processing flow of SophiaFramework UNIVERSE application.
Example 10.87. Hello World : .hpp file (class definition)
// // HelloWorld.hpp // // This source code was automatically // generated by SophiaFramework UNIVERSE 5.3. // #ifndef __HELLOWORLD_HPP #define __HELLOWORLD_HPP #include <SophiaFramework.hpp> #include "HelloWorld.bid" SFMTYPEDEFCLASS(HelloWorld) class HelloWorld : public SFRApplication { SFMSEALCOPY(HelloWorld) public: static SFCInvokerPtr Factory(Void); private: HelloWorld(Void) static_throws; virtual ~HelloWorld(Void); HANDLER_DECLARE_VOIDRENDER(OnRenderContent) }; #endif // __HELLOWORLD_HPP //
Example 10.88. Hello World: .cpp file (Boot Loader and Factory function)
// // HelloWorld.cpp // // This source code was automatically // generated by SophiaFramework UNIVERSE 5.3. // #include "HelloWorld.hpp" // Boot Loader SFCApplet::FactorySPP SFCApplet::Boot(AEECLSID id, SFXAnsiStringPtr license) { *license = "heap://"; return (id == AEECLSID_HELLOWORLD) ? (&HelloWorld::Factory) : (null); } // Factory function SFCInvokerPtr HelloWorld::Factory(Void) { return ::new HelloWorld; } // Constructor HelloWorld::HelloWorld(Void) static_throws { if (static_try()) { static_throw(RegisterHandler(SREVT_RESPONDER_RENDER, SRP16_RENDER_CONTENT, HANDLER_BEFORE, HANDLER_FUNCTION(OnRenderContent))); } return; } // Destructor HelloWorld::~HelloWorld(Void) { return; } // Drawing handler HANDLER_IMPLEMENT_VOIDRENDER(HelloWorld, OnRenderContent, graphics) { // draw the string "Hello World" to the screen graphics->DrawText("Hello World", GetContentWorld()); return; }
The Application class of HelloWorld that uses GUI framework inherits from SFRApplication class.
Note | |
---|---|
In case GUI framework is not used, it inherits from SFCApplication. |
SFMTYPEDEFCLASS is a macro function that automatically generates convenient names related with user-defined types.
Since the instance of Application class must not be copied, the copy operation is prohibited by using the SFMSEALCOPY macro function.
The factory function, the constructor, the destructor, and the drawing handler are defined in the HelloWorld class.
The so-called "Boot Loader" SFCApplet::Boot() function starts the execution of the SophiaFramework UNIVERSE application. In this function, the factory function corresponding to ClassID and Lisence Code is returned. The factory function generates the instance of the HelloWorld application class.
The macro function HANDLER_DECLARE_VOIDRENDER(OnRenderContent) in the header file declares the drawing handler to draw "Hello World".
In the constructor, register the drawing handler with the drawing event by using the RegisterHandler function. The drawing handler is implemented by using the HANDLER_IMPLEMENT_VOIDRENDER(HelloWorld, OnRenderContent, graphics) macro function.
The DrawText function in the drawing handler draws the string "Hello World". The "graphics" variable is a pointer to the instance of SFXGraphics class. When the handler for a certain event is implemented in the child class, the handler of parent class for the same event will not be called. The following code describes how to call the handler of parent class.
Example 10.89. Call the handler of parent class from child class
HANDLER_IMPLEMENT_VOIDRENDER(HelloWorld, OnRenderContent, graphics) { // call drawing handler of parent class SFRApplication::ContentHandler(graphics); // draw string on screen graphics->DrawText("Hello World", GetContentWorld(), SFXRGBColor(0x00, 0x00, 0x00, 0x00)); return; }
In the above code, the whole screen is painted in white, after the drawing handler ContentHandler(graphics) of SFRApplication class (HelloWorld's parent class) is called, the text color is set to black, and the string "Hello World" is drawn.
The static_try function verifies the error value that may occur in the constructor, while the static_throw function sets an error value in the constructor. The error value set by the static_throw function can be caught by using the static_catch function. In general, the static_catch function is called in the class that uses the class instance throwing an error value by the static_throw function.
Example 10.90. How to use the static_catch function
// code to catch and handle an error value helloworld = ::new HelloWorld(); switch( helloworld->static_catch() ){ // handle the error according to its value };
The static_exception class has the variable that holds the error value. The type of this variable is template and the SFCError type is usually used.
The merit of static_exception class lies in the fact that it is the general rule of throwing out the error value inside the constructor or operator.
The Onlybootup application do nothing except starting up. The code below is used to explain the processing when application is starting up.
Example 10.91. Onlybootup : .cpp file ( Boot Loader and Factory function )
// // Onlybootup.cpp // // This source code was automatically // generated by SophiaFramework UNIVERSE 5.3. // #include "Onlybootup.hpp" // Boot Loader SFCApplet::FactorySPP SFCApplet::Boot(AEECLSID id, SFXAnsiStringPtr license) { *license = "heap://"; return (id == AEECLSID_ONLYBOOTUP) ? (&Onlybootup::Factory) : (null); } // Factory function SFCInvokerPtr Onlybootup::Factory(Void) { return ::new Onlybootup; } // Constructor Onlybootup::Onlybootup(Void) static_throws { return; } // Destructor Onlybootup::~Onlybootup(Void) { return; }
The Onlybootup class which inherits from SFRApplication class is the main part of application processing.
The Onlybootup application starts up by invoking the SFCApplet::Boot function called "Boot loader".
In the SFCApplet::Boot function, the license code corresponding to the ClassID is set, the address of Onlybootup::Factory function which generates the instance of Onlybootup class is then returned.
Next, the Onlybootup::Factory function is invoked, the instance of Onlybootup class is generated only once by the constructor of Onlybootup::Onlybootup function. Afterwards, the SFEVT_APP_START event is transmitted to the Onlybootup application, and the starting up of Onlybootup application is completed. When the Onlybootup application terminates, the instance of Onlybootup class is automatically destroyed.
* In SophiaFramework UNIVERSE an Application class can be bound with two or more ClassIDs. The code in which multiple ClassIDs switches and binds with an application is shown below.
Example 10.92. Multiple applications boot up : .hpp file (class definition)
// // Twin.hpp // // This source code was automatically // generated by SophiaFramework UNIVERSE 5.3. // #ifndef __TWIN_HPP #define __TWIN_HPP #include <SophiaFramework.hpp> #include "TwinA.bid" #include "TwinB.bid" SFMTYPEDEFCLASS(TwinA) class TwinA : public SFRApplication { SFMSEALCOPY(TwinA) public: static SFCInvokerPtr Factory(Void); private: TwinA(Void) static_throws; virtual ~TwinA(Void); }; SFMTYPEDEFCLASS(TwinB) class TwinB : public SFRApplication { SFMSEALCOPY(TwinB) public: static SFCInvokerPtr Factory(Void); private: TwinB(Void) static_throws; virtual ~TwinB(Void); }; #endif // __TWIN_HPP //
Example 10.93. Multiple applications start up : .cpp file (Boot Loader and Factory function)
// // Twin.cpp // // This source code was automatically // generated by SophiaFramework UNIVERSE 5.3. // #include "Twin.hpp" // Boot Loader SFCApplet::FactorySPP SFCApplet::Boot(AEECLSID id, SFXAnsiStringPtr license) { SFCApplet::FactorySPP result(null); switch (id) { case AEECLSID_TWINA: result = &TwinA::Factory; *license = "heap://" "TIXDRQXNU5WHU8 ......... ......... LUGEW3U98TLDR8"; break; case AEECLSID_TWINB: result = &TwinB::Factory; *license = "heap://" "DHDV5CR1S4XASC ........... ......... TQS6UHVFVEVLU3R"; break; } return result; } // Factory function SFCInvokerPtr TwinA::Factory(Void) { return ::new TwinA; } // Constructor TwinA::TwinA(Void) static_throws { return; } // Destructor TwinA::~TwinA(Void) { return; } // Factory function SFCInvokerPtr TwinB::Factory(Void) { return ::new TwinB; } // Constructor TwinB::TwinB(Void) static_throws { return; } // Destructor TwinB::~TwinB(Void) { return; }
The extended Hello World code is used as an example to explain the processing flow from start up to termination of application that terminates automatically when the "Select" key is pressed.
Example 10.94. Hello World application: .hpp file (class definition)
// // HelloWorld.hpp // // This source code was automatically // generated by SophiaFramework 4.1. // #ifndef __HELLOWORLD_HPP #define __HELLOWORLD_HPP #include <SophiaFramework.hpp> #include "HelloWorld.bid" SFMTYPEDEFCLASS(HelloWorld) class HelloWorld : public SFRApplication { SFMSEALCOPY(HelloWorld) public: static SFCInvokerPtr Factory(Void); private: HelloWorld(Void) static_throws; virtual ~HelloWorld(Void); HANDLER_DECLARE_VOIDRENDER(OnRenderContent) HANDLER_DECLARE_BOOLEVENT(OnKey) }; #endif // __HELLOWORLD_HPP //
Example 10.95. Hello World application: .cpp file (Boot Loader and Factory function)
// // HelloWorld.cpp // // This source code was automatically // generated by SophiaFramework UNIVERSE 5.3. // #include "HelloWorld.hpp" // Boot Loader SFCApplet::FactorySPP SFCApplet::Boot(AEECLSID id, SFXAnsiStringPtr license) { *license = "heap://"; return (id == AEECLSID_HELLOWORLD) ? (&HelloWorld::Factory) : (null); } // Factory function SFCInvokerPtr HelloWorld::Factory(Void) { return ::new HelloWorld; } // Constructor HelloWorld::HelloWorld(Void) static_throws { if (static_try()) { static_throw(RegisterHandler(SREVT_RESPONDER_RENDER, SRP16_RENDER_CONTENT, HANDLER_BEFORE, HANDLER_FUNCTION(OnRenderContent))); } if (static_try()) { static_throw(RegisterHandler(SFEVT_KEY, HANDLER_AFTER, HANDLER_FUNCTION(OnKey))); } return; } // Destructor HelloWorld::~HelloWorld(Void) { return; } // Drawing handler HANDLER_IMPLEMENT_VOIDRENDER(HelloWorld, OnRenderContent, graphics) { // draw "Hello World" to the screen graphics->DrawText("Hello World", GetContentWorld()); return; } // Key handler HANDLER_IMPLEMENT_BOOLEVENT(HelloWorld, OnKey, event) { // Key events handling switch (event.GetP16()) { case AVK_SELECT: // if select key is pressed Terminate(); // terminate application return true; } return false; }
The first HelloWorld application is extended with the declaration, registration, and implementation of key handler.
In the declaration, registration, and implementation of key handler, the HANDLER_DECLARE_BOOLEVENT, RegisterHandler, and HANDLER_IMPLEMENT_BOOLEVENT functions are used respectively. The key handler is registered in the Constructor.
During the starting up of application, the Boot Loader, the Factory function, and the Constructor function are executed in turn.
When the instance of HelloWorld Application class is created, the SFEVT_APP_START event from BREW is transmitted to the application. In the above code, since the handler for SFEVT_APP_START event is not registered, the default handler of the SFRApplication class (that does nothing) is invoked, and the starting up is completed.
Then the HelloWorld application enters into the event waiting state, and the event handling for events such as key input by user or network's events can be available.
The handler for SFEVT_KEY event is declared, registered, and implemented in the above code. The key handler is invoked when a key is pressed. The key handler will verify which key is pressed, and if it is the "Select" key, the Terminate function will be called to terminate the HelloWorld application.
When the HelloWorld application enters into the terminating state, the SFEVT_APP_STOP event from BREW is transmitted to the application. Since the handler for SFEVT_APP_STOP event is not registered, the default handler of SFRApplication class (that does nothing) is invoked.
Then, the Destructor is called, and the instance of HelloWorld Application class is destroyed. Finally, after this termination is done inside SophiaFramework UNIVERSE, the application's termination is finished. When the instance of HelloWorld Application class is destroyed, all UI components such as window, control, etc, are also automatically destroyed. (No need to explicitly destroy these UI components)
The OnlyWindow application draws the string "Hello World" in a window that will close when the "Select" key is pressed. The source code is shown below.
Example 10.96. OnlyWindow application : .hpp file (class definition)
// // OnlyWindow.hpp // // This source code was automatically // generated by SophiaFramework UNIVERSE 5.3. // #ifndef __ONLYWINDOW_HPP #define __ONLYWINDOW_HPP #include <SophiaFramework.hpp> #include "OnlyWindow.bid" SFMTYPEDEFCLASS(OnlyWindow) class OnlyWindow : public SFRApplication { SFMSEALCOPY(OnlyWindow) public: static SFCInvokerPtr Factory(Void); private: OnlyWindow(Void) static_throws; virtual ~OnlyWindow(Void); }; SFMTYPEDEFCLASS(MyWindow) class MyWindow : public SFRTitleWindow { SFMSEALCOPY(MyWindow) public: MyWindow(Void) static_throws; virtual ~MyWindow(Void); private: HANDLER_DECLARE_VOIDRENDER(OnRenderContent) HANDLER_DECLARE_BOOLEVENT(OnKey) }; #endif // __ONLYWINDOW_HPP //
Example 10.97. OnlyWindow application: .cpp file (Boot Loader and Factory function)
// // OnlyWindow.cpp // // This source code was automatically // generated by SophiaFramework UNIVERSE 5.3. // #include "OnlyWindow.hpp" // Boot Loader SFCApplet::FactorySPP SFCApplet::Boot(AEECLSID id, SFXAnsiStringPtr license) { *license = "heap://"; return (id == AEECLSID_ONLYWINDOW) ? (&OnlyWindow::Factory) : (null); } // Factory function SFCInvokerPtr OnlyWindow::Factory(Void) { return ::new OnlyWindow; } // Constructor OnlyWindow::OnlyWindow(Void) static_throws { SFRWindowPtr window; if (static_try()) { if ((window = ::new MyWindow()) != null) { static_throw(*window); if (!static_try()) { ::delete window; } } else { static_throw(SFERR_NO_MEMORY); } } return; } // Destructor OnlyWindow::~OnlyWindow(Void) { return; } // Constructor MyWindow::MyWindow(Void) : SFRTitleWindow(SFRApplication::GetInstance(), SFXGraphics::GetDeviceRectangle().Deflate(20, 20), "my window") static_throws { if (static_try()) { static_throw(RegisterHandler(SREVT_RESPONDER_RENDER, SRP16_RENDER_CONTENT, HANDLER_BEFORE, HANDLER_FUNCTION(OnRenderContent))); } if (static_try()) { static_throw(RegisterHandler(SFEVT_KEY, HANDLER_AFTER, HANDLER_FUNCTION(OnKey))); } return; } // Destructor MyWindow::~MyWindow(Void) { return; } // Drawing handler HANDLER_IMPLEMENT_VOIDRENDER(MyWindow, OnRenderContent, graphics) { // draw the string "Hello World" to the screen graphics->DrawText("Hello World", GetContentWorld(), SFXRGBColor(0x00, 0x00, 0x00, 0x00)); return; } // Key handler HANDLER_IMPLEMENT_BOOLEVENT(MyWindow, OnKey, event) { // Key events handling switch (event.GetP16()) { case AVK_SELECT:// if select key is pressed // close the window return Invoke(SFXEvent(SREVT_RESPONDER_TERMINATE, SRP16_TERMINATE_INVOKE, true)); } return false; }
In the above code, the MyWindow class that inherits from the SFRTitleWindow class is defined. Handlers for drawing string "Hello World" and handling the "Select" key are declared, registered, and implemented.
The instance of MyWindow class is created inside the Constructor of OnlyWindow Application class
The handler is registered inside the Constructor of MyWindow class. In the key handler of MyWindow class, SREVT_RESPONDER_TERMINATE event is transmitted when the "Select" key is pressed, then the window will destroy itself .
In the next example, the string "Hello World" and a button are displayed on the window, when the button is pressed, the window will close. The source code is shown below.
Example 10.98. ButtonWindow Application: .hpp file (class definition)
// // ButtonWindow.hpp // // This source code was automatically // generated by SophiaFramework UNIVERSE 5.3. // #ifndef __BUTTONWINDOW_HPP #define __BUTTONWINDOW_HPP #include <SophiaFramework.hpp> #include "ButtonWindow.bid" SFMTYPEDEFCLASS(ButtonWindow) class ButtonWindow : public SFRApplication { SFMSEALCOPY(ButtonWindow) public: static SFCInvokerPtr Factory(Void); private: ButtonWindow(Void) static_throws; virtual ~ButtonWindow(Void); }; SFMTYPEDEFCLASS(MyWindow) class MyWindow : public SFRTitleWindow { SFMSEALCOPY(MyWindow) public: MyWindow(Void) static_throws; virtual ~MyWindow(Void); private: HANDLER_DECLARE_VOIDRENDER(OnRenderContent) HANDLER_DECLARE_VOIDVOID(OnButtonControl) }; #endif // __BUTTONWINDOW_HPP //
Example 10.99. ButtonWindow application : .cpp file (Boot Loader and Factory function)
// // ButtonWindow.cpp // // This source code was automatically // generated by SophiaFramework UNIVERSE 5.3. // #include "ButtonWindow.hpp" // Boot Loader SFCApplet::FactorySPP SFCApplet::Boot(AEECLSID id, SFXAnsiStringPtr license) { *license = "heap://"; return (id == AEECLSID_BUTTONWINDOW) ? (&ButtonWindow::Factory) : (null); } // Factory function SFCInvokerPtr ButtonWindow::Factory(Void) { return ::new ButtonWindow; } // Constructor ButtonWindow::ButtonWindow(Void) static_throws { SFRWindowPtr window; if (static_try()) { if ((window = ::new MyWindow()) != null) { static_throw(*window); if (!static_try()) { ::delete window; } } else { static_throw(SFERR_NO_MEMORY); } } return; } // Destructor ButtonWindow::~ButtonWindow(Void) { return; } // Constructor MyWindow::MyWindow(Void) : SFRTitleWindow(SFRApplication::GetInstance(), SFXGraphics::GetDeviceRectangle().Deflate(20, 20), "my window") static_throws { SFRButtonControlPtr control; SFXRectangle rect; if (static_try()) { static_throw(RegisterHandler(SREVT_RESPONDER_RENDER, SRP16_RENDER_CONTENT, HANDLER_BEFORE, HANDLER_FUNCTION(OnRenderContent))); } // calculate the coordinates of the button control rect = GetContentWorld(); rect.AddTop(rect.GetHeight() - 28); rect.Deflate(2, 2); // generate button and register the handler control = ::new SFRButtonControl(this, rect, "Close"); if (static_try()) { static_throw(control->RegisterHandler(SREVT_CONTROL, HANDLER_BEFORE, HANDLER_FUNCTION(OnButtonControl))); } return; } // Destructor MyWindow::~MyWindow(Void) { return; } // Drawing handler HANDLER_IMPLEMENT_VOIDRENDER(MyWindow, OnRenderContent, graphics) { // call the default handler of parent class SFRTitleWindow::ContentHandler(graphics); // draw string "Hello World" to the screen graphics->DrawText("Hello World", GetContentWorld(), SFXRGBColor(0x00, 0x00, 0x00, 0x00)); return; } // Button control handler HANDLER_IMPLEMENT_VOIDCONTROL(MyWindow, OnButtonControl, result, control){ // close the window if the button is pressed Invoke(SFXEvent(SREVT_RESPONDER_TERMINATE, SRP16_TERMINATE_INVOKE, true)); return; }
In this sample code, the button is created in the Constructor of MyWindow class, and the button handler is registered to the button. Window is destroyed in the button handler.
An application without using the GUI framework can be developed by inheriting from the SFCApplication class. This kind of application is called SFC applet.
SFC applet has the same structure as the C program developed with standard BREW SDK.
The C++ wrapper and utility classes of SophiaFramework UNIVERSE can be also used in the SFC applet.
HelloWorld application is used as an example to explain the basic structure and the processing flow of SFC applet.
Example 10.100. HelloWorld application without GUI Framework: .hpp file (class definition)
// // Helloworld.hpp // // This source code was automatically // generated by SophiaFramework UNIVERSE 5.3. // #ifndef __HELLOWORLD_HPP #define __HELLOWORLD_HPP #include <SophiaFramework.hpp> #include "Helloworld.bid" SFMTYPEDEFCLASS(Helloworld) class Helloworld : public SFCApplication { SFMSEALCOPY(Helloworld) public: static SFCInvokerPtr Factory(Void); private: explicit Helloworld(Void) static_throws; virtual ~Helloworld(Void); virtual Bool Invoke(SFXEventConstRef event); Bool OnKey(UInt16 key); // Key handler (declared just like an ordinary function) Void Draw(Void); // Function to draw "Hello World" }; #endif // __HELLOWORLD_HPP //
Example 10.101. HelloWorld application without GUI Framework: .cpp file( implementing Boot Loader, Factory functions and Handlers)
// // Helloworld.cpp // // This source code was automatically // generated by SophiaFramework UNIVERSE 5.3. // #include "Helloworld.hpp" // Boot Loader SFCApplet::FactorySPP SFCApplet::Boot(AEECLSID id, SFXAnsiStringPtr license) { *license = "heap://"; return (id == AEECLSID_HELLOWORLD) ? (&Helloworld::Factory) : (null); } // Factory function SFCInvokerPtr Helloworld::Factory(Void) { return ::new Helloworld; } // Constructor // In order to independently implement the event handler, the handler function must not be registered in constructor Helloworld::Helloworld(Void) static_throws { return; } // Desctructor Helloworld::~Helloworld(Void) { return; } // Event handler Bool Helloworld::Invoke(SFXEventConstRef event) { Bool result(false); // call the handler according to the event type switch (event.GetType()) { case SFEVT_KEY: // Key event result = OnKey(event.GetP16()); break; } if (!result) { result = SFCApplication::Invoke(event); } return result; } // Key handler Bool Helloworld::OnKey(UInt16 key) { // Key event handling switch (key) { case AVK_SELECT: // if the select key is pressed Draw(); // draw string "Hello World" return true; } return false; } // Drawing string "Hello World" Void Helloworld::Draw(Void) { // get SFXGraphics instance SFXGraphicsPtr graphics = SFXGraphics::GetInstance(); // paint screen in white // get entire screen (rectangle) using SFXGraphics::GetDeviceRectangle() // SFXRGBColor(0xFF, 0xFF, 0xFF, 0x00) : display in white graphics->FillRectangle(SFXGraphics::GetDeviceRectangle(), SFXRGBColor(0xFF, 0xFF, 0xFF, 0x00)); // draw "Hello World" to the screen // SFXRGBColor(0x00, 0x00, 0x00, 0x00) : display in black graphics->DrawText("Hello World", SFXGraphics::GetDeviceRectangle(), SFXRGBColor(0x00, 0x00, 0x00, 0x00)); // since GUI Framework is not used, screen must be updated graphics->Update(); }
The above HelloWorld application class inherits from the SFCApplication class, since it does not use the GUI Framework.
Caution | |
---|---|
The SFR applet using the GUI framework; inherits from the SFRApplication class. |
In the SFC applet, the HANDLER_DECLARE macro is not used for declaring a handler function. Instead a handler function is declared in the same way as other functions like the OnKey function.
The Invoke function is the event handler for SFCApplication. It receives all events, and distributes each event to the appropriate handler function.
The event is transmitted through the argument of Invoke function, and sent to the appropriate handler function according to the event type. For instance a key event causes the key handler OnKey to be called.
In the key handler OnKey, when the "Select" key is pressed, the Draw function will be called. The Draw function clears the screen and draws the string "Hello World".
Caution | |
---|---|
In the SFC applet the screen need to be drawn within the function such as Draw called in the key handler. The "graphics->Update();" statement must be included in the "Draw" function to update the screen. |
Copyright(c) 2002 - 2024 Sophia Cradle Incorporated All Rights Reserved. |