运行框架
(以下均构造时订阅接受的事件)
- 创建Context
- 创建Example<Sample<Application<Object
- Application
- 解析参数成vector
- 创建Engine
- 使用context创建注册子系统
- Example
- Example->Run(Application->Run)
- Sample::Setup()
- 更新引擎启动参数(窗口化、标题等)
- 获取启动目录等
- engine初始化
- 根据参数初始化附加库(2D等),打开log,开启多线程,添加资源目录,添加资源package,添加自动加载目录
- 初始化图形和音频输出
- 初始化输入网络等
- Example::Start()
- Sample::Start()
- 自定义初始化
- 自定义初始化
- Sample::Start()
- 主循环:engine->RunFrame()
- ——-Loop——-
- time->BeginFrame(ctime)
- 是否已经暂停或者最小化
- 如果是:停止声音
- 否则如果声音暂停恢复之,engine->Update()
- SendEvent(E_UPDATE, eventData);
- SendEvent(E_POSTUPDATE, eventData);
- SendEvent(E_RENDERUPDATE, eventData);
- SendEvent(E_POSTRENDERUPDATE, eventData);
- engine->Render()
- Graphics->BeginFrame()
- SetRenderTarget(i, (RenderSurface*)0);
- SetDepthStencil((RenderSurface*)0);
- SetViewport(IntRect(0, 0, width_, height_));
- renderer->Render();
- ui->Render();
- Graphics->EndFrame();
- impl_->swapChain_->Present(vsync_ ? 1 : 0, 0);
- Graphics->BeginFrame()
- 限制帧率
- time->EndFrame()
- ——-Loop——-
- Sample->Stop()
- Engine::DumpResources()
事件系统
Engine是一个Object,Event的Sender和Receiver都是Object。
分发事件细节:
-
Engine使用SendEvent发送指定类型(eventType)的事件
-
Check主线程,当前只支持在主线程sendeEvent。
- Enginr继承于Object中的context_调用
context->BeginSendEvent(this,eventType)
,this代表Engine。context->eventSenders_.push(sender)
,eventSenders
是一个装sender的容器,sender这里指engine。
- 根据发送者和事件类型,获取一个接受指定eventType的receiver_group.
- 参考代码片1.
- 如果找到了这样的接受者,接受者调用
BeginSendEvent()
,这个函数自加group的某个成员计数器。 - 遍历group中的所有receiver,为每一个receiver调用onEvent(sender,eventType,eventData)
- 如果sender因为事件处理而被销毁,立即终止group sendEvent,context->EndSendEvent。
- 在已处理receiver集合processed中插入当前处理过的receiver。
- 仅仅根据事件类型获取receiver组
- 如果processed空则按照之前的方法处理receiver,否则,要check防止事件被接收两次。
context->EndSendEvent(this,eventType)
,this代表Engine。eventSenders_.Pop();
-
订阅事件细节:
-
首先创建EventHandler:
URHO3D_HANDLER(SkeletalAnimation, HandleUpdate);
参数1是receiver,参数2是处理函数,由用户自己定义,是类成员。 -
订阅,参考代码片2/3.
代码片1:
EventReceiverGroup* GetEventReceivers(Object* sender, StringHash eventType)
{
HashMap<Object*, HashMap<StringHash, SharedPtr<EventReceiverGroup> > >::Iterator i = specificEventReceivers_.Find(sender);
if (i != specificEventReceivers_.End())
{
HashMap<StringHash, SharedPtr<EventReceiverGroup> >::Iterator j = i->second_.Find(eventType);
return j != i->second_.End() ? j->second_ : (EventReceiverGroup*)0;
}
else
return 0;
}
代码片2:
void Object::SubscribeToEvent(StringHash eventType, EventHandler* handler)
{
if (!handler)
return;
handler->SetSenderAndEventType(0, eventType);
// Remove old event handler first
EventHandler* previous;
EventHandler* oldHandler = FindSpecificEventHandler(0, eventType, &previous);
if (oldHandler)
{
eventHandlers_.Erase(oldHandler, previous);
eventHandlers_.InsertFront(handler);
}
else
{
eventHandlers_.InsertFront(handler);
context_->AddEventReceiver(this, eventType);
}
}
void Object::SubscribeToEvent(Object* sender, StringHash eventType, EventHandler* handler)
{
// If a null sender was specified, the event can not be subscribed to. Delete the handler in that case
if (!sender || !handler)
{
delete handler;
return;
}
handler->SetSenderAndEventType(sender, eventType);
// Remove old event handler first
EventHandler* previous;
EventHandler* oldHandler = FindSpecificEventHandler(sender, eventType, &previous);
if (oldHandler)
{
eventHandlers_.Erase(oldHandler, previous);
eventHandlers_.InsertFront(handler);
}
else
{
eventHandlers_.InsertFront(handler);
context_->AddEventReceiver(this, sender, eventType);
}
}
代码片3:
void Context::AddEventReceiver(Object* receiver, StringHash eventType)
{
SharedPtr<EventReceiverGroup>& group = eventReceivers_[eventType];
if (!group)
group = new EventReceiverGroup();
group->Add(receiver);
}