Re: Question on emission hooks



> I'm using glib 2.4.0, and what I wanted to do (I don't know if it's 
> possible) is to use a emission hook callback every time one of my own 
> types's properties changes. I have 500 GWP_TYPE_SHIPs on my application, 
> so I don't want to connect to the "notify" signal in every ship.

Of course, it is possible. Try attached example


#include <glib-object.h>
#include <glib.h>

#define TEST_TYPE_A (test_a_get_type())

typedef struct _TestA TestA;
typedef struct _TestAClass TestAClass;

struct _TestA {
  GObject parent;
  
  gint v;
};

struct _TestAClass {
  GObjectClass parent_class;

  void (* property_changed) (TestA *self);
};

static void
test_a_class_init (TestAClass *class);

static void
test_a_init (TestA *test_a);

static GType								
test_a_get_type (void)					
{							
  static GType test_a_type = 0;					
							
  if (!test_a_type)						
    {								
      static const GTypeInfo test_a_info =			
	{							
	  sizeof (TestAClass),				
	  (GBaseInitFunc) NULL,				
	  (GBaseFinalizeFunc) NULL,				
	  (GClassInitFunc) test_a_class_init,				
	  (GClassFinalizeFunc) NULL,				
	  NULL,           /* class_data */			
	  sizeof (TestA),					
	  0,             /* n_prelocs */			
	  (GInstanceInitFunc) test_a_init			
	};							
								
      test_a_type = g_type_register_static (G_TYPE_OBJECT,	
					    "TestA",		
					    &test_a_info, 0);	
    }								
								
  return test_a_type;						
}


static guint property_signal_id = 0;

static void
test_a_get_property (GObject         *object,
                     guint            prop_id,
                     GValue          *value,
                     GParamSpec      *pspec)
{
  TestA* test_a = (TestA*) object;
  
  if (prop_id == 1)
      g_value_set_int (value, test_a->v);
  else
    G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
}
static void
test_a_set_property (GObject         *object,
                     guint            prop_id,
                     const GValue    *value,
                     GParamSpec      *pspec)
{
  TestA *test_a = (TestA*)object;
  
  g_signal_emit (object, property_signal_id, 0, NULL);
  
  if (prop_id == 1)
    test_a->v = g_value_get_int (value);
  else
    G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
}


static void
test_a_class_init (TestAClass *class)
{
  GObjectClass *gobject_class = G_OBJECT_CLASS (class);


  property_signal_id = g_signal_new ("property_changed",
				TEST_TYPE_A,
				G_SIGNAL_RUN_LAST,
				G_STRUCT_OFFSET (TestAClass, property_changed),
				NULL, NULL,
				g_cclosure_marshal_VOID__VOID,
				G_TYPE_NONE, 0, NULL);

  gobject_class->set_property = test_a_set_property;
  gobject_class->get_property = test_a_get_property;
  
  g_object_class_install_property (gobject_class,
                                   1,
                                   g_param_spec_int  ("pro",
                                                      "Some property",
                                                      "Some property",
						      0, 1,
						      0,
                                                      G_PARAM_READABLE | G_PARAM_WRITABLE));
}

static void
test_a_init (TestA *test_a) 
{
  return;
}

static void
on_prop_changed (GObject* obj, gboolean data)
{
  g_message ("Property changed callback");
}

static gboolean
prop_changed_hook (GSignalInvocationHint *ihint,
      guint                  n_param_values,
      const GValue          *param_values,
      gpointer               data)
{
  g_message ("Property changed hook");
  return TRUE;
}



int main( int   argc, 
          char *argv[] )
{
    TestA *object;
    
    g_type_init();
    
    object = g_object_new (TEST_TYPE_A, NULL);
    
    g_signal_connect (G_OBJECT (object), "property_changed", G_CALLBACK(on_prop_changed), NULL);
    
    g_signal_add_emission_hook (g_signal_lookup("property_changed", TEST_TYPE_A),
    0, prop_changed_hook,  NULL, NULL);
    
    g_object_set (object, "pro", 1, NULL);
    
    return 0;
}


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]