slate callbacks

11 views
Skip to first unread message

Timmy Douglas

unread,
Jan 10, 2009, 4:16:17 PM1/10/09
to slate-language
for things like GTK, slate will have to support callbacks. I outlined
something that would be simple to add and I was looking for feedback
on it with people familiar with gtk or feedback from Guille since he
started the gtk plugins.

1. Slate calls gtk function to establish callback:

Gtk Lib primitives gtk_window_set_callback applyTo: {w handle. lobby
slateCallbackAddress. lobby currentHeap}}

lobby slateCallbackAddress is a bytearray with
slate_external_callback_handler
lobby currentHeap is a bytearray with the vm's object heap

2. User writes C code to call gtk callback setup function in
myplugin.c:

int gtk_window_set_callback(int handle, void* func, void* heap) {
/*perhaps merge func heap into a struct if callback can pass one
variable only or make set it global?uck*/
/*gtk_setup_callback is a real gtk function (for this example)*/
gtk_setup_callback(handle, my_window_callback, func, heap);
}

/*when gtk calls the callback*/
int my_window_callback(void* func, void* vm_object_heap, int arg1, int
arg2, int arg3) {

word_t args[3];
args[0] = GTK_MESSAGE_TYPE;
args[1] = arg1; /*...*/
func(vm_object_heap, 4, args) /*calls
slate_external_callback_handler*/

}

3. Slate vm code:

int slate_external_callback_handler(struct object_heap* oh, int argc,
word_t* args) {

oh->messageQueue->add(argc, args)

}

4. User slate code:

gtk@(Gtk traits) nextMessage
[
lobby popNextMessageType: GTK_MESSAGE_TYPE
]

5. slate primitive

prim_popNextMessageType(..) {
/*...*/
result = clone_array_with_args(....)

}

Guille

unread,
Jan 11, 2009, 3:57:27 AM1/11/09
to slate-language
It sounds interesting. It is more or less how it is implemented right
now, take a look at:

src/ui/gtk/main.slate
src/ui/glib/callbackdata.slate
src/ui/glib/object.slate
and
src/plugins/glib-wrapper.c

When you start gtk a new thread is created for the main loop (see src/
plugins/glib-wrapper.c, wrapper_gtk_lib_init() ).
The message queue is implemented in src/plugins/glib-wrapper.c, it is
called callbackQueue, it uses a GLIB async queue.
Just one callback (to the plugin) is announced to GTK, it manages
every callback. it is implemented in (src/plugins/glib-wrapper.c,
callback() ), all that it does is generate the CallbackData structure
for each signal that arrives and add an entry into the
callbackQueue.
To connect to a signal you do a #when:do: and friends implemented in:
src/ui/glib/object.slate, they register the callback block to execute
into Gtk Main (every connected block is saved in the callbackBlocks
dictionary), and then it connects the blockid, to the gtk framework
using wrapper_g_object_connect_to_block_id (defined at, src/plugins/
glib-wrapper.c).
Slate is freezed waiting for new callbacks in src/ui/gtk/main.slate,
doEventLoop and friends. It tries to get next callbackdata object from
the callbackQueue, if no more data is available it is put to sleep.
When a new callback arrives, it gets the blockid of the callback, and
executes it using the rest of the parameters at the callback structure
(see src/ui/glib/callbackdata.slate), then destroys the callback data,
and lastly waits again.


So if the callback infrastructure is provided by the VM, I would only
have to care about the marshalling of the data.
How do you plan to schedule the callbacks in slate?
Reply all
Reply to author
Forward
0 new messages