Re: [PHP-GTK-DEV] Custom Signals Support
by Andrei Zmievski other posts by this author
Mar 8 2007 1:14PM messages near this date
Re: [PHP-GTK-DEV] Custom Signals Support
|
Re: [PHP-GTK-DEV] Custom Signals Support
Elizabeth,
Supporting custom signals will be quite a bit more involved than this.
It'll probably be based on created a new class which will contain its
signal descriptions and then registering it with GType system. If I
have time this weekend I might work on that.. Unless we want to do beta
release first.
-Andrei
On Mar 7, 2007, at 9:13 AM, Elizabeth Smith wrote:
> I've been working on getting custom signal support written because I'd
> really like to use it in some work I'm doing.
>
> I have Gobject::signal_new implemented and working (also registered
> the signal run type constants). I've attached the patch for it as
> well as a test script. However, I've run into a few limitations with
> the implementation.
>
> First of all, signals are assigned globally for a gtype. Right now
> php classes that extend a php-gtk gtype aren't creating their own
> gtype but just using their parents. Why is this bad? Well if you
> extend gtkwindow and add a custom signal...the signal is added to
> gtkwindow (and by default also to your extended class) which may not
> be the intended behavior. Now, it is possible to create new gtypes
> that extend a parent gtype so I know HOW to fix the problem, however I
> don't know WHERE that code needs to go. Any suggestions?
>
> The second problem is I'd like to allow custom signals to be created
> using just a class name and not an object instance. I can grab the
> zend_class_entry but right now the gtype is NOT stored in it. You can
> get the class entry from the gtype...but not the other way around.
> Any suggestions for fixing that problem?
>
> Otherwise the patch allows custom signals.
>
> Index: phpg_gobject.c
> ===================================================================
> RCS file: /repository/php-gtk/main/phpg_gobject.c,v
> retrieving revision 1.60
> diff -u -r1.60 phpg_gobject.c
> --- phpg_gobject.c 7 Dec 2006 07:14:20 -0000 1.60
> +++ phpg_gobject.c 7 Mar 2007 16:12:36 -0000
> @@ -886,6 +886,67 @@
> }
> /* }}} */
>
> +/* {{{ GObject::signal_new */
> +static PHP_METHOD(GObject, signal_new)
> +{
> + gchar *signal_name;
> + GType instance_type, *param_types = NULL, return_type = G_TYPE_NONE;
> + GSignalFlags signal_flags;
> + zval *callback, *extra, *instance, **item;
> + guint signal_id;
> + zend_class_entry *ce = NULL;
> + int n_params = 0, i;
> +
> + if (!php_gtk_parse_varargs(ZEND_NUM_ARGS(), 5, &extra, "sViVi",
> &signal_name, &instance, &signal_flags, &callback, &return_type))
> + return;
> +
> + if (Z_TYPE_P(instance) == IS_OBJECT) {
> + instance_type = phpg_gtype_from_zval(instance);
> + } else if (Z_TYPE_P(instance) == IS_STRING) {
> + zend_class_entry **pce;
> + if (zend_lookup_class(Z_STRVAL_P(instance), Z_STRLEN_P(instance),
> &pce TSRMLS_CC) == SUCCESS) {
> + ce = *pce;
> + }
> + php_printf("TODO: use zend_class_entry to grab ce->gtype?");
> +
> + }
> + if (!instance_type)
> + return;
> +
> + if(extra)
> + {
> + n_params = zend_hash_num_elements(Z_ARRVAL_P(extra));
> +
> + if (n_params > 0) {
> + param_types = safe_emalloc(n_params, sizeof(GType), 0);
> + for (i = 0, zend_hash_internal_pointer_reset(Z_ARRVAL_P(extra));
> + zend_hash_get_current_data(Z_ARRVAL_P(extra), (void**)&item) ==
> SUCCESS;
> + zend_hash_move_forward(Z_ARRVAL_P(extra)), i++) {
> +
> + param_types[i] = phpg_gtype_from_zval(*item);
> + if (param_types[i] == 0) {
> + efree(param_types);
> + php_error(E_WARNING, "could not set types for signal callback");
> + return;
> + }
> + }
> + }
> + }
> +
> + signal_id = g_signal_newv(signal_name, instance_type, signal_flags,
> + phpg_closure_new(callback, extra, PHPG_CONNECT_SIMPLE, NULL
> TSRMLS_CC),
> + (GSignalAccumulator)0, NULL,
> + (GSignalCMarshaller)0,
> + return_type, n_params, param_types);
> +
> + efree(param_types);
> + if (signal_id != 0)
> + RETURN_LONG(signal_id);
> + php_error(E_WARNING, "Unable to create signal");
> + return;
> +
> +}
> +/* }}} */
>
> /* {{{ GObject reflection info */
> static
> @@ -989,6 +1050,17 @@
> ZEND_END_ARG_INFO();
>
> static
> +ZEND_BEGIN_ARG_INFO_EX(arginfo_gobject_signal_new, 0, 0, 5)
> + ZEND_ARG_INFO(0, signal)
> + ZEND_ARG_INFO(0, instance)
> + ZEND_ARG_INFO(0, flags)
> + ZEND_ARG_INFO(0, callback)
> + ZEND_ARG_INFO(0, return_gtype)
> + ZEND_ARG_INFO(0, user_data)
> + ZEND_ARG_INFO(0, ...)
> +ZEND_END_ARG_INFO();
> +
> +static
> ZEND_BEGIN_ARG_INFO(arginfo_gobject_unblock, 0)
> ZEND_ARG_INFO(0, handler_id)
> ZEND_END_ARG_INFO();
> @@ -1023,6 +1095,7 @@
> PHP_ME(GObject, is_connected,
> arginfo_gobject_is_connected , ZEND_ACC_PUBLIC)
> PHP_ME(GObject, signal_query,
> arginfo_gobject_signal_query ,
> ZEND_ACC_PUBLIC|ZEND_ACC_STATIC)
> PHP_ME(GObject, stop_emission,
> arginfo_gobject_stop_emission , ZEND_ACC_PUBLIC)
> + PHP_ME(GObject, signal_new, arginfo_gobject_signal_new
> , ZEND_ACC_PUBLIC|ZEND_ACC_STATIC)
> PHP_ME(GObject, signal_list_ids,
> arginfo_gobject_signal_list_ids ,
> ZEND_ACC_PUBLIC|ZEND_ACC_STATIC)
> PHP_ME(GObject, signal_list_names,
> arginfo_gobject_signal_list_names ,
> ZEND_ACC_PUBLIC|ZEND_ACC_STATIC)
> PHP_MALIAS(GObject, emit_stop_by_name, stop_emission,
> arginfo_gobject_stop_emission, ZEND_ACC_PUBLIC)
> @@ -1055,8 +1128,15 @@
>
> gobject_ce = phpg_register_class("GObject", gobject_methods,
> NULL, 0, gobject_props_info, NULL, G_TYPE_OBJECT TSRMLS_CC);
> phpg_register_int_constant(gobject_ce, "gtype",
> sizeof("gtype")-1, G_TYPE_OBJECT);
> + phpg_register_int_constant(gobject_ce, "SIGNAL_RUN_FIRST",
> sizeof("SIGNAL_RUN_FIRST")-1, G_SIGNAL_RUN_FIRST);
> + phpg_register_int_constant(gobject_ce, "SIGNAL_RUN_LAST",
> sizeof("SIGNAL_RUN_LAST")-1, G_SIGNAL_RUN_LAST);
> + phpg_register_int_constant(gobject_ce, "SIGNAL_RUN_CLEANUP",
> sizeof("SIGNAL_RUN_CLEANUP")-1, G_SIGNAL_RUN_CLEANUP);
> + phpg_register_int_constant(gobject_ce, "SIGNAL_NO_RECURSE",
> sizeof("SIGNAL_NO_RECURSE")-1, G_SIGNAL_NO_RECURSE);
> + phpg_register_int_constant(gobject_ce, "SIGNAL_DETAILED",
> sizeof("SIGNAL_DETAILED")-1, G_SIGNAL_DETAILED);
> + phpg_register_int_constant(gobject_ce, "SIGNAL_ACTION",
> sizeof("SIGNAL_ACTION")-1, G_SIGNAL_ACTION);
> + phpg_register_int_constant(gobject_ce, "SIGNAL_NO_HOOKS",
> sizeof("SIGNAL_NO_HOOKS")-1, G_SIGNAL_NO_HOOKS);
> }
>
> #endif /* HAVE_PHP_GTK */
>
> -/* vim: set fdm=marker et sts=4: */
> +/* vim: set fdm=marker et sts=4: */
> \ No newline at end of file
> <?php
> function dome()
> {
> echo "custom signal ahoy\n";
> return TRUE;
> }
> function do_mysignal()
> {
> echo "this is always called on my-signal\n";
> }
> function do_goosignal($widget, $arg)
> {
> echo "$widget\n$arg\n";
> return TRUE;
> }
>
> class Mywindow extends GtkWindow{}
> $widget = new Mywindow();
> $arg1 = 'cat';
> GObject::signal_new('my-signal', $widget, GObject::SIGNAL_RUN_LAST,
> 'do_mysignal', Gtk::TYPE_NONE);
> GObject::signal_new('goo-signal', $widget, GObject::SIGNAL_RUN_LAST,
> 'do_goosignal_full', Gtk::TYPE_BOOLEAN, $widget, $arg1);
> print_r(GObject::signal_list_names(GtkWindow::gtype));
> $widget->connect_simple('destroy', array('Gtk', 'main_quit'));
> $widget->connect_simple('my-signal', 'dome');
> $widget->connect_simple('goo-signal', 'dome');
> $widget->show_all();
> $widget->emit('my-signal');
> $widget->emit('goo-signal');
> Gtk::main();
> ?>
> --
> PHP-GTK Development Mailing List (http://gtk.php.net/)
> To unsubscribe, visit: http://www.php.net/unsub.php
--
PHP-GTK Development Mailing List (http://gtk.php.net/)
To unsubscribe, visit: http://www.php.net/unsub.php
Thread:
Elizabeth Smith
Andrei Zmievski
Steph Fox
Andrei Zmievski
Elizabeth Smith
|