using OSC.NET;
using System;
using System.Collections.Generic;
// using System.Runtime.InteropServices;
namespace TUIO
{
///
/// Tuio server class to send tuio cursors and objects to tuio clients.
///
internal class TuioServer
{
///
/// the maximum packet size
///
private const int MAX_PACKET_SIZE = 65535 - 8;
///
/// current tuio time
///
private TuioTime currentFrameTime;
///
/// list of generated cursors
///
private List cursorList;
///
/// server ip address
///
private String host = "127.0.0.1";
///
/// list of all generated objects
///
private List objectList;
///
/// server port
///
private int port = 3333;
///
/// tuio session id
///
private long sessionID = 0;
///
/// transmitter to send packages over udp
///
private OSCTransmitter transmitter = null;
///
/// list of cursors updated in the current frame
///
private List updatedCursorList;
///
/// list of objects updated in the current frame
///
private List updatedObjectList;
///
/// Creates a tuio server with default ip and port.
///
public TuioServer()
{
init();
}
///
/// Creates a tuio server with default ip.
///
/// server port
public TuioServer(int port)
{
this.port = port;
init();
}
///
/// Creates a tuio server.
///
/// server ip
/// server port
public TuioServer(String host, int port)
{
this.host = host;
this.port = port;
init();
}
///
/// Adds and returns a tuio cursor.
///
/// x position of the cursor
/// y position of the cursor
/// the added cursor
public TuioCursor addTuioCursor(float xp, float yp)
{
TuioCursor tcur = new TuioCursor(sessionID, cursorList.Count, xp, yp);
cursorList.Add(tcur);
updatedCursorList.Add(tcur);
sessionID++;
return tcur;
}
///
/// Adds and returns tuio object.
///
/// x position of the object
/// y position of the object
/// angle of the object
/// the added object
public TuioObject addTuioObject(float xp, float yp, float angle)
{
TuioObject tobj = new TuioObject(sessionID, objectList.Count, xp, yp, angle);
objectList.Add(tobj);
updatedObjectList.Add(tobj);
sessionID++;
return tobj;
}
///
/// Closes the transmission.
///
public void close()
{
transmitter.Close();
}
///
/// Sends cursors and objects which were updated in the current frame.
///
public void commitFrame()
{
sendMessage(updatedCursorList, updatedObjectList);
}
///
/// Initializes cursor and object lists for sending information for a new frame.
///
public void initFrame()
{
currentFrameTime = TuioTime.getSessionTime();
updatedCursorList = new List();
updatedObjectList = new List();
}
///
/// Removes a tuio cursor.
///
/// the cursor to remove
public void removeTuioCursor(TuioCursor tcur)
{
cursorList.Remove(tcur);
}
///
/// Removes a tuio object.
///
/// the object to remove
public void removeTuioObject(TuioObject tobj)
{
objectList.Remove(tobj);
}
///
/// Sends all cursors and objects.
///
public void sendFullMessages()
{
sendMessage(cursorList, objectList);
}
///
/// Updates a tui cursor.
///
/// the cursor to update
/// new x position
/// new y position
public void updateTuioCursor(TuioCursor tcur, float xp, float yp)
{
tcur.update(currentFrameTime, xp, yp);
if (!updatedCursorList.Contains(tcur))
updatedCursorList.Add(tcur);
}
///
/// Updates a tuio object.
///
/// the object to update
/// new x position
/// new y position
public void updateTuioObject(TuioObject tobj, float xp, float yp)
{
tobj.update(currentFrameTime, xp, yp);
if (!updatedObjectList.Contains(tobj))
updatedObjectList.Add(tobj);
}
///
/// Updates a tuio object.
///
/// the object to update
/// new x position
/// new y position
public void updateTuioObject(TuioObject tobj, float xp, float yp, float angle)
{
tobj.update(currentFrameTime, xp, yp, angle);
if (!updatedObjectList.Contains(tobj))
updatedObjectList.Add(tobj);
}
///
/// Adds a tuio cursor alive message to a packet.
///
/// packet to add the message to
private void addAliveCursorMessagesToBundle(OSCBundle packet)
{
OSCMessage mssg = new OSCMessage("/tuio/2Dcur");
mssg.Append("alive");
for (int i = 0; i < cursorList.Count; i++)
{
mssg.Append((Int32)cursorList[i].getSessionID());
}
packet.Append(mssg);
}
///
/// Adds a tuio object alive message to a packet.
///
/// packet to add the message to
private void addAliveObjectMessagesToBundle(OSCBundle packet)
{
OSCMessage mssg = new OSCMessage("/tuio/2Dobj");
mssg.Append("alive");
for (int i = 0; i < objectList.Count; i++)
{
mssg.Append((Int32)objectList[i].getSessionID());
}
packet.Append(mssg);
}
///
/// Initializes the server, cursors and objects.
///
private void init()
{
TuioTime.initSession();
cursorList = new List();
objectList = new List();
transmitter = new OSCTransmitter(host, port);
}
///
/// Sends cursors and objects.
///
/// list of cursors to send
/// list of objects to send
private void sendMessage(List cursorList, List objectList)
{
OSCBundle packet = new OSCBundle();
OSCMessage currentMessage;
// cursors
addAliveCursorMessagesToBundle(packet);
TuioCursor tcur;
for (int i = 0; i < cursorList.Count; i++)
{
tcur = cursorList[i];
currentMessage = new OSCMessage("/tuio/2Dcur");
currentMessage.Append("set");
currentMessage.Append((Int32)tcur.getSessionID());
currentMessage.Append(tcur.getX());
currentMessage.Append(tcur.getY());
currentMessage.Append(tcur.getXSpeed());
currentMessage.Append(tcur.getYSpeed());
currentMessage.Append(tcur.getMotionAccel());
packet.Append(currentMessage);
}
currentMessage = new OSCMessage("/tuio/2Dcur");
currentMessage.Append("fseq");
currentMessage.Append(-1); //sequence_id; actually -1 stands for redundant bundle
packet.Append(currentMessage);
transmitter.Send(packet);
// objects
packet = new OSCBundle();
addAliveObjectMessagesToBundle(packet);
TuioObject tobj;
for (int i = 0; i < objectList.Count; i++)
{
tobj = objectList[i];
currentMessage = new OSCMessage("/tuio/2Dobj");
currentMessage.Append("set");
currentMessage.Append((Int32)tobj.getSessionID());
currentMessage.Append(tobj.getSymbolID());
currentMessage.Append(tobj.getX());
currentMessage.Append(tobj.getY());
currentMessage.Append(tobj.getAngle());
currentMessage.Append(tobj.getXSpeed());
currentMessage.Append(tobj.getYSpeed());
currentMessage.Append(tobj.getRotationSpeed());
currentMessage.Append(tobj.getMotionAccel());
currentMessage.Append(tobj.getRotationAccel());
packet.Append(currentMessage);
}
currentMessage = new OSCMessage("/tuio/2Dobj");
currentMessage.Append("fseq");
currentMessage.Append(-1); //sequence_id; actually -1 stands for redundant bundle
packet.Append(currentMessage);
transmitter.Send(packet);
}
}
}