using System; using System.Collections.Generic; using System.Diagnostics; using System.Linq; namespace FDK { public class Activity { /// /// 子リストに Activity を登録すると、活性化・非活性化・デバイス依存リソースの生成・解放が、親と連動するようになる。 /// /// /// 子リストには静的・動的の2種類があり、それぞれ以下のように使い分ける。 /// /// (A) メンバとして定義する静的な子の場合: ///  ・子Activity の生成と子リストへの追加は、親Activity のコンストラクタで行う。 ///  ・子リストからの削除は不要。 ///   /// (B) 活性化時に生成する動的な子の場合: ///  ・子Activity の生成と子リストへの追加は、親Activity の On活性化() で行う。 ///  ・子リストからの削除は、親Activity の On非活性化() で行う。 ///   /// public List 子リスト { get; } = new List(); public bool 活性化している { get; private set; } = false; // 派生クラスからも設定は禁止。 public bool 活性化していない { get { return !this.活性化している; } private set { this.活性化している = !value; } // 派生クラスからも設定は禁止。 } public bool デバイス依存リソースが生成されている { get; private set; } = false; // 派生クラスからも設定は禁止。 public bool デバイス依存リソースが生成されていない { get { return !this.デバイス依存リソースが生成されている; } private set { this.デバイス依存リソースが生成されている = !value; } // 派生クラスからも設定は禁止。 } /// /// この Activity を初期化し、進行や描画を行える状態にする。 /// これにはデバイス依存リソースの作成も含まれる。 /// public void 活性化する( FDK.メディア.デバイスリソース dr ) { Debug.Assert( this.活性化していない ); // (1) 自分を活性化する。 this.On活性化( dr ); this.活性化している = true; // (2) 自分のデバイス依存リソースを作成する。 this.デバイス依存リソースを作成する( dr, 子へ再帰する: false ); // 自分だけ。 // (3) すべての子Activityを活性化し、デバイス依存リソースを作成する。 foreach( var child in this.子リスト ) child.活性化する( dr ); // この中でデバイス依存リソースが作成される。 } /// /// この Activity を終了し、進行や描画を行わない状態に戻す。 /// これにはデバイス依存リソースの解放も含まれる。 /// public void 非活性化する( FDK.メディア.デバイスリソース dr ) { Debug.Assert( this.活性化している ); // (1) すべての子Activityのデバイス依存リソースを解放し、非活性化する。 foreach( var child in this.子リスト ) child.非活性化する( dr ); // この中でデバイス依存リソースも解放される。 // (2) 自分のデバイス依存リソースを解放する。 this.デバイス依存リソースを解放する( dr, 子へ再帰する: false ); // 自分だけ。 // (3) 自分を非活性化する。 this.On非活性化( dr ); this.活性化していない = true; } /// /// デバイスに依存するリソースを作成する。 /// /// /// 活性化時だけではなく、活性化している最中はいつでも /// (デバイスが再構築またはリサイズされた 後 に)呼び出される可能性がある。 /// public void デバイス依存リソースを作成する( FDK.メディア.デバイスリソース dr, bool 子へ再帰する = true ) { Debug.Assert( this.活性化している ); Debug.Assert( this.デバイス依存リソースが生成されていない ); // 多重呼び出しは NG。 // (1) 自分のデバイス依存リソースを生成する。 this.Onデバイス依存リソースの作成( dr ); this.デバイス依存リソースが生成されている = true; if( 子へ再帰する ) { // (2) すべての子Activityのデバイス依存リソースを生成する。 foreach( var child in this.子リスト ) child.デバイス依存リソースを作成する( dr, 子へ再帰する ); } } /// /// デバイスに依存するリソースを解放する。 /// /// /// 非活性化時だけではなく、活性化している最中はいつでも /// (デバイスが再構築またはリサイズされる 前 に)呼び出される可能性がある。 /// public void デバイス依存リソースを解放する( FDK.メディア.デバイスリソース dr, bool 子へ再帰する = true ) { Debug.Assert( this.活性化している ); Debug.Assert( this.デバイス依存リソースが生成されている ); // 多重呼び出しは NG。 if( 子へ再帰する ) { // (1) すべての子Activityのデバイス依存リソースを解放する。 foreach( var child in this.子リスト ) child.デバイス依存リソースを解放する( dr, 子へ再帰する ); } // (2) 自分のデバイス依存リソースを解放する。 this.Onデバイス依存リソースの解放( dr ); this.デバイス依存リソースが生成されていない = true; } /* public void 進行描画する( FDK.メディア.デバイスリソース dr ) { // このクラスでは、進行描画用の共通メソッドは定義しない。 // (派生クラスにより引数がいろいろ変わるので、共通して定義する意味が薄い。) // 以下は、推奨される実装の一部。 // 活性化していないときに呼び出しがあるならコーディングミス。 Debug.Assert( this.活性化していない ); // デバイス依存リソースが使えないなら何もしない(デバイス再構築またはリサイズ中)。 if( this.デバイス依存リソースが解放済みである ) return; } */ // 以下、派生クラスでオーバーライドするもの。 protected virtual void On活性化( FDK.メディア.デバイスリソース dr ) { } protected virtual void On非活性化( FDK.メディア.デバイスリソース dr ) { } protected virtual void Onデバイス依存リソースの作成( FDK.メディア.デバイスリソース dr ) { } protected virtual void Onデバイス依存リソースの解放( FDK.メディア.デバイスリソース dr ) { } } }