• Nenhum resultado encontrado

4.2 Implementac~ao do CMF

4.2.2 Ponto de Entrada da Aplicac~ao

4.2.2.1 BREW

1Um tipo basico e um tipo de dado que n~ao e composto por outros tipos de dados, como o tipo inteiro,

4.2 implementac~ao do cmf 45 mentar a interface IApplet. Os SDK's de BREW ja fornecem o codigo desta interface implementado, de forma que o desenvolvedor precisa apenas declarar uma estrutura que herda2 de AEEApplet adicionando os membros que sejam necessarios a sua aplicac~ao. De-

pois, basta implementar os metodos para alocar e desalocar memoria para esta estrutura e um metodo para tratar eventos (HandleEvent).

Pelo fato da API de BREW ser escrita na linguagem C e o desenvolvimento do CMF ter sido feito na linguagem C++, foi necessario fazer uma nova imple- mentac~ao da interface IApplet de BREW. Esta implementac~ao de ne uma classe, a CMF_CApplication, para ser usada no lugar da estrutura AEEApplet. Assim, um objeto da classe CMF_CApplication e construdo no lugar da estrutura AEEApplet padr~ao de BREW, e o seu metodo HandleEvent e chamado para enviar os eventos para o CMF.

Com isto, esta classe devera implementar um construtor e um destrutor para alocar e desalocar a memoria dos objetos usados na aplicac~ao, e o metodo HandleEvent para o tratamento de eventos. Neste metodo, s~ao de nidos quais os eventos que ser~ao tratados pelo Framework e quais os eventos que ser~ao enviados para a aplicac~ao. A declarac~ao desta classe pode ser vista a seguir.

class CMF_CApplication {

public:

// Constructor

CMF_CApplication(IShell* iShell, IDisplay* iDisplay); // Destructor

~CMF_CApplication();

// Event handler. All events sent to the // application are handled by this method. bool HandleEvent(UINT16 aeCode,

UINT16 awParam, UINT32 adwParam); private: /// CMF System object CMF_CSystem *iSystem; /// CMF Applet object CMF_MApplet *iApplet;

/// CMF State Machine object

CMF_CStateMachine *iStateMachine; /// CMF Screen Manager object

CMF_CScreenManager *iScreenManager; /// CMF Graphics Context object

CMF_CGraphicsContext *iGC;

2Na linguagem C, e possvel fazer uma heranca de uma estrutura ao declarar a estrutura-m~ae como

sendo o primeiro elemento da estrutura- lha. Assim, os membros da estrutura-m~ae estar~ao nas mesmas posic~oes de memoria da estrutura- lha e esta pode ser utilizada onde a estrutura-m~ae e requerida.

4.2 implementac~ao do cmf 46 };

CMF_CApplication e responsavel por criar todos os objetos do CMF que estar~ao dis- ponveis para a aplicac~ao, alem da classe da aplicac~ao propriamente dita.

4.2.2.2 Embedded Linux Para Embedded Linux, tambem foi criada uma classe CMF_CApplication. Esta classe possui dois atributos a mais que a sua vers~ao em BREW: um objeto QApplication e um objeto QWidget, que representam a aplicac~ao e a janela principal, respectivamente.

Alem dos atributos, foi adicionado o metodo Run() a esta classe. Este metodo e responsavel por de nir os atributos do display (objecto da classe QWidget) e chamar o metodo exec() de QApplication para que a aplicac~ao entre no loop de recebimento e tra- tamento de eventos. O codigo abaixo mostra a declarac~ao desta classe para a plataforma Embedded Linux.

class CMF_CApplication {

public:

// Constructor

CMF_CApplication(int &argc, char** argv); // Destructor

~CMF_CApplication();

// Executes the Qt application int Run();

// Event handler. All events sent to the // application are handled by this method. bool HandleEvent(UINT16 aeCode,

UINT16 awParam, UINT32 adwParam); private: /// CMF System object CMF_CSystem *iSystem; /// CMF Applet object CMF_MApplet *iApplet;

/// CMF State Machine object

