;;; -*- mode: Lisp; Syntax: Common-Lisp; -*- ;;; ;;; Copyright (c) 2009 by the authors. ;;; ;;; See LICENCE for details. (in-package :hu.dwim.projectional-editor) ;;;;;;; ;;; Editor API ;;; ;;; An editor is a way of changing the state of a document. (def (computed-universe e) projectional-editor () () (:computed-state-factory-name as)) (def (generic e) editor? (object) (:documentation "Returns TRUE if OBJECT is an editor, otherwise returns FALSE. Purely functional.")) (def (generic e) make-editor (&key width height) (:documentation "Returns a new editor object. Purely functional.")) (def (generic e) read-from-devices (editor document projection) (:documentation "Reads an operation from the input devices of EDITOR in the context of DOCUMENT using PROJECTION. Does not return until it has successfully read an operation. Has side effects on the state of the input devices, the list of events, gestures and operations that has been read so far by EDITOR.")) (def (generic e) print-to-devices (editor document projection) (:documentation "Prints DOCUMENT to the output devices of EDITOR using PROJECTION. Has side effects on the state of the output devices of EDITOR.")) (def (generic e) run-read-evaluate-print-loop (editor document projection) (:documentation "Runs read-evaluate-print loop of EDITOR on DOCUMENT using PROJECTION. The loop first prints DOCUMENT to the output devices of EDITOR. Next it reads an operation from the input devices of EDITOR. Finally it evaluates the result of read operation and starts over. Has side effects continuously on the state of EDITOR and the content of DOCUMENT while running.")) ;;;;;; ;;; Editor classes (def class* editor () ((devices :type sequence) (output-iomap nil :type t) (event-queue :type event-queue) (gesture-queue :type gesture-queue) (operation-tree :type operation-tree))) ;;;;;; ;;; Editor API implementation (def method editor? (object) (typep object 'editor)) (def method run-read-evaluate-print-loop ((editor editor) document projection) (catch :quit-editor (iter (print-to-devices editor document projection) (funcall (read-from-devices editor document projection))))) (def method read-from-devices ((editor editor) document projection) (bind ((event-queue (event-queue-of editor)) (gesture-queue (gesture-queue-of editor)) (operation-tree (operation-tree-of editor))) (iter (when-bind event (read-event (devices-of editor)) (push event (events-of event-queue)) (when-bind gesture (read-gesture event-queue) (push gesture (gestures-of gesture-queue)) (when-bind operation (or (apply-reader gesture-queue projection) (make-operation/quit)) (push operation (operations-of operation-tree)) (return (lambda () (redo-operation operation document))))))))) (def method print-to-devices ((editor editor) document projection) (bind ((output-iomap (or (output-iomap-of editor) (setf (output-iomap-of editor) (apply-printer document projection))))) (iter (for device :in-sequence (devices-of editor)) (print-to-device (output-of output-iomap) device))))