2

基本的に低レベルのSlimDXラッパー ライブラリをラップし、XBOX 360 コントローラー用の簡単なマネージド API を提供する小さな XBox 360 ワイヤレス コントローラー マネージド インターフェイスを作成しました。

内部的には、クラスは N ミリ秒ごとにゲームパッドをポーリングし、コントローラーの基本的な状態の変化を検出するとイベントを発生させます。

私は、基本的に2つの悪のどちらか少ない方を選択することを余儀なくされているタイマーで行き詰まりを経験しています:

  • XBox360GamePad クラス UI フレームワーク固有のものを作成します (つまり、WPF/WinForms のサポートはクラスでハードコーディングされ、クラスはこれらのフレームワークを参照する必要があります...)

  • クラスを完全にフレームワークにとらわれないようにしますが、生成されたイベントに応じて UI を更新できるように、ユーザーに Dispatcher.Invoke / Invoke() 呼び出しをコードに振りかけるように強制します。

後者のオプション (コードを UI に依存しないものにする) を選択した場合、基本的には「汎用」の System.Timers.Timer または UI に依存しない任意のタイマーを使用します。その場合、UI を直接更新できないスレッドからイベントが生成/呼び出されることになります。つまり、WPF では、(醜い) Dispatcher.Invoke を使用して、360 コントローラー クラスから発生したすべての更新を発行する必要があります。 .

一方、XBox 360 Controller クラス内で DispatcherTimer を使用すると、大騒ぎせずに UI を直接更新できる作業コンポーネントがありますが、今ではコントローラー クラス全体が WPF に結合されており、それなしでは使用できません。 WPF に依存 (つまり、純粋なコンソール アプリ)

私が探しているのは、フレームワークにとらわれず、あらゆる種類の Dispatcher.Invoke() 手法に頼らなくても UI を更新できる、ある種のソリューションです...たとえば、共有ベースがあった場合すべてのタイマーのクラス、関連するシナリオに従って、タイマーを依存関係として何らかの形で注入できます..誰かがこの種の問題にうまく対処したことがありますか?

4

5 に答える 5

1

ポーリング アーキテクチャは唯一のオプションですか?

いずれにせよ、個人的にはシステムを再構築して、コントローラ クラスから発生するイベントを外部からサブスクライブできるようにします。

コントローラーが正しいスレッド コンテキストでイベントを発生させたい場合は、ISynchronizeInvoke インターフェイスのプロパティを追加します。このプロパティがコントローラー内で null でない場合はインターフェイスを使用し、それ以外の場合はイベントを直接呼び出します。コントローラーが実行されるスレッド。

これにより、たとえば、ポーリング全体を N ミリ秒ごとにウェイクアップしてジョブを実行するスレッドにしたり、イベント オブジェクトを使用してイベントを待機したりすることができます (360 コントローラー アーキテクチャにこのようなものがある場合)。

于 2008-11-16T16:58:33.790 に答える
0

また、Microsoft RoboticsDevelopersStudioの一部であるConcurrencyandCoordination Runtimeを確認することもできます(ただし、まもなくスタンドアロン製品になります)。

CCRは、MRDSがロボットを運転するジョイスティックなどを完全にサポートできるようにするスレッドコーディネーターであり、メッセージパッシングモデルで動作します。XBoxジョイスティックからデータを要求するタイマーを設定できます。タイマーは、データをポート(キュー)に送信します。次に、アクションを処理するためにデータがジョイスティックポートに投稿されたときに呼び出されるメソッド(レシーバー)を設定します。WinForms用のアダプターが提供されており、WPF用のアダプターを作成するのは難しくありません。

これは、本格的なMRDSなしでCCRを使用する方法を説明する素晴らしい記事です。 http://msdn.microsoft.com/en-us/magazine/cc163556.aspx

私の経験では、CCRの基本を理解すれば、マルチスレッドの並行非同期プログラミングを実際に簡単に行うことができます。

于 2008-11-17T02:20:27.073 に答える
0

360 コントローラは、現在の状態を報告することしかできません。ポーリングせずに状態を取得する方法は他にありません。System.Threading.Timer を使用するか、Thread.Sleep() を実行する新しい Thread を開くことは、私の見解ではまったく同じであり、どちらも UI のないタイマー クラスの機能を満たしています。

ISynchronizeInvoke について言及していただきありがとうございます。さらにググって、私の痛みを共有し、解決策があるかもしれない人を見つけました 。 -isynchronizeinvoke.aspx

私は彼のコードを試して、このスレッドを投稿し続けます...ヒントをありがとう!

于 2008-11-16T17:34:58.540 に答える
0

だから...情報/コード@ http://geekswithblogs.net/robp/archive/2008/03/28/why-doesnt-dispatcher-implement-isynchronizeinvoke.aspxが実際に機能するソリューションを提供しているようです。コードは UI から完全に独立しており、適切な UI とスレッドの統合のために ISynchronizeInvoke のみに依存しています。

これを使ったばかりなので、このままにしておくのはまだ少し気が進まない.

私の問題の要点は、すべてのイベント呼び出し関数が次のようになっていることです。

protected virtual void OnLeftThumbStickMove(ThumbStickEventArgs e)
{
  if (LeftThumbStickMove == null) return;

  if (_syncObj == null || !_syncObj.InvokeRequired)
    LeftThumbStickMove(this, e);
  else
    _syncObj.BeginInvoke(LeftThumbStickMove, new object[] { this, e });
}

このようにコードを書くのは非常に煩わしく、混乱を招きます。基本的に、すべてのイベント呼び出しを多くのロジック (!) でラップする必要はありません。

したがって、別の/追加の戦略を選択しました: 基本的に、XBox360GamePad クラスのコンストラクターは次のようになります。

public XBox360GamePad(UserIndex controllerIndex, Func<int, Action, object> timerSetupAction)
{
  CurrentController = new Controller(controllerIndex);
  _timerState = timerSetupAction(10, UpdateState);
}

ご覧のとおり、タイマーの作成と接続を担当する Func を受け入れます。

これは、デフォルトでは、360 Controller クラス内で UI 固有のタイマーを使用する必要がないことを意味します...本質的に、コントローラーの「デフォルト」コンストラクターは次のようになります。

public XBox360GamePad(UserIndex controllerIndex) : 
  this(controllerIndex, (i,f) => new Timer(delegate { f(); }, null, i, i)) {}

ラムダ関数を使用して、タイマー「サービス」に対するコントローラー クラスの依存関係をコーディングします。

WPF から、より一般的なコンストラクターを使用して、コントロールが次のように DispatcherTimer を使用するようにします。

  _gamePad = new XBox360GamePad(UserIndex.One, (i, f) => {
    var t = new DispatcherTimer(DispatcherPriority.Render) {Interval = new TimeSpan(0, 0, 0, 0, i) };
    t.Tick += delegate { f(); };
    t.Start();
    return t;
  });

このように、基本的に「ユーザー」に任せて、コントロールのタイマー実装を提供します。デフォルトの実装では、WPF または WinForms 固有のコードを使用する必要はありません。

個人的には、ISynchronizeInvoke を使用するよりも、このほうが便利で優れたデザインだと思います。

これが好き/これを改善したい/これにうんざりしているなどの人々からのフィードバックを楽しみにしています.

于 2008-11-16T19:03:32.917 に答える
0

@MattValerio: CCR については知っていますが、Googlecode にコントロールを配置する予定であり、CCR はフレームワークまたはオープンソースの一部ではないため、これはここでの法案に実際には適合しません。

于 2008-11-17T08:46:54.830 に答える