架构提取

将积累的架构合并为一个文件

打开ShootingEditor2D工程,在Assets目录下新建一个脚本,命名为QFrameWork

我们将之前积累的代码全部放进里面,(下面的代码已经修改过BindablePropertyTypeEventSystem

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
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
using System;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Accessibility;

namespace QFrameWork
{
#region Architecture
public interface IArchitecture
{
T GetUtility<T>() where T : class, IUtility;

T GetModel<T>() where T : class, IModel;

T GetSystem<T>() where T : class, ISystem;

void RegisterModel<T>(T model) where T : IModel;

void RegisterSystem<T>(T system) where T : ISystem;

void RegisterUtility<T>(T isntance) where T : IUtility;

void SendCommand<T>() where T : ICommand, new();
void SendCommand<T>(T command) where T : ICommand;

TResult SendQuery<TResult>(IQuery<TResult> query);

void SendEvent<T>() where T : new();
void SendEvent<T>(T e);
IUnregister RegisterEvent<T>(Action<T> onEvent);
void UnregisterEvent<T>(Action<T> onEvent);
}
public abstract class Architecture<T> : IArchitecture where T : Architecture<T>, new()
{
private bool m_Inited = false;

private List<IModel> m_Models = new List<IModel>();

private List<ISystem> m_Systems = new List<ISystem>();

public static Action<T> OnRegisterPatch = architecture => { };

private static T m_Architecture;

public static IArchitecture Interface
{
get
{
if (m_Architecture == null)
{
MakeSureArchitecture();
}

return m_Architecture;
}
}

static void MakeSureArchitecture()
{
if (m_Architecture == null)
{
m_Architecture = new T();
m_Architecture.Init();

OnRegisterPatch?.Invoke(m_Architecture);

foreach (var architectureModel in m_Architecture.m_Models)
{
architectureModel.Init();
}

m_Architecture.m_Models.Clear();

foreach (var architectureSystem in m_Architecture.m_Systems)
{
architectureSystem.Init();
}

m_Architecture.m_Systems.Clear();

m_Architecture.m_Inited = true;
}
}

protected abstract void Init();

private IOCContainer m_Container = new IOCContainer();
private ITypeEventSystem m_TypeEventSystem = new TypeEventSystem();

public void RegisterModel<T1>(T1 model) where T1 : IModel
{
model.SetArchitecture(this);
m_Container.Register<T1>(model);
if (!m_Inited)
{
m_Models.Add(model);
}
else
{
model.Init();
}
}
public void RegisterSystem<T2>(T2 system) where T2 : ISystem
{
system.SetArchitecture(this);
m_Container.Register<T2>(system);
if (!m_Inited)
{
m_Systems.Add(system);
}
else
{
system.Init();
}
}

public void RegisterUtility<T3>(T3 utility) where T3 : IUtility
{
m_Container.Register<T3>(utility);
}
public IUnregister RegisterEvent<T4>(Action<T4> onEvent)
{
return m_TypeEventSystem.Register<T4>(onEvent);
}
public void UnregisterEvent<T4>(Action<T4> onEvent)
{
m_TypeEventSystem.Unregister<T4>(onEvent);
}
public T3 GetUtility<T3>() where T3 : class, IUtility
{
return m_Container.Get<T3>();
}

public T1 GetModel<T1>() where T1 : class, IModel
{
return m_Container.Get<T1>();
}

public T2 GetSystem<T2>() where T2 : class, ISystem
{
return m_Container.Get<T2>();
}

public void SendCommand<T5>() where T5 : ICommand, new()
{
var command = new T5();
command.SetArchitecture(this);
command.Execute();
}

public void SendCommand<T5>(T5 command) where T5 : ICommand
{
command.SetArchitecture(this);
command.Execute();
}

public TResult SendQuery<TResult>(IQuery<TResult> query)
{
query.SetArchitecture(this);
return query.Do();
}

public void SendEvent<T4>() where T4 : new()
{
m_TypeEventSystem.Send<T4>();
}
public void SendEvent<T4>(T4 e)
{
m_TypeEventSystem.Send<T4>(e);
}

}
#endregion

#region Controller
public interface IController : IBelongToArchitecture, ICanSendCommand, ICanGetSystem, ICanGetModel, ICanRegisterEvent, ICanSendQuery
{

}
#endregion

#region System
public interface ISystem : IBelongToArchitecture, ICanSetArchitecture, ICanGetModel, ICanGetUtility, ICanGetSystem, ICanSendEvent, ICanRegisterEvent
{
void Init();
}
public abstract class AbstractSystem : ISystem
{
private IArchitecture m_Architecture;
IArchitecture IBelongToArchitecture.GetArchitecture()
{
return m_Architecture;
}

void ICanSetArchitecture.SetArchitecture(IArchitecture architecture)
{
m_Architecture = architecture;
}

void ISystem.Init()
{
OnInit();
}

protected abstract void OnInit();
}
#endregion

#region Model
public interface IModel : IBelongToArchitecture, ICanSetArchitecture, ICanGetUtility, ICanSendEvent
{
void Init();
}
public abstract class AbstractModel : IModel
{
private IArchitecture m_Architecture;
IArchitecture IBelongToArchitecture.GetArchitecture()
{
return m_Architecture;
}

void ICanSetArchitecture.SetArchitecture(IArchitecture architecture)
{
m_Architecture = architecture;
}

void IModel.Init()
{
OnInit();
}

protected abstract void OnInit();
}

#endregion

#region Utility
public interface IUtility
{

}
#endregion

#region Command
public interface ICommand : IBelongToArchitecture, ICanSetArchitecture, ICanGetUtility, ICanGetModel, ICanGetSystem, ICanSendEvent, ICanSendCommand, ICanSendQuery
{
void Execute();
}
public abstract class AbstractCommand : ICommand
{
private IArchitecture m_Architecture;
IArchitecture IBelongToArchitecture.GetArchitecture()
{
return m_Architecture;
}

void ICanSetArchitecture.SetArchitecture(IArchitecture architecture)
{
m_Architecture = architecture;
}
void ICommand.Execute()
{
OnExecute();
}

protected abstract void OnExecute();
}
#endregion

#region Query
public interface IQuery<TResult> : IBelongToArchitecture, ICanSetArchitecture, ICanGetModel, ICanGetSystem, ICanSendQuery
{
TResult Do();
}

public abstract class AbstractQuery<TResult> : IQuery<TResult>
{
private IArchitecture mArchitecture;
IArchitecture IBelongToArchitecture.GetArchitecture()
{
return mArchitecture;
}

void ICanSetArchitecture.SetArchitecture(IArchitecture architecture)
{
mArchitecture = architecture;
}
TResult IQuery<TResult>.Do()
{
return OnDo();
}

protected abstract TResult OnDo();

}
#endregion

#region Rule
public interface IBelongToArchitecture
{
IArchitecture GetArchitecture();
}
public interface ICanSetArchitecture
{
void SetArchitecture(IArchitecture architecture);
}
public interface ICanGetModel : IBelongToArchitecture
{

}

public static class CanGetModelExtension
{
public static T GetModel<T>(this ICanGetModel self) where T : class, IModel
{
return self.GetArchitecture().GetModel<T>();
}
}
public interface ICanGetSystem : IBelongToArchitecture
{

}

public static class CanGetSystemExtension
{
public static T GetSystem<T>(this ICanGetSystem self) where T : class, ISystem
{
return self.GetArchitecture().GetSystem<T>();
}
}
public interface ICanGetUtility : IBelongToArchitecture
{

}

public static class CanGetUtilityExtension
{
public static T GetUtility<T>(this ICanGetUtility self) where T : class, IUtility
{
return self.GetArchitecture().GetUtility<T>();
}
}
public interface ICanRegisterEvent : IBelongToArchitecture
{
}
public static class CanRegisterEventExtension
{
public static IUnregister RegisterEvent<T>(this ICanRegisterEvent self, Action<T> onEvent)
{
return self.GetArchitecture().RegisterEvent<T>(onEvent);
}
public static void UnregisterEvent<T>(this ICanRegisterEvent self, Action<T> onEvent)
{
self.GetArchitecture().UnregisterEvent<T>(onEvent);
}
}
public interface ICanSendCommand : IBelongToArchitecture
{

}

public static class CanSendCommandExtension
{
public static void SendCommand<T>(this ICanSendCommand self) where T : ICommand, new()
{
self.GetArchitecture().SendCommand<T>();
}

public static void SendCommand<T>(this ICanSendCommand self, T command) where T : ICommand
{
self.GetArchitecture().SendCommand<T>(command);
}
}
public interface ICanSendEvent : IBelongToArchitecture
{

}
public static class CanSendEventExtension
{
public static void SendEvent<T>(this ICanSendEvent self) where T : new()
{
self.GetArchitecture().SendEvent<T>();
}
public static void SendEvent<T>(this ICanSendEvent self, T e)
{
self.GetArchitecture().SendEvent<T>(e);
}
}
public interface ICanSendQuery : IBelongToArchitecture
{

}
public static class CanSendQueryExtension
{
public static TResult SendQuery<TResult>(this ICanSendQuery self, IQuery<TResult> query)
{
return self.GetArchitecture().SendQuery<TResult>(query);
}
}
#endregion

#region TypeEventSystem
public interface ITypeEventSystem
{
void Send<T>() where T : new();
void Send<T>(T e);
IUnregister Register<T>(Action<T> onEvent);//注册时返回对应的注销
void Unregister<T>(Action<T> onEvent);
}

public interface IUnregister
{
void Unregister();
}
public struct TypeEventSystemUnRegister<T> : IUnregister
{
public ITypeEventSystem TypeEventSystem { get; set; }
public Action<T> OnEvent { get; set; }
public void Unregister()
{
TypeEventSystem.Unregister<T>(OnEvent);
TypeEventSystem = null;
OnEvent = null;
}
}
public class UnregisterOnDestroyTrigger : MonoBehaviour
{
HashSet<IUnregister> m_Unregisters = new HashSet<IUnregister>();//哈希集效率更高

public void AddUnregister(IUnregister unregister)
{
m_Unregisters.Add(unregister);
}

private void OnDestroy()
{
foreach (var unregister in m_Unregisters)
{
unregister.Unregister();
}
m_Unregisters.Clear();
}
}
public static class UnregisterExtension//使用拓展方法,继承IUnregister接口后并实现的同时将表现层对象也放进来
{
public static void UnregisterWhenGameObjectDestroyed(this IUnregister unregister, GameObject gameObject)
{
var trigger = gameObject.GetComponent<UnregisterOnDestroyTrigger>();
if (!trigger)
{
trigger = gameObject.AddComponent<UnregisterOnDestroyTrigger>();
}
trigger.AddUnregister(unregister);
}
}
public class TypeEventSystem : ITypeEventSystem
{
public interface IRegistrations//每个消息类型会有多次注册
{

}
public class Registrations<T> : IRegistrations//用来存储一个TypeEvent各种各样的注册监听
{
public Action<T> OnEvent = e => { };
}

Dictionary<Type, IRegistrations> m_EventRegistration = new Dictionary<Type, IRegistrations>();

public static readonly TypeEventSystem Global = new TypeEventSystem();
public IUnregister Register<T>(Action<T> onEvent)
{
var type = typeof(T);
IRegistrations registrations;
if (m_EventRegistration.TryGetValue(type, out registrations))
{
}
else
{
registrations = new Registrations<T>();
m_EventRegistration.Add(type, registrations);
}

(registrations as Registrations<T>).OnEvent += onEvent;//如果有新方法注册进来,就加进去

return new TypeEventSystemUnRegister<T>()
{
OnEvent = onEvent,
TypeEventSystem = this
};
}

public void Send<T>() where T : new()
{
var e = new T();
Send<T>(e);
}

public void Send<T>(T e)
{
var type = typeof(T);
IRegistrations registrations;
if (m_EventRegistration.TryGetValue(type, out registrations))
{
(registrations as Registrations<T>).OnEvent(e);
}
}

public void Unregister<T>(Action<T> onEvent)
{
var type = typeof(T);
IRegistrations registrations;
if (m_EventRegistration.TryGetValue(type, out registrations))
{
(registrations as Registrations<T>).OnEvent -= onEvent;
}
}
}
public interface IOnEvent<T>
{
void OnEvent(T e);
}
public static class OnGlobalEventExtension
{
public static IUnregister RegisterEvent<T>(this IOnEvent<T> self) where T : struct
{
return TypeEventSystem.Global.Register<T>(self.OnEvent);
}
public static void UnregisterEvent<T>(this IOnEvent<T> self) where T : struct
{
TypeEventSystem.Global.Unregister<T>(self.OnEvent);
}
}
#endregion

#region IOC
public class IOCContainer
{
private Dictionary<Type, object> m_Instances = new Dictionary<Type, object>();

public void Register<T>(T instance)
{
var key = typeof(T);
if (m_Instances.ContainsKey(key))
{
m_Instances[key] = instance;
}
else
{
m_Instances.Add(key, instance);
}
}

public T Get<T>() where T : class
{
var key = typeof(T);
if (m_Instances.TryGetValue(key, out var retInstance))//out var 相当于简化版本,也可以显式写成out object
return retInstance as T;
return null;
}
}
#endregion

#region BindableProerty
public class BindableProperty<T>
{

private T m_Value = default;
public BindableProperty(T defaultValue = default)
{
m_Value = defaultValue;
}


public T Value
{
get => m_Value;
set
{
if (value == null && m_Value == null) return;
if (value != null && value.Equals(m_Value)) return;

m_Value = value;
m_OnValueChanged?.Invoke(value);

}
}

private Action<T> m_OnValueChanged = v => { };

public IUnregister Register(Action<T> onValueChanged)
{
m_OnValueChanged += onValueChanged;
return new BindablePropertyUnregister<T>()
{
BindableProperty = this,
OnValueChanged = onValueChanged
};
}

public static implicit operator T(BindableProperty<T> property)
{
return property.Value;
}
public override string ToString()
{
return Value.ToString();
}
public IUnregister RegisterWithInitValue(Action<T> onValueChanged)
{
onValueChanged.Invoke(m_Value);
return Register(onValueChanged);
}
public void UnRegister(Action<T> onValueChanged)
{
m_OnValueChanged -= onValueChanged;
}

public class BindablePropertyUnregister<T2> : IUnregister
{
public BindableProperty<T2> BindableProperty { get; set; }
public Action<T2> OnValueChanged { get; set; }
public void Unregister()
{
BindableProperty.UnRegister(OnValueChanged);
BindableProperty = null;
OnValueChanged = null;
}
}
}
#endregion
}

更改BindableProperty

  1. 修改BindableProperty,给它添加一个构造,让它能够更方便地赋默认值。

  2. 同时修改其中Value属性的Set访问器,防止传入的value为空时因为空对象没有Equals()方法而报错

  3. 将其中的RegisterOnValueChanged函数名改为RegisterUnregisterOnValueChanged函数名改为Unregister

  4. 添加RegisterWithInitValue,当BindableProperty通过构造赋予初始值时,同时发布事件

  5. 添加BindableProperty和它承载值Value的隐式转换(implict),方便BindableProperty的比较(不需要通过A.Value == B.Value这样的比较了,直接A==B就可以了)

  6. 重载ToString()

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
public class BindableProperty<T>
{

private T m_Value = default;
public BindableProperty(T defaultValue = default)//添加构造
{
m_Value = defaultValue;
}


public T Value
{
get => m_Value;
set//修改Set访问器
{
if (value == null && m_Value == null) return;
if (value != null && value.Equals(m_Value)) return;

m_Value = value;
m_OnValueChanged?.Invoke(value);

}
}

private Action<T> m_OnValueChanged = v => { };

public IUnregister Register(Action<T> onValueChanged)//修改函数名
{
m_OnValueChanged += onValueChanged;
return new BindablePropertyUnregister<T>()
{
BindableProperty = this,
OnValueChanged = onValueChanged
};
}
public static implicit operator T(BindableProperty<T> property)//添加隐式转换
{
return property.Value;
}
public override string ToString()//重载ToString
{
return Value.ToString();
}
public IUnregister RegisterWithInitValue(Action<T> onValueChanged)//添加初始值订阅方法
{
onValueChanged.Invoke(m_Value);
return Register(onValueChanged);
}

public void UnRegister(Action<T> onValueChanged)//修改函数名
{
m_OnValueChanged -= onValueChanged;
}

public class BindablePropertyUnregister<T2> : IUnregister
{
public BindableProperty<T2> BindableProperty { get; set; }
public Action<T2> OnValueChanged { get; set; }
public void Unregister()
{
BindableProperty.UnRegister(OnValueChanged);//修改
BindableProperty = null;
OnValueChanged = null;
}
}
}

更改TypeEventSystem

  1. 添加静态实例,方便使用
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
public class TypeEventSystem : ITypeEventSystem
{
public interface IRegistrations//每个消息类型会有多次注册
{

}
public class Registrations<T> : IRegistrations//用来存储一个TypeEvent各种各样的注册监听
{
public Action<T> OnEvent = e => { };
}

Dictionary<Type, IRegistrations> m_EventRegistration = new Dictionary<Type, IRegistrations>();

public static readonly TypeEventSystem Global = new TypeEventSystem();//+++
public IUnregister Register<T>(Action<T> onEvent)
{//...
}
}
  1. 添加IOnEvent方式注册

TypeEventSystem整个region块底部添加,不要写在TypeEventSystem类里

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
public interface IOnEvent<T>
{
void OnEvent(T e);
}
public static class OnGlobalEventExtension
{
public static IUnregister RegisterEvent<T>(this IOnEvent<T> self) where T : struct
{
return TypeEventSystem.Global.Register<T>(self.OnEvent);
}
public static void UnregisterEvent<T>(this IOnEvent<T> self) where T : struct
{
TypeEventSystem.Global.Unregister<T>(self.OnEvent);
}
}

注意这个是泛型接口,后面的使用案例中我们会发现继承泛型接口的意义和泛型抽象类相似,属于抽象的抽象,我们需要多少个这样的接口,就需要新建多少个传入T的接口