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
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