BennuGD: adding the actual fpg_del() routine

I’m still adding functionalities to the BennuGD language …

This morning I’ve just implemented the actual fpg_del() routine inside BennuGD mainstream. According to these mismatch sources, fpg_del() was, in fact, a clone for the unload_fpg() function. Thus, there was no method of deleting a map (graph) file inside a FPG file at runtime.

Altering the fpg_del() hook routine

We do know perfectly well the way to do something like this. Here, right on mod_map/mod_map.c file:

1006         { "FPG_DEL"             , "II"           , TYPE_INT      ,modmap_fpg_del         },

Then, I coded modmap_fpg_del() this way:

 747 static int modmap_fpg_del ( INSTANCE * my , int * params) {
 748     /* Try to delete this map from the FPG file */
 749     /* In case of sucess, decrease its graph counter : */
 750     if(grlib_unload_map( params[0] , params[1])==1){
 751         gr_tcg_decrease_fpg_count( params[0]);
 752         return 1;
 753     } return 0;
 755 }

As a matter of fact, the yet implemented call grlib_unload_map() was what I needed to dereference and delete a map file for a certain FPG one. So, I did almost nothing: just call this function and then update my dynamic-memory allocated table in order to keep coherence between the FPG loaded onto memory and its number of graphic maps, thanks to gr_tcg_decrease_fpg_count() routine.

Testing the additions

Now, it is pretty feasible to create, at runtime, a new FPG file and add or delete map files from it. I wrote a trivial BennuGD sample which does precissely so. The involved steps could be something like calling fpg_new():

65         If(Key(_n) && !fpg_exists(file))        /* Initialize a new FPG file on memory : */
66             if((fpg_dest_id = fpg_new ())<0)    // Error …
67                 say(“fpg_dest_id”); fpg_errors = true; break;
68             End
69             if((fpg_orig_id = fpg_load(_FPG_SRC))<0)
70                 say(“fpg_load”); fpg_errors = true; break;
71             End
72             file = fpg_dest_id;
73             msg = “Initialized graph [” + graphics_in_fpg(file) + “]”;
74         End

Then, you can add graphic map files directly using a call to fpg_add():

75         If(Key(_a) && fpg_exists(file))     /* Add a new graph – randomly – to the new FPG file. */
76             graph=fpg_add(
77                 file ,                                      // Destination
78                 graphics_in_fpg(file)+1,                    // Add right at the end
79                 fpg_orig_id,                                // Copy from here
80                 rand(1, graphics_in_fpg(fpg_orig_id))       // Pick the graph at random
81             );
82             If(graph>0)
83                 msg=”Graph added: [” + graph + “/” + graphics_in_fpg(file) + “]”;
84             Else
85                 msg=”Error adding graph.”;
86             End
87         End

And, at any moment, or on a second thought, you can simply delete any graphic using my new fpg_del() aid:

124         If(Key(_r) && fpg_exists(file)) /* Remove a graphic inside the FPG randomly */
125             g_del = rand(1,graphics_in_fpg(file));
126             if(fpg_del(file , g_del)==1)
127                 msg = “Deleted last graph. [” + g_del + “]”;
128                 is_erasing = true;
129             Else
130                 msg = “Error deleting graph.”;
131             End
132         End

All you need to know is the FPG file id and the Graphic id to be deleted.

Some considerations about editing a FPG file at runtime

Playing around with this new functionality, I came to realize you cannot call fpg_save() in order to update any previous loaded FPG file yet existing on disk. It seems the BennuGD core code cannot do such a task, that is, to overwrite an existing file on disk. That’s the reason why I coded this line when saving the FPG file at runtime after its changes:

88         If((Key(_c) && fpg_exists(file)) && graphics_in_fpg(file)>0)        /* This action closes – and saves – this new FPG file */
89             if(fpg_save(fpg_dest_id, (is_erasing==true)?_FPG_TMP:_FPG_DST)==false)
90                 say(“fpg_save”); break;
91             End
92             msg = “FPG saved with:  ” + graphics_in_fpg(file) + ” graphs.”;
93             unload_fpg(fpg_dest_id);
94             is_erasing=false;
95         End

Oh, it is no that important, because you surely can store the new FPG changes on another file, and then replace the first one.

And now, some screen-shots

Calling fpg_add() at runtime to insert a new graphic map file

Adding a new graphic map file using fpg_add() routine.

Deleting a graph using fpg_del() at random

You can have a look at the demonstrative video of loading, showing, and deleting – the last and some random – graphic map file HERE: fpg_actions