首页 > 其他分享 >Message Manager 设计思路学习

Message Manager 设计思路学习

时间:2024-08-20 11:20:47浏览次数:12  
标签:EMessageType Get void messageType UMessageManager Manager 思路 Message

Message Manager 设计思路学习

设计思路

设计项目中不同类之间的消息通信和分发系统时,可以考虑以下思路:

  1. 定义消息类型:使用枚举或常量定义所有可能的消息类型,这有助于保持系统的可维护性和可扩展性。
  2. 消息中心:创建一个中央消息管理器或事件总线,它负责接收和分发消息。这个中心应该是线程安全的,以处理并发情况。
  3. 注册和注销:允许类或对象注册和注销对特定消息类型的监听。这样可以实现灵活的消息处理和减少不必要的处理开销。
  4. 消息处理:在处理消息时,考虑使用回调函数或处理器类,这样可以清晰地分离消息的接收和处理逻辑。
  5. 解耦:尽量使发送方和接收方解耦,通过消息中心来传递消息,避免直接的依赖关系。
  6. 性能考虑:如果消息处理频繁,确保系统对高频消息的处理效率足够高,避免性能瓶颈。

通过这些设计思路,你可以构建一个高效且可维护的消息通信系统。

Message.h

所有消息类型的枚举

UENUM(BlueprintType)
enum EMessageType {
    // 初始化,加载一系列
	Message_Init,
	Message_LoadScene,
	Message_LoadAssetList,
	Message_LoadGroupList,
	Message_LoadAssetTexture,
	Message_LoadAssetPak,
	Message_LoadAssetCollectTexture,
	Message_LoadAssetGroupTexture,
	Message_LoadMaterialPak,
	Message_LoadGroupPak,

	Message_LoadColorCardList,
	Message_LoadColorCard,
	// 单例初始化
	Message_SingletonInit,

	Message_ChangeTextureStateToIsReplace,

	Message_SingleGridClick,

	Message_RefreshButtonClick,
	// UI点击
	Message_TagClick,
	Message_TextureClick,
	Message_FurnitureTextureClick,
	Message_MaterialTextureClick,
	Message_ReplaceFurnitureTextureClick,
	Message_GroupTextureClick,
	Message_RoomObjectTextureClick,
	Message_SceneTextureClick,

	Message_TagUIClick,
	Message_LoadFurnitureList,
	// 物体操作
	Message_ActorLocationChange,
	Message_ActorDelete,
	Message_CopyRoomComponentDelete,
	Message_GroupComponentLocationChange,
	Message_RoomPlanDelete,
	Message_UnSelectActor,
	// 下载Pak
	Message_DownLoadPakClick,

	Message_RemoveGroup,
	Message_ClickIsConfirm,

	Message_EnterVR,

	Message_SingleGridHover,
	Message_SingleGridUnHover,

	Message_SetFullScreen,

	Message_CompanyItemClick,

	Message_OnSaveGroupComplete,

	Message_ChangeCompanyId,

	Message_OnScreenshotClick,

	Message_OnBestViewClick,

	Message_LoadNormalPackage,
	Message_LoadNormalTexture,
	Message_LoadNormalThumbnailTexture,

	Message_ExportTextureToMaterialPackage,

	Message_ExportMaterialPackageComplete,

	Message_OpenLevel,

	Message_LoadClientTextureList,
	Message_LoadClientPlanTextureList,
	Message_LoadPlan,

	Message_UnselectPostRoomPlanTexture,
};

消息类单例

UCLASS()
class UMessage : public UObject {
	GENERATED_BODY()
public:
	UMessage() {};
	~UMessage() {};
	template< class T >
	static T* Get() {
		static T* instance;
		if (instance == NULL) {
			instance = NewObject<T>();
			instance->AddToRoot();
		}
		return instance;
	};
};

MessageManager

单例管理

#pragma once

#include "UObject/NoExportTypes.h"
#include "Singleton.h"
#include "../Message/Message.h"
#include "Runtime/Core/Public/Delegates/DelegateInstanceInterface.h"
#include "MessageManager.generated.h"

// 声明多播委托,委托名为MessageCallback,传递 UMessage* 类型
DECLARE_MULTICAST_DELEGATE_OneParam(MessageCallback, UMessage*);
UCLASS()
class UMessageManager : public UObject
{
	GENERATED_BODY()
public:
	UMessageManager();
	~UMessageManager(); 
	void Init();
    // 根据消息类型,对应不同的委托,方便后续管理
	TMap<EMessageType, MessageCallback> MessageCallbackMap;

