2010-01-21 01:33:02 +01:00
|
|
|
|
|
|
|
|
|
/*******************************************************************************/
|
|
|
|
|
/* Copyright (C) 2010 Jonathan Moore Liles */
|
|
|
|
|
/* */
|
|
|
|
|
/* 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; see the file COPYING. If not,write to the Free Software */
|
|
|
|
|
/* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
|
|
|
|
|
/*******************************************************************************/
|
|
|
|
|
|
|
|
|
|
#include <lo/lo.h>
|
|
|
|
|
#include "debug.h"
|
|
|
|
|
#include <stdlib.h>
|
|
|
|
|
#include <stdio.h>
|
2012-02-09 00:39:03 +01:00
|
|
|
|
#include <string.h>
|
2010-01-21 01:33:02 +01:00
|
|
|
|
#include <assert.h>
|
2010-01-21 01:33:02 +01:00
|
|
|
|
|
|
|
|
|
#include "Endpoint.H"
|
|
|
|
|
|
2010-01-21 01:33:02 +01:00
|
|
|
|
#include "Thread.H"
|
|
|
|
|
|
2012-02-27 04:35:31 +01:00
|
|
|
|
#pragma GCC diagnostic ignored "-Wunused-parameter"
|
|
|
|
|
|
2010-01-21 01:33:02 +01:00
|
|
|
|
namespace OSC
|
|
|
|
|
{
|
|
|
|
|
|
2012-02-21 09:48:13 +01:00
|
|
|
|
/**********/
|
|
|
|
|
/* Method */
|
|
|
|
|
/**********/
|
2010-01-21 01:33:02 +01:00
|
|
|
|
|
2012-02-21 09:48:13 +01:00
|
|
|
|
Method::Method ( )
|
|
|
|
|
{
|
|
|
|
|
_path = _typespec = _documentation = 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
Method::~Method ( )
|
|
|
|
|
{
|
|
|
|
|
if ( _path )
|
|
|
|
|
free( _path );
|
|
|
|
|
if ( _typespec )
|
|
|
|
|
free( _typespec );
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**********/
|
|
|
|
|
/* Signal */
|
|
|
|
|
/**********/
|
|
|
|
|
|
2012-05-04 07:57:54 +02:00
|
|
|
|
Signal::Signal ( const char *path, Direction dir )
|
|
|
|
|
{
|
|
|
|
|
_direction = dir;
|
2013-04-09 05:56:33 +02:00
|
|
|
|
_path = NULL;
|
|
|
|
|
if ( path )
|
|
|
|
|
_path = strdup( path );
|
2012-05-04 07:57:54 +02:00
|
|
|
|
_value = 0.0f;
|
|
|
|
|
_endpoint = NULL;
|
|
|
|
|
_peer = NULL;
|
|
|
|
|
_documentation = 0;
|
|
|
|
|
_user_data = 0;
|
|
|
|
|
_connection_state_callback = 0;
|
|
|
|
|
_connection_state_userdata = 0;
|
|
|
|
|
}
|
|
|
|
|
|
2012-02-24 12:52:57 +01:00
|
|
|
|
Signal::~Signal ( )
|
|
|
|
|
{
|
|
|
|
|
if ( _endpoint )
|
|
|
|
|
{
|
|
|
|
|
_endpoint->del_signal( this );
|
|
|
|
|
}
|
2013-04-09 05:56:33 +02:00
|
|
|
|
|
|
|
|
|
if ( _path )
|
|
|
|
|
free( _path );
|
2012-02-24 12:52:57 +01:00
|
|
|
|
_path = NULL;
|
|
|
|
|
|
|
|
|
|
_endpoint = NULL;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
|
Signal::rename ( const char *path )
|
|
|
|
|
{
|
2013-06-06 01:26:36 +02:00
|
|
|
|
char *new_path;
|
|
|
|
|
asprintf( &new_path, "%s%s", _endpoint->name(), path );
|
|
|
|
|
|
|
|
|
|
DMESSAGE( "Renaming signal %s to %s", this->path(), new_path );
|
2012-02-24 12:52:57 +01:00
|
|
|
|
|
2013-06-04 06:57:11 +02:00
|
|
|
|
if ( _direction == Signal::Input )
|
|
|
|
|
{
|
|
|
|
|
lo_server_del_method( _endpoint->_server, _path, NULL );
|
2013-06-06 01:26:36 +02:00
|
|
|
|
lo_server_add_method( _endpoint->_server, new_path, NULL, _endpoint->osc_sig_handler, this );
|
2013-06-04 06:57:11 +02:00
|
|
|
|
}
|
|
|
|
|
|
2013-06-06 01:26:36 +02:00
|
|
|
|
for ( std::list<Peer*>::iterator i = _endpoint->_peers.begin();
|
|
|
|
|
i != _endpoint->_peers.end();
|
|
|
|
|
++i )
|
|
|
|
|
{
|
|
|
|
|
_endpoint->send( (*i)->addr, "/signal/renamed", _path, new_path );
|
|
|
|
|
}
|
2012-02-26 03:01:46 +01:00
|
|
|
|
|
2013-06-06 01:26:36 +02:00
|
|
|
|
_endpoint->rename_translation_destination( _path, new_path );
|
|
|
|
|
|
|
|
|
|
free( _path );
|
|
|
|
|
_path = new_path;
|
2012-02-24 12:52:57 +01:00
|
|
|
|
}
|
2012-02-25 05:23:45 +01:00
|
|
|
|
|
|
|
|
|
bool
|
|
|
|
|
Signal::is_connected_to ( const OSC::Signal *s ) const
|
|
|
|
|
{
|
2012-02-26 03:01:46 +01:00
|
|
|
|
for ( std::list<Signal*>::const_iterator i = _outgoing.begin();
|
2012-02-25 05:23:45 +01:00
|
|
|
|
i != _outgoing.end();
|
|
|
|
|
++i )
|
|
|
|
|
{
|
2013-06-06 01:26:36 +02:00
|
|
|
|
/* if ( (*i)->_peer == s->_peer && */
|
|
|
|
|
/* (*i)->id() == s->id() ) */
|
|
|
|
|
/* return true; */
|
2012-02-25 05:23:45 +01:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return false;
|
|
|
|
|
}
|
2012-02-21 09:48:13 +01:00
|
|
|
|
|
|
|
|
|
void
|
|
|
|
|
Signal::value ( float f )
|
|
|
|
|
{
|
2013-06-06 01:26:36 +02:00
|
|
|
|
if ( f == _value )
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/* for ( std::list<Signal*>::const_iterator i = _outgoing.begin(); */
|
|
|
|
|
/* i != _outgoing.end(); */
|
|
|
|
|
/* ++i ) */
|
|
|
|
|
/* { */
|
|
|
|
|
/* /\* FIXME: won't work for loopback *\/ */
|
|
|
|
|
/* if ( (*i)->_value != f ) */
|
|
|
|
|
/* { */
|
|
|
|
|
/* (*i)->_value = f; */
|
|
|
|
|
|
|
|
|
|
_value = f;
|
|
|
|
|
|
|
|
|
|
if ( direction() == Output )
|
2012-02-21 09:48:13 +01:00
|
|
|
|
{
|
2013-06-06 01:26:36 +02:00
|
|
|
|
for ( std::list<Peer*>::iterator i = _endpoint->_peers.begin();
|
|
|
|
|
i != _endpoint->_peers.end();
|
|
|
|
|
++i )
|
2012-02-21 09:48:13 +01:00
|
|
|
|
{
|
2013-06-06 01:26:36 +02:00
|
|
|
|
_endpoint->send( (*i)->addr,
|
|
|
|
|
path(),
|
|
|
|
|
f );
|
|
|
|
|
}
|
2012-02-21 09:48:13 +01:00
|
|
|
|
|
2013-06-06 01:26:36 +02:00
|
|
|
|
// free(s);
|
|
|
|
|
}
|
|
|
|
|
else if ( direction() == Input )
|
|
|
|
|
{
|
|
|
|
|
DMESSAGE( "Sending value feedback for signal %s...", path() );
|
|
|
|
|
for ( std::list<Signal*>::iterator i = _incoming.begin();
|
|
|
|
|
i != _incoming.end();
|
|
|
|
|
++i )
|
|
|
|
|
{
|
|
|
|
|
DMESSAGE( "Sending value feedback to %s %s %f", lo_address_get_url( (*i)->_peer->addr), (*i)->path() , f);
|
2012-02-26 03:01:46 +01:00
|
|
|
|
_endpoint->send( (*i)->_peer->addr,
|
2013-06-06 01:26:36 +02:00
|
|
|
|
(*i)->path(),
|
2012-02-21 09:48:13 +01:00
|
|
|
|
f );
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2013-06-06 01:26:36 +02:00
|
|
|
|
void
|
|
|
|
|
Signal::learn_connection ( void )
|
|
|
|
|
{
|
|
|
|
|
_endpoint->_learn_signal = this;
|
|
|
|
|
}
|
|
|
|
|
|
2012-02-26 03:01:46 +01:00
|
|
|
|
char *
|
|
|
|
|
Signal::get_output_connection_peer_name_and_path ( int n )
|
2012-02-24 09:59:39 +01:00
|
|
|
|
{
|
2012-11-06 08:50:28 +01:00
|
|
|
|
Signal *t = NULL;
|
2012-02-26 03:01:46 +01:00
|
|
|
|
|
|
|
|
|
int j = 0;
|
|
|
|
|
for ( std::list<Signal*>::const_iterator i = _outgoing.begin();
|
|
|
|
|
i != _outgoing.end();
|
|
|
|
|
++i, ++j )
|
|
|
|
|
{
|
|
|
|
|
if ( j == n )
|
|
|
|
|
{
|
|
|
|
|
t = *i;
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2012-11-06 08:50:28 +01:00
|
|
|
|
if ( t )
|
|
|
|
|
{
|
|
|
|
|
char *r;
|
2013-06-06 01:26:36 +02:00
|
|
|
|
asprintf( &r, "%s%s", t->_peer->name, t->path() );
|
2012-02-24 09:59:39 +01:00
|
|
|
|
|
2012-11-06 08:50:28 +01:00
|
|
|
|
return r;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
return NULL;
|
2012-02-24 09:59:39 +01:00
|
|
|
|
}
|
2012-05-04 07:57:54 +02:00
|
|
|
|
|
2012-02-21 09:48:13 +01:00
|
|
|
|
|
2012-05-04 07:57:54 +02:00
|
|
|
|
|
2010-01-21 01:33:02 +01:00
|
|
|
|
void
|
|
|
|
|
Endpoint::error_handler(int num, const char *msg, const char *path)
|
|
|
|
|
{
|
|
|
|
|
WARNING( "LibLO server error %d in path %s: %s\n", num, path, msg);
|
|
|
|
|
}
|
|
|
|
|
|
2010-01-21 01:33:02 +01:00
|
|
|
|
Endpoint::Endpoint ( )
|
2013-04-09 05:56:33 +02:00
|
|
|
|
{
|
2013-06-06 00:58:52 +02:00
|
|
|
|
_learning_path = NULL;
|
2013-04-09 05:56:33 +02:00
|
|
|
|
_peer_signal_notification_callback = 0;
|
|
|
|
|
_peer_signal_notification_userdata = 0;
|
2012-05-04 07:57:54 +02:00
|
|
|
|
_peer_scan_complete_callback = 0;
|
|
|
|
|
_peer_scan_complete_userdata = 0;
|
|
|
|
|
_server = 0;
|
|
|
|
|
_name = 0;
|
2013-06-06 01:26:36 +02:00
|
|
|
|
_learn_signal = 0;
|
2012-05-04 07:57:54 +02:00
|
|
|
|
owner = 0;
|
2010-01-21 01:33:02 +01:00
|
|
|
|
}
|
2010-01-21 01:33:02 +01:00
|
|
|
|
|
2010-01-21 01:33:02 +01:00
|
|
|
|
int
|
2012-02-24 05:34:07 +01:00
|
|
|
|
Endpoint::init ( int proto, const char *port )
|
2010-01-21 01:33:02 +01:00
|
|
|
|
{
|
|
|
|
|
DMESSAGE( "Creating OSC server" );
|
2010-01-21 01:33:02 +01:00
|
|
|
|
|
2012-02-24 05:34:07 +01:00
|
|
|
|
_server = lo_server_new_with_proto( port, proto, error_handler );
|
2010-01-21 01:33:02 +01:00
|
|
|
|
|
2013-06-06 00:58:52 +02:00
|
|
|
|
char *url = lo_server_get_url( _server );
|
|
|
|
|
_addr = lo_address_new_from_url( url );
|
|
|
|
|
free( url );
|
|
|
|
|
|
2010-01-21 01:33:02 +01:00
|
|
|
|
if ( ! _server )
|
2010-01-21 01:33:02 +01:00
|
|
|
|
{
|
|
|
|
|
WARNING( "Error creating OSC server" );
|
|
|
|
|
return -1;
|
|
|
|
|
}
|
2012-02-09 00:39:03 +01:00
|
|
|
|
|
2012-02-26 03:01:46 +01:00
|
|
|
|
add_method( "/signal/hello", "ss", &Endpoint::osc_sig_hello, this, "" );
|
2013-06-06 01:26:36 +02:00
|
|
|
|
add_method( "/signal/connect", "ss", &Endpoint::osc_sig_connect, this, "" );
|
|
|
|
|
add_method( "/signal/disconnect", "ss", &Endpoint::osc_sig_disconnect, this, "" );
|
|
|
|
|
add_method( "/signal/renamed", "ss", &Endpoint::osc_sig_renamed, this, "" );
|
|
|
|
|
add_method( "/signal/removed", "s", &Endpoint::osc_sig_removed, this, "" );
|
|
|
|
|
add_method( "/signal/created", "ssfff", &Endpoint::osc_sig_created, this, "" );
|
2012-02-25 05:23:45 +01:00
|
|
|
|
add_method( "/signal/list", NULL, &Endpoint::osc_signal_lister, this, "" );
|
2012-02-21 09:48:13 +01:00
|
|
|
|
add_method( "/reply", NULL, &Endpoint::osc_reply, this, "" );
|
2013-06-06 00:58:52 +02:00
|
|
|
|
add_method( NULL, NULL, &Endpoint::osc_generic, this, "" );
|
2012-02-09 00:39:03 +01:00
|
|
|
|
|
2010-01-21 01:33:02 +01:00
|
|
|
|
return 0;
|
2010-01-21 01:33:02 +01:00
|
|
|
|
}
|
|
|
|
|
|
2010-01-21 01:33:02 +01:00
|
|
|
|
|
2010-01-21 01:33:02 +01:00
|
|
|
|
Endpoint::~Endpoint ( )
|
|
|
|
|
{
|
|
|
|
|
// lo_server_thread_free( _st );
|
2012-05-04 07:57:54 +02:00
|
|
|
|
if ( _server )
|
|
|
|
|
{
|
|
|
|
|
lo_server_free( _server );
|
|
|
|
|
_server = 0;
|
|
|
|
|
}
|
2010-01-21 01:33:02 +01:00
|
|
|
|
}
|
|
|
|
|
|
2012-02-26 03:01:46 +01:00
|
|
|
|
OSC::Signal *
|
|
|
|
|
Endpoint::find_target_by_peer_address ( std::list<Signal*> *l, lo_address addr )
|
2010-01-21 01:33:02 +01:00
|
|
|
|
{
|
|
|
|
|
|
2012-02-26 03:01:46 +01:00
|
|
|
|
for ( std::list<Signal*>::iterator i = l->begin();
|
2012-02-21 09:48:13 +01:00
|
|
|
|
i != l->end();
|
|
|
|
|
++i )
|
2010-01-21 01:33:02 +01:00
|
|
|
|
{
|
2012-02-26 03:01:46 +01:00
|
|
|
|
if ( address_matches( addr, (*i)->_peer->addr ) )
|
2010-01-21 01:33:02 +01:00
|
|
|
|
{
|
2012-02-21 09:48:13 +01:00
|
|
|
|
return *i;
|
2010-01-21 01:33:02 +01:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2012-02-21 09:48:13 +01:00
|
|
|
|
return NULL;
|
|
|
|
|
}
|
2013-06-06 01:26:36 +02:00
|
|
|
|
|
2012-02-24 09:59:39 +01:00
|
|
|
|
|
|
|
|
|
OSC::Signal *
|
|
|
|
|
Endpoint::find_peer_signal_by_path ( Peer *p, const char *path )
|
|
|
|
|
{
|
|
|
|
|
for ( std::list<Signal*>::iterator i = p->_signals.begin();
|
|
|
|
|
i != p->_signals.end();
|
|
|
|
|
++i )
|
|
|
|
|
{
|
|
|
|
|
if ( !strcmp( (*i)->path(), path ) )
|
|
|
|
|
return *i;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return NULL;
|
2012-02-21 09:48:13 +01:00
|
|
|
|
}
|
2013-06-06 01:26:36 +02:00
|
|
|
|
|
2012-02-24 12:52:57 +01:00
|
|
|
|
OSC::Signal *
|
2013-06-06 01:26:36 +02:00
|
|
|
|
Endpoint::find_signal_by_path ( const char *path )
|
2012-02-24 12:52:57 +01:00
|
|
|
|
{
|
2013-06-06 01:26:36 +02:00
|
|
|
|
for ( std::list<Signal*>::iterator i = _signals.begin();
|
|
|
|
|
i != _signals.end();
|
2012-02-24 12:52:57 +01:00
|
|
|
|
++i )
|
|
|
|
|
{
|
2013-06-06 01:26:36 +02:00
|
|
|
|
if ( !strcmp( (*i)->path(), path ) )
|
2012-02-24 12:52:57 +01:00
|
|
|
|
return *i;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return NULL;
|
|
|
|
|
}
|
|
|
|
|
|
2012-02-25 05:23:45 +01:00
|
|
|
|
void
|
|
|
|
|
Endpoint::hello ( const char *url )
|
|
|
|
|
{
|
2012-05-04 07:57:54 +02:00
|
|
|
|
assert( name() );
|
|
|
|
|
|
2012-02-25 05:23:45 +01:00
|
|
|
|
lo_address addr = lo_address_new_from_url ( url );
|
|
|
|
|
|
2012-02-26 03:01:46 +01:00
|
|
|
|
char *our_url = this->url();
|
|
|
|
|
send( addr, "/signal/hello", name(), our_url );
|
|
|
|
|
free( our_url );
|
|
|
|
|
|
2012-02-25 05:23:45 +01:00
|
|
|
|
lo_address_free( addr );
|
|
|
|
|
}
|
|
|
|
|
|
2013-04-09 05:56:33 +02:00
|
|
|
|
void
|
|
|
|
|
Endpoint::handle_hello ( const char *peer_name, const char *peer_url )
|
2012-02-25 05:23:45 +01:00
|
|
|
|
{
|
|
|
|
|
DMESSAGE( "Got hello from %s", peer_name );
|
|
|
|
|
|
2013-04-09 05:56:33 +02:00
|
|
|
|
Peer *p = find_peer_by_name( peer_name );
|
|
|
|
|
|
|
|
|
|
if ( ! p )
|
|
|
|
|
{
|
|
|
|
|
scan_peer( peer_name, peer_url );
|
|
|
|
|
}
|
|
|
|
|
else
|
2012-02-25 05:23:45 +01:00
|
|
|
|
{
|
2013-04-09 05:56:33 +02:00
|
|
|
|
/* maybe the peer has a new URL */
|
|
|
|
|
|
|
|
|
|
/* update address */
|
|
|
|
|
lo_address addr = lo_address_new_from_url( peer_url );
|
2012-02-25 05:23:45 +01:00
|
|
|
|
|
2013-04-09 05:56:33 +02:00
|
|
|
|
if ( address_matches( addr, p->addr ) )
|
2012-05-04 07:57:54 +02:00
|
|
|
|
{
|
2013-04-09 05:56:33 +02:00
|
|
|
|
free( addr );
|
|
|
|
|
return;
|
2012-05-04 07:57:54 +02:00
|
|
|
|
}
|
2013-04-09 05:56:33 +02:00
|
|
|
|
|
|
|
|
|
if ( p->addr )
|
|
|
|
|
free( p->addr );
|
|
|
|
|
|
|
|
|
|
p->addr = addr;
|
|
|
|
|
|
|
|
|
|
/* scan it while we're at it */
|
|
|
|
|
p->_scanning = true;
|
|
|
|
|
|
|
|
|
|
DMESSAGE( "Scanning peer %s", peer_name );
|
|
|
|
|
|
|
|
|
|
send( p->addr, "/signal/list" );
|
2012-02-25 05:23:45 +01:00
|
|
|
|
}
|
2013-04-09 05:56:33 +02:00
|
|
|
|
|
|
|
|
|
if ( name() )
|
|
|
|
|
{
|
|
|
|
|
hello( peer_url );
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
DMESSAGE( "Not sending hello because we don't have a name yet!" );
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
int
|
|
|
|
|
Endpoint::osc_sig_hello ( const char *path, const char *types, lo_arg **argv, int argc, lo_message msg, void *user_data )
|
|
|
|
|
{
|
|
|
|
|
Endpoint *ep = (Endpoint*)user_data;
|
|
|
|
|
|
|
|
|
|
const char *peer_name = &argv[0]->s;
|
|
|
|
|
const char *peer_url = &argv[1]->s;
|
|
|
|
|
|
|
|
|
|
ep->handle_hello( peer_name, peer_url );
|
2012-02-25 05:23:45 +01:00
|
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
int
|
|
|
|
|
Endpoint::osc_sig_disconnect ( const char *path, const char *types, lo_arg **argv, int argc, lo_message msg, void *user_data )
|
|
|
|
|
{
|
2013-06-06 01:26:36 +02:00
|
|
|
|
const char *their_name = &argv[0]->s;
|
|
|
|
|
const char *our_name = &argv[1]->s;
|
2012-02-25 05:23:45 +01:00
|
|
|
|
|
|
|
|
|
Endpoint *ep = (Endpoint*)user_data;
|
|
|
|
|
|
2013-06-06 01:26:36 +02:00
|
|
|
|
Signal *s = ep->find_signal_by_path( our_name );
|
2012-02-25 05:23:45 +01:00
|
|
|
|
|
|
|
|
|
if ( ! s )
|
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
|
|
if ( s->_direction == Signal::Input )
|
|
|
|
|
{
|
2013-06-06 01:26:36 +02:00
|
|
|
|
/* s->_incoming.remove( ps ); */
|
2012-02-26 03:01:46 +01:00
|
|
|
|
|
2013-06-06 01:26:36 +02:00
|
|
|
|
DMESSAGE( "Peer %s has disconnected from signal %s", our_name, their_name );
|
2012-02-25 05:23:45 +01:00
|
|
|
|
|
2013-06-06 01:26:36 +02:00
|
|
|
|
ep->del_translation( their_name );
|
|
|
|
|
|
2012-04-27 09:17:00 +02:00
|
|
|
|
if ( s->_connection_state_callback )
|
|
|
|
|
s->_connection_state_callback( s, s->_connection_state_userdata );
|
2012-02-25 05:23:45 +01:00
|
|
|
|
|
2012-02-26 03:01:46 +01:00
|
|
|
|
return 0;
|
2012-02-25 05:23:45 +01:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
int
|
|
|
|
|
Endpoint::osc_sig_connect ( const char *path, const char *types, lo_arg **argv, int argc, lo_message msg, void *user_data )
|
|
|
|
|
{
|
2013-06-06 01:26:36 +02:00
|
|
|
|
const char *src_path = &argv[0]->s;
|
|
|
|
|
const char *dst_path = &argv[1]->s;
|
2012-02-25 05:23:45 +01:00
|
|
|
|
|
|
|
|
|
Endpoint *ep = (Endpoint*)user_data;
|
|
|
|
|
|
2013-06-06 01:26:36 +02:00
|
|
|
|
Signal *dst_s = ep->find_signal_by_path( dst_path );
|
2012-02-25 05:23:45 +01:00
|
|
|
|
|
2013-06-06 01:26:36 +02:00
|
|
|
|
if ( ! dst_s )
|
2012-02-25 05:23:45 +01:00
|
|
|
|
{
|
2013-06-06 01:26:36 +02:00
|
|
|
|
WARNING( "Unknown destination signal in connection attempt: \"%s\"", dst_path );
|
2012-02-25 05:23:45 +01:00
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
2013-06-06 01:26:36 +02:00
|
|
|
|
if ( dst_s->_endpoint != ep )
|
2012-02-25 05:23:45 +01:00
|
|
|
|
{
|
2013-06-06 01:26:36 +02:00
|
|
|
|
WARNING( "Got connection request for a destination signal we don't own" );
|
2012-02-25 05:23:45 +01:00
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
2013-06-06 01:26:36 +02:00
|
|
|
|
DMESSAGE( "Has requested signal connection %s |> %s", src_path, dst_s->path() );
|
2012-02-25 05:23:45 +01:00
|
|
|
|
|
2013-06-06 01:26:36 +02:00
|
|
|
|
ep->add_translation( src_path, dst_s->path() );
|
2012-02-26 03:01:46 +01:00
|
|
|
|
|
2013-06-06 01:26:36 +02:00
|
|
|
|
/* if ( dst_s->_connection_state_callback ) */
|
|
|
|
|
/* dst_s->_connection_state_callback( dst_s, dst_s->_connection_state_userdata ); */
|
2012-02-26 03:01:46 +01:00
|
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
int
|
|
|
|
|
Endpoint::osc_sig_removed ( const char *path, const char *types, lo_arg **argv, int argc, lo_message msg, void *user_data )
|
|
|
|
|
{
|
2013-06-06 01:26:36 +02:00
|
|
|
|
const char *name = &argv[0]->s;
|
2012-02-26 03:01:46 +01:00
|
|
|
|
|
|
|
|
|
Endpoint *ep = (Endpoint*)user_data;
|
|
|
|
|
|
2013-06-06 01:26:36 +02:00
|
|
|
|
/* Peer *p = ep->find_peer_by_address( lo_message_get_source( msg ) ); */
|
2012-02-26 03:01:46 +01:00
|
|
|
|
|
2013-06-06 01:26:36 +02:00
|
|
|
|
/* if ( ! p ) */
|
|
|
|
|
/* { */
|
|
|
|
|
/* WARNING( "Got signal remove notification from unknown peer." ); */
|
|
|
|
|
/* return 0; */
|
|
|
|
|
/* } */
|
2012-02-25 05:23:45 +01:00
|
|
|
|
|
2013-06-06 01:26:36 +02:00
|
|
|
|
Signal *o = ep->find_signal_by_path( name );
|
2012-02-25 05:23:45 +01:00
|
|
|
|
|
2012-02-26 03:01:46 +01:00
|
|
|
|
if ( ! o )
|
|
|
|
|
{
|
2013-06-06 01:26:36 +02:00
|
|
|
|
WARNING( "Unknown signal: %s", name );
|
2012-02-25 05:23:45 +01:00
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
2012-02-26 03:01:46 +01:00
|
|
|
|
DMESSAGE( "Signal %s:%s was removed", o->_peer->name, o->path() );
|
|
|
|
|
|
2013-06-06 01:26:36 +02:00
|
|
|
|
/* /\* disconnect it *\/ */
|
|
|
|
|
/* if ( o->_outgoing.size() ) */
|
|
|
|
|
/* { */
|
|
|
|
|
/* for ( std::list<Signal*>::iterator i = o->_outgoing.begin(); */
|
|
|
|
|
/* i != o->_outgoing.end(); */
|
|
|
|
|
/* ) */
|
|
|
|
|
/* { */
|
|
|
|
|
/* Signal *s = *i; */
|
|
|
|
|
/* /\* avoid messing up iterator *\/ */
|
|
|
|
|
/* ++i; */
|
|
|
|
|
|
|
|
|
|
/* ep->disconnect_signal( o, s ); */
|
|
|
|
|
/* } */
|
|
|
|
|
/* } */
|
2012-02-26 03:01:46 +01:00
|
|
|
|
|
2013-06-06 01:26:36 +02:00
|
|
|
|
/* if ( o->_incoming.size() ) */
|
|
|
|
|
/* { */
|
|
|
|
|
/* for ( std::list<Signal*>::iterator i = o->_incoming.begin(); */
|
|
|
|
|
/* i != o->_incoming.end(); */
|
|
|
|
|
/* ) */
|
|
|
|
|
/* { */
|
|
|
|
|
/* Signal *s = *i; */
|
|
|
|
|
/* /\* avoid messing up iterator *\/ */
|
|
|
|
|
/* ++i; */
|
2013-04-09 05:56:33 +02:00
|
|
|
|
|
2013-06-06 01:26:36 +02:00
|
|
|
|
/* ep->disconnect_signal( s, o ); */
|
|
|
|
|
/* } */
|
|
|
|
|
/* } */
|
2012-02-26 03:01:46 +01:00
|
|
|
|
|
2013-04-09 05:56:33 +02:00
|
|
|
|
if ( ep->_peer_signal_notification_callback )
|
|
|
|
|
ep->_peer_signal_notification_callback( o, Signal::Removed, ep->_peer_signal_notification_userdata );
|
|
|
|
|
|
2013-06-06 01:26:36 +02:00
|
|
|
|
ep->_signals.remove( o );
|
2012-02-26 03:01:46 +01:00
|
|
|
|
|
|
|
|
|
delete o;
|
|
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
int
|
|
|
|
|
Endpoint::osc_sig_created ( const char *path, const char *types, lo_arg **argv, int argc, lo_message msg, void *user_data )
|
|
|
|
|
{
|
|
|
|
|
Endpoint *ep = (Endpoint*)user_data;
|
|
|
|
|
|
2012-02-27 03:47:07 +01:00
|
|
|
|
const char *name = &argv[0]->s;
|
|
|
|
|
const char *direction = &argv[1]->s;
|
2013-06-06 01:26:36 +02:00
|
|
|
|
const float min = argv[2]->f;
|
|
|
|
|
const float max = argv[3]->f;
|
|
|
|
|
const float default_value = argv[4]->f;
|
2012-02-27 03:47:07 +01:00
|
|
|
|
|
2013-04-09 05:56:33 +02:00
|
|
|
|
Peer *p = ep->find_peer_by_address( lo_message_get_source( msg ) );
|
|
|
|
|
|
|
|
|
|
if ( ! p )
|
|
|
|
|
{
|
|
|
|
|
WARNING( "Got signal creation notification from unknown peer" );
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
2012-02-27 03:47:07 +01:00
|
|
|
|
Signal::Direction dir = Signal::Input;
|
2012-02-26 03:01:46 +01:00
|
|
|
|
|
2012-02-27 03:47:07 +01:00
|
|
|
|
if ( !strcmp( direction, "in" ) )
|
2012-02-26 03:01:46 +01:00
|
|
|
|
dir = Signal::Input;
|
2012-02-27 03:47:07 +01:00
|
|
|
|
else if ( !strcmp( direction, "out" ) )
|
2012-02-26 03:01:46 +01:00
|
|
|
|
dir = Signal::Output;
|
|
|
|
|
|
2012-02-27 03:47:07 +01:00
|
|
|
|
Signal *s = new Signal( name, dir );
|
2012-02-26 03:01:46 +01:00
|
|
|
|
|
|
|
|
|
s->_peer = p;
|
2012-02-27 03:47:07 +01:00
|
|
|
|
s->parameter_limits( min, max, default_value );
|
2012-02-26 03:01:46 +01:00
|
|
|
|
|
|
|
|
|
p->_signals.push_back( s );
|
2013-04-09 05:56:33 +02:00
|
|
|
|
|
2013-06-06 01:26:36 +02:00
|
|
|
|
DMESSAGE( "Peer %s has created signal %s (%s %f %f %f)", p->name,
|
|
|
|
|
name, direction, min, max, default_value );
|
2013-04-09 05:56:33 +02:00
|
|
|
|
|
|
|
|
|
if ( ep->_peer_signal_notification_callback )
|
|
|
|
|
ep->_peer_signal_notification_callback( s, Signal::Created, ep->_peer_signal_notification_userdata );
|
2012-02-26 03:01:46 +01:00
|
|
|
|
|
2012-02-25 05:23:45 +01:00
|
|
|
|
return 0;
|
|
|
|
|
}
|
2012-02-24 12:52:57 +01:00
|
|
|
|
|
|
|
|
|
int
|
|
|
|
|
Endpoint::osc_sig_renamed ( const char *path, const char *types, lo_arg **argv, int argc, lo_message msg, void *user_data )
|
|
|
|
|
{
|
2012-02-26 03:01:46 +01:00
|
|
|
|
DMESSAGE( "Got renamed message." );
|
|
|
|
|
|
2013-06-06 01:26:36 +02:00
|
|
|
|
const char *old_name = &argv[0]->s;
|
|
|
|
|
const char *new_name = &argv[1]->s;
|
2012-02-24 12:52:57 +01:00
|
|
|
|
|
|
|
|
|
Endpoint *ep = (Endpoint*)user_data;
|
|
|
|
|
|
|
|
|
|
Peer *p = ep->find_peer_by_address( lo_message_get_source( msg ) );
|
|
|
|
|
|
|
|
|
|
if ( ! p )
|
|
|
|
|
{
|
|
|
|
|
WARNING( "Got signal rename notification from unknown peer." );
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
2013-06-06 01:26:36 +02:00
|
|
|
|
Signal *o = ep->find_peer_signal_by_path( p, old_name );
|
2012-02-24 12:52:57 +01:00
|
|
|
|
|
|
|
|
|
if ( ! o )
|
|
|
|
|
{
|
2013-06-06 01:26:36 +02:00
|
|
|
|
WARNING( "Unknown signal: %s", old_name );
|
2012-02-24 12:52:57 +01:00
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
2013-06-06 01:26:36 +02:00
|
|
|
|
DMESSAGE( "Signal %s was renamed to %s", o->_path, new_name );
|
2012-02-24 12:52:57 +01:00
|
|
|
|
|
2013-06-06 01:26:36 +02:00
|
|
|
|
ep->rename_translation_source( o->_path, new_name );
|
|
|
|
|
|
2012-02-24 12:52:57 +01:00
|
|
|
|
free( o->_path );
|
|
|
|
|
o->_path = strdup( new_name );
|
|
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
2012-02-21 09:48:13 +01:00
|
|
|
|
int
|
|
|
|
|
Endpoint::osc_sig_handler ( const char *path, const char *types, lo_arg **argv, int argc, lo_message msg, void *user_data )
|
|
|
|
|
{
|
|
|
|
|
Signal *o;
|
|
|
|
|
float f = 0.0;
|
2012-02-26 03:01:46 +01:00
|
|
|
|
Endpoint *ep = NULL;
|
|
|
|
|
|
2013-06-06 01:26:36 +02:00
|
|
|
|
if ( ! strcmp( types, "f" ) )
|
2012-02-21 09:48:13 +01:00
|
|
|
|
{
|
|
|
|
|
/* accept a value for signal named in path */
|
|
|
|
|
o = (Signal*)user_data;
|
2013-06-06 01:26:36 +02:00
|
|
|
|
ep = o->_endpoint;
|
2012-02-21 09:48:13 +01:00
|
|
|
|
f = argv[0]->f;
|
|
|
|
|
}
|
|
|
|
|
else if ( ! types || 0 == types[0] )
|
|
|
|
|
{
|
|
|
|
|
/* reply with current value */
|
|
|
|
|
o = (Signal*)user_data;
|
|
|
|
|
o->_endpoint->send( lo_message_get_source( msg ), "/reply", path, o->value() );
|
2012-04-25 03:15:26 +02:00
|
|
|
|
return 0;
|
2012-02-21 09:48:13 +01:00
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
return -1;
|
2010-01-21 01:33:02 +01:00
|
|
|
|
}
|
|
|
|
|
|
2013-06-06 01:26:36 +02:00
|
|
|
|
o->_value = f;
|
2012-02-26 03:01:46 +01:00
|
|
|
|
|
2013-06-06 01:26:36 +02:00
|
|
|
|
if ( o->_handler )
|
|
|
|
|
o->_handler( f, o->_user_data );
|
|
|
|
|
|
|
|
|
|
return 1;
|
|
|
|
|
}
|
2012-02-26 03:01:46 +01:00
|
|
|
|
|
2013-07-09 06:51:21 +02:00
|
|
|
|
const char**
|
|
|
|
|
Endpoint::get_connections ( const char *path )
|
|
|
|
|
{
|
|
|
|
|
const char ** conn = NULL;
|
|
|
|
|
|
|
|
|
|
int j = 0;
|
|
|
|
|
for ( std::map<std::string,TranslationDestination>::iterator i = _translations.begin();
|
|
|
|
|
i != _translations.end();
|
|
|
|
|
i++ )
|
|
|
|
|
{
|
|
|
|
|
if ( !strcmp( i->second.path.c_str(), path ) )
|
|
|
|
|
{
|
|
|
|
|
conn = (const char**)realloc( conn, sizeof( char * ) * (j+2));
|
|
|
|
|
conn[j++] = i->first.c_str();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if ( conn )
|
|
|
|
|
conn[j] = 0;
|
|
|
|
|
|
|
|
|
|
return conn;
|
|
|
|
|
}
|
|
|
|
|
|
2013-06-06 01:26:36 +02:00
|
|
|
|
void
|
|
|
|
|
Endpoint::clear_translations ( void )
|
|
|
|
|
{
|
|
|
|
|
_translations.clear();
|
|
|
|
|
}
|
2010-01-21 01:33:02 +01:00
|
|
|
|
|
2013-06-06 01:26:36 +02:00
|
|
|
|
void
|
|
|
|
|
Endpoint::add_translation ( const char *a, const char *b )
|
|
|
|
|
{
|
|
|
|
|
_translations[a].path = b;
|
|
|
|
|
}
|
2010-01-21 01:33:02 +01:00
|
|
|
|
|
2013-06-06 01:26:36 +02:00
|
|
|
|
void
|
|
|
|
|
Endpoint::del_translation ( const char *a )
|
|
|
|
|
{
|
|
|
|
|
std::map<std::string,TranslationDestination>::iterator i = _translations.find( a );
|
2012-02-26 03:01:46 +01:00
|
|
|
|
|
2013-06-06 01:26:36 +02:00
|
|
|
|
if ( i != _translations.end() )
|
|
|
|
|
_translations.erase( i );
|
|
|
|
|
}
|
2012-04-25 03:15:26 +02:00
|
|
|
|
|
2013-06-06 01:26:36 +02:00
|
|
|
|
void
|
|
|
|
|
Endpoint::rename_translation_destination ( const char *a, const char *b )
|
|
|
|
|
{
|
|
|
|
|
|
|
|
|
|
for ( std::map<std::string,TranslationDestination>::iterator i = _translations.begin();
|
|
|
|
|
i != _translations.end();
|
|
|
|
|
i++ )
|
|
|
|
|
{
|
|
|
|
|
if ( !strcmp( i->second.path.c_str(), a ) )
|
2012-02-26 03:01:46 +01:00
|
|
|
|
{
|
2013-06-06 01:26:36 +02:00
|
|
|
|
i->second.path = b;
|
2012-02-26 03:01:46 +01:00
|
|
|
|
}
|
2013-06-06 01:26:36 +02:00
|
|
|
|
}
|
|
|
|
|
}
|
2010-01-21 01:33:02 +01:00
|
|
|
|
|
2013-06-06 01:26:36 +02:00
|
|
|
|
void
|
|
|
|
|
Endpoint::rename_translation_source ( const char *a, const char *b )
|
|
|
|
|
{
|
|
|
|
|
std::map<std::string,TranslationDestination>::iterator i = _translations.find( a );
|
2010-01-21 01:33:02 +01:00
|
|
|
|
|
2013-06-06 01:26:36 +02:00
|
|
|
|
if ( i != _translations.end() )
|
|
|
|
|
{
|
|
|
|
|
_translations[b] = _translations[a];
|
2010-01-21 01:33:02 +01:00
|
|
|
|
|
2013-06-06 01:26:36 +02:00
|
|
|
|
_translations.erase( i );
|
|
|
|
|
}
|
|
|
|
|
}
|
2010-01-21 01:33:02 +01:00
|
|
|
|
|
2013-06-06 01:26:36 +02:00
|
|
|
|
int
|
|
|
|
|
Endpoint::ntranslations ( void )
|
|
|
|
|
{
|
|
|
|
|
return _translations.size();
|
2010-01-21 01:33:02 +01:00
|
|
|
|
}
|
2012-02-09 00:39:03 +01:00
|
|
|
|
|
2013-06-06 01:26:36 +02:00
|
|
|
|
bool
|
|
|
|
|
Endpoint::get_translation ( int n, const char **from, const char **to )
|
2013-06-06 00:58:52 +02:00
|
|
|
|
{
|
2013-06-06 01:26:36 +02:00
|
|
|
|
int j = 0;
|
|
|
|
|
for ( std::map<std::string,TranslationDestination>::const_iterator i = _translations.begin();
|
|
|
|
|
i != _translations.end();
|
|
|
|
|
i++, j++)
|
|
|
|
|
{
|
|
|
|
|
if ( j == n )
|
|
|
|
|
{
|
|
|
|
|
*from = i->first.c_str();
|
|
|
|
|
*to = i->second.path.c_str();
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return false;
|
2013-06-06 00:58:52 +02:00
|
|
|
|
}
|
|
|
|
|
|
2012-02-09 00:39:03 +01:00
|
|
|
|
int
|
|
|
|
|
Endpoint::osc_generic ( const char *path, const char *types, lo_arg **argv, int argc, lo_message msg, void *user_data )
|
|
|
|
|
{
|
2010-01-21 01:33:02 +01:00
|
|
|
|
// OSC_DMSG();
|
2013-06-06 00:58:52 +02:00
|
|
|
|
Endpoint *ep = (Endpoint*)user_data;
|
|
|
|
|
|
|
|
|
|
if ( ep->_learning_path )
|
|
|
|
|
{
|
|
|
|
|
ep->add_translation( path, ep->_learning_path );
|
|
|
|
|
|
|
|
|
|
DMESSAGE( "Learned translation \"%s\" -> \"%s\"", path, ep->_learning_path );
|
|
|
|
|
|
|
|
|
|
free(ep->_learning_path);
|
|
|
|
|
ep->_learning_path = NULL;
|
|
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
{
|
2013-06-06 01:26:36 +02:00
|
|
|
|
std::map<std::string,TranslationDestination>::iterator i = ep->_translations.find( path );
|
2013-06-06 00:58:52 +02:00
|
|
|
|
|
|
|
|
|
if ( i != ep->_translations.end() )
|
|
|
|
|
{
|
|
|
|
|
const char *dpath = i->second.path.c_str();
|
|
|
|
|
|
2013-06-06 01:26:36 +02:00
|
|
|
|
// DMESSAGE( "Translating message \"%s\" to \"%s\"", path, dpath );
|
|
|
|
|
|
|
|
|
|
if ( !strcmp(types, "f" ))
|
|
|
|
|
{
|
|
|
|
|
// DMESSAGE( "recording value %f", argv[0]->f );
|
|
|
|
|
i->second.current_value = argv[0]->f;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
i->second.suppress_feedback = true;
|
|
|
|
|
|
2013-06-06 00:58:52 +02:00
|
|
|
|
lo_send_message(ep->_addr, dpath, msg );
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
}
|
2012-02-09 00:39:03 +01:00
|
|
|
|
|
2012-02-24 09:59:39 +01:00
|
|
|
|
if ( argc || path[ strlen(path) - 1 ] != '/' )
|
2012-02-09 09:37:49 +01:00
|
|
|
|
return -1;
|
2012-02-09 00:39:03 +01:00
|
|
|
|
|
2012-02-21 09:48:13 +01:00
|
|
|
|
for ( std::list<Method*>::const_iterator i = ep->_methods.begin(); i != ep->_methods.end(); ++i )
|
|
|
|
|
{
|
|
|
|
|
if ( ! (*i)->path() )
|
|
|
|
|
continue;
|
2012-02-09 00:39:03 +01:00
|
|
|
|
|
2012-02-21 09:48:13 +01:00
|
|
|
|
if (! strncmp( (*i)->path(), path, strlen(path) ) )
|
|
|
|
|
{
|
|
|
|
|
/* asprintf( &stored_path, "%s (%s); %s", path, typespec, argument_description ); */
|
|
|
|
|
|
|
|
|
|
((Endpoint*)user_data)->send( lo_message_get_source( msg ), "/reply", path, (*i)->path() );
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
((Endpoint*)user_data)->send( lo_message_get_source( msg ), "/reply", path );
|
2012-02-09 00:39:03 +01:00
|
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
2012-02-21 09:48:13 +01:00
|
|
|
|
int
|
|
|
|
|
Endpoint::osc_signal_lister ( const char *path, const char *types, lo_arg **argv, int argc, lo_message msg, void *user_data )
|
2012-02-09 00:39:03 +01:00
|
|
|
|
{
|
2012-02-21 09:48:13 +01:00
|
|
|
|
// OSC_DMSG();
|
2013-04-09 05:56:33 +02:00
|
|
|
|
|
|
|
|
|
DMESSAGE( "Listing signals." );
|
2012-02-21 09:48:13 +01:00
|
|
|
|
|
|
|
|
|
const char *prefix = NULL;
|
|
|
|
|
|
|
|
|
|
if ( argc )
|
|
|
|
|
prefix = &argv[0]->s;
|
2012-02-09 00:39:03 +01:00
|
|
|
|
|
2012-02-21 09:48:13 +01:00
|
|
|
|
Endpoint *ep = (Endpoint*)user_data;
|
|
|
|
|
|
|
|
|
|
for ( std::list<Signal*>::const_iterator i = ep->_signals.begin(); i != ep->_signals.end(); ++i )
|
|
|
|
|
{
|
|
|
|
|
Signal *o = *i;
|
|
|
|
|
|
2012-02-25 05:23:45 +01:00
|
|
|
|
if ( ! prefix || ! strncmp( o->path(), prefix, strlen(prefix) ) )
|
2012-02-09 00:39:03 +01:00
|
|
|
|
{
|
2012-02-25 05:23:45 +01:00
|
|
|
|
ep->send( lo_message_get_source( msg ),
|
|
|
|
|
"/reply",
|
|
|
|
|
path,
|
|
|
|
|
o->path(),
|
|
|
|
|
o->_direction == Signal::Input ? "in" : "out",
|
|
|
|
|
o->parameter_limits().min,
|
|
|
|
|
o->parameter_limits().max,
|
|
|
|
|
o->parameter_limits().default_value
|
|
|
|
|
);
|
2012-02-21 09:48:13 +01:00
|
|
|
|
}
|
|
|
|
|
}
|
2012-02-25 05:23:45 +01:00
|
|
|
|
|
2012-02-21 09:48:13 +01:00
|
|
|
|
ep->send( lo_message_get_source( msg ), "/reply", path );
|
|
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool
|
|
|
|
|
Endpoint::address_matches ( lo_address addr1, lo_address addr2 )
|
|
|
|
|
{
|
|
|
|
|
char *purl = strdup( lo_address_get_port( addr1 ) );
|
|
|
|
|
char *url = strdup( lo_address_get_port( addr2 ) );
|
|
|
|
|
|
|
|
|
|
bool r = !strcmp( purl, url );
|
|
|
|
|
|
|
|
|
|
free( purl );
|
|
|
|
|
free( url );
|
2010-01-21 01:33:02 +01:00
|
|
|
|
|
2012-02-21 09:48:13 +01:00
|
|
|
|
return r;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void
|
2013-04-09 05:56:33 +02:00
|
|
|
|
Endpoint::list_peer_signals ( void *v )
|
2012-02-21 09:48:13 +01:00
|
|
|
|
{
|
|
|
|
|
for ( std::list<Peer*>::iterator i = _peers.begin();
|
|
|
|
|
i != _peers.end();
|
|
|
|
|
++i )
|
|
|
|
|
{
|
|
|
|
|
for ( std::list<Signal*>::iterator j = (*i)->_signals.begin();
|
|
|
|
|
j != (*i)->_signals.end();
|
|
|
|
|
++j )
|
|
|
|
|
{
|
2013-04-09 05:56:33 +02:00
|
|
|
|
if ( _peer_signal_notification_callback )
|
|
|
|
|
_peer_signal_notification_callback( *j, OSC::Signal::Created, v );
|
2012-02-09 00:39:03 +01:00
|
|
|
|
}
|
|
|
|
|
}
|
2012-02-21 09:48:13 +01:00
|
|
|
|
}
|
2012-02-09 00:39:03 +01:00
|
|
|
|
|
2012-02-21 09:48:13 +01:00
|
|
|
|
Peer *
|
|
|
|
|
Endpoint::find_peer_by_address ( lo_address addr )
|
|
|
|
|
{
|
|
|
|
|
char *url = strdup( lo_address_get_port( addr ) );
|
|
|
|
|
|
|
|
|
|
Peer *p = NULL;
|
|
|
|
|
|
|
|
|
|
for ( std::list<Peer*>::iterator i = _peers.begin();
|
|
|
|
|
i != _peers.end();
|
|
|
|
|
++i )
|
|
|
|
|
{
|
|
|
|
|
char *purl = strdup( lo_address_get_port( (*i)->addr ) );
|
|
|
|
|
|
|
|
|
|
if ( !strcmp( purl, url ) )
|
|
|
|
|
{
|
|
|
|
|
free( purl );
|
|
|
|
|
p = *i;
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
free(purl);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
free( url );
|
|
|
|
|
|
|
|
|
|
return p;
|
2012-02-09 00:39:03 +01:00
|
|
|
|
}
|
|
|
|
|
|
2012-02-21 09:48:13 +01:00
|
|
|
|
Peer *
|
|
|
|
|
Endpoint::find_peer_by_name ( const char *name )
|
2010-01-21 01:33:02 +01:00
|
|
|
|
{
|
2012-02-21 09:48:13 +01:00
|
|
|
|
for ( std::list<Peer*>::iterator i = _peers.begin();
|
|
|
|
|
i != _peers.end();
|
|
|
|
|
++i )
|
|
|
|
|
{
|
|
|
|
|
if ( !strcmp( name, (*i)->name ) )
|
|
|
|
|
{
|
|
|
|
|
return *i;
|
|
|
|
|
}
|
|
|
|
|
}
|
2010-01-21 01:33:02 +01:00
|
|
|
|
|
2012-02-21 09:48:13 +01:00
|
|
|
|
return NULL;
|
|
|
|
|
}
|
2010-01-21 01:33:02 +01:00
|
|
|
|
|
2012-02-24 09:59:39 +01:00
|
|
|
|
bool
|
2012-02-26 03:01:46 +01:00
|
|
|
|
Endpoint::disconnect_signal ( OSC::Signal *s, OSC::Signal *d )
|
|
|
|
|
{
|
2013-06-06 01:26:36 +02:00
|
|
|
|
/* if ( ! s->is_connected_to( d ) ) */
|
|
|
|
|
/* return false; */
|
2012-02-26 03:01:46 +01:00
|
|
|
|
|
2013-04-09 05:56:33 +02:00
|
|
|
|
if ( d->_peer )
|
|
|
|
|
{
|
|
|
|
|
MESSAGE( "Disconnecting signal output \"%s\" from %s:%s", s->path(), d->_peer->name, d->_path );
|
|
|
|
|
|
2013-06-06 01:26:36 +02:00
|
|
|
|
/* send( d->_peer->addr, "/signal/disconnect", */
|
|
|
|
|
/* s->_id, /\* our signal id *\/ */
|
|
|
|
|
/* d->_id /\* their signal id *\/ ); */
|
2013-04-09 05:56:33 +02:00
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
2013-06-06 01:26:36 +02:00
|
|
|
|
/* MESSAGE( "Disconnecting signal output \"%s\" to (unknown):%i", s->path(), d->_id ); */
|
2013-04-09 05:56:33 +02:00
|
|
|
|
}
|
|
|
|
|
|
2012-02-26 03:01:46 +01:00
|
|
|
|
s->_outgoing.remove( d );
|
2013-04-09 05:56:33 +02:00
|
|
|
|
d->_incoming.remove( s );
|
2012-02-26 03:01:46 +01:00
|
|
|
|
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool
|
2013-06-06 01:26:36 +02:00
|
|
|
|
Endpoint::disconnect_signal ( OSC::Signal *s, const char *signal_path )
|
2012-02-24 09:59:39 +01:00
|
|
|
|
{
|
|
|
|
|
if ( s->_direction == Signal::Output )
|
|
|
|
|
{
|
2013-06-06 01:26:36 +02:00
|
|
|
|
/* Peer *p = find_peer_by_name( peer_name ); */
|
2012-02-24 09:59:39 +01:00
|
|
|
|
|
2013-06-06 01:26:36 +02:00
|
|
|
|
/* if ( ! p ) */
|
|
|
|
|
/* return false; */
|
2012-02-24 09:59:39 +01:00
|
|
|
|
|
2013-06-06 01:26:36 +02:00
|
|
|
|
Signal *ps = find_signal_by_path( signal_path );
|
2012-02-24 09:59:39 +01:00
|
|
|
|
|
|
|
|
|
if ( ! ps )
|
|
|
|
|
return false;
|
|
|
|
|
|
2012-02-26 03:01:46 +01:00
|
|
|
|
if ( ! s->is_connected_to( ps ) )
|
|
|
|
|
return false;
|
2012-02-25 05:23:45 +01:00
|
|
|
|
|
2012-02-26 03:01:46 +01:00
|
|
|
|
return disconnect_signal( s, ps );
|
2012-02-25 05:23:45 +01:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
2012-02-26 03:01:46 +01:00
|
|
|
|
|
2013-06-06 01:26:36 +02:00
|
|
|
|
/* bool */
|
|
|
|
|
/* Endpoint::connect_signal ( OSC::Signal *s, OSC::Signal *d ) */
|
|
|
|
|
/* { */
|
|
|
|
|
/* /\* if ( s->is_connected_to( d ) ) *\/ */
|
|
|
|
|
/* /\* { *\/ */
|
|
|
|
|
/* /\* return false; *\/ */
|
|
|
|
|
/* /\* } *\/ */
|
2012-02-26 03:01:46 +01:00
|
|
|
|
|
2013-06-06 01:26:36 +02:00
|
|
|
|
/* MESSAGE( "Connecting signal output \"%s\" to %s:%s", s->path(), d->_peer->name, d->path() ); */
|
2012-02-26 03:01:46 +01:00
|
|
|
|
|
2013-06-06 01:26:36 +02:00
|
|
|
|
/* s->_outgoing.push_back( d ); */
|
2012-02-26 03:01:46 +01:00
|
|
|
|
|
2013-06-06 01:26:36 +02:00
|
|
|
|
/* /\* make a record of it ourselves *\/ */
|
|
|
|
|
/* d->_incoming.push_back( s ); */
|
2012-02-26 03:01:46 +01:00
|
|
|
|
|
2013-06-06 01:26:36 +02:00
|
|
|
|
/* send( d->_peer->addr, "/signal/connect", */
|
|
|
|
|
/* s->path(), */
|
|
|
|
|
/* d->path() ); */
|
2012-02-26 03:01:46 +01:00
|
|
|
|
|
2013-06-06 01:26:36 +02:00
|
|
|
|
/* return true; */
|
|
|
|
|
/* } */
|
2012-02-25 05:23:45 +01:00
|
|
|
|
|
2012-02-26 03:01:46 +01:00
|
|
|
|
|
2012-02-25 05:23:45 +01:00
|
|
|
|
bool
|
2013-06-06 01:26:36 +02:00
|
|
|
|
Endpoint::connect_signal( OSC::Signal *s, const char *signal_path )
|
2012-02-25 05:23:45 +01:00
|
|
|
|
{
|
|
|
|
|
if ( s->_direction == Signal::Output )
|
|
|
|
|
{
|
2013-06-06 01:26:36 +02:00
|
|
|
|
for ( std::list<Peer*>::iterator i = _peers.begin();
|
|
|
|
|
i != _peers.end();
|
|
|
|
|
i++ )
|
|
|
|
|
{
|
2012-02-25 05:23:45 +01:00
|
|
|
|
|
2013-06-06 01:26:36 +02:00
|
|
|
|
send( (*i)->addr, "/signal/connect",
|
|
|
|
|
s->path(),
|
|
|
|
|
signal_path );
|
|
|
|
|
}
|
2012-02-24 09:59:39 +01:00
|
|
|
|
}
|
|
|
|
|
|
2013-06-06 01:26:36 +02:00
|
|
|
|
return true;
|
2012-02-24 09:59:39 +01:00
|
|
|
|
}
|
2012-02-21 09:48:13 +01:00
|
|
|
|
|
|
|
|
|
int
|
|
|
|
|
Endpoint::osc_reply ( const char *path, const char *types, lo_arg **argv, int argc, lo_message msg, void *user_data )
|
|
|
|
|
|
|
|
|
|
{
|
|
|
|
|
Endpoint *ep = (Endpoint*)user_data;
|
|
|
|
|
|
2012-02-25 05:23:45 +01:00
|
|
|
|
if ( argc && !strcmp( &argv[0]->s, "/signal/list" ) )
|
2012-02-21 09:48:13 +01:00
|
|
|
|
{
|
|
|
|
|
Peer *p = ep->find_peer_by_address( lo_message_get_source( msg ) );
|
|
|
|
|
|
|
|
|
|
if ( ! p )
|
|
|
|
|
{
|
|
|
|
|
WARNING( "Got input list reply from unknown peer." );
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if ( argc == 1 )
|
|
|
|
|
{
|
|
|
|
|
p->_scanning = false;
|
|
|
|
|
DMESSAGE( "Done scanning %s", p->name );
|
2012-02-26 03:01:46 +01:00
|
|
|
|
|
2012-04-27 09:17:00 +02:00
|
|
|
|
if ( ep->_peer_scan_complete_callback )
|
|
|
|
|
ep->_peer_scan_complete_callback(ep->_peer_scan_complete_userdata);
|
2010-01-21 01:33:02 +01:00
|
|
|
|
}
|
2013-06-06 01:26:36 +02:00
|
|
|
|
else if ( argc == 6 && p->_scanning )
|
2012-02-21 09:48:13 +01:00
|
|
|
|
{
|
2013-06-06 01:26:36 +02:00
|
|
|
|
Signal *s = ep->find_peer_signal_by_path( p, &argv[1]->s );
|
|
|
|
|
|
|
|
|
|
if ( s )
|
|
|
|
|
return 0;
|
|
|
|
|
|
2012-02-26 03:01:46 +01:00
|
|
|
|
DMESSAGE( "Peer %s has signal %s (%s)", p->name, &argv[1]->s, &argv[2]->s );
|
2012-02-21 09:48:13 +01:00
|
|
|
|
|
2012-02-25 05:23:45 +01:00
|
|
|
|
int dir = 0;
|
|
|
|
|
|
|
|
|
|
if ( !strcmp( &argv[2]->s, "in" ) )
|
|
|
|
|
dir = Signal::Input;
|
|
|
|
|
else if ( !strcmp( &argv[2]->s, "out" ) )
|
|
|
|
|
dir = Signal::Output;
|
|
|
|
|
|
2013-04-09 05:56:33 +02:00
|
|
|
|
|
|
|
|
|
s = new Signal( &argv[1]->s, (Signal::Direction)dir );
|
2012-02-21 09:48:13 +01:00
|
|
|
|
|
2012-02-25 05:23:45 +01:00
|
|
|
|
s->_peer = p;
|
2013-06-06 01:26:36 +02:00
|
|
|
|
|
|
|
|
|
s->parameter_limits( argv[3]->f, argv[4]->f, argv[5]->f );
|
2012-02-21 09:48:13 +01:00
|
|
|
|
|
|
|
|
|
p->_signals.push_back( s );
|
2013-06-06 01:26:36 +02:00
|
|
|
|
|
|
|
|
|
// ep->_signals.push_back(s);
|
2013-04-09 05:56:33 +02:00
|
|
|
|
|
|
|
|
|
if ( ep->_peer_signal_notification_callback )
|
|
|
|
|
ep->_peer_signal_notification_callback( s, Signal::Created, ep->_peer_signal_notification_userdata );
|
2012-02-21 09:48:13 +01:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return 0;
|
2010-01-21 01:33:02 +01:00
|
|
|
|
}
|
2012-02-21 09:48:13 +01:00
|
|
|
|
else
|
|
|
|
|
return -1;
|
2010-01-21 01:33:02 +01:00
|
|
|
|
}
|
|
|
|
|
|
2012-02-21 09:48:13 +01:00
|
|
|
|
Method *
|
2012-02-09 00:39:03 +01:00
|
|
|
|
Endpoint::add_method ( const char *path, const char *typespec, lo_method_handler handler, void *user_data, const char *argument_description )
|
2010-01-21 01:33:02 +01:00
|
|
|
|
{
|
2010-01-21 01:33:02 +01:00
|
|
|
|
// DMESSAGE( "Added OSC method %s (%s)", path, typespec );
|
2012-02-08 04:44:40 +01:00
|
|
|
|
|
2010-01-21 01:33:02 +01:00
|
|
|
|
lo_server_add_method( _server, path, typespec, handler, user_data );
|
2012-02-09 00:39:03 +01:00
|
|
|
|
|
2012-02-21 09:48:13 +01:00
|
|
|
|
Method *md = new Method;
|
2012-02-10 09:28:37 +01:00
|
|
|
|
|
2010-01-21 01:33:02 +01:00
|
|
|
|
if ( path )
|
2012-02-21 09:48:13 +01:00
|
|
|
|
md->_path = strdup( path );
|
2010-01-21 01:33:02 +01:00
|
|
|
|
if ( typespec )
|
2012-02-21 09:48:13 +01:00
|
|
|
|
md->_typespec = strdup( typespec );
|
2010-01-21 01:33:02 +01:00
|
|
|
|
if ( argument_description )
|
2012-02-21 09:48:13 +01:00
|
|
|
|
md->_documentation = strdup( argument_description );
|
2012-02-10 09:28:37 +01:00
|
|
|
|
|
2010-01-21 01:33:02 +01:00
|
|
|
|
_methods.push_back( md );
|
|
|
|
|
|
|
|
|
|
return md;
|
2012-02-21 09:48:13 +01:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
Signal *
|
2012-02-27 03:47:07 +01:00
|
|
|
|
Endpoint::add_signal ( const char *path, Signal::Direction dir, float min, float max, float default_value, signal_handler handler, void *user_data )
|
2012-02-21 09:48:13 +01:00
|
|
|
|
{
|
2012-02-26 03:01:46 +01:00
|
|
|
|
Signal *o = new Signal( path, dir );
|
2010-01-21 01:33:02 +01:00
|
|
|
|
|
2013-06-06 01:26:36 +02:00
|
|
|
|
char *s;
|
|
|
|
|
asprintf( &s, "%s%s", name(), path );
|
|
|
|
|
|
|
|
|
|
if ( s )
|
|
|
|
|
o->_path = s;
|
2012-02-21 09:48:13 +01:00
|
|
|
|
|
2012-02-26 03:01:46 +01:00
|
|
|
|
o->_handler = handler;
|
|
|
|
|
o->_user_data = user_data;
|
|
|
|
|
o->_endpoint = this;
|
2013-06-06 01:26:36 +02:00
|
|
|
|
|
|
|
|
|
o->parameter_limits( min, max, default_value );
|
2012-02-21 09:48:13 +01:00
|
|
|
|
|
2012-02-26 03:01:46 +01:00
|
|
|
|
_signals.push_back( o );
|
2012-02-21 09:48:13 +01:00
|
|
|
|
|
2013-06-06 01:26:36 +02:00
|
|
|
|
/* if ( dir == Signal::Input ) */
|
|
|
|
|
/* { */
|
|
|
|
|
lo_server_add_method( _server, o->_path, NULL, osc_sig_handler, o );
|
|
|
|
|
/* } */
|
2012-02-27 03:47:07 +01:00
|
|
|
|
|
2012-02-26 03:01:46 +01:00
|
|
|
|
/* tell our peers about it */
|
|
|
|
|
for ( std::list<Peer*>::iterator i = _peers.begin();
|
|
|
|
|
i != _peers.end();
|
|
|
|
|
++i )
|
|
|
|
|
{
|
|
|
|
|
send( (*i)->addr,
|
2013-04-09 05:56:33 +02:00
|
|
|
|
"/signal/created",
|
2012-02-26 03:01:46 +01:00
|
|
|
|
o->path(),
|
|
|
|
|
o->_direction == Signal::Input ? "in" : "out",
|
2012-02-27 03:47:07 +01:00
|
|
|
|
min,
|
|
|
|
|
max,
|
|
|
|
|
default_value
|
2012-02-26 03:01:46 +01:00
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return o;
|
2010-01-21 01:33:02 +01:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
|
Endpoint::del_method ( const char *path, const char *typespec )
|
|
|
|
|
{
|
2010-01-21 01:33:02 +01:00
|
|
|
|
// DMESSAGE( "Deleted OSC method %s (%s)", path, typespec );
|
2012-02-08 04:44:40 +01:00
|
|
|
|
|
2010-01-21 01:33:02 +01:00
|
|
|
|
lo_server_del_method( _server, path, typespec );
|
2012-02-09 00:39:03 +01:00
|
|
|
|
|
2012-02-21 09:48:13 +01:00
|
|
|
|
for ( std::list<Method *>::iterator i = _methods.begin(); i != _methods.end(); ++i )
|
2012-02-09 00:39:03 +01:00
|
|
|
|
{
|
2012-02-21 09:48:13 +01:00
|
|
|
|
if ( ! (*i)->path() )
|
2012-02-09 00:39:03 +01:00
|
|
|
|
continue;
|
|
|
|
|
|
2012-02-21 09:48:13 +01:00
|
|
|
|
if ( ! strcmp( path, (*i)->path() ) &&
|
|
|
|
|
! strcmp( typespec, (*i)->typespec() ) )
|
2012-02-09 00:39:03 +01:00
|
|
|
|
{
|
2010-01-21 01:33:02 +01:00
|
|
|
|
delete *i;
|
|
|
|
|
i = _methods.erase( i );
|
|
|
|
|
|
|
|
|
|
break;
|
2012-02-09 00:39:03 +01:00
|
|
|
|
}
|
|
|
|
|
}
|
2010-01-21 01:33:02 +01:00
|
|
|
|
}
|
|
|
|
|
|
2010-01-21 01:33:02 +01:00
|
|
|
|
void
|
2012-02-21 09:48:13 +01:00
|
|
|
|
Endpoint::del_method ( Method *meth )
|
2010-01-21 01:33:02 +01:00
|
|
|
|
{
|
|
|
|
|
// DMESSAGE( "Deleted OSC method %s (%s)", path, typespec );
|
|
|
|
|
|
2012-02-21 09:48:13 +01:00
|
|
|
|
lo_server_del_method( _server, meth->path(), meth->typespec() );
|
2010-01-21 01:33:02 +01:00
|
|
|
|
|
|
|
|
|
delete meth;
|
2010-01-21 01:33:02 +01:00
|
|
|
|
|
2010-01-21 01:33:02 +01:00
|
|
|
|
_methods.remove( meth );
|
2012-02-21 09:48:13 +01:00
|
|
|
|
}
|
2010-01-21 01:33:02 +01:00
|
|
|
|
|
2012-02-21 09:48:13 +01:00
|
|
|
|
void
|
|
|
|
|
Endpoint::del_signal ( Signal *o )
|
|
|
|
|
{
|
|
|
|
|
// DMESSAGE( "Deleted OSC method %s (%s)", path, typespec );
|
2010-01-21 01:33:02 +01:00
|
|
|
|
|
2012-02-21 09:48:13 +01:00
|
|
|
|
lo_server_del_method( _server, o->path(), "f" );
|
2010-01-21 01:33:02 +01:00
|
|
|
|
|
2012-02-26 03:01:46 +01:00
|
|
|
|
/* tell our peers about it */
|
|
|
|
|
for ( std::list<Peer*>::iterator i = _peers.begin();
|
|
|
|
|
i != _peers.end();
|
|
|
|
|
++i )
|
|
|
|
|
{
|
|
|
|
|
send( (*i)->addr,
|
|
|
|
|
"/signal/removed",
|
2013-06-06 01:26:36 +02:00
|
|
|
|
o->path() );
|
2012-02-26 03:01:46 +01:00
|
|
|
|
}
|
|
|
|
|
|
2013-04-09 05:56:33 +02:00
|
|
|
|
Endpoint *ep = this;
|
|
|
|
|
|
2013-06-06 01:26:36 +02:00
|
|
|
|
/* /\* disconnect it *\/ */
|
|
|
|
|
/* if ( o->_outgoing.size() ) */
|
|
|
|
|
/* { */
|
|
|
|
|
/* for ( std::list<Signal*>::iterator i = o->_outgoing.begin(); */
|
|
|
|
|
/* i != o->_outgoing.end(); */
|
|
|
|
|
/* ) */
|
|
|
|
|
/* { */
|
|
|
|
|
/* Signal *s = *i; */
|
|
|
|
|
/* /\* avoid messing up iterator *\/ */
|
|
|
|
|
/* ++i; */
|
|
|
|
|
|
|
|
|
|
/* ep->disconnect_signal( o, s ); */
|
|
|
|
|
/* } */
|
|
|
|
|
/* } */
|
2013-04-09 05:56:33 +02:00
|
|
|
|
|
2013-06-06 01:26:36 +02:00
|
|
|
|
/* if ( o->_incoming.size() ) */
|
|
|
|
|
/* { */
|
|
|
|
|
/* for ( std::list<Signal*>::iterator i = o->_incoming.begin(); */
|
|
|
|
|
/* i != o->_incoming.end(); */
|
|
|
|
|
/* ) */
|
|
|
|
|
/* { */
|
|
|
|
|
/* Signal *s = *i; */
|
|
|
|
|
/* /\* avoid messing up iterator *\/ */
|
|
|
|
|
/* ++i; */
|
2013-04-09 05:56:33 +02:00
|
|
|
|
|
2013-06-06 01:26:36 +02:00
|
|
|
|
/* ep->disconnect_signal( s, o ); */
|
|
|
|
|
/* } */
|
|
|
|
|
/* } */
|
2013-04-09 05:56:33 +02:00
|
|
|
|
|
2012-02-26 03:01:46 +01:00
|
|
|
|
/* FIXME: clear loopback connections first! */
|
2010-01-21 01:33:02 +01:00
|
|
|
|
|
2012-02-21 09:48:13 +01:00
|
|
|
|
_signals.remove( o );
|
2010-01-21 01:33:02 +01:00
|
|
|
|
}
|
|
|
|
|
|
2013-06-06 00:58:52 +02:00
|
|
|
|
/* prepare to learn a translation for /path/. The next unhandled message to come through will be mapped to /path/ */
|
|
|
|
|
void
|
|
|
|
|
Endpoint::learn ( const char *path )
|
|
|
|
|
{
|
|
|
|
|
if ( _learning_path )
|
|
|
|
|
free( _learning_path );
|
|
|
|
|
|
|
|
|
|
_learning_path = NULL;
|
|
|
|
|
|
|
|
|
|
if ( path )
|
|
|
|
|
_learning_path = strdup( path );
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/** if there's a translation with a destination of 'path', then send feedback for it */
|
|
|
|
|
void
|
|
|
|
|
Endpoint::send_feedback ( const char *path, float v )
|
|
|
|
|
{
|
|
|
|
|
for ( std::map<std::string,TranslationDestination>::iterator i = _translations.begin();
|
|
|
|
|
i != _translations.end();
|
|
|
|
|
i++ )
|
|
|
|
|
{
|
|
|
|
|
if ( ! strcmp( i->second.path.c_str(), path ) )
|
|
|
|
|
{
|
|
|
|
|
/* found it */
|
2013-06-06 01:26:36 +02:00
|
|
|
|
if ( !i->second.suppress_feedback && i->second.current_value != v )
|
2013-06-06 00:58:52 +02:00
|
|
|
|
{
|
|
|
|
|
const char *spath = i->first.c_str();
|
|
|
|
|
|
2013-06-06 01:26:36 +02:00
|
|
|
|
// DMESSAGE( "Sending feedback to \"%s\": %f", spath, v );
|
2013-06-06 00:58:52 +02:00
|
|
|
|
|
|
|
|
|
/* send to all peers */
|
|
|
|
|
for ( std::list<Peer*>::iterator p = _peers.begin();
|
|
|
|
|
p != _peers.end();
|
|
|
|
|
++p )
|
|
|
|
|
{
|
|
|
|
|
send( (*p)->addr, spath, v );
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
i->second.current_value = v;
|
|
|
|
|
}
|
|
|
|
|
|
2013-06-06 01:26:36 +02:00
|
|
|
|
i->second.suppress_feedback = false;
|
|
|
|
|
|
|
|
|
|
/* break; */
|
|
|
|
|
|
2013-06-06 00:58:52 +02:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2013-04-09 05:56:33 +02:00
|
|
|
|
Peer *
|
|
|
|
|
Endpoint::add_peer ( const char *name, const char *url )
|
2012-02-21 09:48:13 +01:00
|
|
|
|
{
|
|
|
|
|
Peer *p = new Peer;
|
|
|
|
|
|
2013-04-09 05:56:33 +02:00
|
|
|
|
DMESSAGE( "Adding peer %s @ %s...", name, url );
|
2012-02-25 05:23:45 +01:00
|
|
|
|
|
2012-02-21 09:48:13 +01:00
|
|
|
|
p->name = strdup( name );
|
|
|
|
|
p->addr = lo_address_new_from_url( url );
|
2013-04-09 05:56:33 +02:00
|
|
|
|
|
|
|
|
|
_peers.push_back( p );
|
|
|
|
|
|
|
|
|
|
return p;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
|
Endpoint::scan_peer ( const char *name, const char *url )
|
|
|
|
|
{
|
|
|
|
|
Peer *p = add_peer(name,url);
|
|
|
|
|
|
2012-02-21 09:48:13 +01:00
|
|
|
|
p->_scanning = true;
|
|
|
|
|
|
2013-04-09 05:56:33 +02:00
|
|
|
|
DMESSAGE( "Scanning peer %s", name );
|
2010-01-21 01:33:02 +01:00
|
|
|
|
|
2012-02-25 05:23:45 +01:00
|
|
|
|
send( p->addr, "/signal/list" );
|
2012-02-21 09:48:13 +01:00
|
|
|
|
}
|
2010-01-21 01:33:02 +01:00
|
|
|
|
|
|
|
|
|
void *
|
|
|
|
|
Endpoint::osc_thread ( void * arg )
|
|
|
|
|
{
|
|
|
|
|
((Endpoint*)arg)->osc_thread();
|
|
|
|
|
|
|
|
|
|
return NULL;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
|
Endpoint::osc_thread ( void )
|
|
|
|
|
{
|
|
|
|
|
_thread.name( "OSC" );
|
|
|
|
|
|
|
|
|
|
DMESSAGE( "OSC Thread running" );
|
|
|
|
|
|
|
|
|
|
run();
|
|
|
|
|
}
|
2010-01-21 01:33:02 +01:00
|
|
|
|
|
|
|
|
|
void
|
|
|
|
|
Endpoint::start ( void )
|
|
|
|
|
{
|
|
|
|
|
|
2010-01-21 01:33:02 +01:00
|
|
|
|
if ( !_thread.clone( &Endpoint::osc_thread, this ) )
|
|
|
|
|
FATAL( "Could not create OSC thread" );
|
2010-01-21 01:33:02 +01:00
|
|
|
|
|
|
|
|
|
/* lo_server_thread_start( _st ); */
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
|
Endpoint::stop ( void )
|
|
|
|
|
{
|
2010-01-21 01:33:02 +01:00
|
|
|
|
_thread.join();
|
2010-01-21 01:33:02 +01:00
|
|
|
|
// lo_server_thread_stop( _st );
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
int
|
|
|
|
|
Endpoint::port ( void ) const
|
|
|
|
|
{
|
|
|
|
|
return lo_server_get_port( _server );
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
char *
|
|
|
|
|
Endpoint::url ( void ) const
|
|
|
|
|
{
|
|
|
|
|
return lo_server_get_url( _server );
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/** Process any waiting events and return immediately */
|
|
|
|
|
void
|
|
|
|
|
Endpoint::check ( void ) const
|
|
|
|
|
{
|
|
|
|
|
wait( 0 );
|
|
|
|
|
}
|
|
|
|
|
|
2012-02-23 10:40:20 +01:00
|
|
|
|
/** Process any waiting events and return after timeout */
|
2010-01-21 01:33:02 +01:00
|
|
|
|
void
|
|
|
|
|
Endpoint::wait ( int timeout ) const
|
2012-02-21 09:48:13 +01:00
|
|
|
|
{
|
2012-02-23 10:40:20 +01:00
|
|
|
|
if ( lo_server_wait( _server, timeout ) )
|
|
|
|
|
while ( lo_server_recv_noblock( _server, 0 ) ) { }
|
2010-01-21 01:33:02 +01:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/** Process events forever */
|
|
|
|
|
void
|
|
|
|
|
Endpoint::run ( void ) const
|
|
|
|
|
{
|
|
|
|
|
for ( ;; )
|
|
|
|
|
{
|
|
|
|
|
lo_server_recv( _server );
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
int
|
|
|
|
|
Endpoint::send ( lo_address to, const char *path, std::list< OSC_Value > values )
|
|
|
|
|
{
|
|
|
|
|
|
|
|
|
|
lo_message m = lo_message_new();
|
|
|
|
|
|
|
|
|
|
for ( std::list< OSC_Value >::const_iterator i = values.begin();
|
|
|
|
|
i != values.end();
|
|
|
|
|
++i )
|
|
|
|
|
{
|
|
|
|
|
const OSC_Value *ov = &(*i);
|
|
|
|
|
|
|
|
|
|
switch ( ov->type() )
|
|
|
|
|
{
|
|
|
|
|
case 'f':
|
2013-04-09 05:56:33 +02:00
|
|
|
|
// DMESSAGE( "Adding float %f", ((OSC_Float*)ov)->value() );
|
2010-01-21 01:33:02 +01:00
|
|
|
|
lo_message_add_float( m, ((OSC_Float*)ov)->value() );
|
|
|
|
|
break;
|
|
|
|
|
case 'i':
|
2013-04-09 05:56:33 +02:00
|
|
|
|
// DMESSAGE( "Adding int %i", ((OSC_Int*)ov)->value() );
|
2010-01-21 01:33:02 +01:00
|
|
|
|
lo_message_add_int32( m, ((OSC_Int*)ov)->value() );
|
|
|
|
|
break;
|
|
|
|
|
case 's':
|
2013-04-09 05:56:33 +02:00
|
|
|
|
// DMESSAGE( "Adding string %s", ((OSC_String*)ov)->value() );
|
2010-01-21 01:33:02 +01:00
|
|
|
|
lo_message_add_string( m, ((OSC_String*)ov)->value() );
|
|
|
|
|
break;
|
|
|
|
|
default:
|
|
|
|
|
FATAL( "Unknown format: %c", ov->type() );
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2013-04-09 05:56:33 +02:00
|
|
|
|
// DMESSAGE( "Path: %s", path );
|
2010-01-21 01:33:02 +01:00
|
|
|
|
|
|
|
|
|
lo_bundle b = lo_bundle_new( LO_TT_IMMEDIATE );
|
|
|
|
|
|
|
|
|
|
lo_bundle_add_message(b, path, m );
|
|
|
|
|
|
|
|
|
|
int r = lo_send_bundle_from( to, _server, b );
|
|
|
|
|
|
|
|
|
|
// int r = lo_send_message_from( to, _server, path, m );
|
|
|
|
|
|
|
|
|
|
// lo_message_free( m );
|
|
|
|
|
|
|
|
|
|
return r;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
int
|
|
|
|
|
Endpoint::send ( lo_address to, const char *path )
|
|
|
|
|
{
|
|
|
|
|
return lo_send_from( to, _server, LO_TT_IMMEDIATE, path, "" );
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
int
|
|
|
|
|
Endpoint::send ( lo_address to, const char *path, int v )
|
|
|
|
|
{
|
|
|
|
|
return lo_send_from( to, _server, LO_TT_IMMEDIATE, path, "i", v );
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
int
|
|
|
|
|
Endpoint::send ( lo_address to, const char *path, float v )
|
|
|
|
|
{
|
|
|
|
|
return lo_send_from( to, _server, LO_TT_IMMEDIATE, path, "f", v );
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
int
|
|
|
|
|
Endpoint::send ( lo_address to, const char *path, double v )
|
|
|
|
|
{
|
|
|
|
|
return lo_send_from( to, _server, LO_TT_IMMEDIATE, path, "d", v );
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
int
|
|
|
|
|
Endpoint::send ( lo_address to, const char *path, const char * v )
|
|
|
|
|
{
|
|
|
|
|
return lo_send_from( to, _server, LO_TT_IMMEDIATE, path, "s", v );
|
|
|
|
|
}
|
|
|
|
|
|
2010-01-21 01:33:02 +01:00
|
|
|
|
int
|
|
|
|
|
Endpoint::send ( lo_address to, const char *path, const char * v1, float v2 )
|
|
|
|
|
{
|
|
|
|
|
return lo_send_from( to, _server, LO_TT_IMMEDIATE, path, "sf", v1, v2 );
|
|
|
|
|
}
|
|
|
|
|
|
2010-01-21 01:33:02 +01:00
|
|
|
|
int
|
|
|
|
|
Endpoint::send ( lo_address to, const char *path, const char * v1, const char *v2 )
|
|
|
|
|
{
|
|
|
|
|
return lo_send_from( to, _server, LO_TT_IMMEDIATE, path, "ss", v1, v2 );
|
|
|
|
|
}
|
|
|
|
|
|
2010-01-21 01:33:02 +01:00
|
|
|
|
int
|
|
|
|
|
Endpoint::send ( lo_address to, const char *path, const char * v1, const char *v2, const char *v3 )
|
|
|
|
|
{
|
|
|
|
|
return lo_send_from( to, _server, LO_TT_IMMEDIATE, path, "sss", v1, v2, v3 );
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
int
|
|
|
|
|
Endpoint::send ( lo_address to, const char *path, const char *v1, int v2, int v3, int v4 )
|
|
|
|
|
{
|
|
|
|
|
return lo_send_from( to, _server, LO_TT_IMMEDIATE, path, "siii", v1, v2, v3, v4 );
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
int
|
|
|
|
|
Endpoint::send ( lo_address to, const char *path, const char *v1, const char *v2, int v3, int v4, int v5 )
|
2012-02-21 09:48:13 +01:00
|
|
|
|
{
|
2010-01-21 01:33:02 +01:00
|
|
|
|
return lo_send_from( to, _server, LO_TT_IMMEDIATE, path, "ssiii", v1, v2, v3, v4, v5 );
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
int
|
|
|
|
|
Endpoint::send ( lo_address to, const char *path, const char *v1, const char *v2, const char *v3, int v4, int v5, int v6 )
|
|
|
|
|
{
|
|
|
|
|
return lo_send_from( to, _server, LO_TT_IMMEDIATE, path, "sssiii", v1, v2, v3, v4, v5, v6 );
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
int
|
|
|
|
|
Endpoint::send ( lo_address to, const char *path, const char *v1, int v2 )
|
|
|
|
|
{
|
|
|
|
|
return lo_send_from( to, _server, LO_TT_IMMEDIATE, path, "si", v1, v2 );
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
int
|
|
|
|
|
Endpoint::send ( lo_address to, const char *path, int v1, const char *v2 )
|
|
|
|
|
{
|
|
|
|
|
return lo_send_from( to, _server, LO_TT_IMMEDIATE, path, "is", v1, v2 );
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
int
|
|
|
|
|
Endpoint::send ( lo_address to, const char *path, const char *v1, int v2, const char *v3 )
|
|
|
|
|
{
|
|
|
|
|
return lo_send_from( to, _server, LO_TT_IMMEDIATE, path, "sis", v1, v2, v3 );
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
int
|
|
|
|
|
Endpoint::send ( lo_address to, const char *path, int v1, const char *v2, const char *v3, const char *v4 )
|
|
|
|
|
{
|
|
|
|
|
return lo_send_from( to, _server, LO_TT_IMMEDIATE, path, "isss", v1, v2, v3, v4 );
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
int
|
|
|
|
|
Endpoint::send ( lo_address to, const char *path, const char *v1, int v2, const char *v3, const char *v4, const char *v5 )
|
|
|
|
|
{
|
|
|
|
|
return lo_send_from( to, _server, LO_TT_IMMEDIATE, path, "sisss", v1, v2, v3, v4, v5 );
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
int
|
|
|
|
|
Endpoint::send ( lo_address to, const char *path, const char *v1, const char *v2, const char *v3, const char *v4, const char *v5 )
|
|
|
|
|
{
|
|
|
|
|
return lo_send_from( to, _server, LO_TT_IMMEDIATE, path, "sssss", v1, v2, v3, v4, v5 );
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
int
|
|
|
|
|
Endpoint::send ( lo_address to, const char *path, const char *v1, const char *v2, const char *v3, const char *v4 )
|
|
|
|
|
{
|
|
|
|
|
return lo_send_from( to, _server, LO_TT_IMMEDIATE, path, "ssss", v1, v2, v3, v4 );
|
|
|
|
|
}
|
|
|
|
|
|
2012-02-23 09:40:54 +01:00
|
|
|
|
int
|
|
|
|
|
Endpoint::send ( lo_address to, const char *path, lo_message msg )
|
|
|
|
|
{
|
|
|
|
|
return lo_send_message_from( to, _server, path, msg );
|
|
|
|
|
}
|
|
|
|
|
|
2012-02-21 09:48:13 +01:00
|
|
|
|
int
|
|
|
|
|
Endpoint::send ( lo_address to, const char *path, const char *v1, const char *v2, int v3, float v4, float v5, float v6 )
|
|
|
|
|
{
|
|
|
|
|
return lo_send_from( to, _server, LO_TT_IMMEDIATE, path, "ssifff", v1, v2, v3, v4, v5, v6 );
|
|
|
|
|
}
|
|
|
|
|
|
2012-02-25 05:23:45 +01:00
|
|
|
|
int
|
|
|
|
|
Endpoint::send ( lo_address to, const char *path, const char *v1, const char *v2, const char *v3, int v4, float v5, float v6, float v7 )
|
|
|
|
|
{
|
2012-02-26 03:01:46 +01:00
|
|
|
|
return lo_send_from( to, _server, LO_TT_IMMEDIATE, path, "sssifff", v1, v2, v3, v4, v5, v6, v7 );
|
2012-02-25 05:23:45 +01:00
|
|
|
|
}
|
2013-06-06 01:26:36 +02:00
|
|
|
|
|
|
|
|
|
int
|
|
|
|
|
Endpoint::send ( lo_address to, const char *path, const char *v1, const char *v2, const char *v3, float v4, float v5, float v6 )
|
|
|
|
|
{
|
|
|
|
|
return lo_send_from( to, _server, LO_TT_IMMEDIATE, path, "sssfff", v1, v2, v3, v4, v5, v6 );
|
|
|
|
|
}
|
2012-02-25 05:23:45 +01:00
|
|
|
|
|
2012-02-21 09:48:13 +01:00
|
|
|
|
int
|
|
|
|
|
Endpoint::send ( lo_address to, const char *path, const char *v1, int v2, int v3 )
|
|
|
|
|
{
|
|
|
|
|
return lo_send_from( to, _server, LO_TT_IMMEDIATE, path, "sii", v1, v2, v3 );
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
int
|
|
|
|
|
Endpoint::send ( lo_address to, const char *path, int v1, int v2 )
|
|
|
|
|
{
|
|
|
|
|
return lo_send_from( to, _server, LO_TT_IMMEDIATE, path, "ii", v1, v2 );
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
int
|
|
|
|
|
Endpoint::send ( lo_address to, const char *path, int v1, float v2 )
|
|
|
|
|
{
|
|
|
|
|
return lo_send_from( to, _server, LO_TT_IMMEDIATE, path, "if", v1, v2 );
|
|
|
|
|
}
|
2012-02-26 03:01:46 +01:00
|
|
|
|
|
|
|
|
|
int
|
|
|
|
|
Endpoint::send ( lo_address to, const char *path, const char *v1, int v2, int v3, float v4 )
|
|
|
|
|
{
|
|
|
|
|
return lo_send_from( to, _server, LO_TT_IMMEDIATE, path, "siif", v1, v2, v3, v4 );
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
int
|
|
|
|
|
Endpoint::send ( lo_address to, const char *path, int v1, int v2, float v3 )
|
|
|
|
|
{
|
|
|
|
|
return lo_send_from( to, _server, LO_TT_IMMEDIATE, path, "iif", v1, v2, v3 );
|
|
|
|
|
}
|
2010-01-21 01:33:02 +01:00
|
|
|
|
}
|