front_idill/extern/fajran-npTuioClient/TuioClient/TuioClient.cpp
author bastiena
Fri, 06 Apr 2012 11:48:00 +0200
changeset 24 2bdf5d51d434
parent 21 e4e5f02787a1
child 25 a7b0e40bcab0
permissions -rw-r--r--
Front IDILL : TuioPoint class header modified in order to manage 3D points TuioContainer class header modified in order to manage 3D points TuioCursor class header modified in order to manage 3D points TuioClient class header modified in order to manage 3D points TuioClient class modified in order to manage 3D points client class header modified in order to manage 3D points client class modified in order to manage 3D points

/*
	TUIO C++ Library - part of the reacTIVision project
	http://reactivision.sourceforge.net/

	Copyright (c) 2005-2008 Martin Kaltenbrunner <mkalten@iua.upf.edu>

    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation; either version 2 of the License, or
    (at your option) any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program; if not, write to the Free Software
    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
*/

#include "TuioClient.h"

#ifndef WIN32
static void* ThreadFunc( void* obj )
#else
static DWORD WINAPI ThreadFunc( LPVOID obj )
#endif
{
	static_cast<TuioClient*>(obj)->socket->Run();
	return 0;
};
	
TuioClient::TuioClient() {
	TuioClient(3333);
}

TuioClient::TuioClient(int port) {
	try {
		socket = new UdpListeningReceiveSocket(IpEndpointName( IpEndpointName::ANY_ADDRESS, port ), this );
	} catch (std::exception &e) { 
		std::cout << "could not bind to UDP port " << port << std::endl;
		socket = NULL;
	}
	
	if (socket!=NULL) {
		if (!socket->IsBound()) {
			delete socket;
			socket = NULL;
		} else std::cout << "listening to TUIO messages on UDP port " << port << std::endl;
	}

	locked = false;
	running = false;
	currentFrame = lastFrame = maxFingerID = -1;
}

TuioClient::~TuioClient() {
	delete socket;
}

void TuioClient::ProcessBundle( const ReceivedBundle& b, const IpEndpointName& remoteEndpoint) {
	for( ReceivedBundle::const_iterator i = b.ElementsBegin(); i != b.ElementsEnd(); ++i ){
		if( i->IsBundle() )
			ProcessBundle( ReceivedBundle(*i), remoteEndpoint);
		else
			ProcessMessage( ReceivedMessage(*i), remoteEndpoint);
	}
}

