This repository has been archived by the owner on Apr 2, 2023. It is now read-only.
-
-
Notifications
You must be signed in to change notification settings - Fork 5
/
Copy pathexecutable.lisp
49 lines (39 loc) · 1.69 KB
/
executable.lisp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
#|
This file is a part of Qtools-UI
(c) 2016 Shirakumo http://tymoon.eu ([email protected])
Author: Nicolas Hafner <[email protected]>
|#
(in-package #:org.shirakumo.qtools.ui)
(in-readtable :qtools)
(defvar *within-gui-thread* NIL)
(define-object executable (QObject)
((fill-queue :initform (make-array 0 :adjustable T :fill-pointer T) :reader fill-queue)
(proc-queue :initform (make-array 0 :adjustable T :fill-pointer T) :reader proc-queue)
(lock :initform (bt:make-lock) :reader lock)))
(defmethod initialize-instance :after ((executable executable) &key)
(signal! executable (process-executions)))
(define-signal (executable process-executions) ())
(define-slot (executable process-executions) ()
(declare (connected executable (process-executions)))
(let ((*within-gui-thread* executable))
(bt:with-lock-held (lock)
(rotatef fill-queue proc-queue))
(loop for i from 0 below (length proc-queue)
for execution = (aref proc-queue i)
do (setf (aref proc-queue i) NIL)
(when execution (execute execution)))
(setf (fill-pointer proc-queue) 0)))
(defmethod execute ((function cl:function))
(funcall function))
(defmethod execute :around (thing)
(with-simple-restart (abort "Abort executing ~a" thing)
(call-next-method)))
(defmethod execute-in-gui (execution (executable executable))
(cond ((eql *within-gui-thread* executable)
(execute execution))
(T
(bt:with-lock-held ((lock executable))
(vector-push-extend execution (fill-queue executable)))
(signal! executable (process-executions)))))
(defmacro with-body-in-gui ((executable) &body body)
`(execute-in-gui (lambda () ,@body) ,executable))