1

I'm trying to write a VAPI file to use libui (https://github.com/andlabs/libui) in Vala.

I don't know how to connect events from the controls to vala signals.

In the libui headers is, for example of closing a window, this method defined:

_UI_EXTERN void uiWindowOnClosing(uiWindow *w, int (*f)(uiWindow *w, void *data), void *data);  

In the C examples this method is called with the method "onClosing" as argument:

uiWindowOnClosing(w, onClosing, NULL);  

How can I make something like:

window.OnClosing.connect(()=>{print("End");});
Seanny123
  • 8,776
  • 13
  • 68
  • 124
ibinshoid
  • 31
  • 2

3 Answers3

2

Signals in Vala are implemented using GLib's signals, which is an example of the observer pattern. To use signals in Vala the class needs to inherit from Object and it doesn't look like libui is using GLib's GObject. So it won't be possible to use signals in this binding. Although it is possible to use signals in a Vala binding. For example the gtksourceview VAPI binds the redo and undo signals of SourceBuffer.

The pattern used in uiWindowOnClosing is to pass a C function pointer to use as the callback. On the Vala side these are called delegates. libui hasn't added a typedef for the function point, so Vala needs to generate that. This is indicated by using [CCode (has_typedef = false)] in the VAPI.

The other problem here is the void pointer for the user data - void *data. This is probably best bound using simple generics.

A rough cut at a binding would be:

[CCode (cname = "uiWindow")]
public class Window {
  [CCode (has_typedef = false, simple_generics = true)]
  public delegate int Callback<T> (T data);

  [CCode (cname = "uiWindowOnClosing", simple_generics = true)]
  public void on_closing<K> (Callback callback, K data);
}

This is untested, but should give you a better idea of the underlying concepts.

AlThomas
  • 4,169
  • 12
  • 22
1

This is not possible. Vala's signal mechanism is based on GLib's signal system. You can make these use lambdas, but not signals.

apmasell
  • 7,033
  • 19
  • 28
0

using your code in the vapi and call it with this:

w.on_closing(()=>{Quit();return 0;}, null);  

brings this message:

error: too many arguments to function ‘uiWindowOnClosing’
uiWindowOnClosing (_tmp3_, ___lambda4__ui_window_callback, NULL, NULL);

But this works:

public void on_closing (Callback callback);  

in the vapi, and

w.on_closing(()=>{Quit();return 0;});  

in the vala code.

Thank you for your help.

ibinshoid
  • 31
  • 2