(in-package :glib)
(eval-when (:compile-toplevel :load-toplevel :execute)
+ (defvar *initializers-table* (make-hash-table :test 'equalp))
(defvar *initializers* nil)
- (defun register-initializer (fn)
- (setf *initializers* (nconc *initializers* (list fn)))))
+ (defun register-initializer (key fn)
+ (unless (gethash key *initializers-table*)
+ (setf (gethash key *initializers-table*) t
+ *initializers* (nconc *initializers* (list fn))))))
(defun run-initializers ()
(iter (for fn in *initializers*)
(funcall fn)))
-(defmacro at-init (&body body)
+(defmacro at-init ((&rest keys) &body body)
"@arg[body]{the code}
Runs the code normally but also schedules the code to be run at image load time.
-It is used to reinitialize the libraries when the dumped image is loaded.
-(Works only on SBCL for now)
+It is used to reinitialize the libraries when the dumped image is loaded. (Works only on SBCL for now)
"
- `(progn (register-initializer (lambda () ,@body))
+ `(progn (register-initializer (list ,@keys ',body) (lambda () ,@body))
,@body))
(eval-when (:compile-toplevel :load-toplevel :execute)
(defvar *threads-initialized-p* nil)
-(at-init
+(at-init ()
(unless *threads-initialized-p*
(g-thread-init (null-pointer))
(setf *threads-initialized-p* t)))
(setf parent (g-type-name (ensure-g-type parent))))
`(progn
(setf (gethash ,name *registered-types*) (make-object-type :name ,name :class ',class :parent ,parent :interfaces ',interfaces :properties ',properties))
- (at-init
+ (at-init (',class)
(debugf "Registering GObject type implementation ~A for type ~A~%" ',class ,name)
(with-foreign-object (query 'g-type-query)
(g-type-query (g-type-from-name ,parent) query)
,@(when export
(list `(export ',name (find-package ,(package-name (symbol-package name))))))
,@(when type-initializer
- (list (type-initializer-call type-initializer)))))
+ (list `(at-init () ,(type-initializer-call type-initializer))))))
(defun enum-value->definition (enum-value)
(let ((value-name (intern (lispify-name (enum-item-nick enum-value))
,@(when export
(list `(export ',name (find-package ,(package-name (symbol-package name))))))
,@(when type-initializer
- (list (type-initializer-call type-initializer)))))
+ (list `(at-init () ,(type-initializer-call type-initializer))))))
(defun flags-value->definition (flags-value)
(let ((value-name (intern (lispify-name (flags-item-nick flags-value))
(defmethod initialize-instance :after ((object gobject-class) &key &allow-other-keys)
(register-object-type (gobject-class-g-type-name object) (class-name object))
- (at-init (initialize-gobject-class-g-type object)))
+ (at-init (object) (initialize-gobject-class-g-type object)))
(defclass gobject-direct-slot-definition (standard-direct-slot-definition)
((g-property-type :initform nil
(defcfun (%g-type-init "g_type_init") :void)
-(at-init (%g-type-init))
+(at-init () (%g-type-init))
(defcfun (g-type-name "g_type_name") :string
"Returns the GType name