On Sat, Feb 10, 2007 at 10:38:11PM +0100, David Nečas (Yeti) wrote: > > A testing (non-real world) example is attached
Maybe this time I won't forget? Yeti -- Whatever. =========================================================================== #include <glib-object.h> /****************************************************************************/ /* */ /* Interface */ /* */ /* Consists of one virtual method: print(). */ /* */ /****************************************************************************/ #define MY_TYPE_PRINTABLE (my_printable_get_type()) #define MY_PRINTABLE(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), MY_TYPE_PRINTABLE, MyPrintable)) #define MY_PRINTABLE_CLASS(obj) (G_TYPE_CHECK_CLASS_CAST((obj), MY_TYPE_PRINTABLE, MyPrintableIface)) #define MY_IS_PRINTABLE(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), MY_TYPE_PRINTABLE)) #define MY_PRINTABLE_GET_IFACE(obj) (G_TYPE_INSTANCE_GET_INTERFACE((obj), MY_TYPE_PRINTABLE, MyPrintableIface)) typedef struct _MyPrintable MyPrintable; /* Dummy typedef */ typedef struct _MyPrintableIface MyPrintableIface; struct _MyPrintableIface { GTypeInterface g_iface; void (*print)(MyPrintable *printable); }; GType my_printable_get_type (void) G_GNUC_CONST; void my_printable_print (MyPrintable *printable); /****************************************************************************/ GType my_printable_get_type(void) { static GType printable_type = 0; if (!printable_type) { static const GTypeInfo printable_info = { sizeof(MyPrintableIface), NULL, NULL, NULL, NULL, NULL, 0, 0, NULL }; printable_type = g_type_register_static(G_TYPE_INTERFACE, "MyPrintable", &printable_info, 0); g_type_interface_add_prerequisite(printable_type, G_TYPE_OBJECT); } return printable_type; } void my_printable_print(MyPrintable *printable) { g_return_if_fail(MY_IS_PRINTABLE(printable)); g_return_if_fail(MY_PRINTABLE_GET_IFACE(printable)->print != NULL); MY_PRINTABLE_GET_IFACE(printable)->print(printable); } /****************************************************************************/ /* */ /* Parent class */ /* */ /* Implements MyPrintable. */ /* */ /****************************************************************************/ #define MY_TYPE_PARENT (my_parent_get_type()) #define MY_PARENT(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), MY_TYPE_PARENT, MyParent)) #define MY_PARENT_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), MY_TYPE_PARENT, MyParentClass)) #define MY_IS_PARENT(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), MY_TYPE_PARENT)) #define MY_IS_PARENT_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), MY_TYPE_PARENT)) #define MY_PARENT_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), MY_TYPE_PARENT, MyParentClass)) typedef struct _MyParent MyParent; typedef struct _MyParentClass MyParentClass; struct _MyParent { GObject object; gint data; }; struct _MyParentClass { GObjectClass object_class; }; GType my_parent_get_type (void) G_GNUC_CONST; MyParent* my_parent_new (gint i); void my_parent_set_data (MyParent *parent, gint i); /****************************************************************************/ static void my_parent_printable_init(MyPrintableIface *iface); static void my_parent_print (MyPrintable *printable); G_DEFINE_TYPE_EXTENDED (MyParent, my_parent, G_TYPE_OBJECT, 0, G_IMPLEMENT_INTERFACE(MY_TYPE_PRINTABLE, my_parent_printable_init)) static void my_parent_printable_init(MyPrintableIface *iface) { iface->print = my_parent_print; } static void my_parent_class_init(MyParentClass *klass) { } static void my_parent_init(MyParent *parent) { } static void my_parent_print(MyPrintable *printable) { MyParent *parent = MY_PARENT(printable); g_print("%p: data=%d\n", parent, parent->data); } MyParent* my_parent_new(gint i) { MyParent *instance; instance = g_object_new(MY_TYPE_PARENT, NULL); instance->data = i; return instance; } void my_parent_set_data(MyParent *parent, gint i) { parent->data = i; } /****************************************************************************/ /* */ /* Child class */ /* */ /* Derives from MyParent. */ /* */ /****************************************************************************/ #define MY_TYPE_CHILD (my_child_get_type()) #define MY_CHILD(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), MY_TYPE_CHILD, MyChild)) #define MY_CHILD_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), MY_TYPE_CHILD, MyChildClass)) #define MY_IS_CHILD(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), MY_TYPE_CHILD)) #define MY_IS_CHILD_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), MY_TYPE_CHILD)) #define MY_CHILD_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), MY_TYPE_CHILD, MyChildClass)) typedef struct _MyChild MyChild; typedef struct _MyChildClass MyChildClass; struct _MyChild { MyParent parent; gint more_data; }; struct _MyChildClass { MyParentClass parent_class; }; GType my_child_get_type (void) G_GNUC_CONST; MyChild* my_child_new (gint i, gint j); /****************************************************************************/ static void my_child_print (MyPrintable *printable); G_DEFINE_TYPE(MyChild, my_child, MY_TYPE_PARENT) static void my_child_class_init(MyChildClass *klass) { } static void my_child_init(MyChild *child) { } /* Cannot invoke this */ static void my_child_print(MyPrintable *printable) { MyChild *child = MY_CHILD(printable); g_print("%p: more_data=%d\n", child, child->more_data); } MyChild* my_child_new(gint i, gint j) { MyChild *instance; instance = g_object_new(MY_TYPE_CHILD, NULL); my_parent_set_data(MY_PARENT(instance), i); instance->more_data = j; return instance; } /****************************************************************************/ /* */ /* Child class 2 */ /* */ /* Derives from MyParent and implements MyPrintable *again*. */ /* */ /****************************************************************************/ #define MY_TYPE_CHILD2 (my_child2_get_type()) #define MY_CHILD2(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), MY_TYPE_CHILD2, MyChild2)) #define MY_CHILD2_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), MY_TYPE_CHILD2, MyChild2Class)) #define MY_IS_CHILD2(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), MY_TYPE_CHILD2)) #define MY_IS_CHILD2_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), MY_TYPE_CHILD2)) #define MY_CHILD2_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), MY_TYPE_CHILD2, MyChild2Class)) typedef struct _MyChild2 MyChild2; typedef struct _MyChild2Class MyChild2Class; struct _MyChild2 { MyParent parent; gint more_data; }; struct _MyChild2Class { MyParentClass parent_class; }; GType my_child2_get_type (void) G_GNUC_CONST; MyChild2* my_child2_new (gint i, gint j); /****************************************************************************/ static void my_child2_printable_init(MyPrintableIface *iface); static void my_child2_print (MyPrintable *printable); static MyPrintableIface *my_child2_parent_printable; G_DEFINE_TYPE_EXTENDED (MyChild2, my_child2, MY_TYPE_PARENT, 0, G_IMPLEMENT_INTERFACE(MY_TYPE_PRINTABLE, my_child2_printable_init)) static void my_child2_printable_init(MyPrintableIface *iface) { my_child2_parent_printable = g_type_interface_peek_parent(iface); iface->print = my_child2_print; } static void my_child2_class_init(MyChild2Class *klass) { } static void my_child2_init(MyChild2 *child2) { } static void my_child2_print(MyPrintable *printable) { MyChild2 *child2 = MY_CHILD2(printable); my_child2_parent_printable->print(printable); g_print("%p: more_data2=%d\n", child2, child2->more_data); } MyChild2* my_child2_new(gint i, gint j) { MyChild2 *instance; instance = g_object_new(MY_TYPE_CHILD2, NULL); my_parent_set_data(MY_PARENT(instance), i); instance->more_data = j; return instance; } /****************************************************************************/ /* */ /* Main program. */ /* */ /****************************************************************************/ static void test(gpointer object) { GType type, *ifaces; gint i, n; type = G_TYPE_FROM_INSTANCE(object); g_print("Type: %s\n", g_type_name(type)); g_print("Derives from: %s\n", g_type_name(g_type_parent(type))); g_print("Is Printable? %d\n", MY_IS_PRINTABLE(object)); ifaces = g_type_interfaces(type, &n); g_print("Implements:"); for (i = 0; i < n; i++) g_print(" %s", g_type_name(ifaces[i])); g_print("\n"); g_free(ifaces); if (MY_IS_PRINTABLE(object)) { g_print("Prints:\n"); my_printable_print(MY_PRINTABLE(object)); } else g_print("Type is not printable.\n"); g_print("\n"); } int main(int argc, char *argv[]) { g_type_init(); test(my_parent_new(3)); test(my_child_new(5, 6)); test(my_child2_new(1, 0)); return 0; } _______________________________________________ gtk-app-devel-list mailing list gtk-app-devel-list@gnome.org http://mail.gnome.org/mailman/listinfo/gtk-app-devel-list