RuntimeStatus.cs 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367
  1. // Magica Cloth.
  2. // Copyright (c) MagicaSoft, 2020-2022.
  3. // https://magicasoft.jp
  4. using System.Collections.Generic;
  5. namespace MagicaCloth
  6. {
  7. /// <summary>
  8. /// コンテンツの実行状態を管理する
  9. /// </summary>
  10. public class RuntimeStatus
  11. {
  12. // 以下は現在の状態フラグ
  13. /// <summary>
  14. /// 初期化処理が開始したかどうか
  15. /// </summary>
  16. bool initStart;
  17. /// <summary>
  18. /// 初期化が完了するとtrueになる(エラーの有無は問わない)
  19. /// </summary>
  20. bool init;
  21. /// <summary>
  22. /// 初期化エラーが発生するとtrueになる
  23. /// </summary>
  24. bool initError;
  25. /// <summary>
  26. /// コンテンツの有効状態の切り替え
  27. /// </summary>
  28. bool enable;
  29. /// <summary>
  30. /// ユーザー操作によるコンテンツの有効状態の切り替え(v1.2)
  31. /// </summary>
  32. bool userEnable = true;
  33. /// <summary>
  34. /// 実行中にエラーが発生した場合にtrueになる
  35. /// </summary>
  36. bool runtimeError;
  37. /// <summary>
  38. /// コンテンツが破棄された場合にtrueとなる
  39. /// </summary>
  40. bool dispose;
  41. /// <summary>
  42. /// コンテンツの現在の稼働状態
  43. /// </summary>
  44. bool isActive;
  45. /// <summary>
  46. /// コンテンツの内容に変更が発生した
  47. /// </summary>
  48. bool isDirty;
  49. /// <summary>
  50. /// 連動(親)ステータス
  51. /// 設定されている場合、こららのステータスがすべて停止中ならば自身も停止する
  52. /// </summary>
  53. internal HashSet<RuntimeStatus> parentStatusSet { get; private set; } = new HashSet<RuntimeStatus>();
  54. /// <summary>
  55. /// 連動(子)ステータス
  56. /// 設定されている場合、自身のアクティブ変更時に子のすべてのUpdateStatus()を呼び出す
  57. /// </summary>
  58. internal HashSet<RuntimeStatus> childStatusSet { get; private set; } = new HashSet<RuntimeStatus>();
  59. //=========================================================================================
  60. /// <summary>
  61. /// アクティブ変更時コールバック
  62. /// </summary>
  63. internal System.Action UpdateStatusAction;
  64. /// <summary>
  65. /// 連動がすべて切断された時のコールバッグ
  66. /// </summary>
  67. internal System.Action DisconnectedAction;
  68. /// <summary>
  69. /// この状態管理のオーナークラス
  70. /// </summary>
  71. internal System.Func<System.Object> OwnerFunc;
  72. //=========================================================================================
  73. /// <summary>
  74. /// 現在稼働中か判定する
  75. /// </summary>
  76. public bool IsActive
  77. {
  78. get
  79. {
  80. return isActive && !dispose;
  81. }
  82. }
  83. /// <summary>
  84. /// 初期化が開始されたか判定する
  85. /// </summary>
  86. /// <value></value>
  87. public bool IsInitStart
  88. {
  89. get
  90. {
  91. return initStart;
  92. }
  93. }
  94. /// <summary>
  95. /// 初期化済みか判定する(エラーの有無は問わない)
  96. /// </summary>
  97. public bool IsInitComplete
  98. {
  99. get
  100. {
  101. return init;
  102. }
  103. }
  104. /// <summary>
  105. /// 初期化が成功しているか判定する
  106. /// </summary>
  107. public bool IsInitSuccess
  108. {
  109. get
  110. {
  111. return init && !initError;
  112. }
  113. }
  114. /// <summary>
  115. /// 初期化が失敗しているか判定する
  116. /// </summary>
  117. public bool IsInitError
  118. {
  119. get
  120. {
  121. return init && initError;
  122. }
  123. }
  124. /// <summary>
  125. /// 破棄済みか判定する
  126. /// </summary>
  127. public bool IsDispose
  128. {
  129. get
  130. {
  131. return dispose;
  132. }
  133. }
  134. /// <summary>
  135. /// 内容に変更が発生したか判定する
  136. /// </summary>
  137. public bool IsDirty => isDirty;
  138. /// <summary>
  139. /// 初期化の開始フラグを立てる
  140. /// </summary>
  141. public void SetInitStart()
  142. {
  143. initStart = true;
  144. }
  145. /// <summary>
  146. /// 初期化済みフラグを立てる
  147. /// </summary>
  148. public void SetInitComplete()
  149. {
  150. init = true;
  151. }
  152. /// <summary>
  153. /// 初期化エラーフラグを立てる
  154. /// </summary>
  155. public void SetInitError()
  156. {
  157. initError = true;
  158. }
  159. /// <summary>
  160. /// 有効フラグを設定する
  161. /// </summary>
  162. /// <param name="sw"></param>
  163. /// <returns>フラグに変更があった場合はtrueが返る</returns>
  164. public bool SetEnable(bool sw)
  165. {
  166. bool ret = enable != sw;
  167. enable = sw;
  168. return ret;
  169. }
  170. /// <summary>
  171. /// ユーザー操作による有効フラグを設定する
  172. /// </summary>
  173. /// <param name="sw"></param>
  174. /// <returns>フラグに変更があった場合はtrueが返る</returns>
  175. public bool SetUserEnable(bool sw)
  176. {
  177. bool ret = userEnable != sw;
  178. userEnable = sw;
  179. return ret;
  180. }
  181. /// <summary>
  182. /// ランタイムエラーフラグを設定する
  183. /// </summary>
  184. /// <param name="sw"></param>
  185. /// <returns>フラグに変更があった場合はtrueが返る</returns>
  186. public bool SetRuntimeError(bool sw)
  187. {
  188. bool ret = runtimeError != sw;
  189. runtimeError = sw;
  190. return ret;
  191. }
  192. /// <summary>
  193. /// 破棄フラグを立てる
  194. /// </summary>
  195. /// <returns></returns>
  196. public void SetDispose()
  197. {
  198. dispose = true;
  199. }
  200. /// <summary>
  201. /// 変更フラグを立てる
  202. /// </summary>
  203. public void SetDirty()
  204. {
  205. isDirty = true;
  206. }
  207. /// <summary>
  208. /// 変更フラグをクリアする
  209. /// </summary>
  210. public void ClearDirty()
  211. {
  212. isDirty = false;
  213. }
  214. /// <summary>
  215. /// 現在のアクティブ状態を更新する
  216. /// </summary>
  217. /// <returns>アクティブ状態に変更があった場合はtrueが返る</returns>
  218. public bool UpdateStatus()
  219. {
  220. if (dispose)
  221. return false;
  222. // 初期化済み、有効状態、エラー状態、連動(親)ステータス状態、がすべてクリアならばアクティブ状態と判定
  223. var active = init && !initError && enable && userEnable && !runtimeError && IsParentStatusActive();
  224. // およびマネージャのアクティブ状態を判定
  225. if (MagicaPhysicsManager.IsInstance())
  226. active = active && MagicaPhysicsManager.Instance.IsActive;
  227. if (active != isActive)
  228. {
  229. isActive = active;
  230. // コールバック
  231. UpdateStatusAction?.Invoke();
  232. // すべての連動(子)ステータスの更新を呼び出す
  233. foreach (var status in childStatusSet)
  234. {
  235. status?.UpdateStatus();
  236. }
  237. return true;
  238. }
  239. else
  240. return false;
  241. }
  242. //=========================================================================================
  243. /// <summary>
  244. /// 連動(親)ステータスを追加する
  245. /// </summary>
  246. /// <param name="status"></param>
  247. public void AddParentStatus(RuntimeStatus status)
  248. {
  249. parentStatusSet.Add(status);
  250. }
  251. /// <summary>
  252. /// 連動(親)ステータスを削除する
  253. /// </summary>
  254. /// <param name="status"></param>
  255. public void RemoveParentStatus(RuntimeStatus status)
  256. {
  257. parentStatusSet.Remove(status);
  258. parentStatusSet.Remove(null);
  259. // 連動切断アクション
  260. if (parentStatusSet.Count == 0 && childStatusSet.Count == 0)
  261. DisconnectedAction?.Invoke();
  262. }
  263. /// <summary>
  264. /// 連動(子)ステータスを追加する
  265. /// </summary>
  266. /// <param name="status"></param>
  267. public void AddChildStatus(RuntimeStatus status)
  268. {
  269. childStatusSet.Add(status);
  270. }
  271. /// <summary>
  272. /// 連動(子)ステータスを削除する
  273. /// </summary>
  274. /// <param name="status"></param>
  275. public void RemoveChildStatus(RuntimeStatus status)
  276. {
  277. childStatusSet.Remove(status);
  278. childStatusSet.Remove(null);
  279. // 連動切断アクション
  280. if (parentStatusSet.Count == 0 && childStatusSet.Count == 0)
  281. DisconnectedAction?.Invoke();
  282. }
  283. /// <summary>
  284. /// 親スタータスと連動する
  285. /// </summary>
  286. /// <param name="parent"></param>
  287. public void LinkParentStatus(RuntimeStatus parent)
  288. {
  289. AddParentStatus(parent);
  290. parent.AddChildStatus(this);
  291. }
  292. /// <summary>
  293. /// 親ステータスとの連動を解除する
  294. /// </summary>
  295. /// <param name="parent"></param>
  296. public void UnlinkParentStatus(RuntimeStatus parent)
  297. {
  298. RemoveParentStatus(parent);
  299. parent.RemoveChildStatus(this);
  300. }
  301. /// <summary>
  302. /// 連動(親)ステータスが1つでも稼働状態か調べる
  303. /// 連動ステータスが無い場合は稼働状態として返す
  304. /// </summary>
  305. /// <returns></returns>
  306. bool IsParentStatusActive()
  307. {
  308. if (parentStatusSet.Count == 0)
  309. return true;
  310. foreach (var status in parentStatusSet)
  311. {
  312. if (status != null && status.IsActive)
  313. return true;
  314. }
  315. return false;
  316. }
  317. }
  318. }