void TuioClient::ProcessMessage( const ReceivedMessage& msg, const IpEndpointName& remoteEndpoint) {
	try {
		ReceivedMessageArgumentStream args = msg.ArgumentStream();
		ReceivedMessage::const_iterator arg = msg.ArgumentsBegin();

		if( strcmp( msg.AddressPattern(), "/tuio/2Dobj" ) == 0 ){

			const char* cmd;
			args >> cmd;
			
			if( strcmp( cmd, "set" ) == 0 ){	
				if ((currentFrame<lastFrame) && (currentFrame>0)) return;

				int32 s_id, f_id;
				float xpos, ypos, angle, xspeed, yspeed, rspeed, maccel, raccel;

				args >> s_id >> f_id >> xpos >> ypos >> angle >> xspeed >> yspeed >> rspeed >> maccel >> raccel >> EndMessage;

				std::list<TuioObject*>::iterator tobj;
				for (tobj=objectList.begin(); tobj!= objectList.end(); tobj++)
					if((*tobj)->getSessionID()==(long)s_id) break;

				if (tobj == objectList.end()) {

					TuioObject *addObject = new TuioObject((long)s_id,(int)f_id,xpos,ypos,angle);
					objectList.push_back(addObject);
					
					for (std::list<TuioListener*>::iterator listener=listenerList.begin(); listener != listenerList.end(); listener++)
						(*listener)->addTuioObject(addObject);

				} else if ( ((*tobj)->getX()!=xpos) || ((*tobj)->getY()!=ypos) || ((*tobj)->getAngle()!=angle) || ((*tobj)->getXSpeed()!=xspeed) || ((*tobj)->getYSpeed()!=yspeed) || ((*tobj)->getRotationSpeed()!=rspeed) || ((*tobj)->getMotionAccel()!=maccel) || ((*tobj)->getRotationAccel()!=raccel) ) {
					(*tobj)->update(xpos,ypos,angle,xspeed,yspeed,rspeed,maccel,raccel);

					for (std::list<TuioListener*>::iterator listener=listenerList.begin(); listener != listenerList.end(); listener++)
						(*listener)->updateTuioObject((*tobj));
				}

			} else if( strcmp( cmd, "alive" ) == 0 ){
				if ((currentFrame<lastFrame) && (currentFrame>0)) return;

				int32 s_id;
				while(!args.Eos()) {
					args >> s_id;
					objectBuffer.push_back((long)s_id);
					
					std::list<long>::iterator iter;
					iter = find(aliveObjectList.begin(), aliveObjectList.end(), (long)s_id); 
					if (iter != aliveObjectList.end()) aliveObjectList.erase(iter);
				}
				args >> EndMessage;
				
				std::list<long>::iterator alive_iter;
				for (alive_iter=aliveObjectList.begin(); alive_iter != aliveObjectList.end(); alive_iter++) {
					std::list<TuioObject*>::iterator tobj;
					for (tobj=objectList.begin(); tobj!=objectList.end(); tobj++) {
						TuioObject *deleteObject = (*tobj);
						if(deleteObject->getSessionID()==*alive_iter) {
							deleteObject->remove();
							for (std::list<TuioListener*>::iterator listener=listenerList.begin(); listener != listenerList.end(); listener++)
								(*listener)->removeTuioObject(deleteObject);
							objectList.erase(tobj);
							delete deleteObject;
							break;
						}
					}
					
				}
			
				aliveObjectList = objectBuffer;
				objectBuffer.clear();
			} else if( strcmp( cmd, "fseq" ) == 0 ){
				
				if(currentFrame>0) lastFrame = currentFrame;
				args >> currentFrame  >> EndMessage;

				if ((currentFrame>=lastFrame) || (currentFrame<0)) {
					
					long currentTime = lastTime;
					if (currentFrame>lastFrame) {
						currentTime = getCurrentTime()-startTime;
						lastTime = currentTime;
					}
					
					for (std::list<TuioObject*>::iterator refreshObject=objectList.begin(); refreshObject!=objectList.end(); refreshObject++)
						if ((*refreshObject)->getUpdateTime()==TUIO_UNDEFINED) (*refreshObject)->setUpdateTime(currentTime);
					
					for (std::list<TuioListener*>::iterator listener=listenerList.begin(); listener!=listenerList.end(); listener++)
						(*listener)->refresh(currentTime);
				}
			}
		} else if( strcmp( msg.AddressPattern(), "/tuio/3Dcur" ) == 0 ) {
			const char* cmd;
			args >> cmd;
			
			if( strcmp( cmd, "set" ) == 0 ){	
				if ((currentFrame<lastFrame) && (currentFrame>0)) return;

				int32 s_id;
				float xpos, ypos, zpos, xspeed, yspeed, maccel;
				//Modifi� par alexandre.bastien@iri.centrepompidou.fr
				args >> s_id >> xpos >> ypos >> zpos >> xspeed >> yspeed >> maccel >> EndMessage;

				std::list<TuioCursor*>::iterator tcur;
				for (tcur=cursorList.begin(); tcur != cursorList.end(); tcur++)
					if((*tcur)->getSessionID()==(long)s_id) break;

				if (tcur == cursorList.end()) {

					int f_id = (int)cursorList.size();
					if ((int)(cursorList.size())<=maxFingerID) {
						std::list<TuioCursor*>::iterator closestCursor = freeCursorList.begin();
						//Modifi� par alexandre.bastien@iri.centrepompidou.fr
						for(std::list<TuioCursor*>::iterator testCursor = freeCursorList.begin();testCursor!= freeCursorList.end(); testCursor++) {
							if((*testCursor)->getDistance(xpos,ypos,zpos)<(*closestCursor)->getDistance(xpos,ypos,zpos)) closestCursor = testCursor;
						}
						
						f_id = (*closestCursor)->getFingerID();
						freeCursorList.erase(closestCursor);
						delete *closestCursor;
					} else maxFingerID = f_id;	
					//Modifi� par alexandre.bastien@iri.centrepompidou.fr
					TuioCursor *addCursor = new TuioCursor((long)s_id,f_id,xpos,ypos);
					cursorList.push_back(addCursor);
					
					for (std::list<TuioListener*>::iterator listener=listenerList.begin(); listener != listenerList.end(); listener++)
						(*listener)->addTuioCursor(addCursor);
					
				//Modifi� par alexandre.bastien@iri.centrepompidou.fr
				} else if ( ((*tcur)->getX()!=xpos) || ((*tcur)->getY()!=ypos) || ((*tcur)->getZ()!=zpos) || ((*tcur)->getXSpeed()!=xspeed) || ((*tcur)->getYSpeed()!=yspeed) || ((*tcur)->getMotionAccel()!=maccel) ) {
					(*tcur)->update(xpos,ypos,xspeed,yspeed,maccel);
					for (std::list<TuioListener*>::iterator listener=listenerList.begin(); listener != listenerList.end(); listener++)
						(*listener)->updateTuioCursor((*tcur));
				}

			} else if( strcmp( cmd, "alive" ) == 0 ){
				if ((currentFrame<lastFrame) && (currentFrame>0)) return;

				int32 s_id;
				while(!args.Eos()) {
					args >> s_id;
					cursorBuffer.push_back((long)s_id);
					
					std::list<long>::iterator iter;
					iter = find(aliveCursorList.begin(), aliveCursorList.end(), (long)s_id); 
					if (iter != aliveCursorList.end()) aliveCursorList.erase(iter);
				}
				args >> EndMessage;
				
				std::list<long>::iterator alive_iter;
				for (alive_iter=aliveCursorList.begin(); alive_iter != aliveCursorList.end(); alive_iter++) {
					std::list<TuioCursor*>::iterator tcur;
					for (tcur=cursorList.begin(); tcur != cursorList.end(); tcur++) {
						TuioCursor *deleteCursor = (*tcur);
						if(deleteCursor->getSessionID()==*alive_iter) {
							
							cursorList.erase(tcur);
							deleteCursor->remove();
							for (std::list<TuioListener*>::iterator listener=listenerList.begin(); listener != listenerList.end(); listener++)
								(*listener)->removeTuioCursor(deleteCursor);
							
							if (deleteCursor->getFingerID()==maxFingerID) {
								maxFingerID = -1;
								delete deleteCursor;
								
								if (cursorList.size()>0) {
									std::list<TuioCursor*>::iterator clist;
									for (clist=cursorList.begin(); clist != cursorList.end(); clist++) {
										int f_id = (*clist)->getFingerID();
										if (f_id>maxFingerID) maxFingerID=f_id;
									}
									
									
									std::list<TuioCursor*>::iterator flist;
									for (flist=freeCursorList.begin(); flist != freeCursorList.end(); flist++) {
										TuioCursor *freeCursor = (*flist);
										if (freeCursor->getFingerID()>maxFingerID) delete freeCursor;
										else freeCursorBuffer.push_back(freeCursor);
									}

									freeCursorList = freeCursorBuffer;
									freeCursorBuffer.clear();
								} 
							} else if (deleteCursor->getFingerID()<maxFingerID) freeCursorList.push_back(deleteCursor);
							
							break;
						}
					}
					
				}
			
				aliveCursorList = cursorBuffer;
				cursorBuffer.clear();
			} else if( strcmp( cmd, "fseq" ) == 0 ){
				
				if(currentFrame>0) lastFrame = currentFrame;
				args >> currentFrame  >> EndMessage;

				if ((currentFrame>=lastFrame) || (currentFrame<0)) {
					long currentTime = lastTime;
					if (currentFrame>lastFrame) {
						currentTime = getCurrentTime()-startTime;
						lastTime = currentTime;
					}

					for (std::list<TuioCursor*>::iterator refreshCursor=cursorList.begin(); refreshCursor!=cursorList.end(); refreshCursor++)
						if ((*refreshCursor)->getUpdateTime()==TUIO_UNDEFINED) (*refreshCursor)->setUpdateTime(currentTime);

					for (std::list<TuioListener*>::iterator listener=listenerList.begin(); listener != listenerList.end(); listener++)
						(*listener)->refresh(currentTime);
				}
			}
		}
	} catch( Exception& e ){
		std::cout << "error while parsing message: "<< msg.AddressPattern() << ": " << e.what() << "\n";
	}
}

