Lee,

"Lee McColl-Sylvester" <[EMAIL PROTECTED]> (on Mon, 5 Jun
2006 08:33:07 +0100):

  > Another question, in my port of GTK to neko, I need a way to respond
to
  > events in my C libs... Can this be done?  Calling and exposing
functions
  > is easy enough, but I can't fathom how setting up event callbacks
can be
  > achieved.

GObject provides something called "closures" and "marshallers" for that
exact purpose. I had some problems when they where called from another
thread, which might be unrelated. In principle, it works:


/* --------------------------------------------------
    GClosure/Neko marshaller
   -------------------------------------------------- */

typedef struct _NekoClosure  {
  GClosure closure;
  /* extra data goes here */
} NekoClosure;
    

void neko_marshal( GClosure *closure, GValue *g_result, guint nr_vals,
const GValue *g_vals, gpointer invocation_hint, gpointer marshal_data )
{
    int i;
    value f = (value)closure->data;
    value *n_vals = (value*)malloc( sizeof(value*)*nr_vals );
    value n_result = val_null;
    
    for( i=0; i<nr_vals; i++ ) {
        n_vals[i] = gvalue_to_neko( &g_vals[i] );
    }

    n_result = val_callEx( val_null, f, n_vals, nr_vals, NULL );
    
    free(n_vals);

    if( g_result != NULL ) {
        neko_to_gvalue( n_result, g_result );
    }
}

static void neko_closure_finalize( gpointer notify_data, GClosure
*closure ) {
  NekoClosure *neko_closure = (NekoClosure*)closure;

  /* free extra data here */
}

NekoClosure *neko_closure_new( gpointer data ) {
  GClosure *closure;
  NekoClosure *neko_closure;
  
  closure = g_closure_new_simple( sizeof(NekoClosure), data );
  neko_closure = (NekoClosure*)closure;

  /* initialize extra data here */

  g_closure_add_finalize_notifier( closure, notify_data,
neko_closure_finalize );
  g_closure_set_marshal( closure, (GClosureMarshal)neko_marshal );
  return neko_closure;
}

value object_connect( value obj, value v_signal_name, value data ) {
    GObject *o = val_gobject( obj );
    if( !o ) return val_null;
    
    const char *signal_name = haxe_string( v_signal_name );
    NekoClosure *closure = neko_closure_new( (gpointer)data );
    gulong id = g_signal_connect_closure( o, signal_name,
(GClosure*)closure, FALSE );
    
    return val_true;
}
DEFINE_PRIM(object_connect,3);


hth,
-dan

-- 
http://0xDF.com/
http://iterative.org/

-- 
Neko : One VM to run them all
(http://nekovm.org)

Reply via email to