Reputation: 3214
So I thought I'd be clever one of the more generic and easy to use classes, namely Gee.ArrayList for the data for a ListBox. Turns out that ListBox will take a ListModel, and I figured, since I was using ArrayList, that I might as well just make a class that is both a Gee.ArrayList and a ListModel:
public class ObservableArrayList<T> : ListModel, Gee.ArrayList<T>{
//Implement ListModel
public Object? get_item(uint position){
if((int)position > size){
return null;
}
return (Object?) this.get((int)position);
}
public Type get_item_type(){
return element_type;
}
public uint get_n_items(){
return (uint)size;
}
public new Object? get_object(uint position){
if((int)position > size){
return null;
}
return (Object) this.get((int)position);
}
}
This, however gives me a strange compile message:
/home/rasmus/Projects/Vala/Test/ObservableList.vala.c: In function ‘observable_array_list_g_list_model_interface_init’:
/home/rasmus/Projects/Vala/Test/ObservableList.vala.c:189:18: warning: assignment from incompatible pointer type [-Wincompatible-pointer-types]
iface->get_item = (GObject* (*) (GListModel*, guint)) observable_array_list_real_get_item;
And while the compilation succeeds, the class is very much unusable as a ListModel:
using Gtk;
public class TestApp : Gtk.Application{
public TestApp () {
Object (
application_id: "TestApp",
flags: ApplicationFlags.FLAGS_NONE
);
}
protected override void activate(){
var main_window = new Gtk.ApplicationWindow (this);
main_window.default_height = 400;
main_window.default_width = 600;
main_window.title = "test";
ListModel t = new ObservableArrayList<int>();
var list_box = new Gtk.ListBox();
list_box.bind_model(t, null);
main_window.add(list_box);
main_window.show_all ();
}
public static int main (string[] args) {
Gtk.init (ref args);
var app = new TestApp ();
return app.run(args);
}
}
The output of which, when trying to run a compiled program is:
segmentationfault
Is there a good way to resolve this, or have i been trying something that was wrong from the outset?
Upvotes: 1
Views: 654
Reputation: 637
An important thing to remember is that Vala actually compiles to C which is then fed into GCC to build an executable, your compiler warning is actually comping from gcc
not valac
On my machine the message is formatted slightly differently
warning: assignment to ‘void * (*)(GListModel *, guint)’ {aka ‘void * (*)(struct _GListModel *, unsigned int)’} from incompatible pointer type ‘GObject * (*)(GListModel *, guint)’ {aka ‘struct _GObject * (*)(struct _GListModel *, unsigned int)’}
Which can be simplified to
assignment to ‘void * (*)(GListModel *, guint)’ from incompatible type ‘GObject * (*)(GListModel *, guint)’
Which is basically saying that GLib expects get_item to return void *
instead of a GObject, this is a bug in the bindings so can be ignored
The run comes with the runtime warnings
(list:4511): GLib-GIO-CRITICAL **: 21:44:24.003: g_application_set_application_id: assertion 'application_id == NULL || g_application_id_is_valid (application_id)' failed
(list:4511): Gtk-CRITICAL **: 21:44:24.008: gtk_list_box_bind_model: assertion 'model == NULL || create_widget_func != NULL' failed
So you have 2 problems
com.githost.me.App
However neither of those tell us why your getting SEGV
The answer lies in that your GListModel contains elements of type int
whereas GtkListBox is expecting a collection of Object
Upvotes: 2