Updates to tuts and new with-sync-event

This commit is contained in:
David Botton 2022-02-10 20:44:11 -05:00
parent ec81e5fb2b
commit 18a5f8d78e
33 changed files with 157 additions and 104 deletions

View file

@ -40,8 +40,13 @@
(initialize #'on-new-window)
;; Set the function on-new-window to execute
;; everytime a browser connection to our app.
;; #' tells common lisp to pass the function
;; to intialize and not to execute it.
;; #' tells common lisp to pass the function.
;; If we pass the symbol 'on-new-window it
;; it will look each time for the function
;; represented by our symbol. This is generally
;; prefered in development as then we can
;; recompile our events while running ie. M-C-x
;; in emacs.
;; Open a browser to http://127.0.0.1:8080 - the default for CLOG apps
(open-browser))

View file

@ -38,5 +38,5 @@
(defun start-tutorial ()
"Start turtorial."
(initialize #'on-new-window)
(initialize 'on-new-window)
(open-browser))

View file

@ -12,22 +12,26 @@
(let ((x 0))
(set-on-click hello-element
(lambda (obj)
(declare (ignore obj))
(incf x)
(dotimes (n x)
(create-p body
:content (format nil "Clicked ~A times." x))
(sleep x)))))
(declare (ignorable obj))
;; Add to try non-parallel events:
;; (with-sync-event (obj)
(let ((y (incf x)))
(dotimes (n y)
(create-p body
:content (format nil "Clicked ~A times." y))
(sleep y)))))) ;)
(run body)))
;;; Running this version of the last tutorial and clicking quickly on the (click me!)
;;; will demonstrate an important aspect of CLOG, events can happen in _parallel_.
;;; This means that appropriate precautions to thread protect data should be taken
;;; and that events do not wait for previous event handlers to complete. One simple
;;; way to avoid issues is to use the key :one-time t on the set-on-click or other
;;; event, this will turn off the event immediately when the user clicks and can then
;;; set the event again when done handling the event if want to again accept the event.
;;; and that events do not wait for previous event handlers to complete. To change
;;; this behavior just add at start of event WITH-SYNC-EVENT and then all events
;;; will be serialized like in "traditional" GUIs to that event, events using
;;; WITH-SYNC-EVENT will be on same queue of incoming events and syncronized.
;;; But... notice what happens once syncing is on the next event doesn't hit until
;;; SLEEP returns.
(defun start-tutorial ()
"Start turtorial."
(initialize #'on-new-window)
(initialize 'on-new-window)
(open-browser))

View file

@ -12,12 +12,12 @@
(setf (title (html-document body)) "Tutorial 4")
;; The same handler #'my-on-click is set on both targets
(set-on-click (create-section body :h1 :content "Hello World! (click me!)")
#'my-on-click)
'my-on-click)
(set-on-click (create-section body :h3 :content "Click me too!")
#'my-on-click)
'my-on-click)
(run body))
(defun start-tutorial ()
"Start turtorial."
(initialize #'on-new-window)
(initialize 'on-new-window)
(open-browser))

View file

@ -15,12 +15,12 @@
"On-new-window handler."
(setf (title (html-document body)) "Tutorial 5")
(set-on-click (create-section body :h1 :content "Hello World! (click me!)")
#'my-on-click)
'my-on-click)
(setf (connection-data-item body "changer")
(create-section body :h1 :content "I change"))
(run body))
(defun start-tutorial ()
"Start turtorial."
(initialize #'on-new-window)
(initialize 'on-new-window)
(open-browser))

View file

@ -28,10 +28,10 @@
"On-new-window handler."
(setf (title (html-document body)) "Tutorial 6")
(set-on-click (create-section body :h1 :content "(click me to start!)")
#'my-on-click)
'my-on-click)
(run body))
(defun start-tutorial ()
"Start turtorial."
(initialize #'on-new-window)
(initialize 'on-new-window)
(open-browser))

View file

@ -34,7 +34,7 @@
(set-bounds))))
;; Setup our "mover". Darth
(setf (positioning mover) :fixed)
(set-on-click mover #'on-click)
(set-on-click mover 'on-click)
;; Get Darth moving!
(bordeaux-threads:make-thread ; In addtion to the main task (the on-new-window)
(lambda () ; and the task created for each event like clicks
@ -80,5 +80,5 @@
(defun start-tutorial ()
"Start turtorial."
(initialize #'on-new-window)
(initialize 'on-new-window)
(open-browser))

View file

@ -5,11 +5,7 @@
(in-package :clog-tut-8)
(defclass app-data ()
((drag-mutex
:reader drag-mutex
:initform (bordeaux-threads:make-lock)
:documentation "Serialize access to the on-mouse-down event.")
(in-drag
((in-drag
:accessor in-drag-p
:initform nil
:documentation "Ensure only one box is dragged at a time.")
@ -22,25 +18,25 @@
(:documentation "App data specific to each instance of our tutorial 8 app"))
(defun on-mouse-down (obj data)
(let ((app (connection-data-item obj "app-data"))) ; Access our instance of App-Data
(bordeaux-threads:with-lock-held ((drag-mutex app)) ; Ensure the first event received
(unless (in-drag-p app) ; to drag is the only one, ie only
(setf (in-drag-p app) t) ; the innermost box is dragged.
(let* ((mouse-x (getf data :screen-x)) ; Use the screen coordinates not
(mouse-y (getf data :screen-y)) ; the coordinates relative to the obj
(obj-top (parse-integer (top obj) :junk-allowed t))
(obj-left (parse-integer (left obj) :junk-allowed t)))
(setf (drag-x app) (- mouse-x obj-left))
(setf (drag-y app) (- mouse-y obj-top))
(if (eq (getf data :event-type) :touch)
(progn
(set-on-touch-move obj 'on-mouse-move)
(set-on-touch-end obj 'stop-obj-grab)
(set-on-touch-cancel obj 'on-mouse-leave))
(progn
(set-on-mouse-move obj 'on-mouse-move)
(set-on-mouse-up obj 'stop-obj-grab)
(set-on-mouse-leave obj 'on-mouse-leave))))))))
(with-sync-event (obj) ; Serialize events to on-mouse-down.
(let ((app (connection-data-item obj "app-data"))) ; Ensure the first event received
(unless (in-drag-p app) ; to drag is the only one, ie only
(setf (in-drag-p app) t) ; the innermost box is dragged.
(let* ((mouse-x (getf data :screen-x)) ; Use the screen coordinates not
(mouse-y (getf data :screen-y)) ; the coordinates relative to the obj
(obj-top (parse-integer (top obj) :junk-allowed t))
(obj-left (parse-integer (left obj) :junk-allowed t)))
(setf (drag-x app) (- mouse-x obj-left))
(setf (drag-y app) (- mouse-y obj-top))
(if (eq (getf data :event-type) :touch)
(progn
(set-on-touch-move obj 'on-mouse-move)
(set-on-touch-end obj 'stop-obj-grab)
(set-on-touch-cancel obj 'on-mouse-leave))
(progn
(set-on-mouse-move obj 'on-mouse-move)
(set-on-mouse-up obj 'stop-obj-grab)
(set-on-mouse-leave obj 'on-mouse-leave))))))))
(defun on-mouse-move (obj data)
(let* ((app (connection-data-item obj "app-data"))
@ -102,5 +98,5 @@
(defun start-tutorial ()
"Start turtorial."
(initialize #'on-new-window)
(initialize 'on-new-window)
(open-browser))

View file

@ -158,5 +158,5 @@
(defun start-tutorial ()
"Start turtorial."
(initialize #'on-new-window)
(initialize 'on-new-window)
(open-browser))

View file

@ -24,5 +24,5 @@
(defun start-tutorial ()
"Start turtorial."
(initialize #'on-new-window)
(initialize 'on-new-window)
(open-browser))

View file

@ -66,11 +66,11 @@
(reset form)))
;; We need to override the boostrap default to submit the form html style
(set-on-submit form (lambda (obj)(declare (ignore obj))()))
(set-on-click good-button #'on-click-good)
(set-on-click scary-button #'on-click-scary))
(set-on-click good-button 'on-click-good)
(set-on-click scary-button 'on-click-scary))
(run body)))
(defun start-tutorial ()
"Start tutorial."
(initialize #'on-new-window)
(initialize 'on-new-window)
(open-browser :url "http://127.0.0.1:8080/tutorial/tut-11.html"))

View file

@ -81,35 +81,35 @@
(reset form)))
;; We need to override the boostrap default to submit the form html style
(set-on-submit form (lambda (obj)(declare (ignore obj))()))
(set-on-click good-button #'on-click-good)
(set-on-click scary-button #'on-click-scary))
(set-on-click good-button 'on-click-good)
(set-on-click scary-button 'on-click-scary))
(run body)))
(defun start-tutorial ()
"Start turtorial."
(initialize #'on-main)
(initialize 'on-main)
;; Navigating to http://127.0.0.1:8080/page1 executes on-page1
(set-on-new-window #'on-page1 :path "/page1")
(set-on-new-window 'on-page1 :path "/page1")
;; Navigating to http://127.0.0.1:8080/page1.html executes on-page1
;; There is no .html file - it is just a route to CLOG handler
;; but the user thinks it is like any other html file.
(set-on-new-window #'on-page1 :path "/page1.html")
(set-on-new-window 'on-page1 :path "/page1.html")
;; Navigating to http://127.0.0.1:8080/somepath/page1/ executes on-page1
;; the path set can be any valid html path and has no meaning.
(set-on-new-window #'on-page1 :path "/somepath/hi/")
(set-on-new-window 'on-page1 :path "/somepath/hi/")
;; Here we add another page, page2. It uses a boot file that turns
;; on debugging to the browser console of communications with the
;; server.
(set-on-new-window #'on-page2 :path "/page2" :boot-file "/debug.html")
(set-on-new-window 'on-page2 :path "/page2" :boot-file "/debug.html")
;; Here we add another page, page3. But this time we use the html file
;; from tutorial 11 and make it the boot-file and execute the same code
;; in (on-tutorial11) as in tutorial 11.
(set-on-new-window #'on-tutorial11 :path "/page3"
(set-on-new-window 'on-tutorial11 :path "/page3"
:boot-file "/tutorial/tut-11.html")
;; Setting a "default" path says that any use of an included boot.js
;; file will route to this function, in this case #'on-default
;; which will determine if this is coming from the path used in tutorial
;; 11 - "http://127.0.0.1:8080/tutorial/tut-11.html" and if it does
;; use on-tutorial11, and if not say "No Dice!"
(set-on-new-window #'on-default :path "default")
(set-on-new-window 'on-default :path "default")
(open-browser))

View file

@ -9,7 +9,7 @@
(run body))
(defun start-app ()
(initialize #'on-new-window
(initialize 'on-new-window
:static-root (merge-pathnames "./www/"
(asdf:system-source-directory :hello-clog)))
(open-browser))

View file

@ -54,5 +54,5 @@ Changes made to a local key will fire an event and print below:<br>"
(defun start-tutorial ()
"Start turtorial."
(initialize #'on-new-window)
(initialize 'on-new-window)
(open-browser))

View file

@ -29,5 +29,5 @@
(defun start-tutorial ()
"Start turtorial."
(initialize #'on-new-window)
(initialize 'on-new-window)
(open-browser))

View file

@ -75,6 +75,6 @@
(defun start-tutorial ()
"Start turtorial."
(initialize #'on-index)
(set-on-new-window #'on-page2 :path "/page2")
(initialize 'on-index)
(set-on-new-window 'on-page2 :path "/page2")
(open-browser))

View file

@ -110,8 +110,8 @@
(defun start-tutorial ()
"Start tutorial."
(initialize #'on-index)
(set-on-new-window #'on-page2 :path "/page2")
(set-on-new-window #'on-page3 :path "/page3")
(set-on-new-window #'on-page4 :path "/page4")
(initialize 'on-index)
(set-on-new-window 'on-page2 :path "/page2")
(set-on-new-window 'on-page3 :path "/page3")
(set-on-new-window 'on-page4 :path "/page4")
(open-browser))

View file

@ -57,5 +57,5 @@
(defun start-tutorial ()
"Start tutorial."
(initialize #'on-new-window)
(initialize 'on-new-window)
(open-browser))

View file

@ -29,5 +29,5 @@
(defun start-tutorial ()
"Start tutorial."
(initialize #'on-new-window)
(initialize 'on-new-window)
(open-browser))

View file

@ -71,5 +71,5 @@
(defun start-tutorial ()
"Start tutorial."
(initialize #'on-new-window)
(initialize 'on-new-window)
(open-browser))

View file

@ -59,5 +59,5 @@ on the drop-root."))
(defun start-tutorial ()
"Start tutorial."
(initialize #'on-new-window)
(initialize 'on-new-window)
(open-browser))

View file

@ -125,29 +125,29 @@
(clog-gui-initialize body)
(add-class body "w3-cyan")
(let* ((menu (create-gui-menu-bar body))
(tmp (create-gui-menu-icon menu :on-click #'on-help-about))
(tmp (create-gui-menu-icon menu :on-click 'on-help-about))
(file (create-gui-menu-drop-down menu :content "File"))
(tmp (create-gui-menu-item file :content "Count" :on-click #'on-file-count))
(tmp (create-gui-menu-item file :content "Browse" :on-click #'on-file-browse))
(tmp (create-gui-menu-item file :content "Drawing" :on-click #'on-file-drawing))
(tmp (create-gui-menu-item file :content "Movie" :on-click #'on-file-movies))
(tmp (create-gui-menu-item file :content "Pinned" :on-click #'on-file-pinned))
(tmp (create-gui-menu-item file :content "Count" :on-click 'on-file-count))
(tmp (create-gui-menu-item file :content "Browse" :on-click 'on-file-browse))
(tmp (create-gui-menu-item file :content "Drawing" :on-click 'on-file-drawing))
(tmp (create-gui-menu-item file :content "Movie" :on-click 'on-file-movies))
(tmp (create-gui-menu-item file :content "Pinned" :on-click 'on-file-pinned))
(win (create-gui-menu-drop-down menu :content "Window"))
(tmp (create-gui-menu-item win :content "Maximize All" :on-click #'maximize-all-windows))
(tmp (create-gui-menu-item win :content "Normalize All" :on-click #'normalize-all-windows))
(tmp (create-gui-menu-item win :content "Maximize All" :on-click 'maximize-all-windows))
(tmp (create-gui-menu-item win :content "Normalize All" :on-click 'normalize-all-windows))
(tmp (create-gui-menu-window-select win))
(dlg (create-gui-menu-drop-down menu :content "Dialogs"))
(tmp (create-gui-menu-item dlg :content "Alert Dialog Box" :on-click #'on-dlg-alert))
(tmp (create-gui-menu-item dlg :content "Input Dialog Box" :on-click #'on-dlg-input))
(tmp (create-gui-menu-item dlg :content "Confirm Dialog Box" :on-click #'on-dlg-confirm))
(tmp (create-gui-menu-item dlg :content "Form Dialog Box" :on-click #'on-dlg-form))
(tmp (create-gui-menu-item dlg :content "Server File Dialog Box" :on-click #'on-dlg-file))
(tmp (create-gui-menu-item dlg :content "Alert Dialog Box" :on-click 'on-dlg-alert))
(tmp (create-gui-menu-item dlg :content "Input Dialog Box" :on-click 'on-dlg-input))
(tmp (create-gui-menu-item dlg :content "Confirm Dialog Box" :on-click 'on-dlg-confirm))
(tmp (create-gui-menu-item dlg :content "Form Dialog Box" :on-click 'on-dlg-form))
(tmp (create-gui-menu-item dlg :content "Server File Dialog Box" :on-click 'on-dlg-file))
(tst (create-gui-menu-drop-down menu :content "Toasts"))
(tmp (create-gui-menu-item tst :content "Alert Toast" :on-click #'on-toast-alert))
(tmp (create-gui-menu-item tst :content "Warning Toast" :on-click #'on-toast-warn))
(tmp (create-gui-menu-item tst :content "Success Toast" :on-click #'on-toast-success))
(tmp (create-gui-menu-item tst :content "Alert Toast" :on-click 'on-toast-alert))
(tmp (create-gui-menu-item tst :content "Warning Toast" :on-click 'on-toast-warn))
(tmp (create-gui-menu-item tst :content "Success Toast" :on-click 'on-toast-success))
(help (create-gui-menu-drop-down menu :content "Help"))
(tmp (create-gui-menu-item help :content "About" :on-click #'on-help-about))
(tmp (create-gui-menu-item help :content "About" :on-click 'on-help-about))
(tmp (create-gui-menu-full-screen menu)))
(declare (ignore tmp)))
(set-on-before-unload (window body) (lambda(obj)
@ -158,5 +158,5 @@
(defun start-tutorial ()
"Start turtorial."
(initialize #'on-new-window)
(initialize 'on-new-window)
(open-browser))

View file

@ -52,5 +52,5 @@
(defun start-tutorial ()
"Start turtorial."
(initialize #'on-new-window)
(initialize 'on-new-window)
(open-browser))

View file

@ -98,11 +98,11 @@
";; This is a code block<br>
(defun start-tutorial ()<br>
\"Start turtorial.\"<br>
(initialize #'on-new-window)<br>
(initialize 'on-new-window)<br>
(open-browser))")
(run body)))
(defun start-tutorial ()
"Start turtorial."
(initialize #'on-new-window)
(initialize 'on-new-window)
(open-browser))

View file

@ -66,5 +66,5 @@
(defun start-tutorial ()
"Start turtorial."
(initialize #'on-new-window)
(initialize 'on-new-window)
(open-browser))

View file

@ -99,7 +99,7 @@
(defun start-tutorial ()
"Start turtorial."
;; We would probably set :host to my IP and :port 80 here if running a live site
(initialize #'on-new-window)
(initialize 'on-new-window)
;; In real life, if we openning a browser here it would likely be
;; to a page with a monitor of system etc. since it is local.
(open-browser))

View file

@ -9,7 +9,7 @@
(setf (color (hello-span panel)) (rgb (random 255) (random 255) (random 255))))
(defun start-app ()
(initialize #'create-hello-page
(initialize 'create-hello-page
:static-root (merge-pathnames "./www/"
(asdf:system-source-directory :hello-builder)))
(open-browser))