-
-
Notifications
You must be signed in to change notification settings - Fork 47
/
asset-pool.lisp
84 lines (63 loc) · 2.65 KB
/
asset-pool.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
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
#|
This file is a part of trial
(c) 2017 Shirakumo http://tymoon.eu (shinmera@tymoon.eu)
Author: Nicolas Hafner <shinmera@tymoon.eu>
|#
(in-package #:org.shirakumo.fraf.trial)
(defmethod coerce-base (base)
(destructuring-bind (base &rest sub) (if (listp base) base (list base))
(if *standalone*
(merge-pathnames (format NIL "pool/~(~a~)/~{~a/~}" base sub) (deploy:data-directory))
(merge-pathnames (format NIL "data/~{~a/~}" sub) (asdf:system-source-directory base)))))
(defvar *pools* (make-hash-table :test 'eql))
(defun find-pool (name &optional errorp)
(or (gethash name *pools*)
(when errorp (error "No pool with name ~s." name))))
(defun (setf find-pool) (pool name)
(setf (gethash name *pools*) pool))
(defun remove-pool (name)
(remhash name *pools*))
(defun list-pools ()
(alexandria:hash-table-values *pools*))
(defclass pool ()
((name :initarg :name :accessor name)
(base :initarg :base :accessor base)
(assets :initform (make-hash-table :test 'eq) :accessor assets))
(:default-initargs
:name (error "NAME required.")
:base (error "BASE required.")))
(defmethod print-object ((pool pool) stream)
(print-unreadable-object (pool stream :type T)
(format stream "~a ~s" (name pool) (base pool))))
(defmacro define-pool (name &body initargs)
(check-type name symbol)
`(eval-when (:compile-toplevel :load-toplevel :execute)
(cond ((find-pool ',name)
(reinitialize-instance (find-pool ',name) ,@initargs))
(T
(setf (find-pool ',name) (make-instance 'pool :name ',name ,@initargs))))
',name))
(defmethod asset ((pool pool) name &optional (errorp T))
(or (gethash name (assets pool))
(when errorp (error "No asset with name ~s on pool ~a." name pool))))
(defmethod asset ((pool symbol) name &optional (errorp T))
(let ((pool (find-pool pool errorp)))
(when pool (asset pool name errorp))))
(defmethod (setf asset) (asset (pool symbol) name)
(setf (asset (find-pool pool T) name) asset))
(defmethod (setf asset) ((asset asset) (pool pool) name)
(setf (gethash name (assets pool)) asset))
(defmethod (setf asset) ((null null) (pool pool) name)
(deallocate (remhash name (assets pool))))
(defmethod list-assets ((pool pool))
(alexandria:hash-table-values (assets pool)))
(defmethod finalize ((pool pool))
(mapc #'finalize (list-assets pool)))
(defmethod pool-path ((pool pool) (null null))
(coerce-base (base pool)))
(defmethod pool-path ((pool pool) pathname)
(merge-pathnames pathname (coerce-base (base pool))))
(defmethod pool-path ((name symbol) pathname)
(pool-path (find-pool name T) pathname))
(eval '(define-pool trial
:base :trial))