comp.lang.ada
 help / color / mirror / Atom feed
* "Plugin°-based code
@ 2018-06-04 10:29 mockturtle
  2018-06-04 11:59 ` Dmitry A. Kazakov
                   ` (3 more replies)
  0 siblings, 4 replies; 5+ messages in thread
From: mockturtle @ 2018-06-04 10:29 UTC (permalink / raw)


Dear.all, 
I have a doubt about what it could be the best solution for some code that I am writing.  I am afraid that the introduction before the actual question is a bit long.  

** The problem **

Let me use an example.  Suppose I am writing a program to plot, say, a GANTT chart.  I want the user to be able to choose the output format (say, PDF, SVG or even LaTeX) by giving a suitable option on the command line and I want to be able to add new output format easily, maybe even load the "format handler" as a dynamic library at run-time (so I do not need recompilation).  (Incidentally, I did some experiments with the dynamic loading and it works)

The structure I give to the code is as follows: first I define an interface for an "abstract plotter," for example

  package Plotters is 
    type Abstract_Plotter is interface;

    procedure Line(P: Abstract_Plotter;
                   X1,Y1, X2, Y2:Float) 
    is abstract;

    -- And so on...
  end Plotters;

Every actual plotter will be a descendant of Abstract_Plotters, for example

  package Plotters.SVG is
     type SVG_Plotter is 
     new Abstract_Plotter with private;

     -- Blah, blah ...
  end Plotters.SVG;

In order to allow the user to select the actual plotter via the command line I use a generic package Plugin_Table that implements a kind of "map" from names to descendant of Abstract_Plotter.  Plugin_Table provides two operations:

  (1) Register_Plugin(T: Tag; Name: String)  

         used by a concrete plotter to "register" itself to the table.  Usually it is called from the "initialization" part of the body of the package definynig the concrete plotter.  For example, plotters-svg.adb could call

     Register_Plugin(SVG_Plotter'Tag, "svg");

  (2) Get_Plugin (Name:String) return Abstract_Plotter'Class

       to be called to generate a concrete plotter.

In a future version Plugin_Table will be able to search for some dynamic library to be loaded if a plugin with the given name is not registered.

   ** The Question ** 

In order to have all the built-in plugins registered in my executable, I need to "with" them, so that they are linked to my code and the initialization part of their bodies is elaborated. However, no part of my code call explicitly, say, SVG_Plotter.  Therefore, my solution is to add something like

  with Plotters.SVG;
  pragma Warnings(Off, Plotter.SVG);

in the "main." It works, but it leaves me a bit unsatisfied since it seems an "hack".  Also, since no actual code is called directly I am not sure if the binder could take the liberty of not including them (maybe it cannot, but I am not sure).

Do you have any better solution?

Also, I am not sure if I risk getting in trouble with Elaboration order.  I think not, but I am not 100% sure.  What do you think?


Thanks,

Riccardo

^ permalink raw reply	[flat|nested] 5+ messages in thread

end of thread, other threads:[~2018-06-05  8:42 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2018-06-04 10:29 "Plugin°-based code mockturtle
2018-06-04 11:59 ` Dmitry A. Kazakov
2018-06-04 14:03 ` Dan'l Miller
2018-06-04 22:08 ` Plugin-based code Randy Brukardt
2018-06-05  8:42 ` "Plugin°-based code Brian Drummond

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox