Entity.cs 14 KB

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