Unity3D有限状态机(FSM)学习笔记【6】Dispatcher类

本系列笔记转载自游戏蛮牛专栏作家Jackel的论坛文章,详细介绍了FSM的创建与使用,特与众分享。链接:http://www.manew.com/thread-37136-1-1.html

该类主要实现的是事件的注册、触发,以及分发Event消息。提供接口对外使用。使用了大量魔板函数。分发消息使用的队列方式,先进先出。代码如下:

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

namespace EventSystem
{
	
	public class Dispatcher 
	{	
		public void Trigger( string eventName )
		{
			Call ( eventName, null, null, null );
		}
		
		public void Dispatch( string eventName )
		{
			Dispatched d = ( mFreeDispatch.Count == 0 ) ? new Dispatched() : mFreeDispatch.Pop();
			mDispatched.Enqueue( d.Set( eventName ));
		}
		
		public int On( string eventName, Func<bool> action )
		{
			return Register ( eventName, delegate( object arg1, object arg2, object arg3 )
			{
				return ( action() );
			});
		}
		
		public int On( string eventName, Action action )
		{
			return Register( eventName, delegate( object arg1, object arg2, object arg3 )
			{
				action();
				return true;
			});
		}

		public void Trigger( string eventName, object param1 )
		{
			Call ( eventName, param1, null, null );				
		}
	
		public void Dispatch( string eventName, object param1 )
		{
			Dispatched d = ( mFreeDispatch.Count == 0 ) ? new Dispatched() : mFreeDispatch.Pop();
			mDispatched.Enqueue( d.Set( eventName, param1 ));
		}
		
		public int On<T>( string eventName, Func<T,bool> action )
		{
			return Register( eventName, delegate( object arg1, object arg2, object arg3 ) 
			{
				T param1;
				try{ param1 = (T)arg1; } catch { param1 = default(T); }
				return ( action( param1 ));
			});
		}
		
		public int On<T>( string eventName, Action<T> action )
		{
			return Register( eventName, delegate( object arg1, object arg2, object arg3 )
			{
				T param1;
				try { param1 = (T)arg1; } catch { param1 = default(T); }
				action( param1 );
				return true;
			});
		}
		
		public void Trigger( string eventName, object param1, object param2 )
		{
			Call( eventName, param1, param2, null );
		}
		
		public void Dispatch( string eventName, object param1, object param2 )
		{
			Dispatched d = ( mFreeDispatch.Count == 0 ) ? new Dispatched() : mFreeDispatch.Pop();
			mDispatched.Enqueue( d.Set( eventName, param1, param2 ));
		}
		
		public int On<T1,T2>( string eventName, Func<T1,T2,bool> action )
		{
			return Register( eventName, delegate( object arg1, object arg2, object arg3 )
			{
				T1 param1;
				T2 param2;
				try { param1 = (T1)arg1; } catch { param1 = default(T1); }
				try { param2 = (T2)arg2; } catch { param2 = default(T2); }
				return ( action( param1, param2 ));
			});
		}
		
		public int On<T1,T2>( string eventName, Action<T1,T2> action )
		{
			return Register( eventName, delegate( object arg1, object arg2, object arg3 )
			{
				T1	param1;
                T2 param2;
                try { param1 = (T1)arg1; } catch { param1 = default(T1); }
                try { param2 = (T2)arg2; } catch { param2 = default(T2); }
                action( param1, param2 );
                return true;	
			});
		}
		
		public void Trigger( string eventName, object param1, object param2, object param3 )
		{
			Call( eventName, param1, param2, param3 );
		}
		
		public void Dispatch( string eventName, object param1, object param2, object param3 )
		{
			Dispatched d = ( mFreeDispatch.Count == 0 ) ? new Dispatched() : mFreeDispatch.Pop();
			mDispatched.Enqueue( d.Set( eventName, param1, param2, param3 ));
		}
		
		public int On<T1,T2,T3>( string eventName, Func<T1,T2,T3,bool> action )
		{
			return Register( eventName, delegate( object arg1, object arg2, object arg3 )
			{
				T1 param1;
				T2 param2;
				T3 param3;
				try{ param1 = (T1)arg1; } catch { param1 = default(T1); }
				try{ param2 = (T2)arg2; } catch { param2 = default(T2); }
				try{ param3 = (T3)arg3; } catch { param3 = default(T3); }
				return ( action( param1, param2, param3 ) );
			});
		}
		
		public int On<T1,T2,T3>( string eventName, Action<T1,T2,T3> action )
		{
			return Register( eventName, delegate( object arg1, object arg2, object arg3 )
			{
				T1 param1;
				T2 param2;
				T3 param3;
				try{ param1 = (T1)arg1; } catch { param1 = default(T1); }
				try{ param2 = (T2)arg2; } catch { param2 = default(T2); }
				try{ param3 = (T3)arg3; } catch { param3 = default(T3); }
				action( param1, param2, param3 );
				return true;
			});
		}
			
