diff options
| author | mick grierson <mickgrierson@gmail.com> | 2015-06-29 15:57:31 +0100 |
|---|---|---|
| committer | mick grierson <mickgrierson@gmail.com> | 2015-06-29 15:57:31 +0100 |
| commit | b86dfa8f6f99713ee4605c30ebb1a58309aaeb8a (patch) | |
| tree | 519c6acfe487d3d2f844b21c4d1d062670c57ee3 /ofxMaxim/ofxMaximExample_0.8.4_OSX_Granular/ofxOsc/src/ofxOscReceiver.cpp | |
| parent | 440498446db27a6883de668ebf407f489c979016 (diff) | |
Updating post-hackday
Diffstat (limited to 'ofxMaxim/ofxMaximExample_0.8.4_OSX_Granular/ofxOsc/src/ofxOscReceiver.cpp')
| -rwxr-xr-x | ofxMaxim/ofxMaximExample_0.8.4_OSX_Granular/ofxOsc/src/ofxOscReceiver.cpp | 284 |
1 files changed, 284 insertions, 0 deletions
diff --git a/ofxMaxim/ofxMaximExample_0.8.4_OSX_Granular/ofxOsc/src/ofxOscReceiver.cpp b/ofxMaxim/ofxMaximExample_0.8.4_OSX_Granular/ofxOsc/src/ofxOscReceiver.cpp new file mode 100755 index 0000000..d7ffd4e --- /dev/null +++ b/ofxMaxim/ofxMaximExample_0.8.4_OSX_Granular/ofxOsc/src/ofxOscReceiver.cpp @@ -0,0 +1,284 @@ +/* + + Copyright (c) 2007-2009, Damian Stewart + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + * Neither the name of the developer nor the + names of its contributors may be used to endorse or promote products + derived from this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY DAMIAN STEWART ''AS IS'' AND ANY + EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + DISCLAIMED. IN NO EVENT SHALL DAMIAN STEWART BE LIABLE FOR ANY + DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "ofxOscReceiver.h" + +#ifndef TARGET_WIN32 + #include <pthread.h> +#endif +#include <iostream> +#include <assert.h> + +ofxOscReceiver::ofxOscReceiver() +{ + listen_socket = NULL; +} + +void ofxOscReceiver::setup( int listen_port ) +{ + // if we're already running, shutdown before running again + if ( listen_socket ) + shutdown(); + + // create the mutex + #ifdef TARGET_WIN32 + mutex = CreateMutexA( NULL, FALSE, NULL ); + #else + pthread_mutex_init( &mutex, NULL ); + #endif + + // create socket + socketHasShutdown = false; + listen_socket = new UdpListeningReceiveSocket( IpEndpointName( IpEndpointName::ANY_ADDRESS, listen_port ), this ); + + // start thread + #ifdef TARGET_WIN32 + thread = CreateThread( + NULL, // default security attributes + 0, // use default stack size + &ofxOscReceiver::startThread, // thread function + (void*)this, // 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*)this ); + #endif +} + +void ofxOscReceiver::shutdown() +{ + if ( listen_socket ) + { + // tell the socket to shutdown + listen_socket->AsynchronousBreak(); + // wait for shutdown to complete + while (!socketHasShutdown) + { + #ifdef TARGET_WIN32 + Sleep(1); + #else + // sleep 0.1ms + usleep(100); + #endif + } + + // thread will clean up itself + + // clean up the mutex + #ifdef TARGET_WIN32 + ReleaseMutex( mutex ); + #else + pthread_mutex_destroy( &mutex ); + #endif + + // delete the socket + delete listen_socket; + listen_socket = NULL; + } +} + +ofxOscReceiver::~ofxOscReceiver() +{ + shutdown(); +} + +#ifdef TARGET_WIN32 +DWORD WINAPI +#else +void* +#endif + +ofxOscReceiver::startThread( void* receiverInstance ) +{ + // cast the instance + ofxOscReceiver* instance = (ofxOscReceiver*)receiverInstance; + // start the socket listener + instance->listen_socket->Run(); + // socket listener has finished - remember this fact + instance->socketHasShutdown = true; + // return + #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->IsInt64() ) + ofMessage->addInt64Arg( arg->AsInt64Unchecked() ); + else if ( arg->IsFloat() ) + ofMessage->addFloatArg( arg->AsFloatUnchecked() ); + else if ( arg->IsString() ) + ofMessage->addStringArg( arg->AsStringUnchecked() ); + else if ( arg->IsBlob() ){ + const char * dataPtr; + unsigned long len = 0; + arg->AsBlobUnchecked((const void*&)dataPtr, len); + ofBuffer buffer(dataPtr, len); + ofMessage->addBlobArg( buffer ); + }else + { + ofLogError("ofxOscReceiver") << "ProcessMessage: argument in message " << m.AddressPattern() << " is not an 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; +} + + +bool ofxOscReceiver::getParameter(ofAbstractParameter & parameter){ + ofxOscMessage msg; + if ( messages.size() == 0 ) return false; + while(hasWaitingMessages()){ + ofAbstractParameter * p = ¶meter; + + getNextMessage(&msg); + vector<string> address = ofSplitString(msg.getAddress(),"/",true); + + for(int i=0;i<address.size();i++){ + + if(p) { + if(address[i]==p->getEscapedName()){ + if(p->type()==typeid(ofParameterGroup).name()){ + if(address.size()>=i+1){ + p = &static_cast<ofParameterGroup*>(p)->get(address[i+1]); + } + }else if(p->type()==typeid(ofParameter<int>).name() && msg.getArgType(0)==OFXOSC_TYPE_INT32){ + p->cast<int>() = msg.getArgAsInt32(0); + }else if(p->type()==typeid(ofParameter<float>).name() && msg.getArgType(0)==OFXOSC_TYPE_FLOAT){ + p->cast<float>() = msg.getArgAsFloat(0); + }else if(p->type()==typeid(ofParameter<bool>).name() && msg.getArgType(0)==OFXOSC_TYPE_INT32){ + p->cast<bool>() = msg.getArgAsInt32(0); + }else if(msg.getArgType(0)==OFXOSC_TYPE_STRING){ + p->fromString(msg.getArgAsString(0)); + } + } + } + } + } + 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 +} |
