[mcclim-devel] Displayed Output Records Proposal

Robert Strandh strandh at labri.fr
Sat Sep 3 21:18:11 UTC 2005


Hello, 

Just some immediate comments: 

Gilbert Baumann writes:
 > PROPOSAL
 > 
 > I propose that we open an opportunity for the backend to implement its
 > own output recording classes

The question is when the specific subclass of output-record is then
determined.  The output record is created by an :around method that
specializes on the stream, but the stream is not backend-specific
AFAIK; the medium is. 

 > PROTOCOL
 > 
 > We could specify MEDIUM-RECORD-xyz* methods to complement
 > MEDIUM-DRAW-xyz, like this:
 > 
 > MEDIUM-RECORD-LINE* medium x1 y1 x2 y2 drawp recordp         [Generic Function]
 > 
 >     If /drawp/ is non-NIL, behave as MEDIUM-DRAW-LINE*.
 > 
 >     If /recordp/ is non-NIL, return a displayed output record which,
 >     when replayed has the effect or MEDIUM-DRAW-LINE* with the given
 >     arguments and the current drawing options installed in /medium/.

This in itself looks OK to me, but I have a problem with the way it is
used below. 

 > We could specify that an implementation of MEDIUM-RECORD-LINE* for a
 > medium is optional and that a default implementation is provided by
 > CLIM.

OK

 > So the implementation of MEDIUM-DRAW-LINE* on output recording streams
 > would look like this:
 > 
 > (defmethod medium-draw-line* ((stream output-record-stream) x1 y1 x2 y2)
 >   (let ((record
 >          (medium-record-line* stream x1 y1 x2 y2
 >                               (stream-drawing-p stream)
 >                               (stream-recording-p stream))))
 >     (when (stream-recording-p stream)
 >       (stream-add-output-record stream record))))

I don't see how this can work.  According to the spec, the output
record is created by the :around method on medium-draw-line*
specialized on the stream.  The main method has no business creating
output records, if I read the spec right.  It looks to me like you
would have to do:

(defmethod medium-draw-line* :around ((stream output-recording-stream) 
                                      x1 y1 x2 y2)
  (when (stream-recording-p stream)
    (let ((record (medium-record-line* (sheet-medium stream) 
                                       x1 y1 x2 y2
                                       nil t)))
      (stream-add-output-record stream record)))
  (when (stream-drawing-p stream)
    (medium-record-line* (sheet-medium stream)
                         x1 y1 x2 y2 t nil)))

which somewhat defeats the purpose of having a single
medium-record-line, since you can replace the last call with one to
medium-draw-line and skip the {recording,drawing}-p arguments to
medium-record-line*.

But you can still have medium-specific output records, and a
medium-specific medium-record-line*.

Also, we must not forget that the spec allows the user to define his
or her own output record subclasses.  This must be possible to do
without taking into account the backend.  There are already too many
places in McCLIM where the implementation makes too many assumptions
about the superclasses of certain classes, and by doing so makes it
impossible for client code to extend it by using the documented
protocols.

We must therefore be careful and make sure that any subclass of
output-record continue to work properly and independently of the
backend. 

-- 
Robert Strandh

---------------------------------------------------------------------
Greenspun's Tenth Rule of Programming: any sufficiently complicated C
or Fortran program contains an ad hoc informally-specified bug-ridden
slow implementation of half of Common Lisp.
---------------------------------------------------------------------



More information about the mcclim-devel mailing list