From 77497320bfa715b5d7976a8a632c7c957677c6ab Mon Sep 17 00:00:00 2001 From: fcolin Date: Thu, 1 Feb 2007 12:55:38 +0000 Subject: Utilisateur : Fcolin Date : 16/06/00 Heure : 10:14 Créé (vss 1) --- Bus/Ivy/Ivy.cxx | 304 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 304 insertions(+) create mode 100644 Bus/Ivy/Ivy.cxx (limited to 'Bus/Ivy/Ivy.cxx') diff --git a/Bus/Ivy/Ivy.cxx b/Bus/Ivy/Ivy.cxx new file mode 100644 index 0000000..e3c6bc6 --- /dev/null +++ b/Bus/Ivy/Ivy.cxx @@ -0,0 +1,304 @@ +// Ivy.cpp: implementation of the Ivy class. +// +////////////////////////////////////////////////////////////////////// + +#include "stdafx.h" +//#include "libIvy.h" +#include "Ivy.h" + +#include "IvyWatcher.h" +#include "IvyApplication.h" +#include "IvySynchroWnd.h" + + +#define DEFAULT_ADDR "127.255.255.255" +#define SEPARATOR ":" +#define DEFAULT_PORT "2010" +#define DEFAULT_DOMAIN DEFAULT_ADDR/**/SEPARATOR/**/DEFAULT_PORT + + +////////////////////////////////////////////////////////////////////// +// Construction/Destruction +////////////////////////////////////////////////////////////////////// + + +Ivy::~Ivy() +{ + // remove all app and stop watcher + stop(); + regexp_out.clear(); + + for ( int i = 0; i < callbacks.size(); i ++) + { + delete callbacks[i]; + } + callbacks.clear(); + +// if ( direct_callback ) delete direct_callback; +// if ( application_callback ) delete application_callback; + + delete watcher; + server->Close(); + delete server; + if ( synchronous ) + { + delete IvySynchronousCallback::m_synchro; + delete application_callback; + } +} + + +Ivy::Ivy(const char* name, const char * ready, IvyApplicationCallback *callback, bool Synchronous) +{ + InitializeCriticalSection( &m_application_cs ); + + synchronous = Synchronous; + if ( synchronous ) + IvySynchronousCallback::m_synchro = new IvySynchroWnd(); + ready_message = ready; + appname = name; + messages_classes_count = 0; + messages_classes = NULL; + application_callback = synchronous ? new IvySynchronousApplicationCallback(callback) : callback; + direct_callback = NULL; + die_callback = NULL; + server = new IvyApplication(this); + applicationPort = server->Create(); + if ( !applicationPort ) + { + TRACE( " Can't Create server %d\n", server->GetLastError( ) ); + return; + } + watcher = new IvyWatcher(this); + + +} +const char * Ivy::GetDomain(const char *domainlist) +{ + // determine domain to use + // the syntax of domain is "IpBroadcastAddr1,IpBroadcastAddr2,IpBroadcastAddr2:port" + if ( domainlist ) + { + domain = domainlist; + } + if ( domain.empty() ) + { + domain = getenv ( "IVYBUS" ); + if ( domain.empty() ) + domain = DEFAULT_DOMAIN; + } + // first find our UDP port + int sep_index = domain.rfind( ':' ); + if ( sep_index == -1 ) + { + domain = DEFAULT_DOMAIN; + TRACE(" Missing ':' in domain list using default domain %s\n", domain.c_str() ); + } + if ( sep_index == 0 ) + { + /* missing addr using localhost */ + domain.insert(0,DEFAULT_ADDR); + } + return domain.c_str(); +} + +void Ivy::start(const char *domain) +{ + watcher->start(domain); +} +void Ivy::stop() +{ + watcher->stop(); + + for ( int pos = 0 ; pos < applications.size() ; pos++ ) + { + IvyApplication *app = applications[pos]; + delete app; + } + applications.clear(); +} +int Ivy::BindMsg(const char *regexp, IvyMessageCallback *cb) +{ + static int id = 0; + regexp_out.push_back( regexp ); + callbacks.push_back( synchronous ? new IvySynchronousMessageCallback(cb) : cb ); + + /* send to already connected */ + for ( int pos = 0 ; pos < applications.size() ; pos ++ ) + { + IvyApplication *app = applications[ pos ]; + app->SendMsg(IvyApplication::AddRegexp, id, regexp ); + } + return id++; +} + +void Ivy::UnbindMsg(int id) +{ + regexp_out[ id ] = ""; + callbacks[ id ] = NULL; + /* send to already connected */ + for ( int pos = 0 ; pos < applications.size(); pos ++ ) + { + IvyApplication *app = applications[ pos ]; + app->SendMsg(IvyApplication::DelRegexp, id, "" ); + } + +} + +void Ivy::BindDirectMsg(IvyDirectMessageCallback *callback) +{ +direct_callback = callback; +} + +UINT Ivy::GetApplicationPort() +{ + return applicationPort; +} + +void Ivy::AddApplication(IvyApplication *app) +{ + EnterCriticalSection( &m_application_cs ); + // Check for disconnected Application + for ( int pos = 0; pos < applications.size(); pos ++ ) + { + IvyApplication *disc_app = applications[ pos ]; + if ( disc_app->m_hSocket == INVALID_SOCKET ) + { + //applications.erase( pos ); + delete disc_app; + } + } + applications.push_back( app ); + LeaveCriticalSection( &m_application_cs ); + SendSubscriptions( app ); +} +void Ivy::RemoveApplication(IvyApplication * app) +{ + /// OLD NOT called because of deallocation PB + // the real remove is done at arrival of a new Application + // or at the bus Stop + assert( TRUE ); + if ( app ) + { + for ( int pos = 0; pos < applications.size(); pos ++ ) + { + if ( app == applications[ pos ] ) + { + EnterCriticalSection( &m_application_cs ); + //applications.erase( pos ); + LeaveCriticalSection( &m_application_cs ); + delete app; + } + } + } +} + +void Ivy::SendSubscriptions(IvyApplication *app) +{ + app->SendMsg( IvyApplication::StartRegexp, GetApplicationPort(), appname.c_str()); + for ( int id = 0 ; id < regexp_out.size(); id++ ) + { + const string& regexp = regexp_out[id]; + if ( !regexp.empty() ) + app->SendMsg( IvyApplication::AddRegexp, id, regexp.c_str()); + } + app->SendMsg( IvyApplication::EndRegexp, 0); + +} + + +int Ivy::SendMsg(const char * message) +{ + int count = 0; + /* send to already connected */ + for ( int pos = 0 ; pos < applications.size(); pos ++ ) + { + IvyApplication *app = applications[ pos ]; + count += app->SendMsg( message ); + } + return count; +} + + +void Ivy::CallMessageCallback(IvyApplication *app, int id, int argc, const char ** argv) +{ + IvyMessageCallback *callback; + callback = callbacks[ id ]; + if ( callback ) + { + callback->OnMessage( app, argc, argv ); + } +} + +void Ivy::CallDirectMessageCallback(IvyApplication *app, int id, const char *arg) +{ + if ( direct_callback ) + { + direct_callback->OnDirectMessage( app, id, arg ); + } +} + +BOOL Ivy::CallDieCallback(IvyApplication *app, int id, const char *arg) +{ + if ( die_callback ) + { + return die_callback->OnDie( app, id, arg ); + } + return TRUE; +} + +void Ivy::CallApplicationConnectedCallback(IvyApplication * app) +{ + if ( application_callback ) + { + application_callback->OnApplicationConnected( app ); + } +} +void Ivy::CallApplicationDisconnectedCallback(IvyApplication * app) +{ + if ( application_callback ) + { + application_callback->OnApplicationDisconnected( app ); + } +} +void Ivy::SendDirectMsg(IvyApplication * app, int id, const char *message) +{ + app->SendMsg( IvyApplication::DirectMsg, id, message ); +} + +BOOL Ivy::CheckRegexp(const char * exp) +{ + /* accepte tout par default */ + int i; + int regexp_ok = 1; + if ( *exp =='^' && messages_classes_count !=0 ) + { + regexp_ok = 0; + for ( i = 0 ; i < messages_classes_count; i++ ) + { + if (strncmp( messages_classes[i], exp+1, strlen( messages_classes[i] )) == 0) + return 1; + } + } + return regexp_ok; +} + +void Ivy::Classes(int argc, const char **argv ) +{ + messages_classes_count = argc; + messages_classes = argv; +} + +BOOL Ivy::CheckConnected(IvyApplication * app) +{ + if (app->remoteService == 0) /* old application dont check */ + return false; + /* check to see if app already connected */ + for ( int pos = 0; pos < applications.size(); pos++ ) + { + IvyApplication *application = applications[ pos ]; + if ( application != app && application->SameApplication(app)) + return true; + } + return false; +} -- cgit v1.1