CMF_CStateMachine *iStateMachine; /// CMF Screen Manager object

CMF_CScreenManager *iScreenManager; /// CMF Graphics Context object

CMF_CGraphicsContext *iGC; };

4.2 implementac~ao do cmf 47 4.2.3 Classe de Aplicac~ao

Conforme visto na Sec~ao 3.5.1, a classe CMF_MApplet representa uma aplicac~ao no CMF. Esta classe recebe os principais objetos do CMF: CMF_CScreenManager, CMF_CStateMachine e CMF_CSystem para acessar as funcionalidades da plataforma. Ao criar uma aplicac~ao, esta deve herdar da classe CMF_MApplet e implementar seus metodos abstratos. Os metodos que devem ser implementados obrigatoriamente s~ao:

 Construct

Neste metodo, todos os estados e telas que v~ao ser utilizados pela aplicac~ao devem ser contrudos e a memoria alocada. Alem disto, os metodos Construct da maquina de estados e do gerenciador de telas devem ser chamados informando o numero de estados e telas da aplicac~ao, respectivamente.

 OnStartApplet

Metodo chamado pelo CMF quando a aplicac~ao e inicializada. Neste ponto, todos os objetos do CMF e os estados e telas da aplicac~ao ja est~ao criados.

 OnStopApplet

Metodo chamado pelo CMF quando a aplicac~ao e nalizada. Neste ponto, pode-se desalocar a memoria usada pela aplicac~ao e nalizar todas as operac~oes pendentes. Esta classe n~ao possui nenhuma depend^encia com a plataforma alvo, apenas de ne um conjunto de metodos da aplicac~ao que ser~ao chamados pelo CMF. Assim, a sua implementac~ao e igual nas duas plataformas.

Abaixo temos a declarac~ao da classe CMF_MApplet. class CMF_MApplet

{

public:

// Class constructor.

CMF_MApplet( CMF_CSystem *aSystem,

CMF_CStateMachine *aStateMachine, CMF_CScreenManager *aScreenManager); // Method that shall be implemented

// to construct all applet objects. virtual int Construct() = 0;

// Method that is called when applet starts virtual void OnStartApplet(UINT32 adwParam) = 0; // Method that is called when applet stops

virtual void OnStopApplet(UINT32 adwParam) = 0; // Method that is called when applet is suspended virtual void OnSuspendApplet(){}

4.2 implementac~ao do cmf 48 // its execution after being suspended

virtual void OnResumeApplet(){}

// inline method that returns the Screen Manager inline CMF_CScreenManager* ScreenManager(); // inline method that returns the State Machine inline CMF_CStateMachine* StateMachine(); // inline method that returns the System object inline CMF_CSystem* System();

protected:

// Screen Manager object

CMF_CScreenManager *iScreenManager; // State Machine object

CMF_CStateMachine *iStateMachine; // System object

CMF_CSystem *iSystem;

};

4.2.4 Gerenciador de Objetos

Esta classe representa um gerenciador generico de objetos. E uma classe template3

que implementa o padr~ao de projeto Manager[Som97].

