Changeset 16
- Timestamp:
- 04/14/06 21:09:14 (3 years ago)
- Files:
-
- 1 modified
-
trunk/sagot/src/sagot_glib_eventloop.c (modified) (3 diffs)
Legend:
- Unmodified
- Added
- Removed
-
trunk/sagot/src/sagot_glib_eventloop.c
r7 r16 74 74 75 75 struct queue_item { 76 jsval *argv; 76 int *esid; 77 JSObject *args; 77 78 uintN argc; 78 79 JSContext *cx; 79 80 }; 80 81 82 /** 83 * Dispatch an event from glib to javascript 84 */ 81 85 gboolean sagot_eventloop_dispatch (void *data) { 82 86 struct queue_item *qitem = (struct queue_item *) data; 83 87 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]; 86 91 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 } 89 95 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]); 91 113 92 114 jsval *rval; 93 jsval *args = g_malloc(sizeof(jsval *) * (argc - 1));115 jsval args[argc]; 94 116 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]; 97 119 } 98 120 99 JS_CallFunction(cx, parent, function, qitem->argc, args, rval); 100 101 g_free(args); 121 JS_CallFunction(cx, parent, function, argc, args, rval); 102 122 103 123 return FALSE; … … 107 127 struct queue_item *qitem = (struct queue_item *) data; 108 128 109 JS_RemoveRoot(qitem->cx, qitem->argv);129 JS_RemoveRoot(qitem->cx, &qitem->args); 110 130 131 g_free(qitem->esid); 111 132 g_free(qitem); 112 133 } … … 119 140 struct queue_item *qitem = g_malloc(sizeof(struct queue_item)); 120 141 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"); 128 144 return false; 129 145 } 130 146 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]); 133 150 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 */ 136 157 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 }; 138 164 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 } 140 175 } 141 176 142 JS_ReportError(cx, "argument 1 to enqueue() must be a function");177 JS_ReportError(cx, "argument 1 to enqueue() must be a string"); 143 178 144 179 return false;