		public bool Cancel( int listenerID )
		{
			return mRegistered.Remove( listenerID );	
		}
		public void DispatchPending()
		{
			while( mDispatched.Count > 0 )
			{
				Dispatched d = mDispatched.Dequeue();
				Call( d.mEventName, d.mArg1, d.mArg2, d.mArg3 );
				mFreeDispatch.Push( d );
			}
		}
		
		int Register( string eventName, Func<object,object,object,bool> action )	
		{
			int listenID 	= ++ mNextListenID;
			Listen listen	= ( mFreeListen.Count == 0 ) ? new Listen() : mFreeListen.Pop();
			listen.mID		= listenID;
			listen.mAction	= action;
			mRegistered.Add( listenID, listen );
			List<int> eventList;
			if( !mRegisteredEvents.TryGetValue( eventName, out eventList ))
			{
				eventList = mRegisteredEvents[ eventName ] = new List<int>();	
			}
			eventList.Add( listenID );
			return listenID;
		}
		
		void Call( string eventName, object arg1, object arg2, object arg3 )
		{
			List<int> listenerList;
			if( mRegisteredEvents.TryGetValue( eventName, out listenerList ))
			{
				for( int i = listenerList.Count - 1; i >= 0; --i )
				{
					Listen listener;
					if( mRegistered.TryGetValue( listenerList[ i ], out listener ))
					{
						if( !listener.mAction( arg1, arg2, arg3 ))	
						{
							mRegistered.Remove( listenerList[ i ] );
							mFreeListen.Push( listener );
						}
					}
					else
					{
						listenerList.RemoveAt( i );	
					}
				}
				if( listenerList.Count == 0 )
				{
					mRegisteredEvents.Remove( eventName );	
				}
			}
		}
		
		class Listen
		{
			public int mID;
			public Func<object,object,object,bool> mAction;
		}
		
		class Dispatched
		{
			public Dispatched Set( string eventName, object arg1 = null, object arg2 = null, object arg3 = null )
			{
				mEventName  = eventName;
				mArg1 		= arg1;
				mArg2 		= arg2;
				mArg3 	 	= arg3;
				return this;
			}
			
			public string mEventName;
			public object mArg1, mArg2, mArg3;
		}
		Dictionary<string,List<int>> mRegisteredEvents  = new Dictionary<string, List<int>>();
		Dictionary<int, Listen> mRegistered 			= new Dictionary<int, Listen>();
		Stack<Listen> mFreeListen 						= new Stack<Listen>();
		Stack<Dispatched> mFreeDispatch					= new Stack<Dispatched>();
		Queue<Dispatched> mDispatched					= new Queue<Dispatched>();
		int mNextListenID								= 4711;
	}
}

一、事件注册与触发

在使用状态机是需先对消息事件注册,放到字典中保存

1、Register注册

按照事件名称,存放事件

2、Trigger触发


3、On



  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
YOLO高分设计资源源码,详情请查看资源内容中使用说明 YOLO高分设计资源源码,详情请查看资源内容中使用说明 YOLO高分设计资源源码,详情请查看资源内容中使用说明 YOLO高分设计资源源码,详情请查看资源内容中使用说明YOLO高分设计资源源码,详情请查看资源内容中使用说明YOLO高分设计资源源码,详情请查看资源内容中使用说明YOLO高分设计资源源码,详情请查看资源内容中使用说明YOLO高分设计资源源码,详情请查看资源内容中使用说明YOLO高分设计资源源码,详情请查看资源内容中使用说明YOLO高分设计资源源码,详情请查看资源内容中使用说明YOLO高分设计资源源码,详情请查看资源内容中使用说明YOLO高分设计资源源码,详情请查看资源内容中使用说明YOLO高分设计资源源码,详情请查看资源内容中使用说明YOLO高分设计资源源码,详情请查看资源内容中使用说明YOLO高分设计资源源码,详情请查看资源内容中使用说明YOLO高分设计资源源码,详情请查看资源内容中使用说明YOLO高分设计资源源码,详情请查看资源内容中使用说明YOLO高分设计资源源码,详情请查看资源内容中使用说明YOLO高分设计资源源码,详情请查看资源内容中使用说明YOLO高分设计资源源码,详情请查看资源内容中使用说明YOLO高分设计资源源码,详情请查看资源内容中使用说明YOLO高分设计资源源码,详情请查看资源内容中使用说明YOLO高分设计资源源码,详情请查看资源内容中使用说明YOLO高分设计资源源码,详情请查看资源内容中使用说明YOLO高分设计资源源码,详情请查看资源内容中使用说明YOLO高分设计资源源码,详情请查看资源内容中使用说明

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值