diff --git a/libvips/iofuncs/object.c b/libvips/iofuncs/object.c index 1b2136be..00fdc59a 100644 --- a/libvips/iofuncs/object.c +++ b/libvips/iofuncs/object.c @@ -396,19 +396,22 @@ static void vips_argument_instance_detach( VipsArgumentInstance *argument_instance ) { VipsObject *object = argument_instance->object; + VipsArgumentClass *argument_class = argument_instance->argument_class; + GObject *member = G_STRUCT_MEMBER( GObject *, object, + argument_class->offset ); if( argument_instance->close_id ) { - if( g_signal_handler_is_connected( object, + if( g_signal_handler_is_connected( member, argument_instance->close_id ) ) - g_signal_handler_disconnect( object, + g_signal_handler_disconnect( member, argument_instance->close_id ); argument_instance->close_id = 0; } if( argument_instance->invalidate_id ) { - if( g_signal_handler_is_connected( object, + if( g_signal_handler_is_connected( member, argument_instance->invalidate_id ) ) - g_signal_handler_disconnect( object, + g_signal_handler_disconnect( member, argument_instance->invalidate_id ); argument_instance->invalidate_id = 0; } @@ -739,14 +742,12 @@ vips_object_get_argument_priority( VipsObject *object, const char *name ) } static void -vips_object_clear_member( VipsObject *object, GParamSpec *pspec, - GObject **member ) +vips_object_clear_member( VipsArgumentInstance *argument_instance ) { - VipsObjectClass *class = VIPS_OBJECT_GET_CLASS( object ); - VipsArgumentClass *argument_class = (VipsArgumentClass *) - vips__argument_table_lookup( class->argument_table, pspec ); - VipsArgumentInstance *argument_instance = - vips__argument_get_instance( argument_class, object ); + VipsObject *object = argument_instance->object; + VipsArgumentClass *argument_class = argument_instance->argument_class; + GObject **member = &G_STRUCT_MEMBER( GObject *, object, + argument_class->offset ); vips_argument_instance_detach( argument_instance ); @@ -933,7 +934,12 @@ static void vips_object_arg_invalidate( GObject *argument, VipsArgumentInstance *argument_instance ) { - vips_operation_invalidate( VIPS_OPERATION( argument ) ); + /* Image @argument has signalled "invalidate" ... resignal on our + * operation. + */ + if( VIPS_IS_OPERATION( argument_instance->object ) ) + vips_operation_invalidate( + VIPS_OPERATION( argument_instance->object ) ); } static void @@ -963,10 +969,11 @@ vips__object_set_member( VipsObject *object, GParamSpec *pspec, vips__argument_table_lookup( class->argument_table, pspec ); VipsArgumentInstance *argument_instance = vips__argument_get_instance( argument_class, object ); + GType otype = G_PARAM_SPEC_VALUE_TYPE( pspec ); g_assert( argument_instance ); - vips_object_clear_member( object, pspec, member ); + vips_object_clear_member( argument_instance ); g_assert( !*member ); *member = argument; @@ -974,7 +981,7 @@ vips__object_set_member( VipsObject *object, GParamSpec *pspec, if( *member ) { if( argument_class->flags & VIPS_ARGUMENT_INPUT ) { #ifdef DEBUG_REF - printf( "vips_object_set_member: vips object: " ); + printf( "vips__object_set_member: vips object: " ); vips_object_print_name( object ); printf( " refers to gobject %s (%p)\n", G_OBJECT_TYPE_NAME( *member ), *member ); @@ -985,17 +992,10 @@ vips__object_set_member( VipsObject *object, GParamSpec *pspec, /* Ref the argument. */ g_object_ref( *member ); - - g_assert( !argument_instance->invalidate_id ); - argument_instance->invalidate_id = - g_signal_connect( *member, "invalidate", - G_CALLBACK( - vips_object_arg_invalidate ), - argument_instance ); } else if( argument_class->flags & VIPS_ARGUMENT_OUTPUT ) { #ifdef DEBUG_REF - printf( "vips_object_set_member: gobject %s (%p)\n", + printf( "vips__object_set_member: gobject %s (%p)\n", G_OBJECT_TYPE_NAME( *member ), *member ); printf( " refers to vips object: " ); vips_object_print_name( object ); @@ -1006,10 +1006,23 @@ vips__object_set_member( VipsObject *object, GParamSpec *pspec, /* The argument reffs us. */ g_object_ref( object ); + } + } - /* FIXME ... could use a NULLing weakref - */ + if( *member && + g_type_is_a( otype, VIPS_TYPE_IMAGE ) ) { + if( argument_class->flags & VIPS_ARGUMENT_INPUT ) { + g_assert( !argument_instance->invalidate_id ); + + argument_instance->invalidate_id = + g_signal_connect( *member, "invalidate", + G_CALLBACK( + vips_object_arg_invalidate ), + argument_instance ); + } + else if( argument_class->flags & VIPS_ARGUMENT_OUTPUT ) { g_assert( !argument_instance->close_id ); + argument_instance->close_id = g_signal_connect( *member, "close", G_CALLBACK( vips_object_arg_close ), @@ -1122,7 +1135,7 @@ vips_object_set_property( GObject *gobject, GObject **member = &G_STRUCT_MEMBER( GObject *, object, argument_class->offset ); - vips__object_set_member( object, pspec, member, + vips__object_set_member( object, pspec, member, g_value_get_object( value ) ); } else if( G_IS_PARAM_SPEC_INT( pspec ) ) {