mirror of
https://gitlab.gnome.org/GNOME/gimp.git
synced 2025-07-03 17:33:25 +00:00
libgimp: memory/lifecycle manage the new libgmp proxy objects
Turn GimpPlugIn into the main factory for all proxies and keep the main hash tables there. The hash tables keep the initial reference. For each GimpProcedure::run(), have s "sub-factory" which hands out proxies to the actual procedure code. Each run() has hash tables of its own which hold additional references. When run() is done, get rid of its hash tables and their references, *and* drop the main plug-in reference counts from the global hashes if the proxies' refcount has dropped to one.
This commit is contained in:
parent
e3fdf254e0
commit
75bf3865b8
7 changed files with 462 additions and 152 deletions
|
@ -23,7 +23,11 @@
|
||||||
|
|
||||||
#include "gimp.h"
|
#include "gimp.h"
|
||||||
|
|
||||||
#include "gimppixbuf.h"
|
#include "libgimpbase/gimpwire.h" /* FIXME kill this include */
|
||||||
|
|
||||||
|
#include "gimpplugin-private.h"
|
||||||
|
#include "gimpprocedure-private.h"
|
||||||
|
|
||||||
|
|
||||||
enum
|
enum
|
||||||
{
|
{
|
||||||
|
@ -32,13 +36,12 @@ enum
|
||||||
N_PROPS
|
N_PROPS
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
struct _GimpDisplayPrivate
|
struct _GimpDisplayPrivate
|
||||||
{
|
{
|
||||||
gint id;
|
gint id;
|
||||||
};
|
};
|
||||||
|
|
||||||
static GHashTable *gimp_displays = NULL;
|
|
||||||
|
|
||||||
|
|
||||||
static void gimp_display_set_property (GObject *object,
|
static void gimp_display_set_property (GObject *object,
|
||||||
guint property_id,
|
guint property_id,
|
||||||
|
@ -49,12 +52,14 @@ static void gimp_display_get_property (GObject *object,
|
||||||
GValue *value,
|
GValue *value,
|
||||||
GParamSpec *pspec);
|
GParamSpec *pspec);
|
||||||
|
|
||||||
|
|
||||||
G_DEFINE_TYPE_WITH_PRIVATE (GimpDisplay, gimp_display, G_TYPE_OBJECT)
|
G_DEFINE_TYPE_WITH_PRIVATE (GimpDisplay, gimp_display, G_TYPE_OBJECT)
|
||||||
|
|
||||||
#define parent_class gimp_display_parent_class
|
#define parent_class gimp_display_parent_class
|
||||||
|
|
||||||
static GParamSpec *props[N_PROPS] = { NULL, };
|
static GParamSpec *props[N_PROPS] = { NULL, };
|
||||||
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
gimp_display_class_init (GimpDisplayClass *klass)
|
gimp_display_class_init (GimpDisplayClass *klass)
|
||||||
{
|
{
|
||||||
|
@ -121,8 +126,7 @@ gimp_display_get_property (GObject *object,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* Public API. */
|
/* Public API */
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* gimp_display_get_id:
|
* gimp_display_get_id:
|
||||||
|
@ -142,44 +146,25 @@ gimp_display_get_id (GimpDisplay *display)
|
||||||
* gimp_display_get_by_id:
|
* gimp_display_get_by_id:
|
||||||
* @display_id: The display id.
|
* @display_id: The display id.
|
||||||
*
|
*
|
||||||
* Creates a #GimpDisplay representing @display_id.
|
* Returns a #GimpDisplay representing @display_id.
|
||||||
*
|
*
|
||||||
* Returns: (nullable) (transfer none): a #GimpDisplay for @display_id or
|
* Returns: (nullable) (transfer none): a #GimpDisplay for @display_id or
|
||||||
* %NULL if @display_id does not represent a valid display.
|
* %NULL if @display_id does not represent a valid display.
|
||||||
* The object belongs to libgimp and you should not free it.
|
* The object belongs to libgimp and you must not modify or
|
||||||
|
* unref it.
|
||||||
*
|
*
|
||||||
* Since: 3.0
|
* Since: 3.0
|
||||||
**/
|
**/
|
||||||
GimpDisplay *
|
GimpDisplay *
|
||||||
gimp_display_get_by_id (gint32 display_id)
|
gimp_display_get_by_id (gint32 display_id)
|
||||||
{
|
{
|
||||||
GimpDisplay *display = NULL;
|
if (display_id > 0)
|
||||||
|
|
||||||
if (G_UNLIKELY (! gimp_displays))
|
|
||||||
gimp_displays = g_hash_table_new_full (g_direct_hash,
|
|
||||||
g_direct_equal,
|
|
||||||
NULL,
|
|
||||||
(GDestroyNotify) g_object_unref);
|
|
||||||
|
|
||||||
if (! _gimp_display_is_valid (display_id))
|
|
||||||
{
|
{
|
||||||
g_hash_table_remove (gimp_displays, GINT_TO_POINTER (display_id));
|
GimpPlugIn *plug_in = gimp_get_plug_in ();
|
||||||
}
|
GimpProcedure *procedure = _gimp_plug_in_get_procedure (plug_in);
|
||||||
else
|
|
||||||
{
|
|
||||||
display = g_hash_table_lookup (gimp_displays,
|
|
||||||
GINT_TO_POINTER (display_id));
|
|
||||||
|
|
||||||
if (! display)
|
return _gimp_procedure_get_display (procedure, display_id);
|
||||||
{
|
|
||||||
display = g_object_new (GIMP_TYPE_DISPLAY,
|
|
||||||
"id", display_id,
|
|
||||||
NULL);
|
|
||||||
g_hash_table_insert (gimp_displays,
|
|
||||||
GINT_TO_POINTER (display_id),
|
|
||||||
display);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return display;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
|
@ -22,7 +22,12 @@
|
||||||
|
|
||||||
#include "gimp.h"
|
#include "gimp.h"
|
||||||
|
|
||||||
|
#include "libgimpbase/gimpwire.h" /* FIXME kill this include */
|
||||||
|
|
||||||
#include "gimppixbuf.h"
|
#include "gimppixbuf.h"
|
||||||
|
#include "gimpplugin-private.h"
|
||||||
|
#include "gimpprocedure-private.h"
|
||||||
|
|
||||||
|
|
||||||
enum
|
enum
|
||||||
{
|
{
|
||||||
|
@ -31,13 +36,12 @@ enum
|
||||||
N_PROPS
|
N_PROPS
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
struct _GimpImagePrivate
|
struct _GimpImagePrivate
|
||||||
{
|
{
|
||||||
gint id;
|
gint id;
|
||||||
};
|
};
|
||||||
|
|
||||||
static GHashTable *gimp_images = NULL;
|
|
||||||
|
|
||||||
|
|
||||||
static void gimp_image_set_property (GObject *object,
|
static void gimp_image_set_property (GObject *object,
|
||||||
guint property_id,
|
guint property_id,
|
||||||
|
@ -48,12 +52,14 @@ static void gimp_image_get_property (GObject *object,
|
||||||
GValue *value,
|
GValue *value,
|
||||||
GParamSpec *pspec);
|
GParamSpec *pspec);
|
||||||
|
|
||||||
|
|
||||||
G_DEFINE_TYPE_WITH_PRIVATE (GimpImage, gimp_image, G_TYPE_OBJECT)
|
G_DEFINE_TYPE_WITH_PRIVATE (GimpImage, gimp_image, G_TYPE_OBJECT)
|
||||||
|
|
||||||
#define parent_class gimp_image_parent_class
|
#define parent_class gimp_image_parent_class
|
||||||
|
|
||||||
static GParamSpec *props[N_PROPS] = { NULL, };
|
static GParamSpec *props[N_PROPS] = { NULL, };
|
||||||
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
gimp_image_class_init (GimpImageClass *klass)
|
gimp_image_class_init (GimpImageClass *klass)
|
||||||
{
|
{
|
||||||
|
@ -120,8 +126,7 @@ gimp_image_get_property (GObject *object,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* Public API. */
|
/* Public API */
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* gimp_image_get_id:
|
* gimp_image_get_id:
|
||||||
|
@ -143,42 +148,23 @@ gimp_image_get_id (GimpImage *image)
|
||||||
*
|
*
|
||||||
* Returns: (nullable) (transfer none): a #GimpImage for @image_id or
|
* Returns: (nullable) (transfer none): a #GimpImage for @image_id or
|
||||||
* %NULL if @image_id does not represent a valid image.
|
* %NULL if @image_id does not represent a valid image.
|
||||||
* The object belongs to libgimp and you should not free it.
|
* The object belongs to libgimp and you must not modify
|
||||||
|
* or unref it.
|
||||||
*
|
*
|
||||||
* Since: 3.0
|
* Since: 3.0
|
||||||
**/
|
**/
|
||||||
GimpImage *
|
GimpImage *
|
||||||
gimp_image_get_by_id (gint32 image_id)
|
gimp_image_get_by_id (gint32 image_id)
|
||||||
{
|
{
|
||||||
GimpImage *image = NULL;
|
if (image_id > 0)
|
||||||
|
|
||||||
if (G_UNLIKELY (! gimp_images))
|
|
||||||
gimp_images = g_hash_table_new_full (g_direct_hash,
|
|
||||||
g_direct_equal,
|
|
||||||
NULL,
|
|
||||||
(GDestroyNotify) g_object_unref);
|
|
||||||
|
|
||||||
if (! _gimp_image_is_valid (image_id))
|
|
||||||
{
|
{
|
||||||
g_hash_table_remove (gimp_images, GINT_TO_POINTER (image_id));
|
GimpPlugIn *plug_in = gimp_get_plug_in ();
|
||||||
}
|
GimpProcedure *procedure = _gimp_plug_in_get_procedure (plug_in);
|
||||||
else
|
|
||||||
{
|
|
||||||
image = g_hash_table_lookup (gimp_images,
|
|
||||||
GINT_TO_POINTER (image_id));
|
|
||||||
|
|
||||||
if (! image)
|
return _gimp_procedure_get_image (procedure, image_id);
|
||||||
{
|
|
||||||
image = g_object_new (GIMP_TYPE_IMAGE,
|
|
||||||
"id", image_id,
|
|
||||||
NULL);
|
|
||||||
g_hash_table_insert (gimp_images,
|
|
||||||
GINT_TO_POINTER (image_id),
|
|
||||||
image);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return image;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -202,13 +188,14 @@ gimp_image_list (void)
|
||||||
gint i;
|
gint i;
|
||||||
|
|
||||||
ids = _gimp_image_list (&num_images);
|
ids = _gimp_image_list (&num_images);
|
||||||
|
|
||||||
for (i = 0; i < num_images; i++)
|
for (i = 0; i < num_images; i++)
|
||||||
images = g_list_prepend (images,
|
images = g_list_prepend (images,
|
||||||
gimp_image_get_by_id (ids[i]));
|
gimp_image_get_by_id (ids[i]));
|
||||||
images = g_list_reverse (images);
|
|
||||||
g_free (ids);
|
g_free (ids);
|
||||||
|
|
||||||
return images;
|
return g_list_reverse (images);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -23,7 +23,11 @@
|
||||||
|
|
||||||
#include "gimp.h"
|
#include "gimp.h"
|
||||||
|
|
||||||
#include "gimppixbuf.h"
|
#include "libgimpbase/gimpwire.h" /* FIXME kill this include */
|
||||||
|
|
||||||
|
#include "gimpplugin-private.h"
|
||||||
|
#include "gimpprocedure-private.h"
|
||||||
|
|
||||||
|
|
||||||
enum
|
enum
|
||||||
{
|
{
|
||||||
|
@ -32,13 +36,12 @@ enum
|
||||||
N_PROPS
|
N_PROPS
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
struct _GimpItemPrivate
|
struct _GimpItemPrivate
|
||||||
{
|
{
|
||||||
gint id;
|
gint id;
|
||||||
};
|
};
|
||||||
|
|
||||||
static GHashTable *gimp_items = NULL;
|
|
||||||
|
|
||||||
|
|
||||||
static void gimp_item_set_property (GObject *object,
|
static void gimp_item_set_property (GObject *object,
|
||||||
guint property_id,
|
guint property_id,
|
||||||
|
@ -49,12 +52,14 @@ static void gimp_item_get_property (GObject *object,
|
||||||
GValue *value,
|
GValue *value,
|
||||||
GParamSpec *pspec);
|
GParamSpec *pspec);
|
||||||
|
|
||||||
|
|
||||||
G_DEFINE_ABSTRACT_TYPE_WITH_PRIVATE (GimpItem, gimp_item, G_TYPE_OBJECT)
|
G_DEFINE_ABSTRACT_TYPE_WITH_PRIVATE (GimpItem, gimp_item, G_TYPE_OBJECT)
|
||||||
|
|
||||||
#define parent_class gimp_item_parent_class
|
#define parent_class gimp_item_parent_class
|
||||||
|
|
||||||
static GParamSpec *props[N_PROPS] = { NULL, };
|
static GParamSpec *props[N_PROPS] = { NULL, };
|
||||||
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
gimp_item_class_init (GimpItemClass *klass)
|
gimp_item_class_init (GimpItemClass *klass)
|
||||||
{
|
{
|
||||||
|
@ -142,89 +147,29 @@ gimp_item_get_id (GimpItem *item)
|
||||||
* gimp_item_get_by_id:
|
* gimp_item_get_by_id:
|
||||||
* @item_id: The item id.
|
* @item_id: The item id.
|
||||||
*
|
*
|
||||||
* Creates a #GimpItem representing @item_id. Since #GimpItem is an
|
* Returns a #GimpItem representing @item_id. Since #GimpItem is an
|
||||||
* abstract class, the object real type will actually be the proper
|
* abstract class, the real object type will actually be the proper
|
||||||
* subclass.
|
* subclass.
|
||||||
*
|
*
|
||||||
* Returns: (nullable) (transfer none): a #GimpItem for @item_id or
|
* Returns: (nullable) (transfer none): a #GimpItem for @item_id or
|
||||||
* %NULL if @item_id does not represent a valid item.
|
* %NULL if @item_id does not represent a valid item.
|
||||||
* The object belongs to libgimp and you should not free it.
|
* The object belongs to libgimp and you must not modify
|
||||||
|
* or unref it.
|
||||||
*
|
*
|
||||||
* Since: 3.0
|
* Since: 3.0
|
||||||
**/
|
**/
|
||||||
GimpItem *
|
GimpItem *
|
||||||
gimp_item_get_by_id (gint32 item_id)
|
gimp_item_get_by_id (gint32 item_id)
|
||||||
{
|
{
|
||||||
GimpItem *item = NULL;
|
if (item_id > 0)
|
||||||
|
|
||||||
if (G_UNLIKELY (! gimp_items))
|
|
||||||
gimp_items = g_hash_table_new_full (g_direct_hash,
|
|
||||||
g_direct_equal,
|
|
||||||
NULL,
|
|
||||||
(GDestroyNotify) g_object_unref);
|
|
||||||
|
|
||||||
if (! _gimp_item_is_valid (item_id))
|
|
||||||
{
|
{
|
||||||
g_hash_table_remove (gimp_items, GINT_TO_POINTER (item_id));
|
GimpPlugIn *plug_in = gimp_get_plug_in ();
|
||||||
}
|
GimpProcedure *procedure = _gimp_plug_in_get_procedure (plug_in);
|
||||||
else
|
|
||||||
{
|
|
||||||
item = g_hash_table_lookup (gimp_items,
|
|
||||||
GINT_TO_POINTER (item_id));
|
|
||||||
|
|
||||||
if (item)
|
return _gimp_procedure_get_item (procedure, item_id);
|
||||||
{
|
|
||||||
/* Make sure the item is the proper class, since it could be
|
|
||||||
* reused (which means we'd have cycled over the whole int
|
|
||||||
* range; not that likely yet still possible on a very very
|
|
||||||
* long run process).
|
|
||||||
*/
|
|
||||||
if ((_gimp_item_is_layer (item_id) &&
|
|
||||||
! GIMP_IS_LAYER (item)) ||
|
|
||||||
(_gimp_item_is_layer_mask (item_id) &&
|
|
||||||
! GIMP_IS_LAYER_MASK (item)) ||
|
|
||||||
(_gimp_item_is_selection (item_id) &&
|
|
||||||
! GIMP_IS_SELECTION (item)) ||
|
|
||||||
(_gimp_item_is_channel (item_id) &&
|
|
||||||
! GIMP_IS_CHANNEL (item)) ||
|
|
||||||
(_gimp_item_is_vectors (item_id) &&
|
|
||||||
! GIMP_IS_VECTORS (item)))
|
|
||||||
{
|
|
||||||
g_hash_table_remove (gimp_items, GINT_TO_POINTER (item_id));
|
|
||||||
item = NULL;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (! item)
|
|
||||||
{
|
|
||||||
if (_gimp_item_is_layer (item_id))
|
|
||||||
item = g_object_new (GIMP_TYPE_LAYER,
|
|
||||||
"id", item_id,
|
|
||||||
NULL);
|
|
||||||
else if (_gimp_item_is_layer_mask (item_id))
|
|
||||||
item = g_object_new (GIMP_TYPE_LAYER_MASK,
|
|
||||||
"id", item_id,
|
|
||||||
NULL);
|
|
||||||
else if (_gimp_item_is_selection (item_id))
|
|
||||||
item = g_object_new (GIMP_TYPE_SELECTION,
|
|
||||||
"id", item_id,
|
|
||||||
NULL);
|
|
||||||
else if (_gimp_item_is_channel (item_id))
|
|
||||||
item = g_object_new (GIMP_TYPE_CHANNEL,
|
|
||||||
"id", item_id,
|
|
||||||
NULL);
|
|
||||||
else if (_gimp_item_is_vectors (item_id))
|
|
||||||
item = g_object_new (GIMP_TYPE_VECTORS,
|
|
||||||
"id", item_id,
|
|
||||||
NULL);
|
|
||||||
if (item)
|
|
||||||
g_hash_table_insert (gimp_items,
|
|
||||||
GINT_TO_POINTER (item_id),
|
|
||||||
item);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return item;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -239,7 +184,7 @@ gimp_item_get_by_id (gint32 item_id)
|
||||||
* Returns: (element-type GimpItem) (transfer container):
|
* Returns: (element-type GimpItem) (transfer container):
|
||||||
* The item's list of children.
|
* The item's list of children.
|
||||||
* The returned value must be freed with g_list_free(). Item
|
* The returned value must be freed with g_list_free(). Item
|
||||||
* elements belong to libgimp and must not be freed.
|
* elements belong to libgimp and must not be unrefed.
|
||||||
*
|
*
|
||||||
* Since: 3.0
|
* Since: 3.0
|
||||||
**/
|
**/
|
||||||
|
@ -256,10 +201,9 @@ gimp_item_get_children (GimpItem *item)
|
||||||
for (i = 0; i < num_items; i++)
|
for (i = 0; i < num_items; i++)
|
||||||
children = g_list_prepend (children, gimp_item_get_by_id (ids[i]));
|
children = g_list_prepend (children, gimp_item_get_by_id (ids[i]));
|
||||||
|
|
||||||
children = g_list_reverse (children);
|
|
||||||
g_free (ids);
|
g_free (ids);
|
||||||
|
|
||||||
return children;
|
return g_list_reverse (children);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -25,17 +25,26 @@
|
||||||
G_BEGIN_DECLS
|
G_BEGIN_DECLS
|
||||||
|
|
||||||
|
|
||||||
void _gimp_plug_in_query (GimpPlugIn *plug_in);
|
void _gimp_plug_in_query (GimpPlugIn *plug_in);
|
||||||
void _gimp_plug_in_init (GimpPlugIn *plug_in);
|
void _gimp_plug_in_init (GimpPlugIn *plug_in);
|
||||||
void _gimp_plug_in_run (GimpPlugIn *plug_in);
|
void _gimp_plug_in_run (GimpPlugIn *plug_in);
|
||||||
void _gimp_plug_in_quit (GimpPlugIn *plug_in);
|
void _gimp_plug_in_quit (GimpPlugIn *plug_in);
|
||||||
|
|
||||||
GIOChannel * _gimp_plug_in_get_read_channel (GimpPlugIn *plug_in);
|
GIOChannel * _gimp_plug_in_get_read_channel (GimpPlugIn *plug_in);
|
||||||
GIOChannel * _gimp_plug_in_get_write_channel (GimpPlugIn *plug_in);
|
GIOChannel * _gimp_plug_in_get_write_channel (GimpPlugIn *plug_in);
|
||||||
|
|
||||||
void _gimp_plug_in_read_expect_msg (GimpPlugIn *plug_in,
|
void _gimp_plug_in_read_expect_msg (GimpPlugIn *plug_in,
|
||||||
GimpWireMessage *msg,
|
GimpWireMessage *msg,
|
||||||
gint type);
|
gint type);
|
||||||
|
|
||||||
|
GimpProcedure * _gimp_plug_in_get_procedure (GimpPlugIn *plug_in);
|
||||||
|
|
||||||
|
GimpDisplay * _gimp_plug_in_get_display (GimpPlugIn *plug_in,
|
||||||
|
gint32 display_id);
|
||||||
|
GimpImage * _gimp_plug_in_get_image (GimpPlugIn *plug_in,
|
||||||
|
gint32 image_id);
|
||||||
|
GimpItem * _gimp_plug_in_get_item (GimpPlugIn *plug_in,
|
||||||
|
gint32 item_id);
|
||||||
|
|
||||||
|
|
||||||
G_END_DECLS
|
G_END_DECLS
|
||||||
|
|
|
@ -36,6 +36,7 @@
|
||||||
#include "gimpgpparams.h"
|
#include "gimpgpparams.h"
|
||||||
#include "gimpplugin-private.h"
|
#include "gimpplugin-private.h"
|
||||||
#include "gimpplugin_pdb.h"
|
#include "gimpplugin_pdb.h"
|
||||||
|
#include "gimpprocedure-private.h"
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -89,6 +90,11 @@ struct _GimpPlugInPrivate
|
||||||
GList *menu_branches;
|
GList *menu_branches;
|
||||||
|
|
||||||
GList *temp_procedures;
|
GList *temp_procedures;
|
||||||
|
|
||||||
|
GList *procedure_stack;
|
||||||
|
GHashTable *displays;
|
||||||
|
GHashTable *images;
|
||||||
|
GHashTable *items;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -124,13 +130,20 @@ static void gimp_plug_in_proc_run (GimpPlugIn *plug_in,
|
||||||
GPProcRun *proc_run);
|
GPProcRun *proc_run);
|
||||||
static void gimp_plug_in_temp_proc_run (GimpPlugIn *plug_in,
|
static void gimp_plug_in_temp_proc_run (GimpPlugIn *plug_in,
|
||||||
GPProcRun *proc_run);
|
GPProcRun *proc_run);
|
||||||
static void gimp_plug_in_proc_run_internal (GPProcRun *proc_run,
|
static void gimp_plug_in_proc_run_internal (GimpPlugIn *plug_in,
|
||||||
|
GPProcRun *proc_run,
|
||||||
GimpProcedure *procedure,
|
GimpProcedure *procedure,
|
||||||
GPProcReturn *proc_return);
|
GPProcReturn *proc_return);
|
||||||
static gboolean gimp_plug_in_extension_read (GIOChannel *channel,
|
static gboolean gimp_plug_in_extension_read (GIOChannel *channel,
|
||||||
GIOCondition condition,
|
GIOCondition condition,
|
||||||
gpointer data);
|
gpointer data);
|
||||||
|
|
||||||
|
static void gimp_plug_in_push_procedure (GimpPlugIn *plug_in,
|
||||||
|
GimpProcedure *procedure);
|
||||||
|
static void gimp_plug_in_pop_procedure (GimpPlugIn *plug_in,
|
||||||
|
GimpProcedure *procedure);
|
||||||
|
static void gimp_plug_in_destroy_proxies (GimpPlugIn *plug_in);
|
||||||
|
|
||||||
|
|
||||||
G_DEFINE_TYPE_WITH_PRIVATE (GimpPlugIn, gimp_plug_in, G_TYPE_OBJECT)
|
G_DEFINE_TYPE_WITH_PRIVATE (GimpPlugIn, gimp_plug_in, G_TYPE_OBJECT)
|
||||||
|
|
||||||
|
@ -225,6 +238,8 @@ gimp_plug_in_finalize (GObject *object)
|
||||||
|
|
||||||
g_clear_pointer (&plug_in->priv->menu_branches, g_list_free);
|
g_clear_pointer (&plug_in->priv->menu_branches, g_list_free);
|
||||||
|
|
||||||
|
gimp_plug_in_destroy_proxies (plug_in);
|
||||||
|
|
||||||
G_OBJECT_CLASS (parent_class)->finalize (object);
|
G_OBJECT_CLASS (parent_class)->finalize (object);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1097,7 +1112,8 @@ gimp_plug_in_proc_run (GimpPlugIn *plug_in,
|
||||||
|
|
||||||
if (procedure)
|
if (procedure)
|
||||||
{
|
{
|
||||||
gimp_plug_in_proc_run_internal (proc_run, procedure,
|
gimp_plug_in_proc_run_internal (plug_in,
|
||||||
|
proc_run, procedure,
|
||||||
&proc_return);
|
&proc_return);
|
||||||
g_object_unref (procedure);
|
g_object_unref (procedure);
|
||||||
}
|
}
|
||||||
|
@ -1118,7 +1134,8 @@ gimp_plug_in_temp_proc_run (GimpPlugIn *plug_in,
|
||||||
|
|
||||||
if (procedure)
|
if (procedure)
|
||||||
{
|
{
|
||||||
gimp_plug_in_proc_run_internal (proc_run, procedure,
|
gimp_plug_in_proc_run_internal (plug_in,
|
||||||
|
proc_run, procedure,
|
||||||
&proc_return);
|
&proc_return);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1128,7 +1145,8 @@ gimp_plug_in_temp_proc_run (GimpPlugIn *plug_in,
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
gimp_plug_in_proc_run_internal (GPProcRun *proc_run,
|
gimp_plug_in_proc_run_internal (GimpPlugIn *plug_in,
|
||||||
|
GPProcRun *proc_run,
|
||||||
GimpProcedure *procedure,
|
GimpProcedure *procedure,
|
||||||
GPProcReturn *proc_return)
|
GPProcReturn *proc_return)
|
||||||
{
|
{
|
||||||
|
@ -1141,7 +1159,10 @@ gimp_plug_in_proc_run_internal (GPProcRun *proc_run,
|
||||||
proc_run->nparams,
|
proc_run->nparams,
|
||||||
FALSE, FALSE);
|
FALSE, FALSE);
|
||||||
|
|
||||||
|
gimp_plug_in_push_procedure (plug_in, procedure);
|
||||||
return_values = gimp_procedure_run (procedure, arguments);
|
return_values = gimp_procedure_run (procedure, arguments);
|
||||||
|
gimp_plug_in_pop_procedure (plug_in, procedure);
|
||||||
|
|
||||||
gimp_value_array_unref (arguments);
|
gimp_value_array_unref (arguments);
|
||||||
|
|
||||||
proc_return->name = proc_run->name;
|
proc_return->name = proc_run->name;
|
||||||
|
@ -1162,3 +1183,202 @@ gimp_plug_in_extension_read (GIOChannel *channel,
|
||||||
|
|
||||||
return G_SOURCE_CONTINUE;
|
return G_SOURCE_CONTINUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* procedure stack / display-, image-, item-cache */
|
||||||
|
|
||||||
|
GimpProcedure *
|
||||||
|
_gimp_plug_in_get_procedure (GimpPlugIn *plug_in)
|
||||||
|
{
|
||||||
|
g_return_val_if_fail (GIMP_IS_PLUG_IN (plug_in), NULL);
|
||||||
|
g_return_val_if_fail (plug_in->priv->procedure_stack != NULL, NULL);
|
||||||
|
|
||||||
|
return plug_in->priv->procedure_stack->data;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
gimp_plug_in_push_procedure (GimpPlugIn *plug_in,
|
||||||
|
GimpProcedure *procedure)
|
||||||
|
{
|
||||||
|
plug_in->priv->procedure_stack =
|
||||||
|
g_list_prepend (plug_in->priv->procedure_stack, procedure);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
gimp_plug_in_pop_procedure (GimpPlugIn *plug_in,
|
||||||
|
GimpProcedure *procedure)
|
||||||
|
{
|
||||||
|
plug_in->priv->procedure_stack =
|
||||||
|
g_list_remove (plug_in->priv->procedure_stack, procedure);
|
||||||
|
|
||||||
|
_gimp_procedure_destroy_proxies (procedure);
|
||||||
|
|
||||||
|
if (plug_in->priv->procedure_stack)
|
||||||
|
{
|
||||||
|
GHashTableIter iter;
|
||||||
|
gpointer key, value;
|
||||||
|
|
||||||
|
g_hash_table_iter_init (&iter, plug_in->priv->displays);
|
||||||
|
while (g_hash_table_iter_next (&iter, &key, &value))
|
||||||
|
{
|
||||||
|
GObject *object = value;
|
||||||
|
|
||||||
|
if (object->ref_count == 1)
|
||||||
|
g_hash_table_iter_remove (&iter);
|
||||||
|
}
|
||||||
|
|
||||||
|
g_hash_table_iter_init (&iter, plug_in->priv->images);
|
||||||
|
while (g_hash_table_iter_next (&iter, &key, &value))
|
||||||
|
{
|
||||||
|
GObject *object = value;
|
||||||
|
|
||||||
|
if (object->ref_count == 1)
|
||||||
|
g_hash_table_iter_remove (&iter);
|
||||||
|
}
|
||||||
|
|
||||||
|
g_hash_table_iter_init (&iter, plug_in->priv->items);
|
||||||
|
while (g_hash_table_iter_next (&iter, &key, &value))
|
||||||
|
{
|
||||||
|
GObject *object = value;
|
||||||
|
|
||||||
|
if (object->ref_count == 1)
|
||||||
|
g_hash_table_iter_remove (&iter);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
gimp_plug_in_destroy_proxies (plug_in);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
GimpDisplay *
|
||||||
|
_gimp_plug_in_get_display (GimpPlugIn *plug_in,
|
||||||
|
gint32 display_id)
|
||||||
|
{
|
||||||
|
GimpDisplay *display = NULL;
|
||||||
|
|
||||||
|
g_return_val_if_fail (GIMP_IS_PLUG_IN (plug_in), NULL);
|
||||||
|
|
||||||
|
if (G_UNLIKELY (! plug_in->priv->displays))
|
||||||
|
plug_in->priv->displays =
|
||||||
|
g_hash_table_new_full (g_direct_hash,
|
||||||
|
g_direct_equal,
|
||||||
|
NULL,
|
||||||
|
(GDestroyNotify) g_object_unref);
|
||||||
|
|
||||||
|
display = g_hash_table_lookup (plug_in->priv->displays,
|
||||||
|
GINT_TO_POINTER (display_id));
|
||||||
|
|
||||||
|
if (! display)
|
||||||
|
{
|
||||||
|
display = g_object_new (GIMP_TYPE_DISPLAY,
|
||||||
|
"id", display_id,
|
||||||
|
NULL);
|
||||||
|
|
||||||
|
g_hash_table_insert (plug_in->priv->displays,
|
||||||
|
GINT_TO_POINTER (display_id),
|
||||||
|
display);
|
||||||
|
}
|
||||||
|
|
||||||
|
return display;
|
||||||
|
}
|
||||||
|
|
||||||
|
GimpImage *
|
||||||
|
_gimp_plug_in_get_image (GimpPlugIn *plug_in,
|
||||||
|
gint32 image_id)
|
||||||
|
{
|
||||||
|
GimpImage *image = NULL;
|
||||||
|
|
||||||
|
g_return_val_if_fail (GIMP_IS_PLUG_IN (plug_in), NULL);
|
||||||
|
|
||||||
|
if (G_UNLIKELY (! plug_in->priv->images))
|
||||||
|
plug_in->priv->images =
|
||||||
|
g_hash_table_new_full (g_direct_hash,
|
||||||
|
g_direct_equal,
|
||||||
|
NULL,
|
||||||
|
(GDestroyNotify) g_object_unref);
|
||||||
|
|
||||||
|
image = g_hash_table_lookup (plug_in->priv->images,
|
||||||
|
GINT_TO_POINTER (image_id));
|
||||||
|
|
||||||
|
if (! image)
|
||||||
|
{
|
||||||
|
image = g_object_new (GIMP_TYPE_IMAGE,
|
||||||
|
"id", image_id,
|
||||||
|
NULL);
|
||||||
|
|
||||||
|
g_hash_table_insert (plug_in->priv->images,
|
||||||
|
GINT_TO_POINTER (image_id),
|
||||||
|
image);
|
||||||
|
}
|
||||||
|
|
||||||
|
return image;
|
||||||
|
}
|
||||||
|
|
||||||
|
GimpItem *
|
||||||
|
_gimp_plug_in_get_item (GimpPlugIn *plug_in,
|
||||||
|
gint32 item_id)
|
||||||
|
{
|
||||||
|
GimpItem *item = NULL;
|
||||||
|
|
||||||
|
g_return_val_if_fail (GIMP_IS_PLUG_IN (plug_in), NULL);
|
||||||
|
|
||||||
|
if (G_UNLIKELY (! plug_in->priv->items))
|
||||||
|
plug_in->priv->items =
|
||||||
|
g_hash_table_new_full (g_direct_hash,
|
||||||
|
g_direct_equal,
|
||||||
|
NULL,
|
||||||
|
(GDestroyNotify) g_object_unref);
|
||||||
|
|
||||||
|
item = g_hash_table_lookup (plug_in->priv->items,
|
||||||
|
GINT_TO_POINTER (item_id));
|
||||||
|
|
||||||
|
if (! item)
|
||||||
|
{
|
||||||
|
if (_gimp_item_is_layer (item_id))
|
||||||
|
{
|
||||||
|
item = g_object_new (GIMP_TYPE_LAYER,
|
||||||
|
"id", item_id,
|
||||||
|
NULL);
|
||||||
|
}
|
||||||
|
else if (_gimp_item_is_layer_mask (item_id))
|
||||||
|
{
|
||||||
|
item = g_object_new (GIMP_TYPE_LAYER_MASK,
|
||||||
|
"id", item_id,
|
||||||
|
NULL);
|
||||||
|
}
|
||||||
|
else if (_gimp_item_is_selection (item_id))
|
||||||
|
{
|
||||||
|
item = g_object_new (GIMP_TYPE_SELECTION,
|
||||||
|
"id", item_id,
|
||||||
|
NULL);
|
||||||
|
}
|
||||||
|
else if (_gimp_item_is_channel (item_id))
|
||||||
|
{
|
||||||
|
item = g_object_new (GIMP_TYPE_CHANNEL,
|
||||||
|
"id", item_id,
|
||||||
|
NULL);
|
||||||
|
}
|
||||||
|
else if (_gimp_item_is_vectors (item_id))
|
||||||
|
{
|
||||||
|
item = g_object_new (GIMP_TYPE_VECTORS,
|
||||||
|
"id", item_id,
|
||||||
|
NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (item)
|
||||||
|
g_hash_table_insert (plug_in->priv->items,
|
||||||
|
GINT_TO_POINTER (item_id),
|
||||||
|
item);
|
||||||
|
}
|
||||||
|
|
||||||
|
return item;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
gimp_plug_in_destroy_proxies (GimpPlugIn *plug_in)
|
||||||
|
{
|
||||||
|
g_clear_pointer (&plug_in->priv->displays, g_hash_table_unref);
|
||||||
|
g_clear_pointer (&plug_in->priv->images, g_hash_table_unref);
|
||||||
|
g_clear_pointer (&plug_in->priv->items, g_hash_table_unref);
|
||||||
|
}
|
||||||
|
|
46
libgimp/gimpprocedure-private.h
Normal file
46
libgimp/gimpprocedure-private.h
Normal file
|
@ -0,0 +1,46 @@
|
||||||
|
/* GIMP - The GNU Image Manipulation Program
|
||||||
|
* Copyright (C) 1995 Spencer Kimball and Peter Mattis
|
||||||
|
*
|
||||||
|
* gimpprocedure-private.h
|
||||||
|
* Copyright (C) 2019 Michael Natterer <mitch@gimp.org>
|
||||||
|
*
|
||||||
|
* This library is free software: you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU Lesser General Public
|
||||||
|
* License as published by the Free Software Foundation; either
|
||||||
|
* version 3 of the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This library is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
* Lesser General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public
|
||||||
|
* License along with this library. If not, see
|
||||||
|
* <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#if !defined (__GIMP_H_INSIDE__) && !defined (GIMP_COMPILATION)
|
||||||
|
#error "Only <libgimp/gimp.h> can be included directly."
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef __GIMP_PROCEDURE_PRIVATE_H__
|
||||||
|
#define __GIMP_PROCEDURE_PRIVATE_H__
|
||||||
|
|
||||||
|
G_BEGIN_DECLS
|
||||||
|
|
||||||
|
/* For information look into the C source or the html documentation */
|
||||||
|
|
||||||
|
|
||||||
|
GimpDisplay * _gimp_procedure_get_display (GimpProcedure *procedure,
|
||||||
|
gint32 display_id);
|
||||||
|
GimpImage * _gimp_procedure_get_image (GimpProcedure *procedure,
|
||||||
|
gint32 image_id);
|
||||||
|
GimpItem * _gimp_procedure_get_item (GimpProcedure *procedure,
|
||||||
|
gint32 item_id);
|
||||||
|
|
||||||
|
void _gimp_procedure_destroy_proxies (GimpProcedure *procedure);
|
||||||
|
|
||||||
|
|
||||||
|
G_END_DECLS
|
||||||
|
|
||||||
|
#endif /* __GIMP_PROCEDURE_H__ */
|
|
@ -34,6 +34,7 @@
|
||||||
#include "gimppdb-private.h"
|
#include "gimppdb-private.h"
|
||||||
#include "gimpplugin-private.h"
|
#include "gimpplugin-private.h"
|
||||||
#include "gimpplugin_pdb.h"
|
#include "gimpplugin_pdb.h"
|
||||||
|
#include "gimpprocedure-private.h"
|
||||||
|
|
||||||
#include "libgimp-intl.h"
|
#include "libgimp-intl.h"
|
||||||
|
|
||||||
|
@ -82,6 +83,10 @@ struct _GimpProcedurePrivate
|
||||||
GDestroyNotify run_data_destroy;
|
GDestroyNotify run_data_destroy;
|
||||||
|
|
||||||
gboolean installed;
|
gboolean installed;
|
||||||
|
|
||||||
|
GHashTable *displays;
|
||||||
|
GHashTable *images;
|
||||||
|
GHashTable *items;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -222,6 +227,8 @@ gimp_procedure_finalize (GObject *object)
|
||||||
g_clear_pointer (&procedure->priv->values, g_free);
|
g_clear_pointer (&procedure->priv->values, g_free);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
_gimp_procedure_destroy_proxies (procedure);
|
||||||
|
|
||||||
G_OBJECT_CLASS (parent_class)->finalize (object);
|
G_OBJECT_CLASS (parent_class)->finalize (object);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1641,3 +1648,115 @@ gimp_procedure_set_icon (GimpProcedure *procedure,
|
||||||
g_return_if_reached ();
|
g_return_if_reached ();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* internal functions */
|
||||||
|
|
||||||
|
GimpDisplay *
|
||||||
|
_gimp_procedure_get_display (GimpProcedure *procedure,
|
||||||
|
gint32 display_id)
|
||||||
|
{
|
||||||
|
GimpDisplay *display = NULL;
|
||||||
|
|
||||||
|
g_return_val_if_fail (GIMP_IS_PROCEDURE (procedure), NULL);
|
||||||
|
g_return_val_if_fail (_gimp_display_is_valid (display_id), NULL);
|
||||||
|
|
||||||
|
if (G_UNLIKELY (! procedure->priv->displays))
|
||||||
|
procedure->priv->displays =
|
||||||
|
g_hash_table_new_full (g_direct_hash,
|
||||||
|
g_direct_equal,
|
||||||
|
NULL,
|
||||||
|
(GDestroyNotify) g_object_unref);
|
||||||
|
|
||||||
|
display = g_hash_table_lookup (procedure->priv->displays,
|
||||||
|
GINT_TO_POINTER (display_id));
|
||||||
|
|
||||||
|
if (! display)
|
||||||
|
{
|
||||||
|
display = _gimp_plug_in_get_display (procedure->priv->plug_in,
|
||||||
|
display_id);
|
||||||
|
|
||||||
|
if (display)
|
||||||
|
g_hash_table_insert (procedure->priv->displays,
|
||||||
|
GINT_TO_POINTER (display_id),
|
||||||
|
g_object_ref (display));
|
||||||
|
}
|
||||||
|
|
||||||
|
return display;
|
||||||
|
}
|
||||||
|
|
||||||
|
GimpImage *
|
||||||
|
_gimp_procedure_get_image (GimpProcedure *procedure,
|
||||||
|
gint32 image_id)
|
||||||
|
{
|
||||||
|
GimpImage *image = NULL;
|
||||||
|
|
||||||
|
g_return_val_if_fail (GIMP_IS_PROCEDURE (procedure), NULL);
|
||||||
|
g_return_val_if_fail (_gimp_image_is_valid (image_id), NULL);
|
||||||
|
|
||||||
|
if (G_UNLIKELY (! procedure->priv->images))
|
||||||
|
procedure->priv->images =
|
||||||
|
g_hash_table_new_full (g_direct_hash,
|
||||||
|
g_direct_equal,
|
||||||
|
NULL,
|
||||||
|
(GDestroyNotify) g_object_unref);
|
||||||
|
|
||||||
|
image = g_hash_table_lookup (procedure->priv->images,
|
||||||
|
GINT_TO_POINTER (image_id));
|
||||||
|
|
||||||
|
if (! image)
|
||||||
|
{
|
||||||
|
image = _gimp_plug_in_get_image (procedure->priv->plug_in,
|
||||||
|
image_id);
|
||||||
|
|
||||||
|
if (image)
|
||||||
|
g_hash_table_insert (procedure->priv->images,
|
||||||
|
GINT_TO_POINTER (image_id),
|
||||||
|
g_object_ref (image));
|
||||||
|
}
|
||||||
|
|
||||||
|
return image;
|
||||||
|
}
|
||||||
|
|
||||||
|
GimpItem *
|
||||||
|
_gimp_procedure_get_item (GimpProcedure *procedure,
|
||||||
|
gint32 item_id)
|
||||||
|
{
|
||||||
|
GimpItem *item = NULL;
|
||||||
|
|
||||||
|
g_return_val_if_fail (GIMP_IS_PROCEDURE (procedure), NULL);
|
||||||
|
g_return_val_if_fail (_gimp_item_is_valid (item_id), NULL);
|
||||||
|
|
||||||
|
if (G_UNLIKELY (! procedure->priv->items))
|
||||||
|
procedure->priv->items =
|
||||||
|
g_hash_table_new_full (g_direct_hash,
|
||||||
|
g_direct_equal,
|
||||||
|
NULL,
|
||||||
|
(GDestroyNotify) g_object_unref);
|
||||||
|
|
||||||
|
item = g_hash_table_lookup (procedure->priv->items,
|
||||||
|
GINT_TO_POINTER (item_id));
|
||||||
|
|
||||||
|
if (! item)
|
||||||
|
{
|
||||||
|
item = _gimp_plug_in_get_item (procedure->priv->plug_in,
|
||||||
|
item_id);
|
||||||
|
|
||||||
|
if (item)
|
||||||
|
g_hash_table_insert (procedure->priv->items,
|
||||||
|
GINT_TO_POINTER (item_id),
|
||||||
|
g_object_ref (item));
|
||||||
|
}
|
||||||
|
|
||||||
|
return item;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
_gimp_procedure_destroy_proxies (GimpProcedure *procedure)
|
||||||
|
{
|
||||||
|
g_return_if_fail (GIMP_IS_PROCEDURE (procedure));
|
||||||
|
|
||||||
|
g_clear_pointer (&procedure->priv->displays, g_hash_table_unref);
|
||||||
|
g_clear_pointer (&procedure->priv->images, g_hash_table_unref);
|
||||||
|
g_clear_pointer (&procedure->priv->items, g_hash_table_unref);
|
||||||
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue