front_idill/extern/fajran-npTuioClient/TuioClient/TuioClient.cpp
changeset 21 e4e5f02787a1
child 24 2bdf5d51d434
equal deleted inserted replaced
20:f4303074311f 21:e4e5f02787a1
       
     1 /*
       
     2 	TUIO C++ Library - part of the reacTIVision project
       
     3 	http://reactivision.sourceforge.net/
       
     4 
       
     5 	Copyright (c) 2005-2008 Martin Kaltenbrunner <mkalten@iua.upf.edu>
       
     6 
       
     7     This program is free software; you can redistribute it and/or modify
       
     8     it under the terms of the GNU General Public License as published by
       
     9     the Free Software Foundation; either version 2 of the License, or
       
    10     (at your option) any later version.
       
    11 
       
    12     This program is distributed in the hope that it will be useful,
       
    13     but WITHOUT ANY WARRANTY; without even the implied warranty of
       
    14     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
       
    15     GNU General Public License for more details.
       
    16 
       
    17     You should have received a copy of the GNU General Public License
       
    18     along with this program; if not, write to the Free Software
       
    19     Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
       
    20 */
       
    21 
       
    22 #include "TuioClient.h"
       
    23 
       
    24 #ifndef WIN32
       
    25 static void* ThreadFunc( void* obj )
       
    26 #else
       
    27 static DWORD WINAPI ThreadFunc( LPVOID obj )
       
    28 #endif
       
    29 {
       
    30 	static_cast<TuioClient*>(obj)->socket->Run();
       
    31 	return 0;
       
    32 };
       
    33 	
       
    34 TuioClient::TuioClient() {
       
    35 	TuioClient(3333);
       
    36 }
       
    37 
       
    38 TuioClient::TuioClient(int port) {
       
    39 	try {
       
    40 		socket = new UdpListeningReceiveSocket(IpEndpointName( IpEndpointName::ANY_ADDRESS, port ), this );
       
    41 	} catch (std::exception &e) { 
       
    42 		std::cout << "could not bind to UDP port " << port << std::endl;
       
    43 		socket = NULL;
       
    44 	}
       
    45 	
       
    46 	if (socket!=NULL) {
       
    47 		if (!socket->IsBound()) {
       
    48 			delete socket;
       
    49 			socket = NULL;
       
    50 		} else std::cout << "listening to TUIO messages on UDP port " << port << std::endl;
       
    51 	}
       
    52 
       
    53 	locked = false;
       
    54 	running = false;
       
    55 	currentFrame = lastFrame = maxFingerID = -1;
       
    56 }
       
    57 
       
    58 TuioClient::~TuioClient() {
       
    59 	delete socket;
       
    60 }
       
    61 
       
    62 void TuioClient::ProcessBundle( const ReceivedBundle& b, const IpEndpointName& remoteEndpoint) {
       
    63 	for( ReceivedBundle::const_iterator i = b.ElementsBegin(); i != b.ElementsEnd(); ++i ){
       
    64 		if( i->IsBundle() )
       
    65 			ProcessBundle( ReceivedBundle(*i), remoteEndpoint);
       
    66 		else
       
    67 			ProcessMessage( ReceivedMessage(*i), remoteEndpoint);
       
    68 	}
       
    69 }
       
    70 
       
    71 void TuioClient::ProcessMessage( const ReceivedMessage& msg, const IpEndpointName& remoteEndpoint) {
       
    72 	try {
       
    73 		ReceivedMessageArgumentStream args = msg.ArgumentStream();
       
    74 		ReceivedMessage::const_iterator arg = msg.ArgumentsBegin();
       
    75 
       
    76 		if( strcmp( msg.AddressPattern(), "/tuio/2Dobj" ) == 0 ){
       
    77 
       
    78 			const char* cmd;
       
    79 			args >> cmd;
       
    80 			
       
    81 			if( strcmp( cmd, "set" ) == 0 ){	
       
    82 				if ((currentFrame<lastFrame) && (currentFrame>0)) return;
       
    83 
       
    84 				int32 s_id, f_id;
       
    85 				float xpos, ypos, angle, xspeed, yspeed, rspeed, maccel, raccel;
       
    86 					
       
    87 				args >> s_id >> f_id >> xpos >> ypos >> angle >> xspeed >> yspeed >> rspeed >> maccel >> raccel >> EndMessage;
       
    88 
       
    89 				std::list<TuioObject*>::iterator tobj;
       
    90 				for (tobj=objectList.begin(); tobj!= objectList.end(); tobj++)
       
    91 					if((*tobj)->getSessionID()==(long)s_id) break;
       
    92 
       
    93 				if (tobj == objectList.end()) {
       
    94 
       
    95 					TuioObject *addObject = new TuioObject((long)s_id,(int)f_id,xpos,ypos,angle);
       
    96 					objectList.push_back(addObject);
       
    97 					
       
    98 					for (std::list<TuioListener*>::iterator listener=listenerList.begin(); listener != listenerList.end(); listener++)
       
    99 						(*listener)->addTuioObject(addObject);
       
   100 
       
   101 
       
   102 				} 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) ) {
       
   103 					(*tobj)->update(xpos,ypos,angle,xspeed,yspeed,rspeed,maccel,raccel);
       
   104 
       
   105 					for (std::list<TuioListener*>::iterator listener=listenerList.begin(); listener != listenerList.end(); listener++)
       
   106 						(*listener)->updateTuioObject((*tobj));
       
   107 				}
       
   108 
       
   109 			} else if( strcmp( cmd, "alive" ) == 0 ){
       
   110 				if ((currentFrame<lastFrame) && (currentFrame>0)) return;
       
   111 
       
   112 				int32 s_id;
       
   113 				while(!args.Eos()) {
       
   114 					args >> s_id;
       
   115 					objectBuffer.push_back((long)s_id);
       
   116 					
       
   117 					std::list<long>::iterator iter;
       
   118 					iter = find(aliveObjectList.begin(), aliveObjectList.end(), (long)s_id); 
       
   119 					if (iter != aliveObjectList.end()) aliveObjectList.erase(iter);
       
   120 				}
       
   121 				args >> EndMessage;
       
   122 				
       
   123 				std::list<long>::iterator alive_iter;
       
   124 				for (alive_iter=aliveObjectList.begin(); alive_iter != aliveObjectList.end(); alive_iter++) {
       
   125 					std::list<TuioObject*>::iterator tobj;
       
   126 					for (tobj=objectList.begin(); tobj!=objectList.end(); tobj++) {
       
   127 						TuioObject *deleteObject = (*tobj);
       
   128 						if(deleteObject->getSessionID()==*alive_iter) {
       
   129 							deleteObject->remove();
       
   130 							for (std::list<TuioListener*>::iterator listener=listenerList.begin(); listener != listenerList.end(); listener++)
       
   131 								(*listener)->removeTuioObject(deleteObject);
       
   132 							objectList.erase(tobj);
       
   133 							delete deleteObject;
       
   134 							break;
       
   135 						}
       
   136 					}
       
   137 					
       
   138 				}
       
   139 			
       
   140 				aliveObjectList = objectBuffer;
       
   141 				objectBuffer.clear();
       
   142 			} else if( strcmp( cmd, "fseq" ) == 0 ){
       
   143 				
       
   144 				if(currentFrame>0) lastFrame = currentFrame;
       
   145 				args >> currentFrame  >> EndMessage;
       
   146 
       
   147 				if ((currentFrame>=lastFrame) || (currentFrame<0)) {
       
   148 					
       
   149 					long currentTime = lastTime;
       
   150 					if (currentFrame>lastFrame) {
       
   151 						currentTime = getCurrentTime()-startTime;
       
   152 						lastTime = currentTime;
       
   153 					}
       
   154 					
       
   155 					for (std::list<TuioObject*>::iterator refreshObject=objectList.begin(); refreshObject!=objectList.end(); refreshObject++)
       
   156 						if ((*refreshObject)->getUpdateTime()==TUIO_UNDEFINED) (*refreshObject)->setUpdateTime(currentTime);
       
   157 					
       
   158 					for (std::list<TuioListener*>::iterator listener=listenerList.begin(); listener!=listenerList.end(); listener++)
       
   159 						(*listener)->refresh(currentTime);
       
   160 				}
       
   161 			}
       
   162 		} else if( strcmp( msg.AddressPattern(), "/tuio/2Dcur" ) == 0 ) {
       
   163 			const char* cmd;
       
   164 			args >> cmd;
       
   165 			
       
   166 			if( strcmp( cmd, "set" ) == 0 ){	
       
   167 				if ((currentFrame<lastFrame) && (currentFrame>0)) return;
       
   168 
       
   169 				int32 s_id;
       
   170 				float xpos, ypos, xspeed, yspeed, maccel;
       
   171 					
       
   172 				args >> s_id >> xpos >> ypos >> xspeed >> yspeed >> maccel >> EndMessage;
       
   173 
       
   174 				std::list<TuioCursor*>::iterator tcur;
       
   175 				for (tcur=cursorList.begin(); tcur != cursorList.end(); tcur++)
       
   176 					if((*tcur)->getSessionID()==(long)s_id) break;
       
   177 
       
   178 				if (tcur == cursorList.end()) {
       
   179 
       
   180 					int f_id = (int)cursorList.size();
       
   181 					if ((int)(cursorList.size())<=maxFingerID) {
       
   182 						std::list<TuioCursor*>::iterator closestCursor = freeCursorList.begin();
       
   183 						
       
   184 						for(std::list<TuioCursor*>::iterator testCursor = freeCursorList.begin();testCursor!= freeCursorList.end(); testCursor++) {
       
   185 							if((*testCursor)->getDistance(xpos,ypos)<(*closestCursor)->getDistance(xpos,ypos)) closestCursor = testCursor;
       
   186 						}
       
   187 						
       
   188 						f_id = (*closestCursor)->getFingerID();
       
   189 						freeCursorList.erase(closestCursor);
       
   190 						delete *closestCursor;
       
   191 					} else maxFingerID = f_id;	
       
   192 
       
   193 					TuioCursor *addCursor = new TuioCursor((long)s_id,f_id,xpos,ypos);
       
   194 					cursorList.push_back(addCursor);
       
   195 					
       
   196 					for (std::list<TuioListener*>::iterator listener=listenerList.begin(); listener != listenerList.end(); listener++)
       
   197 						(*listener)->addTuioCursor(addCursor);
       
   198 					
       
   199 
       
   200 				} else if ( ((*tcur)->getX()!=xpos) || ((*tcur)->getY()!=ypos) || ((*tcur)->getXSpeed()!=xspeed) || ((*tcur)->getYSpeed()!=yspeed) || ((*tcur)->getMotionAccel()!=maccel) ) {
       
   201 					(*tcur)->update(xpos,ypos,xspeed,yspeed,maccel);
       
   202 					for (std::list<TuioListener*>::iterator listener=listenerList.begin(); listener != listenerList.end(); listener++)
       
   203 						(*listener)->updateTuioCursor((*tcur));
       
   204 				}
       
   205 
       
   206 			} else if( strcmp( cmd, "alive" ) == 0 ){
       
   207 				if ((currentFrame<lastFrame) && (currentFrame>0)) return;
       
   208 
       
   209 				int32 s_id;
       
   210 				while(!args.Eos()) {
       
   211 					args >> s_id;
       
   212 					cursorBuffer.push_back((long)s_id);
       
   213 					
       
   214 					std::list<long>::iterator iter;
       
   215 					iter = find(aliveCursorList.begin(), aliveCursorList.end(), (long)s_id); 
       
   216 					if (iter != aliveCursorList.end()) aliveCursorList.erase(iter);
       
   217 				}
       
   218 				args >> EndMessage;
       
   219 				
       
   220 				std::list<long>::iterator alive_iter;
       
   221 				for (alive_iter=aliveCursorList.begin(); alive_iter != aliveCursorList.end(); alive_iter++) {
       
   222 					std::list<TuioCursor*>::iterator tcur;
       
   223 					for (tcur=cursorList.begin(); tcur != cursorList.end(); tcur++) {
       
   224 						TuioCursor *deleteCursor = (*tcur);
       
   225 						if(deleteCursor->getSessionID()==*alive_iter) {
       
   226 							
       
   227 							cursorList.erase(tcur);
       
   228 							deleteCursor->remove();
       
   229 							for (std::list<TuioListener*>::iterator listener=listenerList.begin(); listener != listenerList.end(); listener++)
       
   230 								(*listener)->removeTuioCursor(deleteCursor);
       
   231 							
       
   232 							if (deleteCursor->getFingerID()==maxFingerID) {
       
   233 								maxFingerID = -1;
       
   234 								delete deleteCursor;
       
   235 								
       
   236 								if (cursorList.size()>0) {
       
   237 									std::list<TuioCursor*>::iterator clist;
       
   238 									for (clist=cursorList.begin(); clist != cursorList.end(); clist++) {
       
   239 										int f_id = (*clist)->getFingerID();
       
   240 										if (f_id>maxFingerID) maxFingerID=f_id;
       
   241 									}
       
   242 									
       
   243 									
       
   244 									std::list<TuioCursor*>::iterator flist;
       
   245 									for (flist=freeCursorList.begin(); flist != freeCursorList.end(); flist++) {
       
   246 										TuioCursor *freeCursor = (*flist);
       
   247 										if (freeCursor->getFingerID()>maxFingerID) delete freeCursor;
       
   248 										else freeCursorBuffer.push_back(freeCursor);
       
   249 									}
       
   250 
       
   251 									freeCursorList = freeCursorBuffer;
       
   252 									freeCursorBuffer.clear();
       
   253 								} 
       
   254 							} else if (deleteCursor->getFingerID()<maxFingerID) freeCursorList.push_back(deleteCursor);
       
   255 							
       
   256 							break;
       
   257 						}
       
   258 					}
       
   259 					
       
   260 				}
       
   261 			
       
   262 				aliveCursorList = cursorBuffer;
       
   263 				cursorBuffer.clear();
       
   264 			} else if( strcmp( cmd, "fseq" ) == 0 ){
       
   265 				
       
   266 				if(currentFrame>0) lastFrame = currentFrame;
       
   267 				args >> currentFrame  >> EndMessage;
       
   268 
       
   269 				if ((currentFrame>=lastFrame) || (currentFrame<0)) {
       
   270 					long currentTime = lastTime;
       
   271 					if (currentFrame>lastFrame) {
       
   272 						currentTime = getCurrentTime()-startTime;
       
   273 						lastTime = currentTime;
       
   274 					}
       
   275 
       
   276 					for (std::list<TuioCursor*>::iterator refreshCursor=cursorList.begin(); refreshCursor!=cursorList.end(); refreshCursor++)
       
   277 						if ((*refreshCursor)->getUpdateTime()==TUIO_UNDEFINED) (*refreshCursor)->setUpdateTime(currentTime);
       
   278 
       
   279 					for (std::list<TuioListener*>::iterator listener=listenerList.begin(); listener != listenerList.end(); listener++)
       
   280 						(*listener)->refresh(currentTime);
       
   281 				}
       
   282 			}
       
   283 		}
       
   284 	} catch( Exception& e ){
       
   285 		std::cout << "error while parsing message: "<< msg.AddressPattern() << ": " << e.what() << "\n";
       
   286 	}
       
   287 }
       
   288 
       
   289 void TuioClient::ProcessPacket( const char *data, int size, const IpEndpointName& remoteEndpoint ) {
       
   290 	if (listenerList.size()==0) return;
       
   291 	ReceivedPacket p( data, size );
       
   292 	if(p.IsBundle()) ProcessBundle( ReceivedBundle(p), remoteEndpoint);
       
   293         else ProcessMessage( ReceivedMessage(p), remoteEndpoint);
       
   294 }
       
   295 
       
   296 void TuioClient::start(bool lk) {
       
   297 
       
   298 	if (socket==NULL) return;
       
   299 
       
   300 	locked = lk;
       
   301 	if (!locked) {
       
   302 		#ifndef WIN32
       
   303 		pthread_create(&thread , NULL, ThreadFunc, this);
       
   304 		#else
       
   305 		DWORD threadId;
       
   306 		thread = CreateThread( 0, 0, ThreadFunc, this, 0, &threadId );
       
   307 		#endif
       
   308 	} else socket->Run();
       
   309 	
       
   310 	startTime = getCurrentTime();
       
   311 	lastTime = 0;
       
   312 
       
   313 	running = true;
       
   314 }
       
   315 
       
   316 void TuioClient::stop() {
       
   317 
       
   318 	if (socket==NULL) return;
       
   319 	socket->Break();
       
   320 
       
   321 	if (!locked) {
       
   322 		#ifdef WIN32
       
   323 		if( thread ) CloseHandle( thread );
       
   324 		#endif
       
   325 		thread = 0;
       
   326 		locked = false;
       
   327 	}
       
   328 	running = false;
       
   329 }
       
   330 
       
   331 void TuioClient::addTuioListener(TuioListener *listener) {
       
   332 	listenerList.push_back(listener);
       
   333 }
       
   334 
       
   335 void TuioClient::removeTuioListener(TuioListener *listener) {
       
   336 	std::list<TuioListener*>::iterator result = find(listenerList.begin(),listenerList.end(),listener);
       
   337 	if (result!=listenerList.end()) listenerList.remove(listener);
       
   338 }
       
   339 
       
   340 TuioObject* TuioClient::getTuioObject(long s_id) {
       
   341 	for (std::list<TuioObject*>::iterator iter=objectList.begin(); iter != objectList.end(); iter++)
       
   342 		if((*iter)->getSessionID()==s_id) return (*iter);
       
   343 		
       
   344 	return NULL;
       
   345 }
       
   346 
       
   347 TuioCursor* TuioClient::getTuioCursor(long s_id) {
       
   348 	for (std::list<TuioCursor*>::iterator iter=cursorList.begin(); iter != cursorList.end(); iter++)
       
   349 		if((*iter)->getSessionID()==s_id) return (*iter);
       
   350 		
       
   351 	return NULL;
       
   352 }
       
   353 
       
   354 std::list<TuioObject*> TuioClient::getTuioObjects() {
       
   355 	return objectList;
       
   356 }
       
   357 
       
   358 std::list<TuioCursor*> TuioClient::getTuioCursors() {
       
   359 	return cursorList;
       
   360 }
       
   361 
       
   362 long TuioClient::getCurrentTime() {
       
   363 	
       
   364 	#ifdef WIN32
       
   365 		long timestamp = GetTickCount();
       
   366 	#else
       
   367 		struct timeval tv;
       
   368 		struct timezone tz;
       
   369 		gettimeofday(&tv,&tz);
       
   370 		long timestamp = (tv.tv_sec*1000)+(tv.tv_usec/1000);
       
   371 	#endif
       
   372 		
       
   373 		return timestamp;
       
   374 }