-
Notifications
You must be signed in to change notification settings - Fork 248
Expand file tree
/
Copy pathSTNodeOptionCollection.cs
More file actions
238 lines (202 loc) · 7.76 KB
/
Copy pathSTNodeOptionCollection.cs
File metadata and controls
238 lines (202 loc) · 7.76 KB
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
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Collections;
namespace ST.Library.UI.NodeEditor
{
public class STNodeOptionCollection : IList, ICollection, IEnumerable
{
/*
* 虽然该集合提供了完整的数据接口 如:Add,Remove,...
* 但是尽可能的不要使用移除的一些操作 如:Remove,RemoveAt,Clear,this[index] = value,...
* 因为在我的定义里面 每个Option的Owner是严格绑定的 一些移除或替换等操作会影响到Owner的变更
* 所以原本的所有连线将会断开 并且触发DisConnect事件
* 为了确保安全在STNode中 仅继承者才能够访问集合
*/
private int _Count;
public int Count { get { return _Count; } }
private STNodeOption[] m_options;
private STNode m_owner;
private bool m_isInput; //当前集合是否是存放的是输入点
internal STNodeOptionCollection(STNode owner, bool isInput) {
if (owner == null) throw new ArgumentNullException("所有者不能为空");
m_owner = owner;
m_isInput = isInput;
m_options = new STNodeOption[4];
}
public STNodeOption Add(string strText, Type dataType, bool bSingle) {
//not do this code -> out of bounds
//return m_options[this.Add(new STNodeOption(strText, dataType, bSingle))];
int nIndex = this.Add(new STNodeOption(strText, dataType, bSingle));
return m_options[nIndex];
}
public int Add(STNodeOption option) {
if (option == null) throw new ArgumentNullException("添加对象不能为空");
this.EnsureSpace(1);
int nIndex = option == STNodeOption.Empty ? -1 : this.IndexOf(option);
if (-1 == nIndex) {
nIndex = this._Count;
option.Owner = m_owner;
option.IsInput = m_isInput;
m_options[this._Count++] = option;
this.Invalidate();
}
return nIndex;
}
public void AddRange(STNodeOption[] options) {
if (options == null) throw new ArgumentNullException("添加对象不能为空");
this.EnsureSpace(options.Length);
foreach (var op in options) {
if (op == null) throw new ArgumentNullException("添加对象不能为空");
if (-1 == this.IndexOf(op)) {
op.Owner = m_owner;
op.IsInput = m_isInput;
m_options[this._Count++] = op;
}
}
this.Invalidate();
}
public void Clear() {
for (int i = 0; i < this._Count; i++) m_options[i].Owner = null;
this._Count = 0;
m_options = new STNodeOption[4];
this.Invalidate();
}
public bool Contains(STNodeOption option) {
return this.IndexOf(option) != -1;
}
public int IndexOf(STNodeOption option) {
return Array.IndexOf<STNodeOption>(m_options, option);
}
public void Insert(int index, STNodeOption option) {
if (index < 0 || index >= this._Count)
throw new IndexOutOfRangeException("索引越界");
if (option == null)
throw new ArgumentNullException("插入对象不能为空");
this.EnsureSpace(1);
for (int i = this._Count; i > index; i--)
m_options[i] = m_options[i - 1];
option.Owner = m_owner;
m_options[index] = option;
this._Count++;
this.Invalidate();
}
public bool IsFixedSize {
get { return false; }
}
public bool IsReadOnly {
get { return false; }
}
public void Remove(STNodeOption option) {
int nIndex = this.IndexOf(option);
if (nIndex != -1) this.RemoveAt(nIndex);
}
public void RemoveAt(int index) {
if (index < 0 || index >= this._Count)
throw new IndexOutOfRangeException("索引越界");
this._Count--;
m_options[index].Owner = null;
for (int i = index, Len = this._Count; i < Len; i++)
m_options[i] = m_options[i + 1];
this.Invalidate();
}
public STNodeOption this[int index] {
get {
if (index < 0 || index >= this._Count)
throw new IndexOutOfRangeException("索引越界");
return m_options[index];
}
set { throw new InvalidOperationException("禁止重新赋值元素"); }
}
public void CopyTo(Array array, int index) {
if (array == null)
throw new ArgumentNullException("数组不能为空");
m_options.CopyTo(array, index);
}
public bool IsSynchronized {
get { return true; }
}
public object SyncRoot {
get { return this; }
}
public IEnumerator GetEnumerator() {
for (int i = 0, Len = this._Count; i < Len; i++)
yield return m_options[i];
}
/// <summary>
/// 确认空间是否足够 空间不足扩大容量
/// </summary>
/// <param name="elements">需要增加的个数</param>
private void EnsureSpace(int elements) {
if (elements + this._Count > m_options.Length) {
STNodeOption[] arrTemp = new STNodeOption[Math.Max(m_options.Length * 2, elements + this._Count)];
m_options.CopyTo(arrTemp, 0);
m_options = arrTemp;
}
}
protected void Invalidate() {
if (m_owner != null && m_owner.Owner != null) {
m_owner.BuildSize(true, true, true);
//m_owner.Invalidate();//.Owner.Invalidate();
}
}
//===================================================================================
int IList.Add(object value) {
return this.Add((STNodeOption)value);
}
void IList.Clear() {
this.Clear();
}
bool IList.Contains(object value) {
return this.Contains((STNodeOption)value);
}
int IList.IndexOf(object value) {
return this.IndexOf((STNodeOption)value);
}
void IList.Insert(int index, object value) {
this.Insert(index, (STNodeOption)value);
}
bool IList.IsFixedSize {
get { return this.IsFixedSize; }
}
bool IList.IsReadOnly {
get { return this.IsReadOnly; }
}
void IList.Remove(object value) {
this.Remove((STNodeOption)value);
}
void IList.RemoveAt(int index) {
this.RemoveAt(index);
}
object IList.this[int index] {
get {
return this[index];
}
set {
this[index] = (STNodeOption)value;
}
}
void ICollection.CopyTo(Array array, int index) {
this.CopyTo(array, index);
}
int ICollection.Count {
get { return this._Count; }
}
bool ICollection.IsSynchronized {
get { return this.IsSynchronized; }
}
object ICollection.SyncRoot {
get { return this.SyncRoot; }
}
IEnumerator IEnumerable.GetEnumerator() {
return this.GetEnumerator();
}
public STNodeOption[] ToArray() {
STNodeOption[] ops = new STNodeOption[this._Count];
for (int i = 0; i < ops.Length; i++)
ops[i] = m_options[i];
return ops;
}
}
}