C# と VB.NET の質問掲示板

ASP.NET、C++/CLI、Java 何でもどうぞ

C# と VB.NET の入門サイト

Re[7]: デリゲート実行順序の反転について


(過去ログ 28 を表示中)

[トピック内 11 記事 (1 - 11 表示)]  << 0 >>

■13275 / inTopicNo.1)  デリゲート実行順序の反転について
  
□投稿者/ Hirotow (152回)-(2008/01/26(Sat) 17:15:28)

分類:[.NET 全般] 

例のバイナリエディタについてなのですが、
アンドゥ、リドゥ機能の実装として、いったん本処理とアンドゥ処理をデリゲートに格納し、本処理を実行してからスタックに積むという実装にしています。
アンドゥ処理のほうは逆順で実行する必要があるため、現状でstackを2段重ねにして対処しているのですが、
こうすると処理が重たいと思うのでデリゲートにスタック状に格納していきたいのですが、何かよい方法はないでしょうか。
引用返信 編集キー/
■13280 / inTopicNo.2)  Re[1]: デリゲート実行順序の反転について
□投稿者/ れい (385回)-(2008/01/26(Sat) 18:36:18)
No13275 (Hirotow さん) に返信
> 例のバイナリエディタについてなのですが、
> アンドゥ、リドゥ機能の実装として、いったん本処理とアンドゥ処理をデリゲートに格納し、本処理を実行してからスタックに積むという実装にしています。
> アンドゥ処理のほうは逆順で実行する必要があるため、現状でstackを2段重ねにして対処しているのですが、
> こうすると処理が重たいと思うのでデリゲートにスタック状に格納していきたいのですが、何かよい方法はないでしょうか。

デリゲートに格納というのは、複数のメソッドを呼ぶデリゲート(マルチキャストデリゲート)のことですか?
スタックはLinkedListとかListで実装してるのですか?
2段重ねとは?

読解力がないせいでしょうか?
ちょっと文章が明確でなくてよくわかりません。

Hirotowさんなら知ってるかと思いますが、
マルチキャストデリゲートは呼び出し順は保証されてません。念のため。

普通にundo用スタック、redo用スタックの二つを使えばそれで十分かと思うんですが。


引用返信 編集キー/
■13282 / inTopicNo.3)  Re[2]: デリゲート実行順序の反転について
□投稿者/ Hirotow (154回)-(2008/01/26(Sat) 18:56:09)
2008/01/26(Sat) 18:58:06 編集(投稿者)
> デリゲートに格納というのは、複数のメソッドを呼ぶデリゲート(マルチキャストデリゲート)のことですか?
> スタックはLinkedListとかListで実装してるのですか?
> 2段重ねとは?
delegate void UndoDelegate();
Stack<Stack<UndoDelegate>> undoBuffer;
みたいにして、
public void FooBar(long pos)
{
    Stack<UndoDelegate> undo;
    //何がしの処理
    gehogeho();
    undo.Push(delegate()
    {
        //アンドゥ処理
        hogehoge();
    }
    //以下繰り返し
    ...
    undoBuffer.Push(undo);
}
みたいな感じです。
リドゥのほうはまだやってません。
> 読解力がないせいでしょうか?
> ちょっと文章が明確でなくてよくわかりません。
いえいえ、わたしの書き方が悪かったですm(__)m
> Hirotowさんなら知ってるかと思いますが、
> マルチキャストデリゲートは呼び出し順は保証されてません。念のため。
よく知らないのでご教示いただけるとうれしいです。
> 普通にundo用スタック、redo用スタックの二つを使えばそれで十分かと思うんですが。
外部からの関数呼び出しを単位としてアンドゥしたいのです。
でもCommandパターンだと泥沼に嵌るのが目に見えてるので安直な方法でやってます。

引用返信 編集キー/
■13283 / inTopicNo.4)  Re[3]: デリゲート実行順序の反転について
□投稿者/ Tom Yama (16回)-(2008/01/26(Sat) 19:00:57)
No13282 (Hirotow さん) に返信
> Stack<Stack<UndoDelegate>> undoBuffer;
これは?
何のために作っていて、どこで使うものなのでしょうか?
端折らないで、ちゃんと説明してください。
引用返信 編集キー/
■13286 / inTopicNo.5)  Re[4]: デリゲート実行順序の反転について
□投稿者/ Hirotow (156回)-(2008/01/26(Sat) 19:11:41)
No13283 (Tom Yama さん) に返信
> ■No13282 (Hirotow さん) に返信
>>Stack<Stack<UndoDelegate>> undoBuffer;
> これは?
> 何のために作っていて、どこで使うものなのでしょうか?
> 端折らないで、ちゃんと説明してください。
公開メソッドごとのごとの処理がローカル変数undoにスタックされ、
それをメソッド終了時にundoBufferにスタックしています。
アンドゥするときは、undoBufferから(上行のundoを)ひとつだけpopして、
それの中身をpopしつつ実行しています。
public void Undo()
{
    Stack<UndoDelegate> undo = undoBuffer.Pop();
    while(undo.Count > 0)
    {
        undo.pop()();
    }
}

