C plug-ins - The Procedural DataBase

[Theory] Introduction

First, you should understand what the PDB is. This stands for Procedural DataBase and as the name implies, this is a database containing “procedures” in the same meaning as we used until now for plug-in procedures.

The main difference is that there are not only plug-in procedures. Core procedures exist as well. These are a bunch of functions allowing plug-ins to request information to the core. For instance, when you call gimp_image_flip() to flip your image, your plug-in process is in fact communicating with the core process and sending a request with the gimp-image-flip PDB procedure.

Note that libgimp functions are not necessary all PDB procedures, yet all core PDB procedures are also libgimp functions.

Now additionally to the core PDB procedures, we have plug-in procedures, as you saw with the few previous tutorials. And this is where things are getting very interesting, because it means any plug-in can call other plug-ins!

[Code] Calling your Hello World Plug-In

Your Hello World plug-in obviously doesn’t have a C function wrapper. Instead here is the code you would use to call it from another plug-in:

  GimpProcedure  *procedure;
  GimpValueArray *return_vals;

  procedure   = gimp_pdb_lookup_procedure (gimp_get_pdb (), "plug-in-zemarmot-c-demo-hello-world");
  return_vals = gimp_procedure_run (procedure,
                                    "run-mode",     GIMP_RUN_NONINTERACTIVE,
                                    "image",        image,
                                    "text",         "Hello Universe!",
                                    "compute-size", TRUE,
                                    NULL);

Notice how we use the procedure name which we created in the first tutorial. Remember how we said this name was important and that it should stay as stable as possible? This is why.

So basically the first step is to query the unique GimpPDB object based on the procedure name, then simply run it with a NULL-terminated list of arguments. When an argument is not set explicitly, the default value will be used since we are in non-interactive run mode.

Another interesting point is the return_vals which is a GimpValueArray struct.

The first value in this array is always the success value returned by the plug-in, therefore you can typically call:

  if (GIMP_VALUES_GET_ENUM (return_vals, 0) == GIMP_PDB_SUCCESS)
    {
      /* Do something in case of success */
    }

When the return value is a GIMP_PDB_SUCCESS, if the plug-in has additional return values, the following items will contain them.

Conclusion

Now you understand why your choice of plug-in arguments can be important, especially if you believe your plug-in is suitable for reusage by other plug-ins. In particular, you may consider your procedure name and argument list as a stable programming interface too.

Fortunately, the argument order doesn’t matter too much and you may add new arguments without breaking this interface.

For instance, imagine some day, you want to add “offset-x” and “offset-y” arguments to your Hello World plug-in. You should set default values for both these arguments so that when the procedure is called without these (which implies they use default values), your procedure will behave the same as it used to when both these arguments did not exist.

This way, updating your plug-in procedure will not break existing scripts and plug-ins calling yours. Which means your procedure’s PDB interface stayed stable.