Issue #50: new gimp_procedure_new2() which automatically stores procedure config.

This new function is meant to replace gimp_procedure_new() when all plug-in
usage will have been switched.

This function creates the GimpProcedureConfig object on behalf of the plug-in
and calls gimp_procedure_config_begin_run() and gimp_procedure_config_end_run().
This way we ensure that all plug-in calls with successful result are properly
stored without asking the developer not to forget to call these (if a "good
practice" is in fact something we request to do every time, especially for good
user experience, we might as well make it rather a core process).

Advantages:

* Better interactive experience: using any plug-in will result in saved
  previously used settings.
* for developers, working on config objects is also much more comfortable than
  working on GValueArray;
* step forward for the future macro infrastructure: if we can ensure that all
  plug-in calls are properly logged, then we can replay plug-in actions, in
  NON_INTERACTIVE with the same settings.
This commit is contained in:
Jehan 2023-06-12 17:56:06 +02:00
parent 2003d26105
commit 7ab87d2b15
3 changed files with 129 additions and 5 deletions

View file

@ -767,6 +767,7 @@ EXPORTS
gimp_procedure_get_sensitivity_mask
gimp_procedure_get_type
gimp_procedure_new
gimp_procedure_new2
gimp_procedure_new_arguments
gimp_procedure_new_return_values
gimp_procedure_run

View file

