diff options
Diffstat (limited to 'ivy.c')
-rw-r--r-- | ivy.c | 299 |
1 files changed, 299 insertions, 0 deletions
@@ -0,0 +1,299 @@ +/** + * Copyright (C) 2007 Gregoire Lejeune <gregoire.lejeune@free.fr> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Lesser 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; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include "rb_ivy.h" + +void ruby_ivy_free( RbTIvy *pRbTIvy ) { + if (pRbTIvy != NULL) + free(pRbTIvy); +} + +void ruby_ivy_mark( RbTIvy *pRbTIvy ) { + if( pRbTIvy == NULL ) return; + if( !NIL_P(pRbTIvy->strAgentName) ) rb_gc_mark( pRbTIvy->strAgentName ); + if( !NIL_P(pRbTIvy->strReadyMsg) ) rb_gc_mark( pRbTIvy->strReadyMsg ); +} + +VALUE ruby_ivy_new( VALUE class ) { + + RbTIvy *pRbTIvy; + + pRbTIvy = (RbTIvy *)malloc(sizeof(RbTIvy)); + if( pRbTIvy == NULL ) + rb_raise(rb_eNoMemError, "No memory left for IVY struct"); + + return( Data_Wrap_Struct( class, ruby_ivy_mark, ruby_ivy_free, pRbTIvy ) ); +} + +/** o = IVY.new( strAgentName, [strReadyMessage] ) */ +static VALUE ruby_ivy_initialize( int iNbArgs, VALUE *vArgs, VALUE class ) { + + RbTIvy *pRbTIvy; + Data_Get_Struct( class, RbTIvy, pRbTIvy ); + + if( iNbArgs < 1 || iNbArgs > 2 ) { + rb_raise( rb_eArgError, "wrong number of arguments (%d for 1)", iNbArgs ); + } + + pRbTIvy->strAgentName = vArgs[0]; + if( iNbArgs == 2 ) { + pRbTIvy->strReadyMsg = vArgs[1]; + } else { + pRbTIvy->strReadyMsg = Qnil; + } + + IvyInit( STR2CSTR( pRbTIvy->strAgentName ), NULL, NULL, NULL, NULL, NULL ); + + return( class ); +} + +/** ------------------------------------------------------------------------ */ + +void ruby_ivy_message_free( RbTIvyMsg *pRbTIvyMsg ) { + if (pRbTIvyMsg != NULL) + free(pRbTIvyMsg); +} + +void ruby_ivy_message_mark( RbTIvyMsg *pRbTIvyMsg ) { + if( pRbTIvyMsg == NULL ) return; + if( !NIL_P(pRbTIvyMsg->cb) ) rb_gc_mark( pRbTIvyMsg->cb ); + if( !NIL_P(pRbTIvyMsg->data) ) rb_gc_mark( pRbTIvyMsg->data ); + if( !NIL_P(pRbTIvyMsg->regexp) ) rb_gc_mark( pRbTIvyMsg->regexp ); +} + +/** o = IVY::Message.new() */ +// VALUE ruby_ivy_message_new( VALUE class, VALUE cb, VALUE data, VALUE regexp ) { +VALUE ruby_ivy_message_new( VALUE class, VALUE data, VALUE regexp ) { + RbTIvyMsg *pRbTIvyMsg; + + pRbTIvyMsg = (RbTIvyMsg *)malloc(sizeof(RbTIvyMsg)); + if( pRbTIvyMsg == NULL ) + rb_raise(rb_eNoMemError, "No memory left for IVY::MESSAGE struct"); + + pRbTIvyMsg->cb = rb_block_proc( ); + pRbTIvyMsg->data = data; + pRbTIvyMsg->regexp = regexp; + pRbTIvyMsg->id = IvyBindMsg( callback, (void*)pRbTIvyMsg, STR2CSTR( pRbTIvyMsg->regexp ) ); + + return( Data_Wrap_Struct( class, ruby_ivy_message_mark, ruby_ivy_message_free, pRbTIvyMsg ) ); +} + +/** ------------------------------------------------------------------------ */ + +void ruby_ivy_client_free( RbTIvyClient *pRbTIvyClient ) { + if (pRbTIvyClient != NULL) + free(pRbTIvyClient); +} + +void ruby_ivy_client_mark( RbTIvyClient *pRbTIvyClient ) { + if( pRbTIvyClient == NULL ) return; +} + +VALUE ruby_ivy_client_new_internal( VALUE class, IvyClientPtr client ) { + RbTIvyClient *pRbTIvyClient; + + pRbTIvyClient = (RbTIvyClient *)malloc(sizeof(RbTIvyClient)); + if( pRbTIvyClient == NULL ) + rb_raise(rb_eNoMemError, "No memory left for IVY::Client struct"); + + pRbTIvyClient->client = client; + + return( Data_Wrap_Struct( class, ruby_ivy_client_mark, ruby_ivy_client_free, pRbTIvyClient ) ); +} + +/** o = IVY::Client.new( xClientName ) */ +VALUE ruby_ivy_client_new( VALUE class, VALUE clientName ) { + RbTIvyClient *pRbTIvyClient; + + pRbTIvyClient = (RbTIvyClient *)malloc(sizeof(RbTIvyClient)); + if( pRbTIvyClient == NULL ) + rb_raise(rb_eNoMemError, "No memory left for IVY::Client struct"); + + pRbTIvyClient->client = IvyGetApplication( STR2CSTR( clientName ) ); + + return( Data_Wrap_Struct( class, ruby_ivy_client_mark, ruby_ivy_client_free, pRbTIvyClient ) ); +} + +/** ------------------------------------------------------------------------ */ + +VALUE ruby_ivy_appname( VALUE class ) { + RbTIvyClient *pRbTIvyClient; + char *xAppName = NULL; + + Data_Get_Struct( class, RbTIvyClient, pRbTIvyClient ); + + if( pRbTIvyClient->client != NULL ) + xAppName = IvyGetApplicationName( pRbTIvyClient->client ); + + return( rb_str_new2( xAppName ) ); +} + +VALUE ruby_ivy_apphost( VALUE class ) { + RbTIvyClient *pRbTIvyClient; + char *xAppHost = NULL; + + Data_Get_Struct( class, RbTIvyClient, pRbTIvyClient ); + + if( pRbTIvyClient->client != NULL ) + xAppHost = IvyGetApplicationHost( pRbTIvyClient->client ); + + return( rb_str_new2( xAppHost ) ); +} + +/** ------------------------------------------------------------------------ */ + +VALUE ruby_ivy_start( int iNbArgs, VALUE *vArgs, VALUE class ) { + RbTIvy *pRbTIvy; + const char *bus = NULL; + + Data_Get_Struct( class, RbTIvy, pRbTIvy ); + + if( iNbArgs == 0 ) { + bus = getenv( "IVYBUS" ); + } else if( iNbArgs == 1 ) { + bus = STR2CSTR( vArgs[0] ); + } else { + rb_raise( rb_eArgError, "wrong number of arguments (%d for 1)", iNbArgs ); + } + + IvyStart( bus ); + + return( Qnil ); +} + +VALUE ruby_ivy_mainloop( VALUE class ) { + RbTIvy *pRbTIvy; + Data_Get_Struct( class, RbTIvy, pRbTIvy ); + + IvyMainLoop( ); + + return( Qnil ); +} + +VALUE ruby_ivy_stop( VALUE class ) { + RbTIvy *pRbTIvy; + Data_Get_Struct( class, RbTIvy, pRbTIvy ); + + IvyStop( ); + + return( Qnil ); +} + +VALUE ruby_ivy_sendmsg( VALUE class, VALUE message ) { + RbTIvy *pRbTIvy; + Data_Get_Struct( class, RbTIvy, pRbTIvy ); + + IvySendMsg( STR2CSTR( message ) ); + + return( Qnil ); +} + +VALUE ruby_ivy_applist( VALUE class ) { + RbTIvy *pRbTIvy; + char *xAppList = NULL; + VALUE aryResult = rb_ary_new(); + + Data_Get_Struct( class, RbTIvy, pRbTIvy ); + + xAppList = IvyGetApplicationList( "|" ); + xAppList = strtok( xAppList, "|" ); + while( xAppList ) { + rb_ary_push( aryResult, rb_str_new2( xAppList ) ); + xAppList = strtok (NULL, " "); + } + return( aryResult ); +} + +/** ------------------------------------------------------------------------ */ + +// VALUE ruby_ivy_bindmsg( VALUE class, VALUE data, VALUE regexp ) { +VALUE ruby_ivy_bindmsg( VALUE class, VALUE data, VALUE regexp ) { + VALUE method; + RbTIvy *pRbTIvy; + + Data_Get_Struct( class, RbTIvy, pRbTIvy ); + + return( ruby_ivy_message_new( cIvyMsg, data, regexp ) ); +} + +VALUE ruby_ivy_unbindmsg( VALUE class ) { + RbTIvyMsg *pRbTIvyMsg; + Data_Get_Struct( class, RbTIvyMsg, pRbTIvyMsg ); + + if( pRbTIvyMsg->id != NULL ) { + IvyUnbindMsg( pRbTIvyMsg->id ); + pRbTIvyMsg->id = NULL; + } else { + rb_warn( "IVY::Message not binded!" ); + } + + return( Qnil ); +} + +/** ------------------------------------------------------------------------ */ + +static void callback( IvyClientPtr app, void *data, int argc, char **argv ) { + RbTIvyMsg *pRbTIvyMsg = (RbTIvyMsg *)data; + + int callID = rb_intern ("call"); + VALUE res; + + int i; + VALUE *aryArgs; + + aryArgs = (VALUE *)malloc( sizeof( VALUE ) ); + + aryArgs[0] = ruby_ivy_client_new_internal( cIvyClient, app ); // IvyClientPtr app + aryArgs[1] = pRbTIvyMsg->data; // void *data + aryArgs[2] = rb_ary_new(); + for( i = 0; i < argc; i++ ) { + rb_ary_push( aryArgs[2], rb_str_new2( argv[i] ) ); + } + + res = rb_funcall2( pRbTIvyMsg->cb, callID, 3, aryArgs ); +} + +/** ------------------------------------------------------------------------ */ + +void Init_ivy( void ) { + cIvy = rb_define_class( "IVY", rb_cObject ); + cIvyMsg = rb_define_class_under( cIvy, "Message", rb_cObject ); + cIvyClient = rb_define_class_under( cIvy, "Client", rb_cObject ); + + rb_define_const( cIvy, "RB_IVY_VERSION", rb_str_new2(RUBY_RBIVY_VERSION) ); + rb_define_const( cIvy, "IVY_VERSION", rb_str_new2(RUBY_IVY_VERSION) ); + + rb_define_alloc_func( cIvy, ruby_ivy_new ); + rb_define_private_method( cIvy, "initialize", ruby_ivy_initialize, -1); + + // IVY + rb_define_method( cIvy, "start", ruby_ivy_start, -1 ); + rb_define_method( cIvy, "mainloop", ruby_ivy_mainloop, 0 ); + rb_define_method( cIvy, "stop", ruby_ivy_stop, 0 ); + rb_define_method( cIvy, "sendmsg", ruby_ivy_sendmsg, 1 ); + rb_define_method( cIvy, "applicationList", ruby_ivy_applist, 0 ); + rb_define_method( cIvy, "bindmsg", ruby_ivy_bindmsg, 2 ); // renvoi un message de type IVY::MESSAGE + + // IVY::Message + rb_define_method( cIvyMsg, "unbindmsg", ruby_ivy_unbindmsg, 0 ); + + // IVY::Client + rb_define_singleton_method( cIvyClient, "new", ruby_ivy_client_new, 1 ); + rb_define_method( cIvyClient, "applicationName", ruby_ivy_appname, 0); + rb_define_method( cIvyClient, "applicationHost", ruby_ivy_apphost, 0); +} |