===================================== Undo/Redo ===================================== 単純な Memorable オブジェクト ===================================== 例によってLINQPadで動作を確認しつつ進めます。 LINQPadを起動し、下記の設定をします。 * 参照設定に MoNo.dll, MoNo.Basics.dll を追加 * namespace に MoNo を追加 * Language を F# Expression に設定 次のコードを実行してみましょう。 .. code-block:: fsharp // ActiveHistory を設定します Core.History.ActiveHistory <- Core.History() // Undo/Redo 可能なオブジェクト(整数値)を生成し、Historyの管理下に置きます let a = CoreUT.Memorable 1 a.AddRef() // 参照カウンタをインクリメント → Undo/Redo対象となる a.Value.Dump() // 1 と出力される // 値を 2 に変更しコミットします a.Value <- 2 Core.History.CommitActiveHistory() |> ignore a.Value.Dump() // 2 と出力される // Undo します(値が 1 に戻ります) Core.History.UndoActiveHistory() |> ignore a.Value.Dump() // 1 と出力される // Redo します(再び値が 2 に設定されます) Core.History.RedoActiveHistory() |> ignore a.Value.Dump() // 2 と出力される これが最もシンプルな Undo/Redo のサンプルコードです。 ``IMemorable`` インターフェイス =============================================================== Undo/Redo の対象となるオブジェクトは、下記の ``IMemorable`` インターフェイスを実装しています。(C#) .. code-block:: csharp // オブジェクトを Undo/Redo に対応するためにはこのインターフェイスを実装する必要があります。 public interface IMemorable { void AddRef(); // ヒストリからの参照カウントをインクリメントします。 void Release(); // ヒストリからの参照カウントをデクリメントします。 } public interface IMemorable : IMemorable { T Value { get; set; } // 保持している値。変更履歴の Undo/Redo が可能です。 } 冒頭のサンプルコードで用いた ``CoreUT.Memorable`` 関数は、入力された値を ``IMemorable<'T>`` オブジェクトに包んで返す関数です。 ``AddRef / Release`` はヒストリからの参照カウントをインクリメント/デクリメントする関数です。 この設計は、ある一つのオブジェクト(Aとします)が複数のオブジェクト(B,Cとします)から共有して参照されているケースで役に立ちます。 BやCがヒストリ管理下に入れられたときは、それらが参照するAもヒストリ管理下に入れる必要があります。 次にBのみがヒストリ管理下から外されたとき、Aは依然としてCを経由してヒストリ管理下に残らなければなりません。 このような管理を行うために参照カウンタが必要となります。 (書くこと) ================================================================ * MemorableReactive について * MoNo.Core.ObservableCollection について * WPF のコマンドとの連動について * 適切な設計について .. toctree:: :maxdepth: 2 :caption: Contents: :glob: