diff options
Diffstat (limited to 'Bus/Ivy/Ivy.cxx')
-rw-r--r-- | Bus/Ivy/Ivy.cxx | 304 |
1 files changed, 304 insertions, 0 deletions
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;
+}
|