引用返信 編集キー/
■13289 / inTopicNo.6)  Re[5]: デリゲート実行順序の反転について
□投稿者/ Tom Yama (17回)-(2008/01/26(Sat) 19:27:47)
No13286 (Hirotow さん) に返信
> ■No13283 (Tom Yama さん) に返信
>>■No13282 (Hirotow さん) に返信
> >>Stack<Stack<UndoDelegate>> undoBuffer;
>>これは?
>>何のために作っていて、どこで使うものなのでしょうか?
>>端折らないで、ちゃんと説明してください。
> 公開メソッドごとのごとの処理がローカル変数undoにスタックされ、
> それをメソッド終了時にundoBufferにスタックしています。
> アンドゥするときは、undoBufferから(上行のundoを)ひとつだけpopして、
> それの中身をpopしつつ実行しています。
> public void Undo()
> {
> Stack<UndoDelegate> undo = undoBuffer.Pop();
> while(undo.Count > 0)
> {
> undo.pop()();
> }
> }
了解。そっか、メソッド(デリゲート)を、スタックするんでしたね。
であれば、アンドゥ処理としては、極、一般的なものかと。

> こうすると処理が重たいと思うのでデリゲートにスタック状に格納していきたいのですが、何かよい方法はないでしょうか。
特に重たいようにも思いませんし、画期的に軽くなる方法もないと思いますけどね。
引用返信 編集キー/
■13292 / inTopicNo.7)  Re[5]: デリゲート実行順序の反転について
□投稿者/ れい (389回)-(2008/01/26(Sat) 19:32:08)
Stackが2重であるのはHirotowさんの実装の都合ですか?

私はデザインパターンを全く学んでないので
Commandパターンが如何なるものか知りませんが、
Undo/Redo用のスタックは1重で十分実装可能です。

1重のスタックは必須なので、たとえ重かったとしてもある程度仕方ありません。
本当に気にするならスタックの実装から組みなおしです。

2重にすると重くて気になるのでしたら、
1重に展開すればOKです。可能であるのは自明ですね。

>> Hirotowさんなら知ってるかと思いますが、
>> マルチキャストデリゲートは呼び出し順は保証されてません。念のため。
> よく知らないのでご教示いただけるとうれしいです。

今回は全く関係のない話のようです。
引用返信 編集キー/
■13294 / inTopicNo.8)  Re[6]: デリゲート実行順序の反転について
□投稿者/ Hirotow (158回)-(2008/01/26(Sat) 19:41:45)
>外部からの関数呼び出しを単位としてアンドゥしたいのです。
と上に書いてあります。

引用返信 編集キー/
■13298 / inTopicNo.9)  Re[6]: デリゲート実行順序の反転について
□投稿者/ Tom Yama (18回)-(2008/01/26(Sat) 20:00:22)
No13292 (れい さん) に返信
> Stackが2重であるのはHirotowさんの実装の都合ですか?
1度のUndoで、複数のメソッドが呼び出される場合があるので、そのためでは?

> Undo/Redo用のスタックは1重で十分実装可能です。
確かに、Undo時にどこまで戻すかの情報を別に持てば、1重で可能ですね。
# 私が以前実装したときも、そうしました。というか、正確には、スタックにそのためのマーカーを積んでいました。

でも、2重のスタックにした方が、プログラムは簡単になるような気がします。
引用返信 編集キー/
■13299 / inTopicNo.10)  Re[7]: デリゲート実行順序の反転について
□投稿者/ れい (391回)-(2008/01/26(Sat) 20:15:37)
No13298 (Tom Yama さん) に返信
> ■No13292 (れい さん) に返信
>>Stackが2重であるのはHirotowさんの実装の都合ですか?
> 1度のUndoで、複数のメソッドが呼び出される場合があるので、そのためでは?

そうでしょうね。

でも私ならその実装は選びません。
複数のメソッドが必要ならまとめて一つのメソッドにして、
ユーザーの操作一つにたいしてDo/Undo一つに対応させます。

>>Undo/Redo用のスタックは1重で十分実装可能です。
> 確かに、Undo時にどこまで戻すかの情報を別に持てば、1重で可能ですね。
> # 私が以前実装したときも、そうしました。というか、正確には、スタックにそのためのマーカーを積んでいました。

そういう展開の仕方もありですね。

2重のスタックはメソッド呼び出しが2段目までしかないという保証がないといけません。
メソッド呼び出しが多段になると、どんどん大変になっていきます。

Tom Yamaさんの方法はつまり、ユーザーの操作一つがマーカー一つに対応するわけですね。
本質的には前述の私の方法とほぼ同じですね。

いずれにせよ、Hirotowさんの方法はそれほど効率悪いようには見えません。
早いがバグあり。
遅いがちゃんと動く。
2者のどちらかを選ぶなら、もちろん後者であるべきですね。
引用返信 編集キー/
■13303 / inTopicNo.11)  Re[7]: デリゲート実行順序の反転について
□投稿者/ Hirotow (159回)-(2008/01/26(Sat) 20:41:22)
現状で問題なしということなので、質問を閉じさせていただきます。
解決済み
引用返信 編集キー/


トピック内ページ移動 / << 0 >>

このトピックに書きこむ

過去ログには書き込み不可

管理者用

- Child Tree -