aboutsummaryrefslogtreecommitdiffstats
path: root/ofxMaxim/ofxMaximExample_0.8.4_OSX_Granular/ofxOsc/src/ofxOscReceiver.cpp
diff options
context:
space:
mode:
authormick grierson <mickgrierson@gmail.com>2015-06-29 15:57:31 +0100
committermick grierson <mickgrierson@gmail.com>2015-06-29 15:57:31 +0100
commitb86dfa8f6f99713ee4605c30ebb1a58309aaeb8a (patch)
tree519c6acfe487d3d2f844b21c4d1d062670c57ee3 /ofxMaxim/ofxMaximExample_0.8.4_OSX_Granular/ofxOsc/src/ofxOscReceiver.cpp
parent440498446db27a6883de668ebf407f489c979016 (diff)
Updating post-hackday
Diffstat (limited to 'ofxMaxim/ofxMaximExample_0.8.4_OSX_Granular/ofxOsc/src/ofxOscReceiver.cpp')
-rwxr-xr-xofxMaxim/ofxMaximExample_0.8.4_OSX_Granular/ofxOsc/src/ofxOscReceiver.cpp284
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 = &parameter;
+
+ 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
+}