[cells-cvs] CVS Celtk
ktilton
ktilton at common-lisp.net
Wed Mar 22 20:41:38 UTC 2006
Update of /project/cells/cvsroot/Celtk
In directory clnet:/tmp/cvs-serv27411
Modified Files:
ltktest-cells-inside.lisp
Log Message:
--- /project/cells/cvsroot/Celtk/ltktest-cells-inside.lisp 2006/03/22 18:50:08 1.2
+++ /project/cells/cvsroot/Celtk/ltktest-cells-inside.lisp 2006/03/22 20:41:37 1.3
@@ -1,18 +1,73 @@
(in-package :celtk-user)
+#|
+The comments throughout this source file cover two broad topics:
+
+ How is programming with Celtk different from LTk?
+ How is programming with Cells different from without Cells?
+
+Those questions are different because not everything different about Celtk
+depends on Cells.
+
+The pattern will be to have explanatory comments appear after the explained code.
+
+|#
#+test-ltktest
(progn
(cells-reset 'tk-user-queue-handler)
+ ;
+ ; Tk is fussy about the order in which things happen. It likes:
+ ; - create widgets .x and .y
+ ; - make .x the -textvariable of .y
+ ; - set .x to "Hi, Mom"
+ ;
+ ; Tk does not like Step 3 going before Step 2. Unfortunately, in a declarative paradigm
+ ; one does not specify in what order different things should happen, one just specifies
+ ; the things we want to have happen. That is a big win when it works. But when it did not
+ ; I created the concept of a so-called "client queue" where client-code could store
+ ; order-sensitive tasks, and then allowed the client also to specify the handler for
+ ; that queue. This handler gets called at just the right time in the larger scheme of
+ ; state propagation one needs for data integrity. Whassat?
+ ;
+ ; Data integrity: when the overall data model gets perturbed by a SETF by imperative code
+ ; (usually processing an event loop) of some datapoint X , we need:
+ ;
+ ; - all state computed off X (directly or indirectly through some intermediate state) must be recomputed;
+ ; - no recomputation can use datapoints not current with the new value of X;
+ ; - when invoking client observers to process a change in a datapoint, no observer can use
+ ; any datapoint not current with X; and a corrollary:
+ ; - should a client observer itself want to SETF a datapoint Y, all the above must
+ ; happen not just with values current with X, but also current with the value of Y /prior/
+ ; to the intended change to Y.
+ ;
+ ; To achieve the above, Cells2 and now Cells3 have taken to using FIFO "unfinished business" queues
+ ; to defer things until The Right Time. Which brings us back to Tk. Inspect the source of
+ ; tk-user-queue-handler and search the Celtk source for "with-integrity (:client" to see how Celtk
+ ; manages to talk to Tk in the order Tk likes. But in short, we just add this requirement:
+ ;
+ ; - Client code must see only values current with X and not any values current with some
+ ; subsequent change to Y queued by an observer
+ ;
(tk-test-class 'ltktest-cells-inside))
+; That is all the imperative code there is to Celtk application development, aside from widget commands. Tk handles some
+; of the driving imperative logic, and Celtk internals handle the rest. The application works via rules reacting to change,
+; computing new state for the application model, which operates on the outside world via observers (on-change callbacks) triggered
+; automatically by the Cells engine. See DEFOBSERVER.
+
(defmodel ltktest-cells-inside (window)
- ((elapsed :initarg :elapsed :accessor elapsed :initform (c-in 0)))
+ ()
(:default-initargs
:kids (c? (the-kids
- (ltk-test-menus)
+ ;
+ ; Cells GUIs get a lot of mileage out of the family class, which is perfect
+ ; for graphical hierarchies.
+ ;
+ (ltk-test-menus) ;; hiding some code. see below for deets
(mk-scroller
- :packing (c?pack-self "-side top -fill both -expand 1")
- :canvas (c? (make-kid 'ltk-test-canvas)))
+ :packing (c?pack-self "-side top -fill both -expand 1")
+ :canvas (c? (make-kid 'ltk-test-canvas)))
+
(mk-row (:packing (c?pack-self "-side bottom"))
(mk-row (:borderwidth 2 :relief 'sunken)
(mk-label :text "Rotation:")
@@ -67,7 +122,7 @@
:timers (c? (when (^repeat)
(list (make-instance 'timer
:tag :moire
- :delay 1
+ :delay 25
:repeat (let ((m self))
(c? (repeat m)))
:action (lambda (timer)
More information about the Cells-cvs
mailing list