	void RegistMessage(EMessageType messageType, UObject* object, FString funcName);
	void UnRegistMessage(EMessageType messageType);
	void ExecuteMessage(EMessageType messageType, UMessage* baseMessage);

	UFUNCTION()
		static UMessageManager* Get();
};
  • 注册:void Register Message(EMessageType messageType, UObject* object, FString funcName);
  • 注销:void Unregister Message (EMessageType messageType);
  • 执行:void Execute Message (EMessageType messageType, UMessage* baseMessage);

Register Message

通过 Message Callback Map [message Type] 去存储对应消息类型的 Callback

如果包含则替换,不包含就添加

void UMessageManager::RegistMessage(EMessageType messageType, UObject* object, FString funcName) {
	MessageCallback messageCallback;
	bool bContains = false;
	if (MessageCallbackMap.Contains(messageType)) {
		messageCallback = MessageCallbackMap[messageType];
		bContains = true;
	}
	messageCallback.AddUFunction(object, *funcName);
	if (bContains) {
		MessageCallbackMap[messageType] = messageCallback;
	}
	else {
		MessageCallbackMap.Add(messageType, messageCallback);
	}
}

UnRegist Message

Message Callback Map [message Type] 移除对应类型的Callback

void UMessageManager::UnRegistMessage(EMessageType messageType)
{
	if (MessageCallbackMap.Contains(messageType))
		MessageCallbackMap.Remove(messageType);
}

Execute Message

如果存在该消息类型的Callback,则直接调用广播

void UMessageManager::ExecuteMessage(EMessageType messageType, UMessage* baseMessage) {
	if (!MessageCallbackMap.Contains(messageType))
		return;
	MessageCallbackMap[messageType].Broadcast(baseMessage);
}

Event Message.h

该类继承至 Message

UEventMessage 类的主要作用是作为一种通用的消息载体,用于在系统中传递多种类型的数据。它提供了多种方法来设置数据并返回自身,以便于 链式调用 ,这种设计模式使得在创建和配置消息对象时更加灵活和简洁。

UCLASS()
class UEventMessage : public UMessage
{
	GENERATED_BODY()
public:
	bool bValue;
	float fValue;
	int16 shortValue;
	int32 iValue;
	uint32 uintValue;
	FString sValue;
	void* ptr;
	UEventMessage* SetBool(bool _bValue){ 
		bValue = _bValue;
		return Get<UEventMessage>();
	}
	UEventMessage* SetFloat(float _fValue) {
		fValue = _fValue;
		return Get<UEventMessage>();
	}
	UEventMessage* SetPtr(void* _ptr) {
		ptr = _ptr;
		return Get<UEventMessage>();
	}
	UEventMessage* SetInt(int32 _iValue) {
		iValue = _iValue;
		return Get<UEventMessage>();
	}
	UEventMessage* SetShort(int16 _iValue) {
		shortValue = _iValue;
		return Get<UEventMessage>();
	}
	UEventMessage* SetUInt(uint32 _iValue) {
		uintValue = _iValue;
		return Get<UEventMessage>();
	}
	UEventMessage* SetString(FString& _sValue) {
		sValue = _sValue;
		return Get<UEventMessage>();
	}
	static UEventMessage* Instance() {
		return Get<UEventMessage>();
	}
};

Other Class

在其他类中,初始构建时注册消息

UMessageManager::Get()->RegistMessage(EMessageType::Message_TextureClick, this, "OnTextureClick");
UMessageManager::Get()->RegistMessage(EMessageType::Message_MaterialTextureClick, this, "OnMaterialTextureClick");
UMessageManager::Get()->RegistMessage(EMessageType::Message_GroupTextureClick, this, "OnGroupTextureClick");
UMessageManager::Get()->RegistMessage(EMessageType::Message_ReplaceFurnitureTextureClick, this, "OnReplaceFurnitureTextureClick");
UMessageManager::Get()->RegistMessage(EMessageType::Message_TagUIClick, this, "OnTagUIClick");
UMessageManager::Get()->RegistMessage(EMessageType::Message_LoadFurnitureList, this, "HandleFurnitureListMessage");

UMessageManager::Get()->RegistMessage(EMessageType::Message_LoadAssetPak, this, "OnTextureUpdate");

调用消息广播,并把自己作为指针存储至Message,广播出去

void UGroupUI::OnDownLoadButtonClick() {
	bOnlyDownLoad = true;
	UMessageManager::Get()->ExecuteMessage(MessageType, UMessage::Get<UEventMessage>()->SetPtr(this));
	bOnlyDownLoad = false;
	DownLoadButton->SetVisibility(ESlateVisibility::Hidden);
}