@ -84,6 +84,7 @@ struct _GimpProcedurePrivate
GParamSpec **values;
GimpRunFunc run_func;
GimpRunConfigFunc run_config_func;
gpointer run_data;
GDestroyNotify run_data_destroy;
@ -480,8 +481,44 @@ static GimpValueArray *
gimp_procedure_real_run (GimpProcedure *procedure,
const GimpValueArray *args)
{
return procedure->priv->run_func (procedure, args,
procedure->priv->run_data);
if (procedure->priv->run_config_func)
{
GimpProcedureConfig *config;
GimpImage *image = NULL;
GimpRunMode run_mode = GIMP_RUN_INTERACTIVE;
GimpValueArray *retvals;
GimpPDBStatusType status = GIMP_PDB_EXECUTION_ERROR;
if (gimp_value_array_length (args) > 0 &&
G_VALUE_HOLDS_ENUM (gimp_value_array_index (args, 0)))
{
run_mode = GIMP_VALUES_GET_ENUM (args, 0);
if (gimp_value_array_length (args) > 1 &&
GIMP_VALUE_HOLDS_IMAGE (gimp_value_array_index (args, 1)))
image = GIMP_VALUES_GET_IMAGE (args, 1);
}
config = gimp_procedure_create_config (procedure);
gimp_procedure_config_begin_run (config, image, run_mode, args);
retvals = procedure->priv->run_config_func (procedure, config,
procedure->priv->run_data);
if (retvals != NULL &&
gimp_value_array_length (retvals) > 0 &&
G_VALUE_HOLDS_ENUM (gimp_value_array_index (retvals, 0)))
status = GIMP_VALUES_GET_ENUM (retvals, 0);
gimp_procedure_config_end_run (config, status);
g_object_unref (config);
return retvals;
}
else
{
return procedure->priv->run_func (procedure, args,
procedure->priv->run_data);
}
}
static GimpProcedureConfig *
@ -605,6 +642,83 @@ gimp_procedure_new (GimpPlugIn *plug_in,
return procedure;
}
/**
* gimp_procedure_new2:
* @plug_in: a #GimpPlugIn.
* @name: the new procedure's name.
* @proc_type: the new procedure's #GimpPDBProcType.
* @run_func: the run function for the new procedure.
* @run_data: user data passed to @run_func.
* @run_data_destroy: (nullable): free function for @run_data, or %NULL.
*
* Creates a new procedure named @name which will call @run_func when
* invoked.
*
* The @name parameter is mandatory and should be unique, or it will
* overwrite an already existing procedure (overwrite procedures only
* if you know what you're doing).
*
* @proc_type should be %GIMP_PDB_PROC_TYPE_PLUGIN for "normal" plug-ins.
*
* Using %GIMP_PDB_PROC_TYPE_EXTENSION means that the plug-in will add
* temporary procedures. Therefore, the GIMP core will wait until the
* %GIMP_PDB_PROC_TYPE_EXTENSION procedure has called
* [method@Procedure.extension_ready], which means that the procedure
* has done its initialization, installed its temporary procedures and
* is ready to run.
*
* *Not calling [method@Procedure.extension_ready] from a
* %GIMP_PDB_PROC_TYPE_EXTENSION procedure will cause the GIMP core to
* lock up.*
*
* Additionally, a %GIMP_PDB_PROC_TYPE_EXTENSION procedure with no
* arguments added is an "automatic" extension that will be
* automatically started on each GIMP startup.
*
* %GIMP_PDB_PROC_TYPE_TEMPORARY must be used for temporary procedures
* that are created during a plug-ins lifetime. They must be added to
* the #GimpPlugIn using [method@PlugIn.add_temp_procedure].
*
* @run_func is called via [method@Procedure.run].
*
* For %GIMP_PDB_PROC_TYPE_PLUGIN and %GIMP_PDB_PROC_TYPE_EXTENSION
* procedures the call of @run_func is basically the lifetime of the
* plug-in.
*
* TODO: when all plug-ins have been ported to gimp_procedure_new2(), it must be
* renamed and gimp_procedure_new() removed.
*
* Returns: a new #GimpProcedure.
*
* Since: 3.0
**/
GimpProcedure *
gimp_procedure_new2 (GimpPlugIn *plug_in,
const gchar *name,
GimpPDBProcType proc_type,
GimpRunConfigFunc run_func,
gpointer run_data,
GDestroyNotify run_data_destroy)
{
GimpProcedure *procedure;
g_return_val_if_fail (GIMP_IS_PLUG_IN (plug_in), NULL);
g_return_val_if_fail (gimp_is_canonical_identifier (name), NULL);
g_return_val_if_fail (proc_type != GIMP_PDB_PROC_TYPE_INTERNAL, NULL);
g_return_val_if_fail (run_func != NULL, NULL);
procedure = g_object_new (GIMP_TYPE_PROCEDURE,
"plug-in", plug_in,
"name", name,
"procedure-type", proc_type,
NULL);
procedure->priv->run_config_func = run_func;
procedure->priv->run_data = run_data;
procedure->priv->run_data_destroy = run_data_destroy;
return procedure;
}
/**
* gimp_procedure_get_plug_in:
* @procedure: A #GimpProcedure.

View file

@ -44,9 +44,12 @@ G_BEGIN_DECLS
*
* Since: 3.0
**/
typedef GimpValueArray * (* GimpRunFunc) (GimpProcedure *procedure,
const GimpValueArray *args,
gpointer run_data);
typedef GimpValueArray * (* GimpRunFunc) (GimpProcedure *procedure,
const GimpValueArray *args,
gpointer run_data);
typedef GimpValueArray * (* GimpRunConfigFunc) (GimpProcedure *procedure,
GimpProcedureConfig *config,
gpointer run_data);
/**
@ -138,6 +141,12 @@ GimpProcedure * gimp_procedure_new (GimpPlugIn *plug_i
GimpRunFunc run_func,
gpointer run_data,
GDestroyNotify run_data_destroy);
GimpProcedure * gimp_procedure_new2 (GimpPlugIn *plug_in,
const gchar *name,
GimpPDBProcType proc_type,
GimpRunConfigFunc run_func,
gpointer run_data,
GDestroyNotify run_data_destroy);
GimpPlugIn * gimp_procedure_get_plug_in (GimpProcedure *procedure);
const gchar * gimp_procedure_get_name (GimpProcedure *procedure);