topical media & game development

talk show tell print

lib-of-vs-addons-ofxOsc-src-ofxOscReceiver.cpp / cpp



  /*
  
   Copyright 2007, 2008 Damian Stewart damian@frey.co.nz
   Distributed under the terms of the GNU Lesser General Public License v3
  
   This file is part of the ofxOsc openFrameworks OSC addon.
  
   ofxOsc is free software: you can redistribute it and/or modify
   it under the terms of the GNU Lesser General Public License as published by
   the Free Software Foundation, either version 3 of the License, or
   (at your option) any later version.
  
   ofxOsc 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 Lesser General Public License
   along with ofxOsc.  If not, see <http://www.gnu.org/licenses/>.
   */
  
  include <ofxOscReceiver.h>
  
  ifndef TARGET_WIN32
          #include <pthread.h>
  endif
  include <iostream>
  include <assert.h>
  
  ofxOscReceiver::ofxOscReceiver()
  {
  ifdef TARGET_WIN32
                  mutex = CreateMutexA( NULL, FALSE, NULL );
          #else
          pthread_mutex_init( &mutex, NULL );
  endif
  }
  
  void ofxOscReceiver::setup( int listen_port )
  {
          listen_socket = new UdpListeningReceiveSocket( IpEndpointName( IpEndpointName::ANY_ADDRESS, listen_port ), this );
  ifdef TARGET_WIN32
          thread        = CreateThread(
                                                             NULL,              // default security attributes
                                                             0,                 // use default stack size
                                                          &ofxOscReceiver::startThread,        // thread function
                                                             (void*)(listen_socket),             // argument to thread function
                                                             0,                 // use default creation flags
                                                             NULL);             // we don't the the thread id
  
  else
          pthread_create( &thread, NULL, &ofxOscReceiver::startThread, (void*)(listen_socket) );
  
  endif
  }
  
  ofxOscReceiver::~ofxOscReceiver()
  {
  //        delete listen_socket;
  }
  
  /*
  if defined TARGET_OSX
  #error target-osx
  #elif defined TARGET_WIN32
  #error target-win32
  else
  #error no target
  endif
   */
  
  ifdef TARGET_WIN32
  DWORD WINAPI
  else
  void*
  endif
  
                  ofxOscReceiver::startThread( void* _socket )
  {
          UdpListeningReceiveSocket* socket = (UdpListeningReceiveSocket*)_socket;
          socket->Run();
      #ifdef TARGET_WIN32
              return 0;
      #else
          return NULL;
      #endif
  }
  
  void ofxOscReceiver::ProcessMessage( const osc::ReceivedMessage &m, const IpEndpointName& remoteEndpoint )
  {
          // convert the message to an ofxOscMessage
          ofxOscMessage* ofMessage = new ofxOscMessage();
  
          // set the address
          ofMessage->setAddress( m.AddressPattern() );
  
          // set the sender ip/host
          char endpoint_host[ IpEndpointName::ADDRESS_STRING_LENGTH ];
          remoteEndpoint.AddressAsString( endpoint_host );
      ofMessage->setRemoteEndpoint( endpoint_host, remoteEndpoint.port );
  
          // transfer the arguments
          for ( osc::ReceivedMessage::const_iterator arg = m.ArgumentsBegin();
                    arg != m.ArgumentsEnd();
                    ++arg )
          {
                  if ( arg->IsInt32() )
                          ofMessage->addIntArg( arg->AsInt32Unchecked() );
                  else if ( arg->IsFloat() )
                          ofMessage->addFloatArg( arg->AsFloatUnchecked() );
                  else if ( arg->IsString() )
                          ofMessage->addStringArg( arg->AsStringUnchecked() );
                  else
                  {
                          assert( false && "message argument is not int, float, or string" );
                  }
          }
  
          // now add to the queue
  
          // at this point we are running inside the thread created by startThread,
          // so anyone who calls hasWaitingMessages() or getNextMessage() is coming
          // from a different thread
  
          // so we have to practise shared memory management
  
          // grab a lock on the queue
          grabMutex();
  
          // add incoming message on to the queue
          messages.push_back( ofMessage );
  
          // release the lock
          releaseMutex();
  }
  
  bool ofxOscReceiver::hasWaitingMessages()
  {
          // grab a lock on the queue
          grabMutex();
  
          // check the length of the queue
          int queue_length = (int)messages.size();
  
          // release the lock
          releaseMutex();
  
          // return whether we have any messages
          return queue_length > 0;
  }
  
  bool ofxOscReceiver::getNextMessage( ofxOscMessage* message )
  {
          // grab a lock on the queue
          grabMutex();
  
          // check if there are any to be got
          if ( messages.size() == 0 )
          {
                  // no: release the mutex
                  releaseMutex();
                  return false;
          }
  
          // copy the message from the queue to message
          ofxOscMessage* src_message = messages.front();
          message->copy( *src_message );
  
          // now delete the src message
          delete src_message;
          // and remove it from the queue
          messages.pop_front();
  
          // release the lock on the queue
          releaseMutex();
  
          // return success
          return true;
  }
  
  void ofxOscReceiver::grabMutex()
  {
  ifdef TARGET_WIN32
          WaitForSingleObject( mutex, INFINITE );
  else
          pthread_mutex_lock( &mutex );
  endif
  }
  
  void ofxOscReceiver::releaseMutex()
  {
  ifdef TARGET_WIN32
          ReleaseMutex( mutex );
  else
          pthread_mutex_unlock( &mutex );
  endif
  }
  


(C) Æliens 04/09/2009

You may not copy or print any of this material without explicit permission of the author or the publisher. In case of other copyright issues, contact the author.