void TuioClient::ProcessPacket( const char *data, int size, const IpEndpointName& remoteEndpoint ) {
	if (listenerList.size()==0) return;
	ReceivedPacket p( data, size );
	if(p.IsBundle()) ProcessBundle( ReceivedBundle(p), remoteEndpoint);
        else ProcessMessage( ReceivedMessage(p), remoteEndpoint);
}

void TuioClient::start(bool lk) {

	if (socket==NULL) return;

	locked = lk;
	if (!locked) {
		#ifndef WIN32
		pthread_create(&thread , NULL, ThreadFunc, this);
		#else
		DWORD threadId;
		thread = CreateThread( 0, 0, ThreadFunc, this, 0, &threadId );
		#endif
	} else socket->Run();
	
	startTime = getCurrentTime();
	lastTime = 0;

	running = true;
}

void TuioClient::stop() {

	if (socket==NULL) return;
	socket->Break();

	if (!locked) {
		#ifdef WIN32
		if( thread ) CloseHandle( thread );
		#endif
		thread = 0;
		locked = false;
	}
	running = false;
}

void TuioClient::addTuioListener(TuioListener *listener) {
	listenerList.push_back(listener);
}

void TuioClient::removeTuioListener(TuioListener *listener) {
	std::list<TuioListener*>::iterator result = find(listenerList.begin(),listenerList.end(),listener);
	if (result!=listenerList.end()) listenerList.remove(listener);
}

TuioObject* TuioClient::getTuioObject(long s_id) {
	for (std::list<TuioObject*>::iterator iter=objectList.begin(); iter != objectList.end(); iter++)
		if((*iter)->getSessionID()==s_id) return (*iter);
		
	return NULL;
}

TuioCursor* TuioClient::getTuioCursor(long s_id) {
	for (std::list<TuioCursor*>::iterator iter=cursorList.begin(); iter != cursorList.end(); iter++)
		if((*iter)->getSessionID()==s_id) return (*iter);
		
	return NULL;
}

std::list<TuioObject*> TuioClient::getTuioObjects() {
	return objectList;
}

std::list<TuioCursor*> TuioClient::getTuioCursors() {
	return cursorList;
}

long TuioClient::getCurrentTime() {
	
	#ifdef WIN32
		long timestamp = GetTickCount();
	#else
		struct timeval tv;
		struct timezone tz;
		gettimeofday(&tv,&tz);
		long timestamp = (tv.tv_sec*1000)+(tv.tv_usec/1000);
	#endif
		
		return timestamp;
}