All Manuals > CAPI User Guide and Reference Manual > 7 Programming with CAPI Windows

7.1 The lifecycle of a CAPI object

Since many CAPI objects interact with an end user on a screen, their lifetimes are controlled more carefully than those of normal Lisp objects.

Each CAPI object goes through the following stages.

  1. CLOS object initialization.

    In the first stage, the object is created by a call to make-instance. The normal CLOS initialization mechanisms such as initialize-instance are used to initialize the object. During this stage, the object is known only to Lisp and can be garbage collected if the next stage is not reached.

  2. Connection to a screen.

    At some point, a CAPI object might be connected to a screen. This causes window system resources to be allocated for the connection and prevents the object from being garbage collected. Functions such as display and display-dialog connect a top level interface to a screen. Panes within a top level interface are also connected to the same screen as the interface and new panes can be connected by setting the pane-layout or layout-description of a connected pane to include them.

  3. Interaction with an end user.

    After the object is connected to a screen, it may become visible to an end user who can interact with the object. Some interactions (for example, clicking a button) cause callbacks to be called, allowing your code to respond to the interaction.

  4. Disconnection from a screen.

    A CAPI object might become disconnected from a screen if the end user closes a top level interface or if you call destroy. Panes within a top level interface can also be disconnected by setting the pane-layout or layout-description of a connected pane to remove them.

    After this stage, the object is again known only to Lisp and can be garbage collected.

  5. Garbage collection.

    The final stage of a CAPI object's lifecycle is the normal Lisp garbage collection process, which removes the object from memory when there are no more references to it.

The functions interface-displayed-p, interface-fully-created-p, interface-being-created-p and interface-fully-destroyed-p can be used to detect which stage a top level interface is at.

If necessary you can run code just before or just after your interface's windows are displayed on screen.

You can do this by defining a :before or :after method on the generic function interface-display. Your method will run just before or just after your interface is displayed on screen.

For example:

(defun make-text (self createdp)
  (multiple-value-bind (s m h dd mm yy)
      (decode-universal-time (get-universal-time))
    (format nil "Window ~S ~:[displayed~;created~] at ~2,'0D:~2,'0D:~2,'0D" 
            self createdp h m s)))
 
(capi:define-interface dd () () (:panes (dp capi:display-pane)))
 
(defmethod capi:interface-display :before ((self dd))
  (with-slots (dp) self
    (setf (capi:display-pane-text dp)
          (make-text self t))))
 
(capi:contain (make-instance 'dd))

Sometimes initialization code can be put in the create-callback of your interface, though adding it in suitable methods for initialize-instance or interface-display is usually better.


CAPI User Guide and Reference Manual (Unix version) - 18 Feb 2025 15:34:15