This commit is contained in:
John Cupitt 2008-12-08 09:42:22 +00:00
parent 534c05c567
commit 3c28a75ede

View File

@ -106,39 +106,38 @@ vips_object_print( VipsObject *object )
/* Free a VipsArgumentInstance ... VipsArgumentClass can just be g_free()d. /* Free a VipsArgumentInstance ... VipsArgumentClass can just be g_free()d.
*/ */
static void static void
vips_argument_instance_free (VipsArgumentInstance *argument_instance) vips_argument_instance_free( VipsArgumentInstance *argument_instance )
{ {
if (argument_instance->destroy_id) { if( argument_instance->destroy_id ) {
g_signal_handler_disconnect (argument_instance->object, g_signal_handler_disconnect( argument_instance->object,
argument_instance->destroy_id); argument_instance->destroy_id );
argument_instance->destroy_id = 0; argument_instance->destroy_id = 0;
} }
g_free (argument_instance); g_free( argument_instance );
} }
VipsArgument * VipsArgument *
vips__argument_table_lookup (VipsArgumentTable *table, vips__argument_table_lookup( VipsArgumentTable *table, GParamSpec *pspec )
GParamSpec *pspec)
{ {
return (g_hash_table_lookup (table, pspec)); return( g_hash_table_lookup( table, pspec ) );
} }
static void static void
vips_argument_table_replace (VipsArgumentTable *table, VipsArgument *argument) vips_argument_table_replace( VipsArgumentTable *table, VipsArgument *argument )
{ {
g_hash_table_replace (table, argument->pspec, argument); g_hash_table_replace( table, argument->pspec, argument );
} }
static void static void
vips_argument_table_destroy (VipsArgumentTable *table) vips_argument_table_destroy( VipsArgumentTable *table )
{ {
g_hash_table_destroy (table); g_hash_table_destroy( table );
} }
static void * static void *
vips_argument_init_sub (VipsObject *object, GParamSpec *pspec, vips_argument_init2( VipsObject *object, GParamSpec *pspec,
VipsArgumentClass *argument_class, VipsArgumentClass *argument_class,
VipsArgumentInstance *argument_instance) VipsArgumentInstance *argument_instance )
{ {
VipsArgument *argument; VipsArgument *argument;
@ -149,9 +148,9 @@ vips_argument_init_sub (VipsObject *object, GParamSpec *pspec,
/* argument_instance should be NULL since we've not set it yet. /* argument_instance should be NULL since we've not set it yet.
*/ */
g_assert (argument_instance == NULL); g_assert( argument_instance == NULL );
argument_instance = g_new (VipsArgumentInstance, 1); argument_instance = g_new( VipsArgumentInstance, 1 );
argument = (VipsArgument *) argument_instance; argument = (VipsArgument *) argument_instance;
argument->pspec = ((VipsArgument *) argument_class)->pspec; argument->pspec = ((VipsArgument *) argument_class)->pspec;
@ -159,9 +158,9 @@ vips_argument_init_sub (VipsObject *object, GParamSpec *pspec,
argument_instance->assigned = FALSE; argument_instance->assigned = FALSE;
argument_instance->destroy_id = 0; argument_instance->destroy_id = 0;
vips_argument_table_replace (object->argument_table, argument); vips_argument_table_replace( object->argument_table, argument );
return (NULL); return( NULL );
} }
/* Create a VipsArgumentInstance for each installed argument property. Ideally /* Create a VipsArgumentInstance for each installed argument property. Ideally
@ -169,105 +168,102 @@ vips_argument_init_sub (VipsObject *object, GParamSpec *pspec,
* to work then :-( so we have to delay it until first access. * to work then :-( so we have to delay it until first access.
*/ */
static void static void
vips_argument_init (VipsObject *object) vips_argument_init( VipsObject *object )
{ {
if( !object->argument_table ) { if( !object->argument_table ) {
object->argument_table = g_hash_table_new_full (g_direct_hash, object->argument_table = g_hash_table_new_full( g_direct_hash,
g_direct_equal, NULL, g_direct_equal, NULL,
(GDestroyNotify) vips_argument_instance_free); (GDestroyNotify) vips_argument_instance_free );
/* Make a VipsArgumentInstance for each installed argument /* Make a VipsArgumentInstance for each installed argument
* property. * property.
*/ */
vips__argument_map (object, vips__argument_map( object,
(VipsArgumentMapFn) vips_argument_init_sub, NULL, NULL); (VipsArgumentMapFn) vips_argument_init2, NULL, NULL );
} }
} }
/* Convenience ... given the VipsArgumentClass, get the VipsArgumentInstance. /* Convenience ... given the VipsArgumentClass, get the VipsArgumentInstance.
*/ */
VipsArgumentInstance * VipsArgumentInstance *
vips__argument_get_instance (VipsArgumentClass *argument_class, vips__argument_get_instance( VipsArgumentClass *argument_class,
VipsObject *object) VipsObject *object )
{ {
/* Make sure the instance args are built. /* Make sure the instance args are built.
*/ */
vips_argument_init (object); vips_argument_init( object );
return ((VipsArgumentInstance *) return( (VipsArgumentInstance *)
vips__argument_table_lookup (object->argument_table, vips__argument_table_lookup( object->argument_table,
((VipsArgument *) argument_class)->pspec)); ((VipsArgument *) argument_class)->pspec ) );
} }
/* Loop over the vips_arguments to an object. /* Loop over the vips_arguments to an object.
*
* Note: this code copy-pasted into vips_operation_call_valist(), keep in sync.
*/ */
void * void *
vips__argument_map (VipsObject *object, VipsArgumentMapFn fn, void *a, void *b) vips__argument_map( VipsObject *object, VipsArgumentMapFn fn, void *a, void *b )
{ {
VipsObjectClass *object_class = VIPS_OBJECT_GET_CLASS (object); VipsObjectClass *class = VIPS_OBJECT_GET_CLASS( object );
GSList *p; GSList *p;
for (p = object_class->argument_table_traverse; p; p = p->next) { for( p = class->argument_table_traverse; p; p = p->next ) {
VipsArgumentClass *argument_class = VipsArgumentClass *argument_class =
(VipsArgumentClass *) p->data; (VipsArgumentClass *) p->data;
VipsArgument *argument = VipsArgument *argument = (VipsArgument *) argument_class;
(VipsArgument *) argument_class;
GParamSpec *pspec = argument->pspec; GParamSpec *pspec = argument->pspec;
VipsArgumentInstance *argument_instance = VipsArgumentInstance *argument_instance =
vips__argument_get_instance (argument_class, object); vips__argument_get_instance( argument_class, object );
/* We have many props on the arg table ... filter out the ones /* We have many props on the arg table ... filter out the ones
* for this class. * for this class.
*/ */
if (g_object_class_find_property (G_OBJECT_CLASS (object_class), if( g_object_class_find_property( G_OBJECT_CLASS( class ),
pspec->name) == pspec) { pspec->name ) == pspec ) {
void *result; void *result;
if ((result = fn (object, pspec, if( (result = fn( object, pspec,
argument_class, argument_instance, a, b))) argument_class, argument_instance, a, b )) )
return (result); return( result );
} }
} }
return (NULL); return( NULL );
} }
static void static void
vips_object_clear_object (VipsObject *object, GParamSpec *pspec) vips_object_clear_object( VipsObject *object, GParamSpec *pspec )
{ {
VipsObjectClass *class = VIPS_OBJECT_GET_CLASS (object); VipsObjectClass *class = VIPS_OBJECT_GET_CLASS( object );
VipsArgumentClass *argument_class = (VipsArgumentClass *) VipsArgumentClass *argument_class = (VipsArgumentClass *)
vips__argument_table_lookup (class->argument_table, pspec); vips__argument_table_lookup( class->argument_table, pspec );
VipsArgumentInstance *argument_instance = VipsArgumentInstance *argument_instance =
vips__argument_get_instance (argument_class, object); vips__argument_get_instance( argument_class, object );
GObject **member = &G_STRUCT_MEMBER (GObject *, object, GObject **member = &G_STRUCT_MEMBER( GObject *, object,
argument_class->offset); argument_class->offset );
if (*member) { if( *member ) {
if (argument_class->flags & VIPS_ARGUMENT_INPUT) { if( argument_class->flags & VIPS_ARGUMENT_INPUT ) {
#ifdef DEBUG_REF #ifdef DEBUG_REF
printf ("vips_object_clear_object: vips object: "); printf( "vips_object_clear_object: vips object: " );
vips_object_print (object); vips_object_print( object );
printf (" no longer refers to gobject %s (%p)\n", printf( " no longer refers to gobject %s (%p)\n",
G_OBJECT_TYPE_NAME (*member), *member); G_OBJECT_TYPE_NAME( *member ), *member );
printf (" count down to %d\n", printf( " count down to %d\n",
G_OBJECT (*member)->ref_count - 1); G_OBJECT( *member )->ref_count - 1 );
#endif /*DEBUG_REF*/ #endif /*DEBUG_REF*/
/* We reffed the object. /* We reffed the object.
*/ */
g_object_unref (*member); g_object_unref( *member );
} }
else if (argument_class->flags & VIPS_ARGUMENT_OUTPUT) { else if( argument_class->flags & VIPS_ARGUMENT_OUTPUT ) {
#ifdef DEBUG_REF #ifdef DEBUG_REF
printf ("vips_object_clear_object: gobject %s (%p)\n", printf( "vips_object_clear_object: gobject %s (%p)\n",
G_OBJECT_TYPE_NAME (*member), *member); G_OBJECT_TYPE_NAME( *member ), *member );
printf (" no longer refers to vips object: "); printf( " no longer refers to vips object: " );
vips_object_print (object); vips_object_print( object );
printf (" count down to %d\n", printf( " count down to %d\n",
G_OBJECT (object)->ref_count - 1); G_OBJECT( object )->ref_count - 1 );
#endif /*DEBUG_REF*/ #endif /*DEBUG_REF*/
/* The object reffed us. Stop listening link to the /* The object reffed us. Stop listening link to the
@ -275,14 +271,14 @@ vips_object_clear_object (VipsObject *object, GParamSpec *pspec)
* object being destroyed, in which case the handler * object being destroyed, in which case the handler
* will already have been disconnected for us. * will already have been disconnected for us.
*/ */
if( g_signal_handler_is_connected (object, if( g_signal_handler_is_connected( object,
argument_instance->destroy_id)) argument_instance->destroy_id ) )
g_signal_handler_disconnect (object, g_signal_handler_disconnect( object,
argument_instance->destroy_id); argument_instance->destroy_id );
argument_instance->destroy_id = 0; argument_instance->destroy_id = 0;
*member = NULL; *member = NULL;
g_object_unref (object); g_object_unref( object );
} }
*member = NULL; *member = NULL;
@ -292,38 +288,39 @@ vips_object_clear_object (VipsObject *object, GParamSpec *pspec)
/* Free any args which are holding resources. /* Free any args which are holding resources.
*/ */
static void * static void *
vips_object_dispose_argument (VipsObject *object, GParamSpec *pspec, vips_object_dispose_argument( VipsObject *object, GParamSpec *pspec,
VipsArgumentClass *argument_class, VipsArgumentClass *argument_class,
VipsArgumentInstance *argument_instance, VipsArgumentInstance *argument_instance,
void *a, void *b) void *a, void *b )
{ {
#ifdef DEBUG #ifdef DEBUG
printf ("vips_object_dispose_argument: %s.%s\n", printf( "vips_object_dispose_argument: %s.%s\n",
object->name, pspec->name); object->name, pspec->name );
#endif /*DEBUG*/ #endif /*DEBUG*/
g_assert (((VipsArgument *) argument_class)->pspec == pspec); g_assert( ((VipsArgument *) argument_class)->pspec == pspec );
g_assert (((VipsArgument *) argument_instance)->pspec == pspec); g_assert( ((VipsArgument *) argument_instance)->pspec == pspec );
if (G_IS_PARAM_SPEC_STRING (pspec)) { if( G_IS_PARAM_SPEC_STRING( pspec ) ) {
char **member = &G_STRUCT_MEMBER (char *, object, char **member = &G_STRUCT_MEMBER( char *, object,
argument_class->offset); argument_class->offset );
IM_FREE (*member); IM_FREE( *member );
} }
else if (G_IS_PARAM_SPEC_OBJECT (pspec)) else if( G_IS_PARAM_SPEC_OBJECT( pspec ) )
vips_object_clear_object (object, pspec); vips_object_clear_object( object, pspec );
else if (G_IS_PARAM_SPEC_BOXED (pspec)) { else if( G_IS_PARAM_SPEC_BOXED( pspec ) ) {
gpointer *member = &G_STRUCT_MEMBER (gpointer, object, gpointer *member = &G_STRUCT_MEMBER( gpointer, object,
argument_class->offset); argument_class->offset );
if (*member) { if( *member ) {
g_boxed_free (G_PARAM_SPEC_VALUE_TYPE (pspec), *member); g_boxed_free( G_PARAM_SPEC_VALUE_TYPE( pspec ),
*member );
*member = NULL; *member = NULL;
} }
} }
return (NULL); return( NULL );
} }
static void static void
@ -338,8 +335,8 @@ vips_object_dispose( GObject *gobject )
/* Clear all our arguments: they may be holding refs we should drop. /* Clear all our arguments: they may be holding refs we should drop.
*/ */
vips__argument_map (object, vips__argument_map( object,
vips_object_dispose_argument, NULL, NULL); vips_object_dispose_argument, NULL, NULL );
G_OBJECT_CLASS( vips_object_parent_class )->dispose( gobject ); G_OBJECT_CLASS( vips_object_parent_class )->dispose( gobject );
} }
@ -354,90 +351,90 @@ vips_object_finalize( GObject *gobject )
vips_object_print( object ); vips_object_print( object );
#endif /*DEBUG*/ #endif /*DEBUG*/
IM_FREEF (vips_argument_table_destroy, object->argument_table); IM_FREEF( vips_argument_table_destroy, object->argument_table );
IM_FREE( object->name ); IM_FREE( object->name );
G_OBJECT_CLASS( vips_object_parent_class )->finalize( gobject ); G_OBJECT_CLASS( vips_object_parent_class )->finalize( gobject );
} }
static void static void
vips_object_arg_destroy (GObject *argument, vips_object_arg_destroy( GObject *argument,
VipsArgumentInstance *argument_instance) VipsArgumentInstance *argument_instance )
{ {
VipsObject *object = argument_instance->object; VipsObject *object = argument_instance->object;
GParamSpec *pspec = ((VipsArgument *) argument_instance)->pspec; GParamSpec *pspec = ((VipsArgument *) argument_instance)->pspec;
/* Argument had reffed us ... now it's being destroyed, so we unref. /* Argument had reffed us ... now it's being destroyed, so we unref.
*/ */
vips_object_clear_object (object, pspec); vips_object_clear_object( object, pspec );
} }
static void static void
vips_object_set_object (VipsObject *object, GParamSpec *pspec, vips_object_set_object( VipsObject *object, GParamSpec *pspec,
GObject *argument) GObject *argument )
{ {
VipsObjectClass *class = VIPS_OBJECT_GET_CLASS (object); VipsObjectClass *class = VIPS_OBJECT_GET_CLASS( object );
VipsArgumentClass *argument_class = (VipsArgumentClass *) VipsArgumentClass *argument_class = (VipsArgumentClass *)
vips__argument_table_lookup (class->argument_table, pspec); vips__argument_table_lookup( class->argument_table, pspec );
VipsArgumentInstance *argument_instance = VipsArgumentInstance *argument_instance =
vips__argument_get_instance (argument_class, object); vips__argument_get_instance( argument_class, object );
GObject **member = &G_STRUCT_MEMBER (GObject *, object, GObject **member = &G_STRUCT_MEMBER( GObject *, object,
argument_class->offset); argument_class->offset );
g_assert (!*member); g_assert( !*member );
*member = argument; *member = argument;
if (*member) { if( *member ) {
if (argument_class->flags & VIPS_ARGUMENT_INPUT) { if( argument_class->flags & VIPS_ARGUMENT_INPUT ) {
#ifdef DEBUG_REF #ifdef DEBUG_REF
printf ("vips_object_set_object: vips object: "); printf( "vips_object_set_object: vips object: " );
vips_object_print (object); vips_object_print( object );
printf (" refers to gobject %s (%p)\n", printf( " refers to gobject %s (%p)\n",
G_OBJECT_TYPE_NAME (*member), *member); G_OBJECT_TYPE_NAME( *member ), *member );
printf (" count up to %d\n", printf( " count up to %d\n",
G_OBJECT (*member)->ref_count); G_OBJECT( *member )->ref_count );
#endif /*DEBUG_REF*/ #endif /*DEBUG_REF*/
/* Ref the argument. /* Ref the argument.
*/ */
g_object_ref (*member); g_object_ref( *member );
} }
else if (argument_class->flags & VIPS_ARGUMENT_OUTPUT) { else if( argument_class->flags & VIPS_ARGUMENT_OUTPUT ) {
#ifdef DEBUG_REF #ifdef DEBUG_REF
printf ("vips_object_set_object: gobject %s (%p)\n", printf( "vips_object_set_object: gobject %s (%p)\n",
G_OBJECT_TYPE_NAME (*member), *member); G_OBJECT_TYPE_NAME( *member ), *member );
printf (" refers to vips object: "); printf( " refers to vips object: " );
vips_object_print (object); vips_object_print( object );
printf (" count up to %d\n", printf( " count up to %d\n",
G_OBJECT (object)->ref_count); G_OBJECT (object)->ref_count );
#endif /*DEBUG_REF*/ #endif /*DEBUG_REF*/
/* The argument reffs us. /* The argument reffs us.
*/ */
g_object_ref (object); g_object_ref( object );
argument_instance->destroy_id = argument_instance->destroy_id =
g_signal_connect (*member, "destroy", g_signal_connect( *member, "destroy",
G_CALLBACK (vips_object_arg_destroy), G_CALLBACK( vips_object_arg_destroy ),
argument_instance); argument_instance );
} }
} }
} }
static void static void
vips_object_set_property (GObject *gobject, vips_object_set_property( GObject *gobject,
guint property_id, const GValue *value, GParamSpec *pspec) guint property_id, const GValue *value, GParamSpec *pspec )
{ {
VipsObject *object = VIPS_OBJECT (gobject); VipsObject *object = VIPS_OBJECT( gobject );
VipsObjectClass *class = VIPS_OBJECT_GET_CLASS (gobject); VipsObjectClass *class = VIPS_OBJECT_GET_CLASS( gobject );
VipsArgumentClass *argument_class = (VipsArgumentClass *) VipsArgumentClass *argument_class = (VipsArgumentClass *)
vips__argument_table_lookup (class->argument_table, pspec); vips__argument_table_lookup( class->argument_table, pspec );
VipsArgumentInstance *argument_instance = VipsArgumentInstance *argument_instance =
vips__argument_get_instance (argument_class, object); vips__argument_get_instance( argument_class, object );
if (!argument_class) { if( !argument_class ) {
G_OBJECT_WARN_INVALID_PROPERTY_ID (gobject, G_OBJECT_WARN_INVALID_PROPERTY_ID( gobject,
property_id, pspec); property_id, pspec );
return; return;
} }
@ -445,95 +442,96 @@ vips_object_set_property (GObject *gobject,
{ {
char *str_value; char *str_value;
str_value = g_strdup_value_contents (value); str_value = g_strdup_value_contents( value );
printf ("vips_object_set_property: %s.%s = %s\n", printf( "vips_object_set_property: %s.%s = %s\n",
object->name, pspec->name, str_value); object->name, pspec->name, str_value );
g_free (str_value); g_free( str_value );
} }
#endif /*DEBUG*/ #endif /*DEBUG*/
g_assert (((VipsArgument *) argument_class)->pspec == pspec); g_assert( ((VipsArgument *) argument_class)->pspec == pspec );
g_assert (((VipsArgument *) argument_instance)->pspec == pspec); g_assert( ((VipsArgument *) argument_instance)->pspec == pspec );
/* If this is a construct-only argument, we can only set before we've /* If this is a construct-only argument, we can only set before we've
* built. * built.
FIXME ... how do we spot end of construct? put this back FIXME ... how do we spot end of construct? put this back
if (argument_class->flags & VIPS_ARGUMENT_CONSTRUCT && if( argument_class->flags & VIPS_ARGUMENT_CONSTRUCT &&
object->done_build) { object->done_build ) {
g_warning ("%s: can't assign '%s' after construct", G_STRLOC, g_warning( "%s: can't assign '%s' after construct", G_STRLOC,
((VipsArgument *)argument_class)->pspec->name); ((VipsArgument *) argument_class)->pspec->name);
return; return;
} }
*/ */
/* If this is a set-once argument, check we've not set it before. /* If this is a set-once argument, check we've not set it before.
*/ */
if (argument_class->flags & VIPS_ARGUMENT_SET_ONCE && if( argument_class->flags & VIPS_ARGUMENT_SET_ONCE &&
argument_instance->assigned) { argument_instance->assigned ) {
g_warning ("%s: can only assign '%s' once", G_STRLOC, g_warning( "%s: can only assign '%s' once", G_STRLOC,
((VipsArgument *)argument_class)->pspec->name); ((VipsArgument *)argument_class)->pspec->name );
return; return;
} }
if (G_IS_PARAM_SPEC_STRING (pspec)) { if( G_IS_PARAM_SPEC_STRING( pspec ) ) {
char **member = &G_STRUCT_MEMBER (char *, object, char **member = &G_STRUCT_MEMBER( char *, object,
argument_class->offset); argument_class->offset );
IM_SETSTR (*member, g_value_get_string (value)); IM_SETSTR( *member, g_value_get_string( value ) );
} }
else if (G_IS_PARAM_SPEC_OBJECT (pspec)) { else if( G_IS_PARAM_SPEC_OBJECT( pspec ) ) {
/* Remove any old object. /* Remove any old object.
*/ */
vips_object_clear_object (object, pspec); vips_object_clear_object( object, pspec );
/* Install the new object. /* Install the new object.
*/ */
vips_object_set_object (object, pspec, vips_object_set_object( object, pspec,
g_value_get_object (value)); g_value_get_object( value ) );
} }
else if (G_IS_PARAM_SPEC_INT (pspec)) { else if( G_IS_PARAM_SPEC_INT( pspec ) ) {
int *member = &G_STRUCT_MEMBER (int, object, int *member = &G_STRUCT_MEMBER( int, object,
argument_class->offset); argument_class->offset );
*member = g_value_get_int (value); *member = g_value_get_int( value );
} }
else if (G_IS_PARAM_SPEC_BOOLEAN (pspec)) { else if( G_IS_PARAM_SPEC_BOOLEAN( pspec ) ) {
gboolean *member = &G_STRUCT_MEMBER (gboolean, object, gboolean *member = &G_STRUCT_MEMBER( gboolean, object,
argument_class->offset); argument_class->offset );
*member = g_value_get_boolean (value); *member = g_value_get_boolean( value );
} }
else if (G_IS_PARAM_SPEC_ENUM (pspec)) { else if( G_IS_PARAM_SPEC_ENUM( pspec ) ) {
int *member = &G_STRUCT_MEMBER (int, object, int *member = &G_STRUCT_MEMBER( int, object,
argument_class->offset); argument_class->offset );
*member = g_value_get_enum (value); *member = g_value_get_enum( value );
} }
else if (G_IS_PARAM_SPEC_POINTER (pspec)) { else if( G_IS_PARAM_SPEC_POINTER( pspec ) ) {
gpointer *member = &G_STRUCT_MEMBER (gpointer, object, gpointer *member = &G_STRUCT_MEMBER( gpointer, object,
argument_class->offset); argument_class->offset );
*member = g_value_get_pointer (value); *member = g_value_get_pointer( value );
} }
else if (G_IS_PARAM_SPEC_BOXED (pspec)) { else if( G_IS_PARAM_SPEC_BOXED( pspec ) ) {
gpointer *member = &G_STRUCT_MEMBER (gpointer, object, gpointer *member = &G_STRUCT_MEMBER( gpointer, object,
argument_class->offset); argument_class->offset );
if (*member) { if( *member ) {
g_boxed_free (G_PARAM_SPEC_VALUE_TYPE (pspec), *member); g_boxed_free( G_PARAM_SPEC_VALUE_TYPE( pspec ),
*member );
*member = NULL; *member = NULL;
} }
/* Copy the boxed into our pointer (will use eg. /* Copy the boxed into our pointer (will use eg.
* vips__object_vector_dup ()). * vips__object_vector_dup ()).
*/ */
*member = g_value_dup_boxed (value); *member = g_value_dup_boxed( value );
} }
else { else {
g_warning ("%s: '%s' has unimplemented type", G_STRLOC, g_warning( "%s: '%s' has unimplemented type", G_STRLOC,
((VipsArgument *)argument_class)->pspec->name); ((VipsArgument *) argument_class)->pspec->name );
} }
/* Note that it's now been set. /* Note that it's now been set.
@ -542,72 +540,100 @@ vips_object_set_property (GObject *gobject,
} }
static void static void
vips_object_get_property (GObject *gobject, vips_object_get_property( GObject *gobject,
guint property_id, GValue *value, GParamSpec *pspec) guint property_id, GValue *value, GParamSpec *pspec )
{ {
VipsObject *object = VIPS_OBJECT (gobject); VipsObject *object = VIPS_OBJECT( gobject );
VipsObjectClass *class = VIPS_OBJECT_GET_CLASS (gobject); VipsObjectClass *class = VIPS_OBJECT_GET_CLASS( gobject );
VipsArgumentClass *argument_class = (VipsArgumentClass *) VipsArgumentClass *argument_class = (VipsArgumentClass *)
vips__argument_table_lookup (class->argument_table, pspec); vips__argument_table_lookup( class->argument_table, pspec );
if (!argument_class) { if( !argument_class ) {
G_OBJECT_WARN_INVALID_PROPERTY_ID (gobject, G_OBJECT_WARN_INVALID_PROPERTY_ID( gobject,
property_id, pspec); property_id, pspec );
return; return;
} }
g_assert (((VipsArgument *) argument_class)->pspec == pspec); g_assert( ((VipsArgument *) argument_class)->pspec == pspec );
if (G_IS_PARAM_SPEC_STRING (pspec)) { if( G_IS_PARAM_SPEC_STRING( pspec ) ) {
char *member = G_STRUCT_MEMBER (char *, object, char *member = G_STRUCT_MEMBER( char *, object,
argument_class->offset); argument_class->offset );
g_value_set_string (value, member); g_value_set_string( value, member );
} }
else if (G_IS_PARAM_SPEC_OBJECT (pspec)) { else if( G_IS_PARAM_SPEC_OBJECT( pspec ) ) {
GObject **member = &G_STRUCT_MEMBER (GObject *, object, GObject **member = &G_STRUCT_MEMBER( GObject *, object,
argument_class->offset); argument_class->offset );
g_value_set_object (value, *member); g_value_set_object( value, *member );
} }
else if (G_IS_PARAM_SPEC_INT (pspec)) { else if( G_IS_PARAM_SPEC_INT( pspec ) ) {
int *member = &G_STRUCT_MEMBER (int, object, int *member = &G_STRUCT_MEMBER( int, object,
argument_class->offset); argument_class->offset );
g_value_set_int (value, *member); g_value_set_int( value, *member );
} }
else if (G_IS_PARAM_SPEC_BOOLEAN (pspec)) { else if( G_IS_PARAM_SPEC_BOOLEAN( pspec ) ) {
gboolean *member = &G_STRUCT_MEMBER (gboolean, object, gboolean *member = &G_STRUCT_MEMBER( gboolean, object,
argument_class->offset); argument_class->offset );
g_value_set_boolean (value, *member); g_value_set_boolean( value, *member );
} }
else if (G_IS_PARAM_SPEC_ENUM (pspec)) { else if( G_IS_PARAM_SPEC_ENUM( pspec ) ) {
int *member = &G_STRUCT_MEMBER (int, object, int *member = &G_STRUCT_MEMBER( int, object,
argument_class->offset); argument_class->offset );
g_value_set_enum (value, *member); g_value_set_enum( value, *member );
} }
else if (G_IS_PARAM_SPEC_POINTER (pspec)) { else if( G_IS_PARAM_SPEC_POINTER( pspec ) ) {
gpointer *member = &G_STRUCT_MEMBER (gpointer, object, gpointer *member = &G_STRUCT_MEMBER( gpointer, object,
argument_class->offset); argument_class->offset );
g_value_set_pointer (value, *member); g_value_set_pointer( value, *member );
} }
else if (G_IS_PARAM_SPEC_BOXED (pspec)) { else if( G_IS_PARAM_SPEC_BOXED( pspec ) ) {
gpointer *member = &G_STRUCT_MEMBER (gpointer, object, gpointer *member = &G_STRUCT_MEMBER( gpointer, object,
argument_class->offset); argument_class->offset );
/* Copy the boxed into our pointer (will use eg. /* Copy the boxed into our pointer (will use eg.
* vips__object_vector_dup ()). * vips__object_vector_dup ()).
*/ */
g_value_set_boxed (value, *member); g_value_set_boxed( value, *member );
} }
else { else {
g_warning ("%s: unimplemented property type", G_STRLOC); g_warning( "%s: unimplemented property type", G_STRLOC );
} }
} }
static GObject *
vips_object_constructor( GType gtype,
guint n_properties, GObjectConstructParam *properties )
{
GObject *obj;
#ifdef DEBUG
printf( "vips_object_constructor\n" );
#endif /*DEBUG*/
/* This will build the object and set the constructor params.
*/
obj = G_OBJECT_CLASS( vips_object_parent_class )->constructor(
gtype, n_properties, properties );
/* Check exactly all required params have been set.
*/
#ifdef DEBUG
printf( "vips_object_constructor: checking params\n" );
#endif /*DEBUG*/
/* Set something to indicate that we have constructed, then check that
* in set_property to make sure we only set those during construct.
*/
return( obj );
}
static void static void
vips_object_real_changed( VipsObject *object ) vips_object_real_changed( VipsObject *object )
{ {
@ -645,6 +671,7 @@ vips_object_class_init( VipsObjectClass *class )
gobject_class->finalize = vips_object_finalize; gobject_class->finalize = vips_object_finalize;
gobject_class->set_property = vips_object_set_property; gobject_class->set_property = vips_object_set_property;
gobject_class->get_property = vips_object_get_property; gobject_class->get_property = vips_object_get_property;
gobject_class->constructor = vips_object_constructor;
class->changed = vips_object_real_changed; class->changed = vips_object_real_changed;
class->print_class = vips_object_real_print_class; class->print_class = vips_object_real_print_class;