1

カスタマイズしたドラッグ アンド ドロップなどの機能を実装する必要がある場合があります。コードは次のようになります。

bool mouse_down = false;
Vec2 mouse_pos;
void on_mouse_down() {
  mouse_down = true;
  mouse_pos = cursor_pos();
}
void on_mouse_move() {
  if(mouse_down) {
    Vec2f c = cursor_pos();
    Vec2f d = c - mouse_pos;
    // dragging. make objects tracing the cursor.
    // ...
  }
}
void on_mouse_up() {
  mouse_down = false;
  // dropped
  // ...
}

これがうまく機能することはわかっていますが、冗長な変数や、このようなものに対する個別の手順はまったく好きではありません。IP(命令型プログラミング)では、それは避けられないかもしれません。私の質問は、FP(関数型プログラミング)でこのようなことを処理するより良い方法はありますか? プログラミング言語、Lisp、Scheme、F#、Ruby など、または IP でこれを行うためのより良い方法に関係なく、アイデアや提案は大歓迎です。

4

1 に答える 1

1

誰も答えようとしなかったので、試してみます。あなたが議論している問題は理解していますが、答えはおそらくオペレーティング システム、言語、およびそのランタイム ライブラリに依存するはずです。

一般的な考え方は、マウスが下がったときに非同期計算を開始するというものです。この計算はイベントを「ブロック」し、フェッチされたものとして独自のループで処理し、必要なことを行います。マウスボタンを離すと存在します。これは命令型スレッドのように機能するように見えますが、実際には、計算が「ブロック」されると、開始された場所 (おそらくマウス ダウン イベントを呼び出すメイン GUI スレッド) に制御が渡されます。このようにして、状態は、字句的にローカルな計算スコープのように見えるものにカプセル化されます。その魔法は言語のランタイムによって処理される必要があるため、これは、言語と OS に依存しない方法で答えを得ることができる限りです。

このような実装の例については、この回答Tomas Petricek による記事を確認してください。どちらもあなたの質問について説明していますが、Windows、.NET、および F# の狭い設定です。同じ Perticek による本、Real World Functional Programming: With Examples in F# and C#があります。驚くべきことに、通常は関数型言語とは見なされない C# で同じアイデアが表現されています。第 16 章は、私の記憶が正しければ、あなたのものです。

IP/OO 言語プログラムで状態をカプセル化する場合、mouse_down ハンドラでクラスのインスタンスを作成できます。インスタンスは、ランタイムに自身を登録して、他のマウスおよび UI イベントを受け取り、それらを処理し、すべての作業を行い、必要に応じて (マウスが上がるか、ウィンドウ システムがキャプチャ モードをキャンセルする)、登録を解除して自身を破棄します。関数型言語が許容するほどエレガントではありませんが、一般的な UI クラスで可変状態を維持するよりははるかに優れています。

于 2012-01-17T07:05:51.727 に答える