The darts.lib.tools Reference Manual

Next: , Previous: , Up: (dir)   [Contents][Index]

The darts.lib.tools Reference Manual

This is the darts.lib.tools Reference Manual, version 0.1, generated automatically by Declt version 4.0 beta 2 "William Riker" on Thu Sep 15 04:33:26 2022 GMT+0.

Table of Contents


1 Introduction

Darts Tools

This is a small library of more or less useful stuff. Most things in here used to be carried over from project to project via copy+paste.

Generic Property List Support

The symbols described here are provide by the darts.lib.tools.properties package. For the benefit of old code, they are also still available via the darts.lib.tools package, but that should be considered deprecated.

Sometimes it is handy, if an application can store additional data in objects managed by other (say: library) code. One way to achieve that is to add support for "property lists" to objects.

This library provides a generic mechanism for that. The basis are the following generic functions, which form the "core" of the property support:

Given an object of a type, which supports these functions, the following accessors and modifiers work out-of-the-box.

The property-value function is setf-able, provided, that a suitable method on update-property-list exists for the argument object:

Besides using setf, an application can modify object property lists by various other functions provided here.

The following functions exist for compatibility reasons. They should not be used in new code:

DEFSTRUCT and CLOS Support

This library provides a simple mixin class, which can be added to an application's class hierarchy in order to gain automatic support for property lists.

Example:

(defclass node (property-support) ())

(defclass parent-node (node)
  ((children :initform nil)))
  
(defclass child-node (node)
  ((parent :initform nil)))
  
(defclass inner-node (parent-node child-node) 
  ())
  
(defvar *node* (make-instance 'inner-node 'property-list (list 'id 16 'display-name "Folder")))

