Hi AndrewJust had a quick look at this as I use the C++ API and I wanted to
make sure it wasn't affecting my code. I hadn't noticed problems, but I think
these three functions have always been preceded by another function which has
called set_stream for my object, so it hasn't affected me so far.
As you say, plstream::fill is being used as a callback function for
plstream::shade and variants. Basically this can't be done, because to work
correctly as a user function plstream::fill cannot be static and must call
set_stream as Alan pointed out.
This problem has probably evolved because of the design of plshade. i think the
fill input should be an enumeration, not a function pointer. This is because
even if other options are added, the fill function is only ever going to be
plplot code (although perhaps I am wrong?). Having this as a function pointer
implies that the user can (or even should) provide their own code for doing the
fill, which isn't really the intention. This implication probably meant that
whoever wrote the C++ code felt obliged to pass a wrapped function rather than
just pass in plfill.
The fixes as I see them are as follows - getting better in terms of style (in
my opinion), but more difficult as we go.1) Remove the static and add
set_stream calls in plfill etc. In the examples replace use of plstream::fill
callbacks with plfill. Everything now acts as intended - fundamentally
plstream::shade and plshade want a c style callback so there is no need to pass
it a wrapped version of plfill.2) In addition to above, modify the
plstream::shade functions, removing the fill input altogether. Then always use
plfill in the call to plshade. There is no functionality loss as plfill is the
only possible option anyway and it will remove the potential for user bugs and
make the functions easier to use. It removes the design implications described
above from the C++ interface. If we ever want to reintroduce this option then
C++ overloading makes this trivial. The negative is a C++ API breakage.3)
Change the plshade functions to accept an enumeration of the fill type rather
than a function pointer. Now it is clear to the user that they are simply
making a choice of which plplot coded fill option they want rather than there
being an expectation of them providing their own callback. However this means a
C API breakage, which would need propagation.
One other potential problem is that it might be possible for another plstream
to be used mid render, e.g. if an error callback displays a dialog box in a GUI
program this freezes rendering and may allow rendering of other windows using
other plstreams. Suddenly plsc has been changed mid render and the fill is now
directed to the wrong window. Although plplot is full of such potential
problems, the hiding of the plsetstream call in the C++ binding makes it less
obvious to the user that this can occur. We could fix this with a lock (like
the equivalent of a mutex and mutex locker), which tracks when plstream methods
are in use.
Phil
From: Andrew Ross <andrewr...@users.sourceforge.net>
To: Alan W. Irwin <ir...@beluga.phys.uvic.ca>
Cc: PLplot development list <Plplot-devel@lists.sourceforge.net>
Sent: Friday, 17 October 2014, 22:56
Subject: Re: [Plplot-devel] Why is the set_stream() call commented out for
plstream::fill, etc.
On Thu, Oct 16, 2014 at 04:34:53PM -0700, Alan Irwin wrote:
> On 2014-10-16 20:39+0100 Andrew Ross wrote:
>
> >
> > Alan,
> >
> > It's because these three functions are callback functions which are
> > called from another plplot function. They do not operate directly on
> > a stream.
>
> Hi Andrew:
>
> I may be misinterpreting what you are saying above, but I noticed many
> direct as well as more limited callback uses of these three functions
> in our examples, see below.
>
> >
> > The C++ class maintains a stream variable for each instance of the
> > PLStream class. This means you can have multiple streams (i.e. windows
> > / files) and not have to worry which one plplot is currently using.
> > It's all hidden in the object orientation by calling set_stream
> > each time a plplot API function is called for a particular object.
> >
> > The callback functions don't need to do this since they are being
> > called from another plplot function. If you look in plstream.h
> > you will see these functions are marked static which means there
> > is a single copy of the function shared across all instances which
> > does not have access to the local variables in the class. This
> > means that calling set_stream wouldn't actually work anyway,
> > enforcing this distinction. Uncommenting would generate a compiler
> > error.
>
> You lost me a bit because of my lack of knowledge concerning C++.
> Nevertheless, let me ask a supplementary question. Your explanation
> indicates these are specially treated because they are callback
> functions, but that is not the full story. For example, those
> functions are used directly and not as callbacks in many examples; if
> you look for "fill" in the C++ examples, there are many references to
> pls->fill rather than plstream::fill. I checked a number of those,
> and the pls->fill ones are mostly direct although in example 21 it
> appears that the pls->fill form may also be used as a callback. I
> have no idea whether that example 21 difference in pattern matters,
> but I do wonder whether if one of our users attempted to use fill,
> fill3, or gradient directly in a multistream application similar to
> example 14, would they run into an error because of the lack of
> set_plstream call in the C++ binding? Note our current set of
> examples does not test this case because fill, fill3, and gradient are
> all missing from example 14.
>
> I emphasize again my concerns boil down to questions concerning
> pattern inconsistencies. Thus, you may well have a good C++ answer
> for the pattern inconsistency I noted above for example 21 when it
> appears that fill in direct form (pls->plfill) may be used as a
> callback, and also C++ answers for when fill, fill3, and gradient are
> used directly throughout our examples and also potentially in a
> multistream environment like example 14.
Alan,
OK. On closer examination I think you may be right. Looking at the
plfill code it does seem there is a potential problem. I'll look into
this. Casting my mind back I seem to remember problems with the
callbacks if they weren't static functions, so I may need to think
about how this will work.
Thanks for spotting the problem anyway!
Andrew
------------------------------------------------------------------------------
Comprehensive Server Monitoring with Site24x7.
Monitor 10 servers for $9/Month.
Get alerted through email, SMS, voice calls or mobile push notifications.
Take corrective actions from your mobile device.
http://p.sf.net/sfu/Zoho
_______________________________________________
Plplot-devel mailing list
Plplot-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/plplot-devel
------------------------------------------------------------------------------
Comprehensive Server Monitoring with Site24x7.
Monitor 10 servers for $9/Month.
Get alerted through email, SMS, voice calls or mobile push notifications.
Take corrective actions from your mobile device.
http://p.sf.net/sfu/Zoho
_______________________________________________
Plplot-devel mailing list
Plplot-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/plplot-devel