Unity3D C# event system combat based on covariance, observers, and unsafe conversion

Project address-CoEvent

insert image description here

CoEvent

CoEvent is a lightweight local message system that can constrain parameter types, constrain call types, parameter and call type safety, and supports all CSharp programming platforms that can support Unsafe.As similar APIs.

The currently supported platforms are .NET CORE and Unity3D 2020.1 OR NEWER.

In theory, Unity3D with a lower version can also be implemented (may provide support in subsequent versions), but there is no native UnsafeUtility.As, you can implement a replacement by yourself.

1. Advantages

The advantage of CoEvent mainly lies in "constraints". Now traditional message systems are generally implemented in the following ways

  • 1. Reflection (Unity's SendMessage has been ruthlessly abandoned)
  • 2.int, string, enum as message identification (registration and cancellation need to manually write a large number of generic parameters, and calls need to manually write generic parameters, if wrong...the consequences are unimaginable)
  • 3. Interface-based, base-class-based (some similar ones have written interfaces based on the observer mode, and inheriting the base class can make it easier to implement this constraint, but it is difficult to implement constraints when inheriting the interface, and it is difficult to judge the message type. Many Interface constraints can only have unique messages)

Show everyone how to call and implement the mainstream implementation

//Unity原生SendMessage,通过反射,效率低,容易写错名字,写错时候字符串是没提示的,很难查错
Monobehaviour.SendMessage("Ttt");
//int,string,enum做标识的
EventCenter.Add<int,int>("name",MyAction);//在注册时需要写泛型
EventCenter.Send("name",10,20);  //调用时没有约束,我也可以传入错误的参数类型,当写多了就变成了灾难。
//基类和接口继承的
//基类不用说了,侵入性太强了
//接口继承的,一般一个类只能有一个事件,不然很难判断类型的参数
//当然也有写分析器的,那都是大牛,QAQ,本渣做不到

And how is CoEvent implemented?
CoEvent adopts the second method, but the difference is that the message identifier is an interface, and it cleverly uses covariance to implement constraints.

CoEvent can omit generic parameters when registering and canceling based on generic inference, and can also limit the parameter types when publishing events.

In other words, CoEvent will not have the type of wrongly written generic parameters, nor will it happen that Send registration will result in Call calling.

It greatly reduces the developer's code error probability and reduces the debugging time.

Two, use

CoEvent implements an event system based on the Observer pattern based on the principle of simplicity and ease of use. It is easy to realize event communication between objects and modules.

1. Pre-configuration:

如果你是在Unity3D 2020.1以上使用,无需配置任何内容。
如果你是在.NetCore使用,需要在任意一个参与编译的文件里加上宏定义,#define NETCORE
如果你在其他平台使用,可以在CoUnsafeAs.cs里去给出Unsafe.As的类似实现。
无法实现?不支持该平台QAQ

2. Event definition

//通用事件,可以Send可以Call,但是只能用一个!!!
public interface MyEvent: IGenericEvent<参数类型,参数类型...>
//可发送
public interface MyEvent: ISendEvent<...>
//可调用(最后一个泛型参数是返回值)
public interface MyEvent: ICallEvent<...>

3. Register and cancel events (MyAction is also constrained)

this.Operator<消息类型接口>().Subcribe(MyAction);
this.Operator<消息类型接口>().UnSubcribe(MyAction);

4. Call and send

this.Operator<消息类型接口>().Send(...参数们);
var results = this.Operator<消息类型接口>().Call(...参数们);

3. Examples

using CoEvent;
using UnityEngine;


public interface IMyTest : ISendEvent<int, int> {
    
     }
public class Test : MonoBehaviour
{
    
    

    void Ttt(int t,int k)
    {
    
    
        Debug.Log($"{
      
      t}:{
      
      k}");
    }

    void Start()
    {
    
    
    	//也无需像其他事件系统一样注册时写明参数的泛型
        this.Operator<IMyTest>().Subscribe(Ttt);
        this.Operator<IMyTest>().UnSubscribe(Ttt);
        //你绝对不会写错参数类型
        this.Operator<IMyTest>().Send(10,100);
    }

}

Guess you like

Origin blog.csdn.net/qq_46273241/article/details/130723091