0

cs-sdl を Rx に接続したいと思っていました。C# では動作するようになりましたが、F# ではかなり奇妙なことが起こり始めています。プログラミング時間を節約し、SDL イベントを引数として渡して IObservable にきちんとラップできるように、F# に固執したいと思います。これが私がそうしようとした方法です:

let fromEvent (e: IEvent<'H,'T>) = Observable.FromEventPattern<'H,'T>((fun h -> e.AddHandler(h)),(fun h -> e.RemoveHandler(h)))

これまでのところ、すべて順調です。ここで、SDL イベントの 1 つを渡して IObservable を取得します...

let MouseMotion = fromEvent(Events.MouseMotion)

などなど、この一連のモジュールが続きます。推論された型はすべて正しいです。MouseMotion はタイプですIObservable<MouseMotionEventArgs>

ここで、このライブラリをテスト用に作成した別のプロジェクトで実際に使用しています。

let observer : IObserver<MouseMotionEventArgs> = Observer.Create(Action<MouseMotionEventArgs>(fun x -> System.Console.WriteLine(x.X.ToString())))
ignore <| SdlDotNet.Reactive.CoreInput.MouseMotion.Subscribe(Observer.AsObserver(observer))

実行すると次のようになります。

  System.ArgumentException was unhandled
  Message="Type must derive from Delegate.\r\nParameter name: type"
  Source="mscorlib"
  ParamName="type"
  StackTrace:
       at System.Delegate.CreateDelegate(Type type, Object firstArgument, MethodInfo method, Boolean throwOnBindFailure)
       at System.Delegate.CreateDelegate(Type type, Object firstArgument, MethodInfo method)
       at System.Reactive.Linq.Observable.<>c__DisplayClass19d`2.<FromEvent>b__19b(IObserver`1 observer)
       at System.Reactive.AnonymousObservable`1.<>c__DisplayClass1.<Subscribe>b__0()
       at System.Reactive.Concurrency.Scheduler.Invoke(IScheduler scheduler, Action action)
       at System.Reactive.Concurrency.ScheduledItem`2.InvokeCore()
       at System.Reactive.Concurrency.ScheduledItem`1.Invoke()
       at System.Reactive.Concurrency.CurrentThreadScheduler.Trampoline.Run()
       at System.Reactive.Concurrency.CurrentThreadScheduler.Schedule[TState](TState state, TimeSpan dueTime, Func`3 action)
       at System.Reactive.Concurrency.CurrentThreadScheduler.Schedule[TState](TState state, Func`3 action)
       at System.Reactive.Concurrency.Scheduler.Schedule(IScheduler scheduler, Action action)
       at System.Reactive.AnonymousObservable`1.Subscribe(IObserver`1 observer)
       at <StartupCode$SdlDemo>.$Tutorial.main@() in C:\Users\Barend Venter\Documents\Visual Studio 2008\Projects\SdlDemo\SdlDemo\Tutorial.fs:line 77
  InnerException: 

私は完全に困惑しています。なぜこうなった?どこかで必要な eta 拡張はありますか?

4

3 に答える 3

1

これでは残りの問題は解決しないかもしれませんが、IEventがIObservableから継承していることに気づきましたか?関数fromEventは単純なキャストとして実装できます...

let fromEvent (e: IEvent<'H,'T>) = e :> IObservable<'T>
于 2012-08-24T19:16:02.960 に答える
1

F# を Rx に適合させるために独自のラッパー関数を作成する代わりに、標準の F#Control.Observableモジュールの関数を使用してみませんか?

于 2012-08-22T12:39:49.713 に答える
1

少しいじった後、実行時例外を便利な型エラーに変えることができました。オブザーバーのタイプを からIObserver<MouseMotionEventArgs>に変更すると、次のようにIObserver<EventPattern<MouseMotionEventArgs>>なります。

let observer = Observer.Create(fun (x : EventPattern<MouseMotionEventArgs>) -> System.Console.WriteLine(x.EventArgs.X.ToString()))
ignore <| SdlDotNet.Reactive.CoreInput.MouseMotion.Subscribe((observer))

何日も私を逃した解決策が、ここに投稿した後すぐに私に来るのはおそらく残念です. うまくいけば、それが誰かにとって役立つことが証明されるでしょう。

于 2012-08-22T10:10:24.653 に答える