0

我目前正在使用 LeapSDK。我想制作一个封装 LeapSDK 的自定义类,以便我可以简单地将它导入到我将来制作的任何应用程序中。

LeapSDK 为开发者提供了一个接口来给控制器添加监听器。我们可以定义在监听器内部做什么。

事实上,我的问题与 LeapSDK 无关,但我想告诉你我在做什么,以便您了解我的需求。由于我不确定我是否以一种好的方法工作,你可能会有一些建议,比如以一种聪明的方式做同样的事情。请随时分享。

因此,这里有一个描述其工作原理的示例(SDK 提供的示例):

class Sample
{
    public static void Main ()
    {
        SampleListener listener = new SampleListener ();
        Controller controller = new Controller ();

        // Have the sample listener receive events from the controller
        controller.AddListener (listener);

        // Keep this process running until Enter is pressed
        Console.WriteLine ("Press Enter to quit...");
        Console.ReadLine ();

        // Remove the sample listener when done
        controller.RemoveListener (listener);
        controller.Dispose ();
    }
}
class SampleListener : Listener
{
    private Object thisLock = new Object ();

    private void SafeWriteLine (String line)
    {
        lock (thisLock) {
            Console.WriteLine (line);
        }
    }

    public override void OnInit (Controller controller)
    {
        SafeWriteLine ("Initialized");
    }

    public override void OnConnect (Controller controller)
    {
        SafeWriteLine ("Connected");
        controller.EnableGesture (Gesture.GestureType.TYPECIRCLE);
        controller.EnableGesture (Gesture.GestureType.TYPEKEYTAP);
        controller.EnableGesture (Gesture.GestureType.TYPESCREENTAP);
        controller.EnableGesture (Gesture.GestureType.TYPESWIPE);
    }

    public override void OnDisconnect (Controller controller)
    {
        //Note: not dispatched when running in a debugger.
        SafeWriteLine ("Disconnected");
    }

    public override void OnExit (Controller controller)
    {
        SafeWriteLine ("Exited");
    }
}

我已经测试了上面的代码,它工作得很好。

现在让我们转到我的问题。我创建了一个名为LeapEventInterpretator的类,它有一个事件侦听器,用于对设备生成的事件做出反应,就像上面的方法一样。我尝试将事件处理程序传递给侦听器,以便侦听器可以调用它来为主应用程序线程生成事件。

这是我的代码:

    class LeapEventInterpretator
{
    private Controller controller;
    private DeviceEventListener deviceEventListener;

    public delegate void LeapEventHandler(object sender, Gesture args);
    public event LeapEventHandler GestureDetected;

    public LeapEventInterpretator()
    {
        Connect();    
    }
    private void Connect()
    {
        controller = new Controller();

        deviceEventListener = new DeviceEventListener(GestureDetected);
        controller.AddListener(deviceEventListener);

    }

    public enum Gesture { SwipeLeft, SwipeRight };
}

class DeviceEventListener : Listener
{
    LeapEventInterpretator.LeapEventHandler handler;
    public DeviceEventListener(LeapEventInterpretator.LeapEventHandler h)
    {
        this.handler = h;
    }
    public override void OnConnect(Controller arg0)
    {
        if (this.handler != null)
            handler(this, LeapEventInterpretator.Gesture.SwipeLeft);
    }
}

引发 OnConnect 时,this.handler 为 null,然后我无法将自定义事件触发到应用程序类。有任何想法吗?

同样,这可能是解决问题的愚蠢方法。即使对我自己来说,我也不喜欢将事件处理程序传递给另一个类,但我就是想不出另一种方法来完成这项工作。因此,请随时发表评论。

非常感谢您的帮助。

4

1 回答 1

1

在这种情况下,您不希望将事件作为参数传递给侦听器。您想将回调传递给将引发事件的方法(即委托)。

在您的示例中,该行将deviceEventListener = new DeviceEventListener(GestureDetected);未初始化的委托(为空)传递给侦听器。这是因为您没有将事件作为参数传递,只是事件的自动生成的支持字段的值。事件只不过是一对方法,添加和删除,外部代码可以使用它来表示“订阅我”或“取消订阅我”。

你想做更多这样的事情:

class LeapEventInterpretator
{
    private Controller controller;
    private DeviceEventListener deviceEventListener;

    public delegate void LeapEventHandler(object sender, Gesture args);
    public event LeapEventHandler GestureDetected;

    public LeapEventInterpretator()
    {
        Connect();    
    }
    private void Connect()
    {
        controller = new Controller();

        // pass a callback that will raise the event.
        deviceEventListener = new DeviceEventListener(RaiseGestureDetected);
        controller.AddListener(deviceEventListener);

    }

    // a method to raise the event
    private void RaiseGestureDetected(Gesture gesture)
    {
         var handler = GestureDetected;
         if (handler != null)
             handler(this, gesture);
    }

    public enum Gesture { SwipeLeft, SwipeRight };
}

class DeviceEventListener : Listener
{
    Action<LeapEventInterpretator.Gesture> handler;
    public DeviceEventListener(Action<LeapEventInterpretator.Gesture> h)
    {
        this.handler = h;
    }
    public override void OnConnect(Controller arg0)
    {
        if (this.handler != null)
            handler(LeapEventInterpretator.Gesture.SwipeLeft);
    }
}

我不确定该OnConnect方法对我是否有意义,但是现在您应该在OnConnect调用时触发一个事件。

当然,您必须为该活动注册一些东西:

var interpreter = new LeapEventInterpretator();
intpreter.GestureDetected += (o, g) => { Console.WriteLine("Gesture detected: {0}", g); };
// do something to make the OnConnected get called.
于 2013-07-30T04:20:51.413 回答