using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Net;
using System.Net.Sockets;
using bbiwarg.Recognition.TouchRecognition;
using bbiwarg.Recognition.PalmRecognition;
using bbiwarg.Utility;
using bbiwarg.Input.InputHandling;
using TUIO;
namespace bbiwarg.TUIO
{
///
/// TuioCommunicator sends generated touch events and palm grid coordinates to tuio clients using a .
///
class TuioCommunicator
{
///
/// the tuio server
///
private TuioServer server;
///
/// dictionary of lists of tuio cursors indexed by touch id
///
private Dictionary tcursors;
///
/// dictionary of lists of tuio objects indexed by palm id
///
private Dictionary> tobjects;
///
/// Constructs a TuioCommunicator.
///
/// server ip
/// server port
public TuioCommunicator(string host, int port)
{
server = new TuioServer(host, port);
tcursors = new Dictionary();
tobjects = new Dictionary>();
}
///
/// Handles the event that a new frame is finished processing by updating the cursors and objects and sending them.
///
/// event sender
/// event arguments
public void handleNewFrameData(object sender, NewProcessedFrameEventArgs e)
{
server.initFrame();
FrameData frameData = e.FrameData;
lock (frameData)
{
if (frameData.ResetFlag)
reset();
foreach (TouchEvent te in frameData.TouchEvents)
{
switch (te.Type)
{
case TouchEventType.Down:
TuioCursor tcur = server.addTuioCursor(te.Touch.RelativePosition.X, te.Touch.RelativePosition.Y);
tcursors.Add(te.Touch.TrackID, tcur);
break;
case TouchEventType.Move:
server.updateTuioCursor(tcursors[te.Touch.TrackID], te.Touch.RelativePosition.X, te.Touch.RelativePosition.Y);
break;
case TouchEventType.Up:
server.removeTuioCursor(tcursors[te.Touch.TrackID]);
tcursors.Remove(te.Touch.TrackID);
break;
}
}
List updatedIDs = new List();
foreach (Palm palm in frameData.TrackedPalms)
{
if (tobjects.Keys.Contains(palm.TrackID))
{
// update / move
List palmTobjs = tobjects[palm.TrackID];
Vector2D[] corners = palm.Quad.Corners;
for (int i = 0; i < 4; i++)
server.updateTuioObject(palmTobjs[i], corners[i].X, corners[i].Y);
updatedIDs.Add(palm.TrackID);
}
else
{
// add / create
List palmTobjs = new List();
Vector2D[] corners = palm.Quad.Corners;
for (int i = 0; i < 4; i++)
palmTobjs.Add(server.addTuioObject(corners[i].X, corners[i].Y, palm.TrackID + 0.1f*i));
tobjects.Add(palm.TrackID, palmTobjs);
updatedIDs.Add(palm.TrackID);
}
}
// remove
List ids = tobjects.Keys.ToList();
for (int i = ids.Count - 1; i >= 0;i-- )
{
int id = ids[i];
if (!updatedIDs.Contains(id))
{
foreach (TuioObject tobj in tobjects[id])
server.removeTuioObject(tobj);
tobjects.Remove(id);
}
}
}
server.commitFrame();
}
///
/// Closes the server.
///
public void close()
{
server.close();
}
///
/// Resets the server by removing all cursors and objects.
///
public void reset()
{
foreach (int id in tcursors.Keys)
server.removeTuioCursor(tcursors[id]);
tcursors.Clear();
foreach (int id in tobjects.Keys)
foreach (TuioObject tobj in tobjects[id])
server.removeTuioObject(tobj);
tobjects.Clear();
}
///
/// Tries to parse an ip address string.
///
/// the ip address string to parse
/// out parameter for the ip address in *.*.*.* format if ipIn is valid and null otherwise
/// true iff ipIn is a valid ip address
public static bool tryParseIPAddress(String ipIn, out String ipOut)
{
IPAddress ipAddress;
bool result = (IPAddress.TryParse(ipIn, out ipAddress) && ipAddress.AddressFamily == AddressFamily.InterNetwork);
if (result)
ipOut = ipAddress.ToString();
else
ipOut = null;
return result;
}
///
/// Tries to parse a port string.
///
/// the port string to parse
/// out parameter for the port as an Int16 if portIn is valid and undefined otherwise
/// true iff portIn is a valid port
public static bool tryParsePort(String portIn, out Int16 portOut)
{
return Int16.TryParse(portIn, out portOut);
}
}
}