(property-value *node* 'id) ;; => 16
(property-value *node* 'display-name) ;; => "Folder"

To add property lists to an application defined structure type, you have to

Example:

(defstruct (handle (:copier nil) 
                   (:constructor make-handle (value &optional plist-init 
                                              &aux (plist (copy-list plist-init)))))
  (value 0 :type fixnum :read-only t)
  (plist nil :type list))
  
(define-structure-property-list handle handle-plist)

Atomic Updates

The implementation in this library updates the property lists atomically.

Important If you want to use the structure property list feature with ECL, you want to define the structure type with atomics:defstruct instead of cl:defstruct in order to get special atomic accessor support.

Missing Support for SYMBOL-PLIST

This module does not map PROPERTY-LIST to SYMBOL-PLIST for symbols, though doing so seems be trivial. However, the way atomic property updates work in some implementations is not easily adaptable to what needs to be stored in a symbol's plist slot. Since I rarely use property lists of symbols (somewhat funny, as I use them for other stuff all the time), I decided to not open that can of worms right now.

Iteration Macros

Event Notification

This library provides a simple facility for event notifications. The feature is split into low-level support code, and a ready to use high level mixin-class.

The symbols described here are provide by the darts.lib.tools.observables package. For the benefit of old code, they are also still available via the darts.lib.tools package, but that should be considered deprecated.

High-Level API

Low-Level API

An "observer chain" (or "chain" for brevity here) is (kind of a) list of lists

(observers1 observers2 ...)

where the elements of each sublist observersk are the actual observer objects. Internally, we use a special structure type for the outer spine for technical reasons. There are two points to this

The second use case requires cooperation of your application. Consider the following example:

(defvar *global-chain* (make-observer-chain))

(defclass session ()
  ((local-chain :initarg :local-chain)))
  
(defclass transaction ()
  ((local-chain :initarg :local-chain)))
  
(defun start-session ()
  (make-instance 'session :local-chain (make-observer-chain *global-chain*)))
  
(defun begin-transaction (session)
  (make-instance 'transaction 
                  :local-chain (make-observer-chain (slot-value session 'local-chain))))
                  
(defun commit-transaction (transaction &rest keys)
  ;; Do whatever needs to be done...
  (notify-observers-in-chain (slot-value transaction 'local-chain)
                             transaction `(commit :status :success ,@keys)))

In this scenario, when a transaction is committed, the event notification is automatically propagated across the "scopes" of the hierarchy:

This ordering is guaranteed by the implementation, though the order of invocation within each of these scopes is undefined.

Copyright

This library is licensend under the terms of the MIT license:

Copyright (c) 2019 Dirk Esser

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.


2 Systems

The main system appears first, followed by any subsystem dependency.


Previous: , Up: Systems   [Contents][Index]

2.1 darts.lib.tools

More or less useful utilities

Maintainer

Dirk Esser

Author

Dirk Esser

License

MIT

Long Description
Version

0.1

Dependency

atomics (system).

Source

darts.lib.tools.asd.

Child Component

src (module).


3 Modules

Modules are listed depth-first from the system components tree.


Previous: , Up: Modules   [Contents][Index]

3.1 darts.lib.tools/src

Source

darts.lib.tools.asd.

Parent Component

darts.lib.tools (system).

Child Components

4 Files

Files are sorted by type and then listed depth-first from the systems components trees.


Previous: , Up: Files   [Contents][Index]

4.1 Lisp


4.1.1 darts.lib.tools/darts.lib.tools.asd

Source

darts.lib.tools.asd.

Parent Component

darts.lib.tools (system).

ASDF Systems

darts.lib.tools.


4.1.2 darts.lib.tools/src/packages.lisp

Source

darts.lib.tools.asd.

Parent Component

src (module).

Packages

4.1.3 darts.lib.tools/src/properties.lisp

Dependency

packages.lisp (file).

Source

darts.lib.tools.asd.

Parent Component

src (module).

Public Interface
Internals

4.1.4 darts.lib.tools/src/iteration.lisp

Dependency

packages.lisp (file).

Source

darts.lib.tools.asd.

Parent Component

src (module).

Public Interface

4.1.5 darts.lib.tools/src/observable.lisp

Dependency

packages.lisp (file).

Source

darts.lib.tools.asd.

Parent Component

src (module).

Public Interface
Internals

observer-chain (structure).


4.1.6 darts.lib.tools/src/misc.lisp

Dependency

packages.lisp (file).

Source

darts.lib.tools.asd.

Parent Component

src (module).

Public Interface

preserving-evaluation-order (macro).


5 Packages

Packages are listed by definition order.


Next: , Previous: , Up: Packages   [Contents][Index]

5.1 darts.lib.tools.properties

Source

packages.lisp.

Used By List

darts.lib.tools.

Public Interface

5.2 darts.lib.tools

Source

packages.lisp.

Use List
Public Interface
Internals

Previous: , Up: Packages   [Contents][Index]

5.3 darts.lib.tools.observables

Source

packages.lisp.

Used By List

darts.lib.tools.

Public Interface

6 Definitions

Definitions are sorted by export status, category, package, and then by lexicographic order.


Next: , Previous: , Up: Definitions   [Contents][Index]

6.1 Public Interface


6.1.1 Macros

Macro: define-structure-property-list (structure-type accessor)

Declares support for a property list slot in the given structure type. For this to work, the given ‘accessor’ must be a ‘setf’-able accessor for some slot of type ‘structure-type’, that should be declared to have type ‘t’ or ‘list’. E.g.:

(defstruct window
(plist nil)
(parent nil)
(title ’window))

(define-structure-property-list window window-plist)

A property list slot should usually never be assigned to directly, since that may break the atomic update feature. Always manipulate the contents of the property list slot via the functions provided by this library.

Package

darts.lib.tools.properties.

Source

properties.lisp.

Macro: do-observers-in-chain ((observer-var &rest aux-bindings) chain-form &body body)
Package

darts.lib.tools.observables.

Source

observable.lisp.

Macro: do-properties ((key value) object-form &body body)
Package

darts.lib.tools.properties.

Source

properties.lisp.

Macro: label (name (&rest bindings) &body body)
Package

darts.lib.tools.

Source

iteration.lisp.

Macro: named-loop (loop-name (&rest bindings) &body body)
Package

darts.lib.tools.

Source

iteration.lisp.

Macro: preserving-evaluation-order ((name) &body body)
Package

darts.lib.tools.

Source

misc.lisp.


6.1.2 Ordinary functions

Function: add-observer-to-chain (observer chain &key test key identity)
Package

darts.lib.tools.observables.

Source

observable.lisp.

Function: delete-properties (object &optional which)

Removes all properties listed in ‘which’ from ‘object”s property list. If ‘which’ is omitted or ‘t’ (the default) removes all properties. Otherwise, it must be a list containing the indicators of all properties that should be removed.

This function returns a plist of all key/value pairs that have been removed by the call.

Package

darts.lib.tools.properties.

Source

properties.lisp.

Function: delete-properties-if (predicate object)

Deletes all properties from the property list of ‘object’ that satisfy the predictate function ‘predicate’. The predicate must be a function of two arguments returning a boolean value. The first argument is the property’s key, and the second argument is the property’s value.

This function returns a plist of all key/value pairs, that have been removed by the call.

Package

darts.lib.tools.properties.

Source

properties.lisp.

Function: delete-properties-if-not (predicate object)

Deletes all properties from the property list of ‘object’ that
fail to satisfy the predictate function ‘predicate’. The predicate must be a function of two arguments returning a boolean value. The
first argument is the property’s key, and the second argument
is the property’s value.

This function returns a plist of all key/value pairs, that have been removed by the call.

Package

darts.lib.tools.properties.

Source

properties.lisp.

Function: delete-property (object indicator)

Delete the property named by ‘indicator’ from ‘object”s property list. Answers the value of the removed property as primary result. The secondary value is a boolean flag that indicates, whether the property has been found (and hence removed, ‘t’) or not (‘nil’).

Package

darts.lib.tools.properties.

Source

properties.lisp.

Function: ensure-property (object indicator constructor)

Makes sure, that ‘object’ has a property named ‘indicator’. If
such a property already exists, this function does nothing. Otherwise, the function calls the ‘constructor’ function to generate a value, and stores it as ‘indicator”s value in ‘object”s property list.

Note, that ‘constructor’ may be called multiple times, and should not have side-effects. Also, even if it is called, there are no guarantees, that any value returned by it gets actually installed in ‘object”s property list, since the call may lose the race with another thread.

This function returns the value found (or constructed) as primary result. The secondary result is ‘t’ if the property already existed, and ‘nil’ if it has been installed by the call.

Package

darts.lib.tools.properties.

Source

properties.lisp.

Function: make-observer-chain (&optional next)
Package

darts.lib.tools.observables.

Source

observable.lisp.

Function: map-over-properties (function object)

Applies ‘function’ to each property of ‘object’. The function receives the property indicator as first, and the associated values as second argument. The return value of the function is ignored. This function always returns ‘object’.

Package

darts.lib.tools.properties.

Source

properties.lisp.

Function: notify-observers-in-chain (chain object event)
Package

darts.lib.tools.observables.

Source

observable.lisp.

Reader: observer-chain-entries (instance)
Writer: (setf observer-chain-entries) (instance)
Package

darts.lib.tools.observables.

Source

observable.lisp.

Target Slot

entries.

Reader: observer-chain-next (instance)
Package

darts.lib.tools.observables.

Source

observable.lisp.

Target Slot

next.

Function: observer-chain-p (object)
Package

darts.lib.tools.observables.

Source

observable.lisp.

Function: property-value (object indicator &optional default)

Answers the value of the property named by ‘indicator’ of the given ‘object’. If no matching property is found, answers ‘default’ instead. This function returns as secondary value a boolean flag, which indicates, whether the property was found or not.

Package

darts.lib.tools.properties.

Source

properties.lisp.

Function: (setf property-value) (object indicator &optional default)

Sets the value of the property named by ‘indicator’ of the given ‘object’ to ‘value’. The optional ‘default’ is ignored and taken only for compatibility with ‘object-property’.

Package

darts.lib.tools.properties.

Source

properties.lisp.

Function: remove-observer-from-chain (observer chain &key test key)
Package

darts.lib.tools.observables.

Source

observable.lisp.

Function: remove-properties (object &optional which)
Package

darts.lib.tools.properties.

Source

properties.lisp.

Function: remove-properties-if (predicate object)
Package

darts.lib.tools.properties.

Source

properties.lisp.

Function: remove-properties-if-not (predicate object)
Package

darts.lib.tools.properties.

Source

properties.lisp.

Function: remove-property (object indicator)
Package

darts.lib.tools.properties.

Source

properties.lisp.

Function: update-property-value (object key modifier &key test test-not default)
Package

darts.lib.tools.properties.

Source

properties.lisp.


6.1.3 Generic functions

Generic Function: add-observer (observer object &key test key identity)

Adds the given ‘observer‘ to the set of registered
event observers of ‘object‘, unless it is already present.

Package

darts.lib.tools.observables.

Source

observable.lisp.

Methods
Method: add-observer (observer (object observable) &key test key identity)
Generic Function: notify-observers (object event)

Notifies all registered event observers of ‘object‘ about the occurence of ‘event‘.

Package

darts.lib.tools.observables.

Source

observable.lisp.

Methods
Method: notify-observers ((object observable) event)
Generic Function: observe-event (observer object event)

Invoked in order to notify ‘observer‘, that the event described by ‘event‘ has happened with respect to ‘object‘.

Package

darts.lib.tools.observables.

Source

observable.lisp.

Methods
Method: observe-event ((observer function) object event)
Generic Function: parent-observer-chain (object)
Package

darts.lib.tools.observables.

Source

observable.lisp.

Methods
Method: parent-observer-chain (object)
Generic Function: property-list (object)

Answers the property list of ‘object’. The
result is a property list of th form

(indicator1 value1 indicator2 value2 ...)

i.e., a list, whose elements are pairs of keys and their associated values. The keys are always compared using ‘eql’. The caller must never modify the return value of this function.

Package

darts.lib.tools.properties.

Source

properties.lisp.

Methods
Method: property-list ((object property-support))
Generic Function: remove-observer (observer object &key test key)

Removes the given ‘observer‘ from the set of registered event observers of ‘object‘

Package

darts.lib.tools.observables.

Source

observable.lisp.

Methods
Method: remove-observer (observer (object observable) &key test key)
Generic Function: update-property-list (object modifier)

Modifies the property list of ‘object’ by applying
the function ‘modifier’ to the current property list, and storing the result as the new property list. On implementations, which support it, this should be an atomic update.

The ‘modifier’ function is not allowed to modify the list destructively.

The modifier function returns two values: the new property list as first, and some other value as second one. This function returns the value returned by the modifier as second result.

Package

darts.lib.tools.properties.

Source

properties.lisp.

Methods
Method: update-property-list ((object property-support) modifier)

6.1.4 Standalone methods

Method: print-object ((object observer-chain) stream)
Source

observable.lisp.

Method: shared-initialize :after ((object property-support) slots &key property-list)
Source

properties.lisp.

Method: shared-initialize :after ((object observable) slots &key)
Source

observable.lisp.


6.1.5 Classes

Class: observable
Package

darts.lib.tools.observables.

Source

observable.lisp.

Direct methods
Direct slots
Slot: observer-list-chain
Package

darts.lib.tools.

Class: property-support

Minimal mix-in class, which supports the object
annotation protocol. By mixing this class into a class hierarchy, all instances gain support for function ‘property’ and
all related functions. The property list is (re-) initializable; note, however, that the initarg is named ‘property-list’
as exported from this package, *not* by a keyword symbol.
The property lists of instances of this class are upated atomically.

Package

darts.lib.tools.properties.

Source

properties.lisp.

Direct methods
Direct slots
Slot: property-list
Type

darts.lib.tools::plist-cell


6.2 Internals


Next: , Previous: , Up: Internals   [Contents][Index]

6.2.1 Macros

Macro: make-plist-cell (&optional inits)
Package

darts.lib.tools.

Source

properties.lisp.

Macro: plist-cell-read (cell-form)
Package

darts.lib.tools.

Source

properties.lisp.

Macro: plist-cell-update (cell-form modifier-form)
Package

darts.lib.tools.

Source

properties.lisp.


Next: , Previous: , Up: Internals   [Contents][Index]

6.2.2 Ordinary functions

Function: copy-with-tail (list limit tail)
Package

darts.lib.tools.

Source

properties.lisp.


Next: , Previous: , Up: Internals   [Contents][Index]

6.2.3 Structures

Structure: observer-chain
Package

darts.lib.tools.

Source

observable.lisp.

Direct superclasses

structure-object.

Direct methods

print-object.

Direct slots
Slot: entries
Readers

observer-chain-entries.

Writers

(setf observer-chain-entries).

Slot: next
Type

(or null darts.lib.tools::observer-chain)

Readers

observer-chain-next.

Writers

This slot is read-only.


Previous: , Up: Internals   [Contents][Index]

6.2.4 Types

Type: plist-cell ()
Package

darts.lib.tools.

Source

properties.lisp.


Appendix A Indexes


Next: , Previous: , Up: Indexes   [Contents][Index]

A.1 Concepts


Next: , Previous: , Up: Indexes   [Contents][Index]

A.2 Functions

Jump to:   (  
A   C   D   E   F   G   L   M   N   O   P   R   S   U  
Index Entry  Section

(
(setf observer-chain-entries): Public ordinary functions
(setf property-value): Public ordinary functions

A
add-observer: Public generic functions
add-observer: Public generic functions
add-observer-to-chain: Public ordinary functions

C
copy-with-tail: Private ordinary functions

D
define-structure-property-list: Public macros
delete-properties: Public ordinary functions
delete-properties-if: Public ordinary functions
delete-properties-if-not: Public ordinary functions
delete-property: Public ordinary functions
do-observers-in-chain: Public macros
do-properties: Public macros

E
ensure-property: Public ordinary functions

F
Function, (setf observer-chain-entries): Public ordinary functions
Function, (setf property-value): Public ordinary functions
Function, add-observer-to-chain: Public ordinary functions
Function, copy-with-tail: Private ordinary functions
Function, delete-properties: Public ordinary functions
Function, delete-properties-if: Public ordinary functions
Function, delete-properties-if-not: Public ordinary functions
Function, delete-property: Public ordinary functions
Function, ensure-property: Public ordinary functions
Function, make-observer-chain: Public ordinary functions
Function, map-over-properties: Public ordinary functions
Function, notify-observers-in-chain: Public ordinary functions
Function, observer-chain-entries: Public ordinary functions
Function, observer-chain-next: Public ordinary functions
Function, observer-chain-p: Public ordinary functions
Function, property-value: Public ordinary functions
Function, remove-observer-from-chain: Public ordinary functions
Function, remove-properties: Public ordinary functions
Function, remove-properties-if: Public ordinary functions
Function, remove-properties-if-not: Public ordinary functions
Function, remove-property: Public ordinary functions
Function, update-property-value: Public ordinary functions

G
Generic Function, add-observer: Public generic functions
Generic Function, notify-observers: Public generic functions
Generic Function, observe-event: Public generic functions
Generic Function, parent-observer-chain: Public generic functions
Generic Function, property-list: Public generic functions
Generic Function, remove-observer: Public generic functions
Generic Function, update-property-list: Public generic functions

L
label: Public macros

M
Macro, define-structure-property-list: Public macros
Macro, do-observers-in-chain: Public macros
Macro, do-properties: Public macros
Macro, label: Public macros
Macro, make-plist-cell: Private macros
Macro, named-loop: Public macros
Macro, plist-cell-read: Private macros
Macro, plist-cell-update: Private macros
Macro, preserving-evaluation-order: Public macros
make-observer-chain: Public ordinary functions
make-plist-cell: Private macros
map-over-properties: Public ordinary functions
Method, add-observer: Public generic functions
Method, notify-observers: Public generic functions
Method, observe-event: Public generic functions
Method, parent-observer-chain: Public generic functions
Method, print-object: Public standalone methods
Method, property-list: Public generic functions
Method, remove-observer: Public generic functions
Method, shared-initialize: Public standalone methods
Method, shared-initialize: Public standalone methods
Method, update-property-list: Public generic functions

N
named-loop: Public macros
notify-observers: Public generic functions
notify-observers: Public generic functions
notify-observers-in-chain: Public ordinary functions

O
observe-event: Public generic functions
observe-event: Public generic functions
observer-chain-entries: Public ordinary functions
observer-chain-next: Public ordinary functions
observer-chain-p: Public ordinary functions

P
parent-observer-chain: Public generic functions
parent-observer-chain: Public generic functions
plist-cell-read: Private macros
plist-cell-update: Private macros
preserving-evaluation-order: Public macros
print-object: Public standalone methods
property-list: Public generic functions
property-list: Public generic functions
property-value: Public ordinary functions

R
remove-observer: Public generic functions
remove-observer: Public generic functions
remove-observer-from-chain: Public ordinary functions
remove-properties: Public ordinary functions
remove-properties-if: Public ordinary functions
remove-properties-if-not: Public ordinary functions
remove-property: Public ordinary functions

S
shared-initialize: Public standalone methods
shared-initialize: Public standalone methods

U
update-property-list: Public generic functions
update-property-list: Public generic functions
update-property-value: Public ordinary functions

Jump to:   (  
A   C   D   E   F   G   L   M   N   O   P   R   S   U  

Previous: , Up: Indexes   [Contents][Index]

A.4 Data types

Jump to:   C   D   F   I   M   O   P   S   T  
Index Entry  Section

C
Class, observable: Public classes
Class, property-support: Public classes

D
darts.lib.tools: The darts․lib․tools system
darts.lib.tools: The darts․lib․tools package
darts.lib.tools.asd: The darts․lib․tools/darts․lib․tools․asd file
darts.lib.tools.observables: The darts․lib․tools․observables package
darts.lib.tools.properties: The darts․lib․tools․properties package

F
File, darts.lib.tools.asd: The darts․lib․tools/darts․lib․tools․asd file
File, iteration.lisp: The darts․lib․tools/src/iteration․lisp file
File, misc.lisp: The darts․lib․tools/src/misc․lisp file
File, observable.lisp: The darts․lib․tools/src/observable․lisp file
File, packages.lisp: The darts․lib․tools/src/packages․lisp file
File, properties.lisp: The darts․lib․tools/src/properties․lisp file

I
iteration.lisp: The darts․lib․tools/src/iteration․lisp file

M
misc.lisp: The darts․lib․tools/src/misc․lisp file
Module, src: The darts․lib․tools/src module

O
observable: Public classes
observable.lisp: The darts․lib․tools/src/observable․lisp file
observer-chain: Private structures

P
Package, darts.lib.tools: The darts․lib․tools package
Package, darts.lib.tools.observables: The darts․lib․tools․observables package
Package, darts.lib.tools.properties: The darts․lib․tools․properties package
packages.lisp: The darts․lib․tools/src/packages․lisp file
plist-cell: Private types
properties.lisp: The darts․lib․tools/src/properties․lisp file
property-support: Public classes

S
src: The darts․lib․tools/src module
Structure, observer-chain: Private structures
System, darts.lib.tools: The darts․lib․tools system

T
Type, plist-cell: Private types

Jump to:   C   D   F   I   M   O   P   S   T