您的位置:首页 > 运维架构 > 网站架构

U3D架构系列之- FSM有限状态机设计二

2016-02-02 11:36 621 查看
由 Benz 于 星期五, 2015-01-30 13:45 发表

在设计一中,我们把IState类设计了一下,接下来,我们写一下FiniteStateMachine这个类,这个类主要的作用就是对于外界调用,这个类是独立封装的,不继承Mono。这个类的功能是提供一个栈,用于存放FSState,还有通过Update进行状态的切换,以及对栈的管理,Pop和Push操作以及状态的注册。最重要的一点是声明了三个委托函数代码如下:

public delegate void EnterState(string stateName);

public delegate void PushState(string stateName, string lastStateName);

public delegate void PopState();

主要是用于状态之间的切换。定义了Dictionary和Stack,前者用于State注册,后者是状态切换。代码如下:

protected Dictionary mStates;

protected Stack mStateStack;

对应的相关处理函数如下:

public void Register(string stateName, IState stateObject) {

if (mStates.Count == 0)

mEntryPoint = stateName;

mStates.Add(stateName, new FSState(stateObject, this, stateName, Enter, Push, Pop));

}

用于状态机的注册,对Stack的操作是如下两个函数,一个是Pop,一个是Push函数。代码如下:

public void Push(string newState) {

string lastName = null;

if (mStateStack.Count > 1) {

lastName = mStateStack.Peek().StateName;

}

Push(newState, lastName);

}

protected void Push(string stateName, string lastStateName) {

mStateStack.Push(mStates[stateName]);

mStateStack.Peek().StateObject.OnEnter(lastStateName);

}

public void Pop() {

Pop(null);

}

protected string Pop(string newName) {

FSState lastState = mStateStack.Peek();

string newState = null;

if (newName == null && mStateStack.Count > 1) {

int index = 0;

foreach (FSState item in mStateStack) {

if (index++ == mStateStack.Count - 2) {

newState = item.StateName;

}

}

}

else {

newState = newName;

}

string lastStateName = null;

if (lastState != null) {

lastStateName = lastState.StateName;

lastState.StateObject.OnExit(newState);

}

mStateStack.Pop();

return lastStateName;

}

下面增加了状态触发消息事件,代码如下:

public void Trigger(string eventName) {

CurrentState.Trigger(eventName);

}

public void Trigger(string eventName, object param1) {

CurrentState.Trigger(eventName, param1);

}

public void Trigger(string eventName, object param1, object param2) {

CurrentState.Trigger(eventName, param1, param2);

}

public void Trigger(string eventName, object param1, object param2, object param3) {

CurrentState.Trigger(eventName, param1, param2, param3);

}

最后把FiniteStateMachine核心的功能给大家介绍完了,下面奉上整个类的代码:

using UnityEngine;

using System.Collections;

using System.Collections.Generic;

public class FiniteStateMachine {

public delegate void EnterState(string stateName);

public delegate void PushState(string stateName, string lastStateName);

public delegate void PopState();

protected Dictionary mStates;

protected string mEntryPoint;

protected Stack mStateStack;

public FiniteStateMachine() {

mStates = new Dictionary();

mStateStack = new Stack();

mEntryPoint = null;

}

public void Update() {

if (CurrentState == null) {

mStateStack.Push(mStates[mEntryPoint]);

CurrentState.StateObject.OnEnter(null);

}

CurrentState.StateObject.OnUpdate();

}

public void Register(string stateName, IState stateObject) {

if (mStates.Count == 0)

mEntryPoint = stateName;

mStates.Add(stateName, new FSState(stateObject, this, stateName, Enter, Push, Pop));

}

public FSState State(string stateName) {

return mStates[stateName];

}

public void EntryPoint(string startName) {

mEntryPoint = startName;

}

public FSState CurrentState {

get {

if (mStateStack.Count == 0)

return null;

return mStateStack.Peek();

}

}

public void Enter(string stateName) {

Push(stateName, Pop(stateName));

}

public void Push(string newState) {

string lastName = null;

if (mStateStack.Count > 1) {

lastName = mStateStack.Peek().StateName;

}

Push(newState, lastName);

}

protected void Push(string stateName, string lastStateName) {

mStateStack.Push(mStates[stateName]);

mStateStack.Peek().StateObject.OnEnter(lastStateName);

}

public void Pop() {

Pop(null);

}

protected string Pop(string newName) {

FSState lastState = mStateStack.Peek();

string newState = null;

if (newName == null && mStateStack.Count > 1) {

int index = 0;

foreach (FSState item in mStateStack) {

if (index++ == mStateStack.Count - 2) {

newState = item.StateName;

}

}

}

else {

newState = newName;

}

string lastStateName = null;

if (lastState != null) {

lastStateName = lastState.StateName;

lastState.StateObject.OnExit(newState);

}

mStateStack.Pop();

return lastStateName;

}

public void Trigger(string eventName) {

CurrentState.Trigger(eventName);

}

public void Trigger(string eventName, object param1) {

CurrentState.Trigger(eventName, param1);

}

public void Trigger(string eventName, object param1, object param2) {

CurrentState.Trigger(eventName, param1, param2);

}

public void Trigger(string eventName, object param1, object param2, object param3) {

CurrentState.Trigger(eventName, param1, param2, param3);

}

}

上面整个FSMStateMachine类就封装完了,要知后事如何?且看系列三的讲解。

本文出自 “海游移动” 博客,出处 /article/4237451.html
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: