-
Notifications
You must be signed in to change notification settings - Fork 4
/
Copy pathgobpool.clj
73 lines (64 loc) · 2.65 KB
/
gobpool.clj
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
(ns hard.gobpool
(:import
[UnityEngine HideFlags GameObject]
[Pooled]))
(Pooled/addTag "pooled")
(Pooled/addTag "clone")
(defn ^UnityEngine.GameObject -tag-clone [^UnityEngine.GameObject o ^System.String n]
(set! (.name o) n)
(set! (.tag o) "clone") o)
(defmacro ^UnityEngine.GameObject -clone [^clojure.lang.Keyword k]
(let []
`(hard.gobpool/-tag-clone (UnityEngine.Object/Instantiate (~'UnityEngine.Resources/Load ~(name k))) ~(name k))))
(defn destroy-tagged [tag]
(dorun (map #(UnityEngine.Object/DestroyImmediate %) (GameObject/FindGameObjectsWithTag tag))))
(defprotocol IGobPool
(-reuse [a])
(-recycle [a b])
(-stats [a]))
(deftype GobPool [^|System.Object[]| pool
^System.Int64 ^:volatile-mutable idx]
IGobPool
(-stats [a]
(list (inc idx) '/ (.Length pool)))
(-reuse [a]
(try
(set! idx (dec idx))
(aget pool (inc idx))
(catch Exception e (set! idx (inc idx)) nil)))
(-recycle [a b]
(try
(set! idx (inc idx))
(aset pool idx b) nil
(catch Exception e (set! idx (dec idx)) nil))))
(defn pool-prep [o]
`((set! (.tag ~o) "pooled")
(.SetParent (.transform ~o) nil false)
(set! (.hideFlags ~o) UnityEngine.HideFlags/HideAndDontSave)
(set! (.position (.transform ~o)) (UnityEngine.Vector3. 0 -100000 0))))
(defn reuse-prep [o]
`((set! (.tag ~o) "clone")
(set! (.hideFlags ~o) UnityEngine.HideFlags/None)
(set! (.position (.transform ~o)) (UnityEngine.Vector3. 0 0 0))))
(defmacro gobpool [length type-sym model]
(let [gob (with-meta (gensym 'gob) {:tag 'UnityEngine.GameObject})
sym (with-meta (symbol (str "*" type-sym)) {:tag 'UnityEngine.GameObject})
pool (with-meta (symbol (str "<>" type-sym)) {:tag 'UnityEngine.GameObject})
return (with-meta (symbol (str "!" type-sym)) {:tag System.Boolean})
o# (gensym)]
`(~'let [~gob ~model]
~@(pool-prep gob)
(declare ~pool)
(when (bound? (var ~pool)) (dorun (map ~'arcadia.core/destroy-immediate (~'.pool ~pool))))
(~'def ~pool (new ~GobPool (~'make-array ~'System.Object ~length) -1))
(~'defn ~return
[~(with-meta (symbol "a") {:tag 'UnityEngine.GameObject})]
(~'hard.gobpool/-recycle ~pool ~'a)
~@(pool-prep 'a))
(~'defn ~sym []
(~'if-let [~(with-meta o# {:tag 'UnityEngine.GameObject}) (~'hard.gobpool/-reuse ~pool)]
(if (~'arcadia.core/null-obj? ~o#) (~sym)
(do ~@(reuse-prep o#) ~o#))
(let [~o# (~'hard.gobpool/-tag-clone (~'arcadia.core/instantiate ~gob) ~(str type-sym))]
(do ~@(reuse-prep o#) ~o#))))
~(mapv keyword [pool sym return]))))