/
ActionManager.cs
143 lines (126 loc) · 3.81 KB
/
ActionManager.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
using UnityEngine;
using System.Collections;
using System.Collections.Generic;
using System;
/// <summary>
/// 一系列异步过程的抽象
/// 一个Action代表一个有序的动作集合
/// </summary>
public interface Action
{
bool isDone();
void pause();
void resumue();
void abort();
}
public class ActionManager : MonoBehaviour {
/// <summary>
/// 核心类 action执行器
/// 为了递归,使得action执行器也可以被yield, 所以本身也是一个action
/// Action是包含了一系列enumerator的栈式层级结构 enumerator其实就是一系列步骤的描述
/// 原理很简单
/// 每帧不断执行这一个系列的enumerator,每次执行到一个yield return 监测yield出的值。
/// yield值是同步值 则立即执行后续代码到下一个yield
/// yield值是异步值(一个Action) 则一直检测Action.isDone();true则执行后续代码到下一个yield
/// yield值是一个enumerator 当前enumerator入栈 上下文切换到enumerator执行上述操作
/// 当enumerator执行完毕 检查栈中是否还有enumerator 如果有则出栈继续执行 如果没有 整个操作结束 设置本身的isDone 为true
/// </summary>
class ActionExecutor :Action
{
IEnumerator enumerator;
ActionExecutor parent;
bool done=false;
bool aborted = false;
public ActionExecutor(IEnumerator enumerator,ActionExecutor parent=null)
{
this.enumerator = enumerator;
this.parent = parent;
}
public bool run()
{
bool flag;
if (aborted) return false;
object current = this.enumerator.Current;
if(current is Action)
{
if((current as Action).isDone())
{
flag = this.enumerator.MoveNext();
}
else
{
return true;
}
}
else if(current is IEnumerator)
{
this.parent = new ActionExecutor(this.enumerator, this.parent);
this.enumerator = current as IEnumerator;
return this.run();
}
else
{
flag = this.enumerator.MoveNext();
}
if (!flag&&this.parent!=null)
{
this.enumerator = this.parent.enumerator;
this.parent = this.parent.parent;
return this.enumerator.MoveNext();
}
return flag;
}
public bool isDone(){
return done;
}
public void pause(){
}
public void resumue(){
}
public void finish(){
done = true;
}
public void abort()
{
}
}
public static ActionManager Instance
{
get;
private set;
}
void Awake()
{
if (!Instance)
{
Instance = this;
}
else
{
Debug.LogError("ActionManager must be added to just only one gameobject");
}
}
List<ActionExecutor> executorList = new List<ActionExecutor>();
// Use this for initialization
void Start () {
}
void Update()
{
}
void LateUpdate () {
for(int i = 0; i < executorList.Count; i++)
{
if (!executorList[i].run()) {
executorList[i].finish();
executorList.RemoveAt(i);
i--;
};
}
}
public static Action excuteAction(IEnumerator enumerator)
{
ActionExecutor actionExecutor = new ActionExecutor(enumerator);
Instance.executorList.Add (actionExecutor);
return actionExecutor;
}
}