Re: "Bottlenecking" connections
- From: Thomas Mailund <mailund mailund dk>
- To: gtk-list gnome org
- Subject: Re: "Bottlenecking" connections
- Date: 25 Aug 2001 14:14:42 +0930
On Sat, 2001-08-25 at 13:32, Thomas Mailund wrote:
> A (potential) problem with that solution is the tight copling between
> dispatcher and operations. Sometimes you need the dispatcher to know
> about the operations so it can chose which operations to call,
> othertimes you just want it to broadcast an event to whoever is
> listening. The later solution you can achive by letting the
> dispatcher signal rather than call functions, and then let the
> operations listen for that signal.(*)
Though now that I think about it, actually coding this is a bit
cumbersome...
> /mailund
>
> (*) I can hack up an example of that if it is unclear what I am trying
> to explain here.
>
and so I have. (The attached code).
Setting up a signal to work as I suggested required writing a new class,
which requires a lot more code than its worth for such a small
example...and that can't be right.
Now, I have been away from gtk+ for quite some time, so there could
easilly be a lot better way of doing what I did here that I am just not
aware of, if this is the case I'd love to hear about it.
/mailund
--
Give a monkey a brain and he'll swear he's the center of the universe.
#include <gtk/gtk.h>
/* --- DEFINING NEW CLASS ------------------------------------------ */
#define TYPE_DISPATCHER (dispatcher_get_type ())
#define DISPATCHER(obj) (GTK_CHECK_CAST (obj, dispatcher_get_type (), Dispatcher))
#define DISPATCHER_CLASS(klass) (GTK_CHECK_CLASS_CAST (klass, dispatcher_get_type (), DispatcherClass))
#define IS_DISPATCHER(obj) (GTK_CHECK_TYPE (obj, dispatcher_get_type ()))
#define IS_DISPATCHER_CLASS(klass) (GTK_CHECK_CLASS_TYPE ((klass), TYPE_DISPATCHER))
typedef struct _Dispatcher Dispatcher;
typedef struct _DispatcherClass DispatcherClass;
struct _Dispatcher {
GtkObject object;
};
struct _DispatcherClass {
GtkObjectClass object_class;
};
guint dispatcher_get_type (void);
/* object stuff */
static void dispatcher_class_init (DispatcherClass *klass);
static void dispatcher_init (Dispatcher *dispatcher);
static void dispatcher_destroy (GtkObject *object);
static GtkObjectClass *parent_class = NULL;
guint
dispatcher_get_type ()
{
static guint dispatcher_type = 0;
if (!dispatcher_type)
{
GtkTypeInfo dispatcher_info =
{
"Dispatcher",
sizeof (Dispatcher),
sizeof (DispatcherClass),
(GtkClassInitFunc) dispatcher_class_init,
(GtkObjectInitFunc) dispatcher_init,
(GtkArgSetFunc) NULL,
(GtkArgGetFunc) NULL,
(GtkClassInitFunc) NULL,
};
dispatcher_type =
gtk_type_unique (gtk_object_get_type (), &dispatcher_info);
}
return dispatcher_type;
}
enum {
TICKLED_1,
TICKLED_2,
TICKLED_3,
LAST_SIGNAL
};
static guint dispatcher_signals[LAST_SIGNAL] = { 0 };
static void
dispatcher_class_init (DispatcherClass *class)
{
GtkObjectClass *object_class;
object_class = (GtkObjectClass*) class;
/* init local data */
parent_class = gtk_type_class (gtk_object_get_type ());
object_class->destroy = dispatcher_destroy;
/* set up signals */
dispatcher_signals[TICKLED_1] =
gtk_signal_new ("tickled_1",
GTK_RUN_FIRST,
object_class->type,
0, /* offset. We don't have a class
signal handler */
gtk_marshal_NONE__NONE,
GTK_TYPE_NONE, 0);
dispatcher_signals[TICKLED_2] =
gtk_signal_new ("tickled_2",
GTK_RUN_FIRST,
object_class->type,
0, /* offset. We don't have a class
signal handler */
gtk_marshal_NONE__NONE,
GTK_TYPE_NONE, 0);
dispatcher_signals[TICKLED_3] =
gtk_signal_new ("tickled_3",
GTK_RUN_FIRST,
object_class->type,
0, /* offset. We don't have a class
signal handler */
gtk_marshal_NONE__NONE,
GTK_TYPE_NONE, 0);
gtk_object_class_add_signals (object_class, dispatcher_signals, LAST_SIGNAL);
}
static void
dispatcher_init (Dispatcher *dispatcher)
{
return;
}
static void
dispatcher_destroy (GtkObject *object)
{
g_return_if_fail (object != NULL);
g_return_if_fail (IS_DISPATCHER (object));
GTK_OBJECT_CLASS(parent_class)->destroy (object);
}
/* --- THE APPLICATION CODE ---------------------------------------- */
static void
op_1_1 (void)
{
g_print ("op 1 1\n");
}
static void
op_1_2 (void)
{
g_print ("op 1 2\n");
}
static void
op_2 (void)
{
g_print ("op 2\n");
}
static void
op_3 (void)
{
g_print ("op 3\n");
}
static gboolean blocked = FALSE;
static Dispatcher *dispatcher;
static void
dispatch(GtkWidget *dummy, int op_id)
{
if (!blocked)
{
switch (op_id)
{
case 1:
gtk_signal_emit (GTK_OBJECT (dispatcher),
dispatcher_signals[TICKLED_1]);
break;
case 2:
gtk_signal_emit (GTK_OBJECT (dispatcher),
dispatcher_signals[TICKLED_2]);
break;
case 3:
gtk_signal_emit (GTK_OBJECT (dispatcher),
dispatcher_signals[TICKLED_3]);
break;
}
}
}
static void
toggle_block(void)
{
blocked = ! blocked;
}
int
main(int argc, char *argv[])
{
GtkWidget *win;
GtkWidget *vbox;
GtkWidget *button;
gtk_init (&argc, &argv);
win = gtk_window_new (GTK_WINDOW_TOPLEVEL);
vbox = gtk_vbox_new (TRUE, 0);
gtk_container_add (GTK_CONTAINER (win), vbox);
button = gtk_button_new_with_label ("op 1");
gtk_box_pack_start (GTK_BOX (vbox), button, FALSE, FALSE, 0);
gtk_signal_connect (GTK_OBJECT (button), "clicked",
GTK_SIGNAL_FUNC (dispatch),
GINT_TO_POINTER (1));
button = gtk_button_new_with_label ("op 2");
gtk_box_pack_start (GTK_BOX (vbox), button, FALSE, FALSE, 0);
gtk_signal_connect (GTK_OBJECT (button), "clicked",
GTK_SIGNAL_FUNC (dispatch),
GINT_TO_POINTER (2));
button = gtk_button_new_with_label ("op 3");
gtk_box_pack_start (GTK_BOX (vbox), button, FALSE, FALSE, 0);
gtk_signal_connect (GTK_OBJECT (button), "clicked",
GTK_SIGNAL_FUNC (dispatch),
GINT_TO_POINTER (3));
button = gtk_button_new_with_label ("toggle block");
gtk_box_pack_start (GTK_BOX (vbox), button, FALSE, FALSE, 0);
gtk_signal_connect (GTK_OBJECT (button), "clicked",
GTK_SIGNAL_FUNC (toggle_block),
NULL);
/* setup dispatcher */
dispatcher = DISPATCHER (gtk_object_new (TYPE_DISPATCHER, NULL));
/* and connect signals */
gtk_signal_connect (GTK_OBJECT (dispatcher), "tickled_1",
GTK_SIGNAL_FUNC (op_1_1), NULL);
gtk_signal_connect (GTK_OBJECT (dispatcher), "tickled_1",
GTK_SIGNAL_FUNC (op_1_2), NULL);
gtk_signal_connect (GTK_OBJECT (dispatcher), "tickled_2",
GTK_SIGNAL_FUNC (op_2), NULL);
gtk_signal_connect (GTK_OBJECT (dispatcher), "tickled_3",
GTK_SIGNAL_FUNC (op_3), NULL);
gtk_widget_show_all (win);
gtk_main ();
return 0;
}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]