当消息广播出去后,接受到消息则调用绑定函数,并可以从Message拿到所需的数据

void UCategoryUI::OnGroupTextureClick(UEventMessage* message)
{
	UGroupUI* groupUI = static_cast<UGroupUI*>(message->ptr);

标签:EMessageType,Get,void,messageType,UMessageManager,Manager,思路,Message
From: https://www.cnblogs.com/Dreammoon/p/18369081

相关文章

  • Android UsbDeviceManager 代码分析
    USBDeviceManager是一个Android系统中用于管理USB设备的类,它是系统服务之一。其主要功能是控制USB设备的连接和断开,以及管理USB设备的权限和状态。下面是对USBDeviceManager代码的简要分析:USBDeviceManager的构造函数:在USBDeviceManager的构造函数中,它会调用系统服务框架的regis......
  • 【LGR-196-Div.4】洛谷入门赛 #26 题A - H 详细题解--优化思路简洁代码(C++,Python语
    前言:    觉得这个比赛很有意思的,都是暴力题,涉及一些细节,难度比较适合刚学编程语言的,可以很好的锻炼基础还有手速,最后两题也是比较有意思,之后也准备更新atc的比赛题解和洛谷的一些高质量比赛题解(算法网瘾就是想参加各种比赛)   如果觉得有帮助,或者觉得我写的好,......
  • AI 创业及变现新思路:零门槛 AI 绘图,定制 ComfyUI Serverless API 应用
    作者:鸥弋、筱姜2023年下半年,ComfyUI以其快速、流畅的图像生成能力,结合多样的自定义节点,迅速在创作者中流行起来。ComfyUI的亮点就是能够批量化生成图像,一键加载大量工作流,让用户可以轻松实现人像生成、背景替换、风格迁移和图像动画化等功能。越来越多的企业及个人开发者希望......
  • CANoe小白上手思路
    本文申明:2024.8.19无实操截图,皆在提供新建仿真工程思路,按个人需求根据CANoe明显的图标名称进行操作。操作环境:CANoe版本9.0.54,CANcase版本VN1610/30/40。新建工程和配置网络第一步:连上CANcase,打开CANoe,选择可用模板并创建配置新建工程,之后配置波特率。第二步:Mapping配......
  • springboot 缓存-cacheManager
    日常项目中如果对接口响应时间要求较高通常需要结合redis对接口进行缓存处理。1.pom文件中引入redisjar<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-data-redis</artifactId><......
  • 数字化转型探索:揭秘检验检测行业转型思路
    最新技术资源(建议收藏)https://www.grapecity.com.cn/resources/行业背景随着科技的不断进步和实验室管理需求的不断发展,传统实验室管理方式面临着许多问题,如采用纸质记录和手工操作、数据易丢失和难以追溯、效率低下、流程复杂以及质量管理不规范等。这些问题已经成为......
  • 2024年高教社杯数学建模国赛B题思路解析+代码+论文
    2024年高教社杯全国大学生数学建模竞赛(以下简称国赛)将于9月5日晚6时正式开始。下文包含:2024国赛思路解析​、国赛参赛时间及规则信息说明、好用的数模技巧及如何备战数学建模竞赛C君将会第一时间发布选题建议、所有题目的思路解析、相关代码、参考文献、参考论文等多项资料,帮......
  • HttpClient、IHttpClientFactory、HttpClientHandler 和 HttpMessageHandler 的生命周
    在C#中,HttpClient、IHttpClientFactory、HttpClientHandler和HttpMessageHandler的生命周期密切相关,它们共同影响着网络请求的性能、资源管理和可靠性。以下是它们的生命周期分析:1.HttpClient的生命周期默认行为:HttpClient是线程安全的,设计为可以在应用程序的整个生命......
  • UsbHostManager解析
    UsbHostManager和UsbDeviceManager的区别在于,UsbDeviceManager是将手机作为一个设备,比如手机连上电脑,使用adb、mtp等;而UsbHostManager,是将手机作为一个host,比如手机连接usb鼠标、usb摄像头等,就会new出一个UsbDevice出来。UsbHostManager初始化UsbHostManager和UsbDeviceManager......
  • Jupyter 二次开发思路(1)
    上篇文章介绍了Jupyter生态及重要组件的原理。基于之前的内容,本文介绍Jupyter二次开发的思路。首先介绍项目的需求,接着进一步介绍架构设计,进行demo的实现,最后进行总结。需求实现图数据管理分析BI平台的NotebookService,具备数据的探索、执行分析任务、sql操作、sp......