为了方便,每个应用都从IMidlet抽象类继承而来,这个类负责声明和实现哑元应用级的事件回调(这个稍候再讨论),以及提供对DisplayableRegistry唯一范例的访问。这就解决了另外一个问题——Singleton的实现。请注意:IMidlet提供的机制和动态多形性并不是必要的,从本质上来说——静态多形性也可以做同样的事。让每个组件都理解应用,相当于为他们提供了上下文。
CODE:class IMidlet
{
public:
DisplayableRegistry* getDisplayable() const
{
return rr_;
}
void setRegistry(DisplayableRegistry* rr)
{
rr_ = rr;
}
virtual bool onStart()
{
return true;
}
virtual bool onStop()
{
return true;
}
virtual bool onSuspend()
{
return false;
}
virtual bool onResume()
{
return false;
}
virtual ~IMidlet()
{}
private:
DisplayableRegistry* rr_;
};
这里是DisplayableRegistry的一个可能实现:
CODE:class DisplayableRegistry
{
public:
int registerResource(IDisplayable* resource)
{
for(int i = resources_.size() - 1; i >= 0; --i)
{
if (resources_[i] && resources_[i] == resource)
{
return i;
}
}
resources_.append(resource);
return resources_.size() - 1;
}
bool unregisterResource(int uid)
{
if (resources_[uid] )
{
delete resources_[uid];
resources_[uid] = 0;
return true;
}
return false;
}
IDisplayable* getRegistered(int uid) const
{
return resources_.isEmpty() || ((resources_.size()-1) < uid)
? 0 : resources_[uid] ;
}
void setCurrent(IDisplayable* resource )
{
setCurrentImpl(resource);
}
int getNextAvailableID()
{
++itemID_;
return itemID_;
}
bool onCmd(int itemID, long data) const
{
int id = INDEX_OUT_OF_BOUNDS;
for(int i = 0, sz = resources_.size(); i< sz; ++i)
{
if (resources_[i]->containsItem(itemID))
{
IDisplayable* d = resources_[i];
return resources_[i]->onCmd();
}
}
return false;
Midlet* getApp() const
{
return m_;
}
bool isHandled(AEEEvent eCode, uint16 wParam,
uint32 dwParam) const
{
for(int i = 0, sz = resources_.size(); i< sz; ++i)
{
IControl* c = resources_[i]->getControl();
if (c && ICONTROL_HandleEvent(c,eCode, wParam, dwParam))
return true;
}
return(false);
}
~DisplayableRegistry()
{
delete m_;
unregisterResources();
}
DisplayableRegistry(IMidlet* m):itemID_(100), m_(m)
{
m_->setRegistry(this);
}
private:
void unregisterResources()
{
for(int i=0, sz = resources_.size(); i < sz; ++i)
{
delete resources_[i];
resources_[i] = 0;
}
}
void eraseAll() const
{
for(int i=0, sz = resources_.size(); i < sz; ++i)
{
IControl* c = resources_[i]->getControl();
ICONTROL_SetActive(c,false);
}
IDISPLAY_ClearScreen(getDisplay());
}
void setCurrentImpl(IDisplayable* resource)
{
eraseAll();
ICONTROL_SetActive(resource->getControl(),true);
IDISPLAY_UpdateEx(getDisplay(), false);
}
private:
int itemID_;
IMidlet* m_;
private:
DisplayableRegistry( const DisplayableRegistry &value );
const DisplayableRegistry &operator =
( const DisplayableRegistry &rhs );
};