Unity ET学习笔记-一种消息机制的简单实现

一直很疑惑在ET中为什么加上特性并实现继承重写方法就可以将这条消息的实现了,记录一下简单版的实现过程。

特性的意义:扫描该程序集中所有拥有特性的类

调用父类中获取泛型类的函数,获得的结果暂时称其为组件类型

将组件类型与该类绑定,加入字典

通过组件类型找到对应类,调用对应类的接口函数,在该类中接口函数实现我们的重写方法

比较绕的就是上面这个部分了

当我们找到对应类型的对应函数之后就好说了

System代表我们的逻辑层,component代表我们的数据层, 不管你怎么写既然我们能得到条数据,正常编写自己的逻辑就可以了

代码如下:

using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public interface ISystem
{
	Type Type();
	void Run(object o);
}
public abstract class MoveSystem<E> : ISystem
{
	public void Run(object o)
	{
		this.Start((E)o);
	}
	public Type Type()
	{
		return typeof(E);
	}
	public abstract void Start(E self);
}
[ObjectSystem]
public class HeroStartSystem : MoveSystem<MoveComponent>
{
	public override void Start(MoveComponent self)
	{
		self.Start();
	}
}
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public abstract class Component
{
	public int SoleID { get; set; }
}

public class MoveComponent : Component
{
	public string moveName = "";
	public int moveSpeed { get; set; }
	public int veerSpeed { get; set; }
}

public static class ComponentHelper
{
	public static void Start(this MoveComponent moveComponent)
	{
		moveComponent.Swiftly();
		moveComponent.Slowly();
		Debug.Log(moveComponent.moveName);
	}
	public static void Swiftly(this MoveComponent moveComponent)
	{
		Debug.Log("-------S------");
	}
	public static void Slowly(this MoveComponent moveComponent)
	{
		Debug.Log("-------L------");
	}
}
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using System;
using System.Reflection;


[AttributeUsage(AttributeTargets.Class, AllowMultiple = true)]
public class ObjectSystemAttribute : Attribute
{

}

public class EventSystem
{
	public static EventSystem instance;
	public static EventSystem Instance
	{
		get
		{
			return instance ?? (instance = new EventSystem());
		}
	}
	private readonly UnOrderMultiMap<Type, ISystem> startSystems = new UnOrderMultiMap<Type, ISystem>();

	// 扫描添加的程序集中的ObjectSystemAttribute对象
	public void Add(Assembly assembly)
	{

		foreach (Type type in assembly.GetTypes())
		{
			object[] objects = type.GetCustomAttributes(typeof(ObjectSystemAttribute), false);
			if (objects.Length == 0)
			{
				continue;
			}

			object obj = Activator.CreateInstance(type);

			switch (obj)
			{
				case ISystem startSystem:
					this.startSystems.Add(startSystem.Type(), startSystem);
					break;
			}
		}

	}

	// 调用组件的Start方法
	public void Start(Component component)
	{
		if (startSystems.Count == 0)
		{
			return;
		}
		List<ISystem> iStartSystems = this.startSystems[component.GetType()];
		if (iStartSystems == null)
		{
			return;
		}

		foreach (ISystem iStartSystem in iStartSystems)
		{
			try
			{
				iStartSystem.Run(component);
				// startSystems.Remove(component.GetType());
			}
			catch (Exception e)
			{
				Console.WriteLine(e);
			}
		}

		startSystems.Remove(component.GetType());

	}
}




public class UnOrderMultiMap<T, K>
{
	// 重用list
	private readonly Queue<List<K>> queue = new Queue<List<K>>();
	private readonly Dictionary<T, List<K>> dictionary = new Dictionary<T, List<K>>();
	public void Add(T t, K k)
	{
		List<K> list;
		this.dictionary.TryGetValue(t, out list);
		if (list == null)
		{
			list = this.FetchList();
			this.dictionary[t] = list;
		}
		list.Add(k);
	}
	public bool Remove(T t)
	{
		List<K> list = null;
		this.dictionary.TryGetValue(t, out list);
		if (list != null)
		{
			this.RecycleList(list);
		}
		return this.dictionary.Remove(t);
	}
	public List<K> this[T t]
	{
		get
		{
			List<K> list;
			this.dictionary.TryGetValue(t, out list);
			return list;
		}
	}
	public int Count
	{
		get
		{
			return this.dictionary.Count;
		}
	}


	private List<K> FetchList()
	{
		if (this.queue.Count > 0)
		{
			List<K> list = this.queue.Dequeue();
			list.Clear();
			return list;
		}
		return new List<K>();
	}

	private void RecycleList(List<K> list)
	{
		// 防止暴涨
		if (this.queue.Count > 100)
		{
			return;
		}
		list.Clear();
		this.queue.Enqueue(list);
	}
}
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using System.Reflection;
public class AppStart : MonoBehaviour
{
	private void Start()
	{
		MoveComponent moveComponent = new MoveComponent();
		EventSystem.Instance.Add(typeof(AppStart).Assembly);
		EventSystem.Instance.Start(moveComponent);
	}
}

猜你喜欢

转载自blog.csdn.net/qq_55042292/article/details/125636177