// Magica Cloth. // Copyright (c) MagicaSoft, 2020-2022. // https://magicasoft.jp using System.Collections.Generic; namespace MagicaCloth { /// /// コンテンツの実行状態を管理する /// public class RuntimeStatus { // 以下は現在の状態フラグ /// /// 初期化処理が開始したかどうか /// bool initStart; /// /// 初期化が完了するとtrueになる(エラーの有無は問わない) /// bool init; /// /// 初期化エラーが発生するとtrueになる /// bool initError; /// /// コンテンツの有効状態の切り替え /// bool enable; /// /// ユーザー操作によるコンテンツの有効状態の切り替え(v1.2) /// bool userEnable = true; /// /// 実行中にエラーが発生した場合にtrueになる /// bool runtimeError; /// /// コンテンツが破棄された場合にtrueとなる /// bool dispose; /// /// コンテンツの現在の稼働状態 /// bool isActive; /// /// コンテンツの内容に変更が発生した /// bool isDirty; /// /// 連動(親)ステータス /// 設定されている場合、こららのステータスがすべて停止中ならば自身も停止する /// internal HashSet parentStatusSet { get; private set; } = new HashSet(); /// /// 連動(子)ステータス /// 設定されている場合、自身のアクティブ変更時に子のすべてのUpdateStatus()を呼び出す /// internal HashSet childStatusSet { get; private set; } = new HashSet(); //========================================================================================= /// /// アクティブ変更時コールバック /// internal System.Action UpdateStatusAction; /// /// 連動がすべて切断された時のコールバッグ /// internal System.Action DisconnectedAction; /// /// この状態管理のオーナークラス /// internal System.Func OwnerFunc; //========================================================================================= /// /// 現在稼働中か判定する /// public bool IsActive { get { return isActive && !dispose; } } /// /// 初期化が開始されたか判定する /// /// public bool IsInitStart { get { return initStart; } } /// /// 初期化済みか判定する(エラーの有無は問わない) /// public bool IsInitComplete { get { return init; } } /// /// 初期化が成功しているか判定する /// public bool IsInitSuccess { get { return init && !initError; } } /// /// 初期化が失敗しているか判定する /// public bool IsInitError { get { return init && initError; } } /// /// 破棄済みか判定する /// public bool IsDispose { get { return dispose; } } /// /// 内容に変更が発生したか判定する /// public bool IsDirty => isDirty; /// /// 初期化の開始フラグを立てる /// public void SetInitStart() { initStart = true; } /// /// 初期化済みフラグを立てる /// public void SetInitComplete() { init = true; } /// /// 初期化エラーフラグを立てる /// public void SetInitError() { initError = true; } /// /// 有効フラグを設定する /// /// /// フラグに変更があった場合はtrueが返る public bool SetEnable(bool sw) { bool ret = enable != sw; enable = sw; return ret; } /// /// ユーザー操作による有効フラグを設定する /// /// /// フラグに変更があった場合はtrueが返る public bool SetUserEnable(bool sw) { bool ret = userEnable != sw; userEnable = sw; return ret; } /// /// ランタイムエラーフラグを設定する /// /// /// フラグに変更があった場合はtrueが返る public bool SetRuntimeError(bool sw) { bool ret = runtimeError != sw; runtimeError = sw; return ret; } /// /// 破棄フラグを立てる /// /// public void SetDispose() { dispose = true; } /// /// 変更フラグを立てる /// public void SetDirty() { isDirty = true; } /// /// 変更フラグをクリアする /// public void ClearDirty() { isDirty = false; } /// /// 現在のアクティブ状態を更新する /// /// アクティブ状態に変更があった場合はtrueが返る public bool UpdateStatus() { if (dispose) return false; // 初期化済み、有効状態、エラー状態、連動(親)ステータス状態、がすべてクリアならばアクティブ状態と判定 var active = init && !initError && enable && userEnable && !runtimeError && IsParentStatusActive(); // およびマネージャのアクティブ状態を判定 if (MagicaPhysicsManager.IsInstance()) active = active && MagicaPhysicsManager.Instance.IsActive; if (active != isActive) { isActive = active; // コールバック UpdateStatusAction?.Invoke(); // すべての連動(子)ステータスの更新を呼び出す foreach (var status in childStatusSet) { status?.UpdateStatus(); } return true; } else return false; } //========================================================================================= /// /// 連動(親)ステータスを追加する /// /// public void AddParentStatus(RuntimeStatus status) { parentStatusSet.Add(status); } /// /// 連動(親)ステータスを削除する /// /// public void RemoveParentStatus(RuntimeStatus status) { parentStatusSet.Remove(status); parentStatusSet.Remove(null); // 連動切断アクション if (parentStatusSet.Count == 0 && childStatusSet.Count == 0) DisconnectedAction?.Invoke(); } /// /// 連動(子)ステータスを追加する /// /// public void AddChildStatus(RuntimeStatus status) { childStatusSet.Add(status); } /// /// 連動(子)ステータスを削除する /// /// public void RemoveChildStatus(RuntimeStatus status) { childStatusSet.Remove(status); childStatusSet.Remove(null); // 連動切断アクション if (parentStatusSet.Count == 0 && childStatusSet.Count == 0) DisconnectedAction?.Invoke(); } /// /// 親スタータスと連動する /// /// public void LinkParentStatus(RuntimeStatus parent) { AddParentStatus(parent); parent.AddChildStatus(this); } /// /// 親ステータスとの連動を解除する /// /// public void UnlinkParentStatus(RuntimeStatus parent) { RemoveParentStatus(parent); parent.RemoveChildStatus(this); } /// /// 連動(親)ステータスが1つでも稼働状態か調べる /// 連動ステータスが無い場合は稼働状態として返す /// /// bool IsParentStatusActive() { if (parentStatusSet.Count == 0) return true; foreach (var status in parentStatusSet) { if (status != null && status.IsActive) return true; } return false; } } }