Entity.cs 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781
  1. using System;
  2. using System.Collections.Generic;
  3. using ETModel;
  4. using MongoDB.Bson.Serialization.Attributes;
  5. #if !SERVER
  6. using UnityEngine;
  7. #endif
  8. namespace ETHotfix
  9. {
  10. [Flags]
  11. public enum EntityStatus: byte
  12. {
  13. None = 0,
  14. IsFromPool = 0x01,
  15. IsRegister = 0x02,
  16. IsComponent = 0x04
  17. }
  18. public partial class Entity : Object, IDisposable
  19. {
  20. private static readonly Pool<HashSet<Entity>> hashSetPool = new Pool<HashSet<Entity>>();
  21. private static readonly Pool<Dictionary<Type, Entity>> dictPool = new Pool<Dictionary<Type, Entity>>();
  22. private static readonly Pool<Dictionary<long, Entity>> childrenPool = new Pool<Dictionary<long, Entity>>();
  23. [BsonIgnore]
  24. public long InstanceId { get; set; }
  25. #if !SERVER
  26. public static GameObject Global { get; } = GameObject.Find("/Global");
  27. [BsonIgnore]
  28. public GameObject ViewGO { get; set; }
  29. #endif
  30. [BsonIgnore]
  31. private EntityStatus status = EntityStatus.None;
  32. [BsonIgnore]
  33. public bool IsFromPool
  34. {
  35. get
  36. {
  37. return (this.status & EntityStatus.IsFromPool) == EntityStatus.IsFromPool;
  38. }
  39. set
  40. {
  41. if (value)
  42. {
  43. this.status |= EntityStatus.IsFromPool;
  44. }
  45. else
  46. {
  47. this.status &= ~EntityStatus.IsFromPool;
  48. }
  49. if (this.InstanceId == 0)
  50. {
  51. this.InstanceId = IdGenerater.GenerateId();
  52. }
  53. this.IsRegister = value;
  54. }
  55. }
  56. [BsonIgnore]
  57. private bool IsRegister
  58. {
  59. get
  60. {
  61. return (this.status & EntityStatus.IsRegister) == EntityStatus.IsRegister;
  62. }
  63. set
  64. {
  65. if (this.IsRegister == value)
  66. {
  67. return;
  68. }
  69. if (value)
  70. {
  71. this.status |= EntityStatus.IsRegister;
  72. }
  73. else
  74. {
  75. this.status &= ~EntityStatus.IsRegister;
  76. }
  77. Game.EventSystem.RegisterSystem(this, value);
  78. }
  79. }
  80. [BsonIgnore]
  81. private bool IsComponent
  82. {
  83. get
  84. {
  85. return (this.status & EntityStatus.IsComponent) == EntityStatus.IsComponent;
  86. }
  87. set
  88. {
  89. if (value)
  90. {
  91. this.status |= EntityStatus.IsComponent;
  92. }
  93. else
  94. {
  95. this.status &= ~EntityStatus.IsComponent;
  96. }
  97. }
  98. }
  99. [BsonIgnore]
  100. public bool IsDisposed
  101. {
  102. get
  103. {
  104. return this.InstanceId == 0;
  105. }
  106. }
  107. [BsonIgnore]
  108. protected Entity parent;
  109. [BsonIgnore]
  110. public Entity Parent
  111. {
  112. get
  113. {
  114. return this.parent;
  115. }
  116. set
  117. {
  118. if (value == null)
  119. {
  120. throw new Exception($"cant set parent null: {this.GetType().Name}");
  121. }
  122. if (this.parent != null) // 之前有parent
  123. {
  124. // parent相同,不设置
  125. if (this.parent.InstanceId == value.InstanceId)
  126. {
  127. Log.Error($"重复设置了Parent: {this.GetType().Name} parent: {this.parent.GetType().Name}");
  128. return;
  129. }
  130. this.parent.RemoveChild(this);
  131. this.parent = value;
  132. this.parent.AddChild(this);
  133. this.Domain = this.parent.domain;
  134. }
  135. else
  136. {
  137. this.parent = value;
  138. this.parent.AddChild(this);
  139. this.IsComponent = false;
  140. AfterSetParent();
  141. }
  142. }
  143. }
  144. // 该方法只能在AddComponent中调用,其他人不允许调用
  145. [BsonIgnore]
  146. private Entity ComponentParent
  147. {
  148. set
  149. {
  150. if (this.parent != null)
  151. {
  152. throw new Exception($"Component parent is null: {this.GetType().Name}");
  153. }
  154. this.parent = value;
  155. this.IsComponent = true;
  156. AfterSetParent();
  157. }
  158. }
  159. private void AfterSetParent()
  160. {
  161. if (this.parent.domain != null)
  162. {
  163. this.Domain = this.parent.domain;
  164. }
  165. // 检测自己的domain是不是跟父亲一样
  166. if (this.Domain != null && this.parent.Domain != null && this.Domain.InstanceId != this.parent.Domain.InstanceId && !(this is Scene))
  167. {
  168. Log.Error($"自己的domain跟parent不一样: {this.GetType().Name}");
  169. }
  170. #if !SERVER
  171. if (this.ViewGO != null && this.parent.ViewGO != null)
  172. {
  173. this.ViewGO.transform.SetParent(this.parent.ViewGO.transform, false);
  174. }
  175. #endif
  176. }
  177. public T GetParent<T>() where T : Entity
  178. {
  179. return this.Parent as T;
  180. }
  181. public override string ToString()
  182. {
  183. return MongoHelper.ToJson(this);
  184. }
  185. [BsonIgnoreIfDefault]
  186. [BsonDefaultValue(0L)]
  187. [BsonElement]
  188. [BsonId]
  189. public long Id { get; set; }
  190. [BsonIgnore]
  191. protected Entity domain;
  192. [BsonIgnore]
  193. public Entity Domain
  194. {
  195. get
  196. {
  197. return this.domain;
  198. }
  199. set
  200. {
  201. if (value == null)
  202. {
  203. return;
  204. }
  205. Entity preDomain = this.domain;
  206. this.domain = value;
  207. if (!(this.domain is Scene))
  208. {
  209. throw new Exception($"domain is not scene: {this.GetType().Name}");
  210. }
  211. this.domain = value;
  212. // 是否注册跟parent一致
  213. if (this.parent != null)
  214. {
  215. this.IsRegister = this.Parent.IsRegister;
  216. }
  217. // 递归设置孩子的Domain
  218. if (this.children != null)
  219. {
  220. foreach (Entity entity in this.children.Values)
  221. {
  222. entity.Domain = this.domain;
  223. }
  224. }
  225. if (this.components != null)
  226. {
  227. foreach (Entity component in this.components.Values)
  228. {
  229. component.Domain = this.domain;
  230. }
  231. }
  232. if (preDomain == null && !this.IsFromPool)
  233. {
  234. Game.EventSystem.Deserialize(this);
  235. }
  236. }
  237. }
  238. [BsonElement("Children")]
  239. [BsonIgnoreIfNull]
  240. private HashSet<Entity> childrenDB;
  241. [BsonIgnore]
  242. private Dictionary<long, Entity> children;
  243. [BsonIgnore]
  244. public Dictionary<long, Entity> Children
  245. {
  246. get
  247. {
  248. if (this.children == null)
  249. {
  250. this.children = childrenPool.Fetch();
  251. }
  252. return this.children;
  253. }
  254. }
  255. private void AddChild(Entity entity)
  256. {
  257. this.Children.Add(entity.Id, entity);
  258. this.AddChildDB(entity);
  259. }
  260. private void RemoveChild(Entity entity)
  261. {
  262. if (this.children == null)
  263. {
  264. return;
  265. }
  266. this.children.Remove(entity.Id);
  267. if (this.children.Count == 0)
  268. {
  269. childrenPool.Recycle(this.children);
  270. this.children = null;
  271. }
  272. this.RemoveChildDB(entity);
  273. }
  274. private void AddChildDB(Entity entity)
  275. {
  276. if (!(entity is ISerializeToEntity))
  277. {
  278. return;
  279. }
  280. if (this.childrenDB == null)
  281. {
  282. this.childrenDB = hashSetPool.Fetch();
  283. }
  284. this.childrenDB.Add(entity);
  285. }
  286. private void RemoveChildDB(Entity entity)
  287. {
  288. if (!(entity is ISerializeToEntity))
  289. {
  290. return;
  291. }
  292. if (this.childrenDB == null)
  293. {
  294. return;
  295. }
  296. this.childrenDB.Remove(entity);
  297. if (this.childrenDB.Count == 0)
  298. {
  299. if (this.IsFromPool)
  300. {
  301. hashSetPool.Recycle(this.childrenDB);
  302. this.childrenDB = null;
  303. }
  304. }
  305. }
  306. [BsonElement("C")]
  307. [BsonIgnoreIfNull]
  308. private HashSet<Entity> componentsDB;
  309. [BsonIgnore]
  310. private Dictionary<Type, Entity> components;
  311. [BsonIgnore]
  312. public Dictionary<Type, Entity> Components
  313. {
  314. get
  315. {
  316. return this.components;
  317. }
  318. }
  319. protected Entity()
  320. {
  321. this.InstanceId = IdGenerater.GenerateId();
  322. #if !SERVER
  323. if (!this.GetType().IsDefined(typeof (HideInHierarchy), true))
  324. {
  325. this.ViewGO = new GameObject();
  326. this.ViewGO.name = this.GetType().Name;
  327. this.ViewGO.layer = LayerNames.GetLayerInt(LayerNames.HIDDEN);
  328. this.ViewGO.transform.SetParent(Global.transform, false);
  329. this.ViewGO.AddComponent<ComponentView>().Component = this;
  330. }
  331. #endif
  332. }
  333. public virtual void Dispose()
  334. {
  335. if (this.IsDisposed)
  336. {
  337. return;
  338. }
  339. long instanceId = this.InstanceId;
  340. this.InstanceId = 0;
  341. Game.EventSystem.Remove(instanceId);
  342. // 触发Destroy事件
  343. Game.EventSystem.Destroy(this);
  344. this.domain = null;
  345. // 清理Children
  346. if (this.children != null)
  347. {
  348. var deletes = this.children;
  349. this.children = null;
  350. foreach (Entity child in deletes.Values)
  351. {
  352. child.Dispose();
  353. }
  354. deletes.Clear();
  355. childrenPool.Recycle(deletes);
  356. if (this.childrenDB != null)
  357. {
  358. this.childrenDB.Clear();
  359. // 从池中创建的才需要回到池中,从db中不需要回收
  360. if (this.IsFromPool)
  361. {
  362. hashSetPool.Recycle(this.childrenDB);
  363. this.childrenDB = null;
  364. }
  365. }
  366. }
  367. // 清理Component
  368. if (this.components != null)
  369. {
  370. var deletes = this.components;
  371. this.components = null;
  372. foreach (var kv in deletes)
  373. {
  374. kv.Value.Dispose();
  375. }
  376. deletes.Clear();
  377. dictPool.Recycle(deletes);
  378. // 从池中创建的才需要回到池中,从db中不需要回收
  379. if (this.componentsDB != null)
  380. {
  381. this.componentsDB.Clear();
  382. if (this.IsFromPool)
  383. {
  384. hashSetPool.Recycle(this.componentsDB);
  385. this.componentsDB = null;
  386. }
  387. }
  388. }
  389. if (this.IsComponent)
  390. {
  391. this.parent?.RemoveComponent(this);
  392. }
  393. else
  394. {
  395. this.parent?.RemoveChild(this);
  396. }
  397. this.parent = null;
  398. if (this.IsFromPool)
  399. {
  400. Game.ObjectPool.Recycle(this);
  401. }
  402. else
  403. {
  404. #if !SERVER
  405. if (this.ViewGO != null)
  406. {
  407. UnityEngine.Object.Destroy(this.ViewGO);
  408. }
  409. #endif
  410. }
  411. status = EntityStatus.None;
  412. }
  413. public override void EndInit()
  414. {
  415. try
  416. {
  417. if (this.childrenDB != null)
  418. {
  419. foreach (Entity child in this.childrenDB)
  420. {
  421. child.IsComponent = false;
  422. this.AddChild(child);
  423. child.parent = this;
  424. }
  425. }
  426. if (this.componentsDB != null)
  427. {
  428. foreach (Entity component in this.componentsDB)
  429. {
  430. component.IsComponent = true;
  431. this.AddToComponent(component.GetType(), component);
  432. component.parent = this;
  433. }
  434. }
  435. }
  436. catch (Exception e)
  437. {
  438. Log.Error(e);
  439. }
  440. }
  441. private void AddToComponentsDB(Entity component)
  442. {
  443. if (this.componentsDB == null)
  444. {
  445. this.componentsDB = hashSetPool.Fetch();
  446. }
  447. this.componentsDB.Add(component);
  448. }
  449. private void RemoveFromComponentsDB(Entity component)
  450. {
  451. if (this.componentsDB == null)
  452. {
  453. return;
  454. }
  455. this.componentsDB.Remove(component);
  456. if (this.componentsDB.Count == 0 && this.IsFromPool)
  457. {
  458. hashSetPool.Recycle(this.componentsDB);
  459. this.componentsDB = null;
  460. }
  461. }
  462. private void AddToComponent(Type type, Entity component)
  463. {
  464. if (this.components == null)
  465. {
  466. this.components = dictPool.Fetch();
  467. }
  468. this.components.Add(type, component);
  469. if (component is ISerializeToEntity)
  470. {
  471. this.AddToComponentsDB(component);
  472. }
  473. }
  474. private void RemoveFromComponent(Type type, Entity component)
  475. {
  476. if (this.components == null)
  477. {
  478. return;
  479. }
  480. this.components.Remove(type);
  481. if (this.components.Count == 0 && this.IsFromPool)
  482. {
  483. dictPool.Recycle(this.components);
  484. this.components = null;
  485. }
  486. this.RemoveFromComponentsDB(component);
  487. }
  488. public Entity AddComponent(Entity component)
  489. {
  490. component.ComponentParent = this;
  491. Type type = component.GetType();
  492. this.AddToComponent(type, component);
  493. return component;
  494. }
  495. public Entity AddComponent(Type type)
  496. {
  497. Entity component = CreateWithComponentParent(type);
  498. this.AddToComponent(type, component);
  499. return component;
  500. }
  501. public K AddComponent<K>() where K : Entity, new()
  502. {
  503. Type type = typeof (K);
  504. K component = CreateWithComponentParent<K>();
  505. this.AddToComponent(type, component);
  506. return component;
  507. }
  508. public K AddComponent<K, P1>(P1 p1) where K : Entity, new()
  509. {
  510. Type type = typeof (K);
  511. K component = CreateWithComponentParent<K, P1>(p1);
  512. this.AddToComponent(type, component);
  513. return component;
  514. }
  515. public K AddComponent<K, P1, P2>(P1 p1, P2 p2) where K : Entity, new()
  516. {
  517. Type type = typeof (K);
  518. K component = CreateWithComponentParent<K, P1, P2>(p1, p2);
  519. this.AddToComponent(type, component);
  520. return component;
  521. }
  522. public K AddComponent<K, P1, P2, P3>(P1 p1, P2 p2, P3 p3) where K : Entity, new()
  523. {
  524. Type type = typeof (K);
  525. K component = CreateWithComponentParent<K, P1, P2, P3>(p1, p2, p3);
  526. this.AddToComponent(type, component);
  527. return component;
  528. }
  529. public K AddComponentNoPool<K>() where K : Entity, new()
  530. {
  531. Type type = typeof (K);
  532. K component = CreateWithComponentParent<K>(false);
  533. this.AddToComponent(type, component);
  534. return component;
  535. }
  536. public K AddComponentNoPool<K, P1>(P1 p1) where K : Entity, new()
  537. {
  538. Type type = typeof (K);
  539. K component = CreateWithComponentParent<K, P1>(p1, false);
  540. this.AddToComponent(type, component);
  541. return component;
  542. }
  543. public K AddComponentNoPool<K, P1, P2>(P1 p1, P2 p2) where K : Entity, new()
  544. {
  545. Type type = typeof (K);
  546. K component = CreateWithComponentParent<K, P1, P2>(p1, p2, false);
  547. this.AddToComponent(type, component);
  548. return component;
  549. }
  550. public K AddComponentNoPool<K, P1, P2, P3>(P1 p1, P2 p2, P3 p3) where K : Entity, new()
  551. {
  552. Type type = typeof (K);
  553. K component = CreateWithComponentParent<K, P1, P2, P3>(p1, p2, p3, false);
  554. this.AddToComponent(type, component);
  555. return component;
  556. }
  557. public void RemoveComponent<K>() where K : Entity
  558. {
  559. if (this.IsDisposed)
  560. {
  561. return;
  562. }
  563. if (this.components == null)
  564. {
  565. return;
  566. }
  567. Type type = typeof (K);
  568. Entity c = this.GetComponent(type);
  569. if (c == null)
  570. {
  571. return;
  572. }
  573. this.RemoveFromComponent(type, c);
  574. c.Dispose();
  575. }
  576. public void RemoveComponent(Entity component)
  577. {
  578. if (this.IsDisposed)
  579. {
  580. return;
  581. }
  582. if (this.components == null)
  583. {
  584. return;
  585. }
  586. Type type = component.GetType();
  587. Entity c = this.GetComponent(component.GetType());
  588. if (c == null)
  589. {
  590. return;
  591. }
  592. if (c.InstanceId != component.InstanceId)
  593. {
  594. return;
  595. }
  596. this.RemoveFromComponent(type, c);
  597. c.Dispose();
  598. }
  599. public void RemoveComponent(Type type)
  600. {
  601. if (this.IsDisposed)
  602. {
  603. return;
  604. }
  605. Entity c = this.GetComponent(type);
  606. if (c == null)
  607. {
  608. return;
  609. }
  610. RemoveFromComponent(type, c);
  611. c.Dispose();
  612. }
  613. public K GetComponent<K>() where K : Entity
  614. {
  615. if (this.components == null)
  616. {
  617. return null;
  618. }
  619. Entity component;
  620. if (!this.components.TryGetValue(typeof(K), out component))
  621. {
  622. return default(K);
  623. }
  624. return (K)component;
  625. }
  626. public Entity GetComponent(Type type)
  627. {
  628. if (this.components == null)
  629. {
  630. return null;
  631. }
  632. Entity component;
  633. if (!this.components.TryGetValue(type, out component))
  634. {
  635. return null;
  636. }
  637. return component;
  638. }
  639. }
  640. }