运行框架
(以下均构造时订阅接受的事件)
- 创建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);
}
