This repository has been archived on 2022-11-18. You can view files and clone it, but cannot push or open issues or pull requests.
emacs/sample/concurrent-sample.el

186 lines
4.7 KiB
EmacsLisp
Raw Normal View History

;;; Sample code for concurrent.el -*- lexical-binding: t; -*-
;; Evaluate following code in the scratch buffer.
(require 'cl-lib)
(require 'concurrent)
;;==================================================
;;; generator
(defvar fib-list nil)
(defvar fib-gen ; Create a generator object.
(let ((a1 0) (a2 1))
(cc:generator
(lambda (x) (push x fib-list)) ; receiving values
(yield a1)
(yield a2)
(while t
(let ((next (+ a1 a2)))
(setq a1 a2
a2 next)
(yield next))))))
(funcall fib-gen) ; Generate 5 times
(funcall fib-gen) (funcall fib-gen)
(funcall fib-gen) (funcall fib-gen)
fib-list ;=> (3 2 1 1 0)
;;==================================================
;;; thread
(let ((count 0) (anm "-/|\\-")
(end 50) (pos (point)))
(cc:thread
60
(message "Animation started.")
(while (> end (cl-incf count))
(save-excursion
(when (< 1 count)
(goto-char pos) (delete-char 1))
(insert (char-to-string
(aref anm (% count (length anm)))))))
(save-excursion
(goto-char pos) (delete-char 1))
(message "Animation finished.")))
;; Play the simple character animation here.
;;==================================================
;;; semaphore
;; create a semaphore object with permit=1.
(defvar smp (cc:semaphore-create 1))
;; executing three tasks...
(deferred:nextc (cc:semaphore-acquire smp)
(lambda (_)
(message "go1")))
(deferred:nextc (cc:semaphore-acquire smp)
(lambda (_)
(message "go2")))
(deferred:nextc (cc:semaphore-acquire smp)
(lambda (_)
(message "go3")))
;; => Only the fist task is executed and displays "go1".
(cc:semaphore-release smp)
;; => The second task is executed and displays "go2".
(cc:semaphore-waiting-deferreds smp) ; return the deferred object that displays "go3".
(cc:semaphore-release-all smp) ; => reset permit count and return the deferred object that displays "go3".
(cc:semaphore-waiting-deferreds smp) ; => nil
;;==================================================
;; Dataflow
;; create a parent environment and bind "aaa" to 256.
(defvar dfenv-parent (cc:dataflow-environment))
(cc:dataflow-set dfenv-parent "aaa" 256)
;; create an environment with the parent one.
(defvar dfenv (cc:dataflow-environment dfenv-parent))
;; Return the parent value.
(cc:dataflow-get-sync dfenv "aaa") ; => 256
(deferred:$
(cc:dataflow-get dfenv "abc")
(deferred:nextc it
(lambda (x) (message "Got abc : %s" x))))
;; => This task is blocked
(cc:dataflow-set dfenv "abc" 256) ; bind 256 to "abc"
;; => The blocked task is executed and displays "Got abc : 256".
(cc:dataflow-get-sync dfenv "abc") ; => 256
;; unbind the variable "abc"
(cc:dataflow-clear dfenv "abc")
(cc:dataflow-get-sync dfenv "abc") ; => nil
;; complicated key (`equal' can compare nested lists.)
(deferred:$
(cc:dataflow-get dfenv '("http://example.com/a.jpg" 300))
(deferred:nextc it
(lambda (x) (message "a.jpg:300 OK %s" x))))
(cc:dataflow-set dfenv '("http://example.com/a.jpg" 300) 'jpeg)
;; waiting for two variables
(deferred:$
(deferred:parallel
(cc:dataflow-get dfenv "abc")
(cc:dataflow-get dfenv "def"))
(deferred:nextc it
(lambda (values)
(apply 'message "Got values : %s, %s" values)
(apply '+ values)))
(deferred:nextc it
(lambda (x) (insert (format ">> %s" x)))))
(cc:dataflow-get-waiting-keys dfenv) ; => ("def" "abc")
(cc:dataflow-get-avalable-pairs dfenv) ; => (("aaa" . 256))
(cc:dataflow-set dfenv "abc" 128)
(cc:dataflow-set dfenv "def" 256)
;; => "Got values : 128, 256"
;; inserted ">> 384"
(cc:dataflow-get-avalable-pairs dfenv)
(cc:dataflow-clear-all dfenv)
(cc:dataflow-get-avalable-pairs dfenv)
;;==================================================
;; Signal
(progn
(defvar parent-channel (cc:signal-channel "parent"))
(cc:signal-connect
parent-channel 'parent-load
(lambda (event) (message "Parent Signal : %s" event)))
(cc:signal-connect
parent-channel t
(lambda (event) (message "Parent Listener : %s" event)))
(defvar channel (cc:signal-channel "child" parent-channel))
(cc:signal-connect
channel 'window-load
(lambda (event) (message "Signal : %s" event)))
(cc:signal-connect
channel t
(lambda (event) (message "Listener : %s" event)))
(deferred:$
(cc:signal-connect channel 'window-load)
(deferred:nextc it
(lambda (x) (message "Deferred Signal : %s" x))))
)
(cc:signal-send channel 'window-load "hello signal!")
(cc:signal-send channel 'some "some signal!")
(cc:signal-send parent-channel 'parent-load "parent hello!")
(cc:signal-send parent-channel 'window-load "parent hello!")
(cc:signal-send parent-channel 'some "parent some hello!")
(cc:signal-send-global channel 'some "parent some hello!")
(cc:signal-disconnect-all channel)