Changeset 16

Show
Ignore:
Timestamp:
04/14/06 21:09:14 (3 years ago)
Author:
scottmc
Message:

Works precisely as desired

  • Bugs worked out of event loop
  • Arguments now rooted properly until the end of event execution
  • Objects live as long as they're supposed to
  • API Changes
    • .yield(object, "methodName", arguments ..)
    • This is fast!


Files:
1 modified

Legend:

Unmodified
Added
Removed
  • trunk/sagot/src/sagot_glib_eventloop.c

    r7 r16  
    7474 
    7575struct queue_item { 
    76     jsval *argv; 
     76    int *esid; 
     77    JSObject *args; 
    7778    uintN argc; 
    7879    JSContext *cx; 
    7980}; 
    8081 
     82/** 
     83 * Dispatch an event from glib to javascript 
     84 */ 
    8185gboolean sagot_eventloop_dispatch (void *data) { 
    8286    struct queue_item *qitem = (struct queue_item *) data; 
    8387    JSContext *cx = qitem->cx; 
    84     jsval *argv = qitem->argv; 
    85     jsval argc = qitem->argc; 
     88    uintN argc = qitem->argc; 
     89    JSObject *arglist = qitem->args; 
     90    jsval argv[qitem->argc]; 
    8691 
    87     JSObject *fobj = JSVAL_TO_OBJECT(argv[0]); 
    88     JSObject *parent = JS_GetParent(cx, fobj); 
     92    for (int i = 0; i < argc; i++) { 
     93        JS_GetElement(cx, arglist, i, &argv[i]); 
     94    } 
    8995 
    90     JSFunction *function = JS_ValueToFunction(cx, argv[0]); 
     96    /* We use the first two parameters, and we don't hand them off.. */ 
     97    argc -= 2; 
     98 
     99    /* Used to try to use the parent of argv[0], which was a function. It never 
     100     * worked though, apparently you cannot bend the rules of ecmascript 
     101     * interfaces just because you're in spidermonkey unless you hack things up 
     102     * a bit ;-) */ 
     103    JSObject *parent = NULL; 
     104     
     105    if (JSVAL_IS_OBJECT(argv[0])) { 
     106        parent = JSVAL_TO_OBJECT(argv[0]); 
     107    } 
     108    else { 
     109        parent = JS_GetParent(cx, JSVAL_TO_OBJECT(argv[1])); 
     110    } 
     111 
     112    JSFunction *function = JS_ValueToFunction(cx, argv[1]); 
    91113 
    92114    jsval *rval; 
    93     jsval *args = g_malloc(sizeof(jsval *) * (argc - 1)); 
     115    jsval args[argc]; 
    94116 
    95     for (int i = 1; i < argc; i++) { 
    96         args[i - 1] = argv[i]; 
     117    for (int i = 0; i < argc; i++) { 
     118        args[i] = argv[i + 2]; 
    97119    } 
    98120 
    99     JS_CallFunction(cx, parent, function, qitem->argc, args, rval);  
    100  
    101     g_free(args); 
     121    JS_CallFunction(cx, parent, function, argc, args, rval);  
    102122 
    103123    return FALSE; 
     
    107127    struct queue_item *qitem = (struct queue_item *) data; 
    108128 
    109     JS_RemoveRoot(qitem->cx, qitem->argv); 
     129    JS_RemoveRoot(qitem->cx, &qitem->args); 
    110130 
     131    g_free(qitem->esid); 
    111132    g_free(qitem); 
    112133} 
     
    119140    struct queue_item *qitem = g_malloc(sizeof(struct queue_item)); 
    120141 
    121     *qitem = (struct queue_item) { 
    122         .argv = argv, 
    123         .argc = argc, 
    124     }; 
    125  
    126     if (argc < 1) { 
    127         JS_ReportError(cx, "EventLoop.enqueue() requires arguments"); 
     142    if (argc < 2) { 
     143        JS_ReportError(cx, "EventLoop.yield() requires 2 arguments"); 
    128144        return false; 
    129145    } 
    130146 
    131     if (JS_ObjectIsFunction(cx, JSVAL_TO_OBJECT(qitem->argv[0]))) { 
    132         qitem->cx = cx; 
     147    if (JSVAL_IS_STRING(argv[1])) { 
     148        JS_GetProperty(cx, JSVAL_TO_OBJECT(argv[0]),  
     149                JS_GetStringBytes(JS_ValueToString(cx, argv[1])), &argv[1]); 
    133150 
    134         g_idle_add_full(0, sagot_eventloop_dispatch, qitem,  
    135                 sagot_eventloop_dispatch_cleanup); 
     151        if (JS_ObjectIsFunction(cx, JSVAL_TO_OBJECT(argv[1]))) { 
     152            /* This might be kind of slow, think about creating a source 
     153             * specifically for these vents, attaching the source to the loop, and 
     154             * creating new events from the source.  g_idle_add_* functions create 
     155             * a new source for each event. 
     156             */ 
    136157 
    137         JS_AddRoot(cx, argv); 
     158            *qitem = (struct queue_item) { 
     159                .esid = g_malloc(sizeof(int)), 
     160                .args = JS_NewArrayObject(cx, argc, argv), 
     161                .argc = argc, 
     162                .cx   = cx, 
     163            }; 
    138164 
    139         return true; 
     165            /* Store the source at the location of the pointer we're pointing 
     166             * to...funky I know.  Later, we'll even store data using this id, then 
     167             * fetch it when the event is invoked */ 
     168            g_idle_add_full(0, sagot_eventloop_dispatch, qitem, 
     169                    sagot_eventloop_dispatch_cleanup); 
     170 
     171            JS_AddRoot(cx, &qitem->args); 
     172 
     173            return true; 
     174        } 
    140175    } 
    141176 
    142     JS_ReportError(cx, "argument 1 to enqueue() must be a function"); 
     177    JS_ReportError(cx, "argument 1 to enqueue() must be a string"); 
    143178 
    144179    return false;