InteractiveScapeGmbH / TuioNet

MIT License
7 stars 1 forks source link

Use events instead of listener interfaces #10

Closed eqbic closed 1 year ago

eqbic commented 1 year ago

Problem

Right now there are several listener interfaces a user needs to implement to get notified when new tuio messages arrive. The pattern behind this machanism is the observer pattern which is a language feature of C# and should be used to avoid writing boilerplate code (i.e. implementing interfaces)

Solution

This PR introduces events which get invoked when new tuio messages arrive. Users can register methods to this events. This is a well known pattern in C# and should better match the expectations of developers.

Other Changes

Before the clients (Tuio11Client and Tuio20Client) did the network communication and processing tuio messages. This PR separates this two tasks. Now there is a unified TuioClient class which is only responsible for the network communication. This PR adds two new classes Tuio11Processor and Tuio20Processor which are responsible for processing the tuio messages and invoke the corresponding events. This leads to less code duplication and a better separation of responsibilities.

Comparison

Old

One has to implement the ITuio11Listener interface with all its methods (even one is only interested in cursors) and add this as a listener to the client:

public class TuioListener : ITuio11Listener
{
    public void AddTuioObject(Tuio11Object tuio11Object)
    {
        Console.WriteLine($"New object added -> ID: {tuio11Object.SymbolId}");
    }

    public void UpdateTuioObject(Tuio11Object tuio11Object)
    {
        Console.WriteLine($"Object {tuio11Object.SymbolId} -> Position: {tuio11Object.Position}, Angle: {tuio11Object.Angle}");
    }

    public void RemoveTuioObject(Tuio11Object tuio11Object)
    {
        Console.WriteLine($"Object {tuio11Object.SymbolId} removed");
    }

    public void AddTuioCursor(Tuio11Cursor tuio11Cursor)
    {
        Console.WriteLine($"New cursor added -> ID: {tuio11Cursor.CursorId}");
    }

    public void UpdateTuioCursor(Tuio11Cursor tuio11Cursor)
    {
        Console.WriteLine($"Cursor {tuio11Cursor.CursorId} -> Position: {tuio11Cursor.Position}");
    }

    public void RemoveTuioCursor(Tuio11Cursor tuio11Cursor)
    {
        Console.WriteLine($"Cursor {tuio11Cursor.CursorId} removed");
    }

    public void AddTuioBlob(Tuio11Blob tuio11Blob)
    {
        Console.WriteLine($"New blob added -> ID: {tuio11Blob.BlobId}");
    }

    public void UpdateTuioBlob(Tuio11Blob tuio11Blob)
    {
        Console.WriteLine($"Blob {tuio11Blob.BlobId} -> Position: {tuio11Blob.Position}, Angle: {tuio11Blob.Angle}, Area: {tuio11Blob.Area}");
    }

    public void RemoveTuioBlob(Tuio11Blob tuio11Blob)
    {
        Console.WriteLine($"Blob {tuio11Blob.BlobId} removed.");
    }

    public void Refresh(TuioTime tuioTime)
    {
    }
}

class Program
{
    private static void Main(string[] args)
    {
        var tuioClient = new Tuio11Client(TuioConnectionType.UDP);
        tuioClient.AddTuioListener(new TuioListener());
        Console.WriteLine("Connect...");
        tuioClient.Connect();
        while (true)
        {
            if (!Console.KeyAvailable) continue;
            var pressedKey = Console.ReadKey().Key;
            if (pressedKey == ConsoleKey.Q) break;
        }
        Console.WriteLine("Disconnect...");
        tuioClient.Disconnect();
    }
}

New

One just register methods to the event one is interested in.

class Program
{
    private static void Main(string[] args)
    {
        var tuioClient = new TuioClient(TuioConnectionType.UDP);
        var processor = new Tuio11Processor(tuioClient);
        processor.OnCursorAdded += CursorAdded;
        processor.OnCursorUpdated += UpdateCursor;
        processor.OnCursorRemoved += RemoveCursor;
        Console.WriteLine("Connect...");
        tuioClient.Connect();
        while (true)
        {
            if (!Console.KeyAvailable) continue;
            var pressedKey = Console.ReadKey().Key;
            if (pressedKey == ConsoleKey.Q) break;
        }
        Console.WriteLine("Disconnect...");
        processor.OnCursorAdded -= CursorAdded;
        processor.OnCursorUpdated -= UpdateCursor;
        processor.OnCursorRemoved -= RemoveCursor;
        tuioClient.Disconnect();
    }

    private static void CursorAdded(Tuio11Cursor cursor)
    {
        Console.WriteLine($"New cursor added -> ID: {cursor.CursorId}");
    }

    private static void UpdateCursor(Tuio11Cursor cursor)
    {
        Console.WriteLine($"Cursor {cursor.CursorId} -> Position: {cursor.Position}");
    }

    private static void RemoveCursor(Tuio11Cursor cursor)
    {
        Console.WriteLine($"Cursor {cursor.CursorId} removed");
    }