CMF_CObjectManager possui metodos para adicionar objetos e reaver objetos de acordo com o seu identi cador. Alem disto, possui metodos para alocar e desalocar memoria para os objetos gerenciados. Abaixo e mostrado o codigo desta classe template em C++. template <typename T> class CMF_CObjectManager { public: // default constructor CMF_CObjectManager() { this->iMaxObjects = 0; this->iObjectTable = NULL; }

// Method used to allocate memory for manager void Construct(const UINT16 &aMaxObjects)

3Template, em C++, representa uma classe que implementa um determinado comportamento que

independe do tipo de dados utilizado. Desta forma, o tipo de dado pode ser parametrizado e pode-se instanciar esta classe para qualquer tipo de dado.

4.2 implementac~ao do cmf 49 {

this->iMaxObjects = aMaxObjects;

this->iObjectTable = new T*[aMaxObjects]; for (int i=0; i < aMaxObjects; i++)

{ this->iObjectTable[i] = NULL; } } // destructor virtual ~CMF_CObjectManager() { DeleteAll(); }

// add an object to the manager

int Add(T *aObject, const UINT16 &aID) { int ret = -1; if (aID < iMaxObjects) { this->iObjectTable[aID] = aObject; ret = aID; } return ret; }

// retrieves an object from the manager T* Get(const UINT16 &aID) const

{ T *object = NULL; if (aID < iMaxObjects) { object = iObjectTable[aID]; } return object; }

4.2 implementac~ao do cmf 50 void DeleteAll()

{

for (int i=0; i<iMaxObjects; i++) if (iObjectTable[i] != NULL)

delete iObjectTable[i]; delete[] iObjectTable;

} private:

// Array of pointers to objects T **iObjectTable;

// Max number of objects UINT16 iMaxObjects; };

4.2.5 Maquina de Estados

A classe CMF_CStateMachine implementa um gerenciador de estados. Esta classe herda do gerenciador generico CMF_CObjectManager, instanciando-o para a classe CMF_MState. CMF_CStateMachine Possui dois metodos principais: HandleEvent, que e responsavel por receber os eventos enviados pela plataforma e encaminha-los para o es- tado ativo; e ChangeState, que permite a mudanca do estado ativo e chama os metodos OnExit do estado anterior e EnterFunction do estado que se tornara ativo.

Como esta classe n~ao possui nenhum codigo dependente de plataforma, temos apenas uma implementac~ao desta classe para todas as plataformas alvo. Abaixo e mostrada a declarac~ao da classe CMF_CStateMachine.

class CMF_CStateMachine : public CMF_CObjectManager<CMF_MState> {

public:

// Class constructor CMF_CStateMachine();

// Receive all events and send them to current active state int HandleEvent(UINT16 aeCode, UINT16 awParam, UINT16 adwParam); // Change current active state

int ChangeState(const UINT16 &aID); private:

4.2 implementac~ao do cmf 51 CMF_MState *iCurrentState;

};

4.2.6 Estados da Aplicac~ao

As classes estados da aplicac~ao devem ser implementadas herdando da classe base dos estados do CMF: CMF_MState. Esta classe possui dois conjuntos de metodos. Os metodos auxiliares, que devem ser utilizados para que a arquitetura proposta para a maquina de estados funcione; e os metodos abstratos, que devem ser implementados pelos estados que herdam desta classe. Os metodos auxiliares s~ao:

 Construct

Metodo de CMF_MState responsavel por construir a tabela de eventos do estado. Deve ser chamado no construtor da classe, informando o numero de eventos que o estado ira tratar.

 MapEvent

Este metodo deve ser chamado para mapear cada evento a ser tratado pelo estado no metodo responsavel por trata-lo.

 HandleEvent

Metodo responsavel por receber o evento da maquina de estados e chamar o metodo do estado responsavel por tratar este evento.

Abaixo s~ao descritos os metodos abstrados da classe CMF_MState:  OnEnter

Metodo chamado quando o estado se torna ativo pela primeira vez. Geralmente deve ser utilizado para alocac~ao de memoria que deve permanecer alocada mesmo que o estado se torne inativo.

 OnResume

Este metodo e chamado em todas as outras vezes, com excec~ao da primeira, em que o estado se torna ativo. Geralmente e utilizada para inicializar o estado. Caso este metodo n~ao seja implementado nas classes que herdam de CMF_MState, sua implementac~ao padr~ao chamara o metodo OnEnter.

 OnExit

Metodo chamado quando o estado estava ativo e torna-se inativo. Deve ser uilizado para desalocar memoria que n~ao sera mais utilizada pelo estado.

Alem destes metodos, a classe CMF_MState declara alguns tipos de dados que ser~ao utilizados no mecanismo de tratamento de eventos.

Foi de nido o tipo CMF_TEventHandler que representa um metodo tratador de eventos do estado. Este novo tipo e um ponteiro para metodos da classe CMF_MState e recebe dois par^ametros, um de 16 bits e outro de 32 bits, que s~ao os par^ametros do evento a ser

4.2 implementac~ao do cmf 52 tratado. Desta forma, todos os metodos tratadores de eventos implementados nas classes que herdam de CMF_MState devem ter esta mesma assinatura.

A classe CMF_TEvent e uma classe privada de CMF_MState e representa um evento da tabela de eventos do estado. Esta classe contem apenas dois atributos, o identi cador do evento e um ponteiro para o metodo (do tipo CMF_TEventHandler) que deve ser chamado para tratar o evento. Assim, ao receber um evento, o estado veri ca na tabela de eventos se existe alguma entrada para este evento e chama o metodo correspondente.

Abaixo segue a declarac~ao da classe CMF_MState. class CMF_MState

{

public:

// Event Handler method pointer

typedef bool (CMF_MState::*CMF_TEventHandler)(UINT16 awParam, UINT32 adwParam); // State enter function pointer

/** This is a pointer to the method that will be called when state becomes active. This method is OnEnter if it is the first time the state becomes active or OnResume if it is not the first time */ typedef void (CMF_MState::*CMF_StateEnterFunction)();

// Class construction

CMF_MState(CMF_MApplet *aApplet, UINT16 aID); // Construct method.

/** This method shall be called to allocate

memory on event handler table for all events that shall be handled by the state. */

int Construct(UINT32 aMaxEvent); // Class destructor.

~CMF_MState();

// Handle events sent to the state.

int HandleEvent(UINT16 aeCode, UINT16 awParam, UINT32 adwParam); // Map events into event handlers (methods)

int MapEvent(UINT16 aEventCode, CMF_TEventHandler aEventHandler); // Method that is called when state becomes active by first time virtual void OnEnter(){}

// Method that is called when state becomes active virtual void OnResume(){OnEnter();}

// Method that is called when state is active and becomes inactive virtual void OnExit(){}

4.2 implementac~ao do cmf 53 // Calls the correct enter function (OnEnter / OnResume)

virtual void EnterFunction(); protected:

// pointer to the applet CMF_MApplet *iApplet; private:

// CMF_TEvent represents an event in the state.

/** This class holds the event code and the Event handler (method from state).*/

class CMF_TEvent { public: // Event code UINT16 iEventCode; // Event handler CMF_TEventHandler iEventHandler; };

// event table that holds all events handled by this state CMF_TEvent *iEventTable;

// max number of events that this state can handle UINT32 iMaxEvents;

// current number of events registered in the state UINT32 iCurrentNumEvents;

// Enter function pointer

CMF_StateEnterFunction iEnterFunction; };

Embora tipo CMF_TEventHandler represente um ponteiro para metodo da classe CMF_MState, os metodos que ser~ao utilizados como tratadores de eventos pertencem as classes que representam os estados da aplicac~ao (e que herdam de CMF_MState). Desta forma, e necessario fazer um cast entre o metodo da classe derivada e o tipo CMF_TEventHandler que representa um ponteiro para metodo da classe base. Abaixo segue um exemplo da chamada do metodo MapEvent, mostrando o cast necessario. // Construct event table

Construct(STATE_MAX_EVENT);

// Map each event ID into the targeted event handler

MapEvent(EVT_BACK, static_cast <CMF_TEventHandler> (&CState1::OnBack)); MapEvent(EVT_START, static_cast <CMF_TEventHandler> (&CState1::OnStart));

4.2 implementac~ao do cmf 54 Este cast so ira funcionar em C++ se a classe derivada n~ao possuir heranca multipla4.

Pois sem possuir heranca multipla, o ponteiro this da classe derivada ca na mesma posic~ao de memoria do ponteiro this da classe base, sendo o this do objeto em quest~ao utilizado, mesmo quando se tem um ponteiro para um metodo da classe base. Este mecanismo funciona da mesma forma que o dynamic binding5 funciona para metodos

virtuais sobrepostos (overhided).

Abaixo temos o trecho de codigo do metodo HandleEvent. Este codigo mostra como o metodo tratador de evento da classe derivada e chamado atraves do ponteiro para metodo da classe base.

int CMF_MState::HandleEvent(UINT16 aeCode, UINT16 awParam, UINT32 adwParam) {

int ret = CMF_FAIL;

// walk through event table, searching for the

// event that has same event code as the aeCode parameter for (int i=0; i<iCurrentNumEvents; i++)

{

if ((iEventTable[i].iEventCode == aeCode) && (iEventTable[i].iEventHandler != NULL)) {

// when event is found, call the handler // passing the parameters

ret = (this->*(iEventTable[i].iEventHandler))(awParam, adwParam); }

}

return ret; }

Neste codigo e possivel ver o uso do operador "->*" que serve para desreferenciar o ponteiro para metodo que esta na variavel iEventHandler.

4.2.7 Dispositivo Gra co

O acesso a tela do dispositivo da-se atraves da classe CMF_RGraphicsContext. Esta classe possui metodos que implementam as principais primitivas de desenho, alem de metodos para escrita de texto na tela e desenho de imagens.

Esta classe e completamente dependente da plataforma, visto que acessa as funciona- lidades de desenho do dispositivo. Assim, foi feita uma implementac~ao para BREW 4A linguagem C++ possui um mecanismo de heranca em que uma classe derivada pode herdar de

mais de uma classe base.

5Ligac~ao din^amica. Mecanismo que permite uma chamada ao metodo do objeto que esta na memoria,

4.2 implementac~ao do cmf 55 e outra para Embedded Linux. Para compatibilizar as duas plataformas, a classe CMF_GRAPHICS_DATA foi de nida contendo os tipos de dado para cada uma das plata- formas e CMF_RGraphicsContext herda desta classe.

A partir dos objetos contidos na classe CMF_GRAPHICS_DATA, foram implementados to- dos os metodos de manipulac~ao dos elementos gra cos da classe CMF_RGraphicsContext. Abaixo segue o codigo que declara esta classe, com todos os metodos de manipulac~ao gra ca implementados.

class CMF_CGraphicsContext : public CMF_MPlugin,

private CMF_GRAPHICS_DATA { public: // Class constructor CMF_CGraphicsContext(CMF_CSystem *aSystem):CMF_MPlugin(aSystem){} // Construct method

virtual int Construct(); // Class destructor

virtual ~CMF_CGraphicsContext();

// Set primary display to be the active display int SetPrimaryDisplay();

// Set secondary display to be the active display int SetSecondaryDisplay();

// Set current display to full screen mode int SetFullScreen(int aValue);

// clear the screen void ClearScreen();

// Updates current display by performing // all pending drawing operations.

void Renderize();

// returns current screen width int Width();

// returns current screen height int Height();

// set drawing foreground color

CMF_TRGB SetFGColor(CMF_TRGB aColor); // set drawing background color

CMF_TRGB SetBGColor(CMF_TRGB aColor); // set drawing area

CMF_TRect SetDrawingArea(CMF_TRect &aRect); // retrieves drawing area

4.2 implementac~ao do cmf 56 ////////////////////////////////////////////////////////

// image related functions

//////////////////////////////////////////////////////// // Retrieves image width and height

void GetImageSize(CMF_TImage* aImage, int* aWidth,

int* aHeight);

// Draw the image in the specified position void Draw(CMF_TImage* aImage, int aX, int aY);

//////////////////////////////////////////////////////// // text related functions

//////////////////////////////////////////////////////// // Calculates string width and height in pixels based // on string chars and font used

void MeasureString(const CMF_TString* aText, CMF_TFont aFont, UINT16 *aWidth, UINT16 *aHeight);

// Draw the string in the specified position with // specified font

void Draw(const CMF_TString* aText, CMF_TFont aFont, int aX, int aY, UINT32 aAlign=0); //////////////////////////////////////////////////////// // rectangle drawing functions

//////////////////////////////////////////////////////// // Draw the edges of a rectangle (with no filling)

void DrawFrame(const CMF_TRect* aRect, CMF_TRGB aColor); // Draw a filled rectangle

void DrawRect(const CMF_TRect* aRect, CMF_TRGB aColor); protected: // screen height int iHeight; // screen width int iWidth; };

A seguir, ser~ao mostradas as de nic~oes da classe CMF_GRAPHICS_DATA para cada uma das plataformas alvo.

4.2.7.1 BREW abaixo segue a de nic~ao da classe CMF_GRAPHICS_DATA para BREW. class CMF_GRAPHICS_DATA

4.2 implementac~ao do cmf 57 { public: IDisplay *pIDisplay1; IDisplay *pIDisplay2; IDisplay *pCurrentDisplay; AEEDeviceInfo di; };

Esta classe possui ponteiros para as inst^ancias das telas interna e externa do disposi- tivo, alem de uma estrutura responsavel por obter as informac~oes gra cas, como tamanho da tela, quantidade de cores e outras propriedades. Manipulando estes atributos e possvel implementar todos os metodos declarados em CMF_RGraphicsContext.

4.2.7.2 Embedded Linux para Embedded Linux, a classe CMF_GRAPHICS_DATA foi de nida de acordo com o codigo abaixo.

class CMF_GRAPHICS_DATA { public: QImage *pDisplay; CMF_CWidget *pDisplayDevice; CMF_TRGB iFGColor; CMF_TRGB iBGColor; CMF_TRect iDrawingRect; };

Esta classe implemeta double bu ering6 possuindo uma imagem pDisplay na qual s~ao

efetuadas todas as operac~oes gra cas e um widget que representa a tela, onde a imagem pDisplay e desenhada sempre que houver um evento de pintura enviado pela plataforma. 4.2.8 Gerenciador de Telas

As telas da aplicac~ao s~ao gerenciadas pela classe CMF_CScreenManager. Esta classe herda do gerenciador generico CMF_CObjectManager, instanciando-o para a classe CMF_MDisplayable, que e a classe base das telas. O CMF ja adiciona todas as telas da aplicac~ao no CMF_CScreenManager assim que elas s~ao criadas.

O construtor do gerenciador de telas recebe um objeto da classe gerenciador gra co para enviar este objeto para o metodo paint das telas. Os principais metodos desta classe s~ao: ChangeScreen, responsavel por trocar a tela ativa, chamando os metodos OnInactivate da tela anterior e OnActivate da proxima tela; e TranslateEvent que ira 6Tecnica de pintura geralmente utilizada em jogos, na qual todos os elementos s~ao desenhados em

4.2 implementac~ao do cmf 58 enviar o evento para a tela ativa, para que este evento seja traduzido de acordo com o que estiver sendo mostrado na tela.

Abaixo, temos o codigo que declara a classe CMF_CScreenManager. class CMF_CScreenManager : public CMF_CObjectManager<CMF_CDisplayable> { public: // class constructor CMF_CScreenManager(CMF_CSystem *aSystem, CMF_CGraphicsContext* aGC); // class destructor ~CMF_CScreenManager();

// Methods to return the active screen

inline UINT16 GetActiveScreenId();

inline CMF_CDisplayable* GetActiveScreen(); // Method to change the active screen

int ChangeScreen(UINT16 aId);

// Method to translate an event according to // active screen

UINT16 TranslateEvent(UINT16 aEvIn, UINT16 aKey,

UINT32 adwParam );

// Repaint method that is called by platform when // active screen must be repainted

void Repaint(); private: // Active screen UINT16 iActiveScreenId; // System object CMF_CSystem* iSystem; // Graphics context object CMF_CGraphicsContext* iGC; };

4.2.9 Telas da Aplicac~ao

As telas da aplicac~ao s~ao classes que herdam de CMF_CDisplayable. O construtor de CMF_CDisplayable recebe o gerenciador de telas e um numero identi cador para a tela como par^ametros, adicionando esta tela no gerenciador com este identi cador.

4.2 implementac~ao do cmf 59 CMF_CDisplayable de ne um conjunto de metodos que devem ser implementados por

Documentos relacionados