网狐棋牌代码分析(三) 调度引擎初步分析
(有什么问题欢迎指教,企鹅:2172243813 更多资讯尽在www.ttkmwl.com)
//启动服务
virtual bool__cdecl StartService();
//停止服务
virtual bool__cdecl StopService();
//设置网络
virtual bool__cdecl SetSocketEngine(IUnknownEx * pIUnknownEx);
//注册钩子
virtual bool__cdecl SetAttemperEngineSink(IUnknownEx * pIUnknownEx);
//获取接口
virtual void* __cdecl GetQueueService(const IID & Guid, DWORDdwQueryVer);
CAttempterEngine实现了两个接口:IQueueServiceSink、IAttemperEngine;
通过前面的分析,偶们了解到,IQueueServiceSink这个接口被是用来处理CQueueService中的数据的,根据上面的UML我们可以看到,CAttemperEngine关联了一个CQueueService(或者直接点说是:持有了一个CQueueService对象,说组合也成)。这样的话这个CAttemperEngine暴露出来的接口就只剩下IAttemperEnging了。
这个接口有两处值得单独讨论的:SetSocketEngine、GetQueueService;
SetSocketEngine,后面的分析中还会出现,我觉得这里是一个设计上的失误导致需要暴露socket引擎接口;
GetQueueService的设计思路可能是说,每个IAttemperEngine接口背后都有一个CQueueService,从以后的分析中可以看到,这个思路是理解整个kernel的关键。调度引擎应该是一个消息汇总(从个个引擎产生的消息)然后派发到IAttemperEngineSink。因为代码中是没有看到有关ITimerSink ISocketSink之类的东东的,,,
整个消息是个引擎产生,然后投递到指定的CQueueService,然后汇总到这里被派发到IAttemperEngineSink出去的,,,
看看CAttemperEngine中处理数据的代码:
1//队列接口
2void __cdecl CAttemperEngine::OnQueueServiceSink(WORD wIdentifier,void * pBuffer, WORD wDataSize, DWORD dwInsertTime)
3 {
4 //内核事件
5 ASSERT(m_pIAttemperEngineSink!=NULL);
6 switch(wIdentifier)
7 {
8 caseEVENT_TIMER: //定时器事件
9 {
10 //效验参数
11 ASSERT(wDataSize==sizeof(NTY_TimerEvent));
12 if (wDataSize!=sizeof(NTY_TimerEvent)) return;
13
14 //处理消息
15 NTY_TimerEvent * pTimerEvent=(NTY_TimerEvent *)pBuffer;
16 m_pIAttemperEngineSink->OnEventTimer(pTimerEvent->wTimerID,pTimerEvent->wBindParam);
17
18 return;
19 }
20 caseEVENT_DATABASE: //数据库事件
21 {
22 //效验参数
23 ASSERT(wDataSize>=sizeof(NTY_DataBaseEvent));
24 if (wDataSize
25
26 //处理消息
27 NTY_DataBaseEvent * pDataBaseEvent=(NTY_DataBaseEvent*)pBuffer;
28 m_pIAttemperEngineSink->OnEventDataBase(pDataBaseEvent+1,wDataSize-sizeof(NTY_DataBaseEvent),pDataBaseEvent);
29
30 return;
31
virtual bool__cdecl StartService();
//停止服务
virtual bool__cdecl StopService();
//设置网络
virtual bool__cdecl SetSocketEngine(IUnknownEx * pIUnknownEx);
//注册钩子
virtual bool__cdecl SetAttemperEngineSink(IUnknownEx * pIUnknownEx);
//获取接口
virtual void* __cdecl GetQueueService(const IID & Guid, DWORDdwQueryVer);
CAttempterEngine实现了两个接口:IQueueServiceSink、IAttemperEngine;
通过前面的分析,偶们了解到,IQueueServiceSink这个接口被是用来处理CQueueService中的数据的,根据上面的UML我们可以看到,CAttemperEngine关联了一个CQueueService(或者直接点说是:持有了一个CQueueService对象,说组合也成)。这样的话这个CAttemperEngine暴露出来的接口就只剩下IAttemperEnging了。
这个接口有两处值得单独讨论的:SetSocketEngine、GetQueueService;
SetSocketEngine,后面的分析中还会出现,我觉得这里是一个设计上的失误导致需要暴露socket引擎接口;
GetQueueService的设计思路可能是说,每个IAttemperEngine接口背后都有一个CQueueService,从以后的分析中可以看到,这个思路是理解整个kernel的关键。调度引擎应该是一个消息汇总(从个个引擎产生的消息)然后派发到IAttemperEngineSink。因为代码中是没有看到有关ITimerSink ISocketSink之类的东东的,,,
整个消息是个引擎产生,然后投递到指定的CQueueService,然后汇总到这里被派发到IAttemperEngineSink出去的,,,
看看CAttemperEngine中处理数据的代码:
1//队列接口
2void __cdecl CAttemperEngine::OnQueueServiceSink(WORD wIdentifier,void * pBuffer, WORD wDataSize, DWORD dwInsertTime)
3 {
4 //内核事件
5 ASSERT(m_pIAttemperEngineSink!=NULL);
6 switch(wIdentifier)
7 {
8 caseEVENT_TIMER: //定时器事件
9 {
10 //效验参数
11 ASSERT(wDataSize==sizeof(NTY_TimerEvent));
12 if (wDataSize!=sizeof(NTY_TimerEvent)) return;
13
14 //处理消息
15 NTY_TimerEvent * pTimerEvent=(NTY_TimerEvent *)pBuffer;
16 m_pIAttemperEngineSink->OnEventTimer(pTimerEvent->wTimerID,pTimerEvent->wBindParam);
17
18 return;
19 }
20 caseEVENT_DATABASE: //数据库事件
21 {
22 //效验参数
23 ASSERT(wDataSize>=sizeof(NTY_DataBaseEvent));
24 if (wDataSize
25
26 //处理消息
27 NTY_DataBaseEvent * pDataBaseEvent=(NTY_DataBaseEvent*)pBuffer;
28 m_pIAttemperEngineSink->OnEventDataBase(pDataBaseEvent+1,wDataSize-sizeof(NTY_DataBaseEvent),pDataBaseEvent);
29
30 return;
31