
# Table of Contents

1.  [Changes](#orga7ffc08)
    1.  [More strict processing of geometry changes, repaints and recording](#org1220f1e)
    2.  [Dynamic slots for medium state and the current text line](#orgbd63dbb)
    3.  [Thread-safe output history and drawing context](#org708b14c)
    4.  [Refactored text renderer for performance and alternative text directions](#orgd873829)
    5.  [New demos](#org867ad57)
2.  [Future changes](#orga25f43e)
    1.  [The repaint queue](#org72ac577)
    2.  [Input editing streams rewrite](#orgde756a2)
    3.  [SDL2 backend and keyboard layouts](#orgcbcfaf6)
3.  [Closing remarks](#org3574be9)

Dear All,

After a year of development it is time to make a release. The codename of this
version is "Ostara", after the second of the eight annual pagan holidays
celebrating the arrival of spring. Ostara was a Germanic goddess representing
rebirth and is the equivalent of Easter.

In this release we mainly focus on robustness with numerous bugs fixed and a few
features implemented. Most notably McCLIM streams are now thread-safe to write
to and to draw on. Here is the list of committers and their number of commits
since the last release:

Daniel Kochmański (502), Charlie McMackin (15), Andrea Demichele (2), John
Carroll (1), José M. Á. Ronquillo Rivera (1) and Robert Brown (1).

This is not an exhaustive list of contributors, as it does not list people who
reported issues, updated the wiki, or performed other non-coding tasks. Thank
you!  Moreover I'd like to thank people who donate money to my [Patreon](https://www.patreon.com/c/jackdaniel_kochmanski) page,
your continuous support means a lot to me.


<a id="orga7ffc08"></a>

# Changes

For a detailed list of changes, consult the NEWS file or the git log directly.
Below is a high-level overview of these changes.


<a id="org1220f1e"></a>

## More strict processing of geometry changes, repaints and recording

This is the least visible change because it pertains to how we process updates
to states of CLIM stream panes. Previously when the program added new output,
the pane was resized immediately, followed by scrolling and repainting. That was
clearly suboptimal, especially when there is a lot of changes done in a short
period of time. Instead, we now batch these changes and execute them when
`STREAM-FINISH-OUTPUT` is called. That greatly improves performance and saves
visual glitches for certain scenarios.


<a id="orgbd63dbb"></a>

## Dynamic slots for medium state and the current text line

To enable concurrent drawing threads, we needed to ensure that there are no
races regarding drawing options (like the drawing ink or the text style). To do
that, CLIM stream panes have a slot that contains an instance of a class that
has dynamic slots (for how this work see my [blog post](https://turtleware.eu/posts/Dynamic-Vars---Return-of-the-Jedi.html)). This allows for drawing
and writing text to streams concurrently from multiple threads. For example:

![Thread Safe Drawing](https://common-lisp.net/project/mcclim/static/media/099ostara/thread-safe-drawing.mp4)

In this demo we have seven concurrent threads:

-   two threads print 1000 lines with prefixes "XXX" and "YYY"
-   four threads drawing dots in different colors
-   one thread monitors the current progress of printing lines

Note that we may also scroll the output while these threads are still running
and modifying the sheet. The cursor is not corrupted and the output proceeds
without glitches.


<a id="org708b14c"></a>

## Thread-safe output history and drawing context

Modifications to the output record history and writing pixels on a buffer are
mutually exclusive operations protected with locks. For forward compatibility,
all repaint requests by the program should be issued with `DISPATCH-REPAINT`.
Moreover the user program should not directly use operators that change the
output recording state of the stream.

![Concurrent Drawing](https://common-lisp.net/project/mcclim/static/media/099ostara/concurrent-drawing.mp4)

Notice how multiple threads are modifying the sheet geometry and the cursor
position. The output record history is a bottleneck because each thread, after
drawing, needs to take the lock and update the record. This is suboptimal, but
enables us to quickly write throwaway code like this:

    (in-package "CLIM-USER")
    
    (defparameter *stream* (open-window-stream :width 800 :height 600))
    (defparameter *stop* t)
    
    (defun woosh (id ink)
      (setf *stop* nil)
      (with-drawing-options (*stream* :ink ink)
        (loop while (null *stop*) do
          (updating-output (*stream* :unique-id id :fixed-position t)
            (format *stream* "Time: ~a~%" (get-internal-real-time)))
          (sleep 1/30))))
    
    (bt:make-thread (lambda () (woosh :thread-1 +dark-red+)))
    (bt:make-thread (lambda () (woosh :thread-2 +dark-blue+)))

and in my opinion it is great for prototyping, because you can add additional
elements while the program is running without invoking arcane protocols.


<a id="orgd873829"></a>

## Refactored text renderer for performance and alternative text directions

The text renderer has been refactored to achieve better performance and exploit
optimization opportunities when they are presented. For example a different code
path is executed when the text is not translucent.

That said, the most notable change with the text renderer is the ability to
change the line and the page directions:

![Concurrent Drawing](https://common-lisp.net/project/mcclim/static/media/099ostara/draw-text-test.mp4)

These changes apply to DRAW-TEXT. Line-oriented integration with CLIM streams
that allows mixing the text that has different directions is not yet
implemented, but we can already mix text and graphics, and the latter will be
correctly wrapped along the text when necessary.

[Mixing in graphics in a text line](https://common-lisp.net/project/mcclim/static/media/099ostara/mix-text-graphics.png)


<a id="org867ad57"></a>

## New demos

I wrote new demos that may be started from the system `clim-examples`:

-   **incremental redisplay:** demonstrates how to work with output record caches
-   **animation with pulse:** an animation with a timer synchronizing redisplay
-   **concurrent drawing:** a demo where we can spin any number of drawing threads
-   **concurrent writing:** a stress test for concurrent writing lines to a stream
-   **concurrent griding:** a stress test with concurrent drawing with many records


<a id="orga25f43e"></a>

# Future changes


<a id="org72ac577"></a>

## The repaint queue

The thread-safety of CLIM streams is factored out from a branch `repaint-queue`.
This branch works, but it still has various regressions that need to be
addressed before merging. The results are very promising and its effect
compounds with thread-safety, because drawing locks the output history far less
often, while recording is rather cheap.


<a id="orgde756a2"></a>

## Input editing streams rewrite

This work is mostly done but it needs more testing and there are a few bugs that
need to be addressed before merging. This change involves also better command
completions that include a fuzzy completer, and makes text editing much easier.
If you want to see the current state of it check out `input-editing` branch.


<a id="orgcbcfaf6"></a>

## SDL2 backend and keyboard layouts

I didn't work on either of these tasks since the last release, but I plan to
finish them after merging branches `repaint-queue` and `input-editing`. After
finishing SDL2 branch and keyboard layouts I want to make the next release.


<a id="org3574be9"></a>

# Closing remarks

McCLIM improves on a daily basis, and this trend continues. I'm very happy that
I've been able to make a timely release unlike the last one. Fixing numerous
issues further accelerates other improvements. From my subjective perspective
the software is much more resilient than a year ago.

You may grab the latest release from here:
<https://codeberg.org/McCLIM/McCLIM/releases/tag/0.9.9-ostara>.

Best regards,
Daniel Kochmański

