修改的原因
- 我们目前的版本里面 大量来自协议的Dispatcher严重影响代码的阅读和维护
- 事件的逻辑处理和数据处理在框架层并没有明确分开
- 事件派发能够有效的减少直接引用
实现原理
-
在MobileZGameInstance中包含两个代理函数:OnProtocolRecvDelegate和PostProtocolRecvDelegate。当网络协议完成从protocol buffer转化为ProtocolTemplate之后会连续执行:
OnProtocolReceivedDelegate().Broadcast(ProtocolObject); PostProtocolRecvDelegate().Broadcast(ProtocolObject); ProtocolObject->Process(Ins)
-
我们在c++代码中完成他们的自动注册。manager被默认为是在创建的时候自动注册OnProtocolRecvDelegate,manager销毁的时候清理代理, 所以可以认为Manager的注册是永久的,UI则默认只注册PostProtocolRecvDelegate,而且UI这边是在Construct的时候进行自动注册,Destruct的时候默认取消注册,可以认为UI只会在显示的时候处理协议。GameInstance Destroy的时候取消所有的注册,
*当上述两个代理出发之后会执行下面的Lambda函数
auto ProcessLambda = [=](UObject* Protocol, const TCHAR* Prefixes)
{
FString ClassName, RightName;
Protocol->GetClass()->GetName().Split(TEXT("_C"), &ClassName, &RightName);
FName FunctionName = FName(*(FString::Printf(TEXT("%s%s"), Prefixes, *ClassName)));
UFunction* Function = Excuter->FindFunction(FunctionName);
if (Function)
{
void* Parameters = (void*)(&Protocol);
Excuter->ProcessEvent(Function, Parameters);
}
};
OnProtocolReceivedDelegate
代理的Prefixes 是OnRecv
,PostProtocolRecvDelegate
的Prefixes 是PostRecv
所以如果一个注册了两个代理的对象类中如果含有Prefixes +协议名函数名的函数,那么该函数将会执行。相当于对协议的抵达做了相应的处理。
函数名字举例:OnRecvActivationKeyRsp
, PostRecvActivationKeyRsp
用法
- 如果一个类希望能够绑定上述的两个代理,需要实现接口类IProtocolProcessInterface
- 需要在适当的地方调用
RegisterDelegate
和UnRegisterDelegate
- 按照需要实现自己的方法OnRecv+Protocol,既可以在c++中也可以在BP中实现该函数,c++中使用UFUNCTION标记函数,BP中直接声明函数即可。
uml图: https://www.processon.com/view/link/584627dee4b0e742e4a9dcdd
网友评论