Use reflection to avoid static initializer in g2d-physics

This commit is contained in:
oakes
2014-04-20 17:56:00 -04:00
parent dd0abf7bc5
commit 694d63448c
7 changed files with 54 additions and 46 deletions

View File

@@ -173,7 +173,7 @@
(focus-listener options execute-fn!)]) (focus-listener options execute-fn!)])
(defmulti contact-listener (defmulti contact-listener
(fn [screen options execute-fn!] (-> screen :world class)) (fn [screen options execute-fn!] (some-> screen :world class .getName))
:default nil) :default nil)
(defmethod contact-listener nil [_ _ _]) (defmethod contact-listener nil [_ _ _])
@@ -199,7 +199,7 @@
(add-input! renderer))) (add-input! renderer)))
(defmulti update-physics! (defmulti update-physics!
(fn [screen & [entities]] (-> screen :world class)) (fn [screen & [entities]] (some-> screen :world class .getName))
:default nil) :default nil)
(defmethod update-physics! nil [_ & _]) (defmethod update-physics! nil [_ & _])

View File

@@ -1,5 +1,6 @@
(ns play-clj.g2d (ns play-clj.g2d
(:require [play-clj.utils :as u]) (:require [play-clj.entities]
[play-clj.utils :as u])
(:import [com.badlogic.gdx.graphics Pixmap Texture] (:import [com.badlogic.gdx.graphics Pixmap Texture]
[com.badlogic.gdx.graphics.g2d Animation BitmapFont NinePatch [com.badlogic.gdx.graphics.g2d Animation BitmapFont NinePatch
ParticleEffect TextureAtlas TextureRegion] ParticleEffect TextureAtlas TextureRegion]

View File

@@ -2,9 +2,10 @@
(:require [play-clj.core :as c] (:require [play-clj.core :as c]
[play-clj.math :as m] [play-clj.math :as m]
[play-clj.utils :as u]) [play-clj.utils :as u])
(:import [com.badlogic.gdx.physics.box2d Body BodyDef ChainShape CircleShape (:import [com.badlogic.gdx.math Vector2]
[com.badlogic.gdx.physics.box2d Body BodyDef ChainShape CircleShape
Contact ContactListener EdgeShape Fixture FixtureDef Joint JointDef Contact ContactListener EdgeShape Fixture FixtureDef Joint JointDef
PolygonShape Transform World])) PolygonShape Transform]))
; world ; world
@@ -14,20 +15,26 @@
([gravity-x gravity-y] ([gravity-x gravity-y]
(box-2d* gravity-x gravity-y true)) (box-2d* gravity-x gravity-y true))
([gravity-x gravity-y sleep?] ([gravity-x gravity-y sleep?]
(World. (m/vector-2 gravity-x gravity-y) sleep?))) ; use reflection to instantiate in order to avoid the static initializer
(some-> (try (Class/forName "com.badlogic.gdx.physics.box2d.World")
(catch Exception _))
.getDeclaredConstructors
first
(.newInstance
(object-array [(m/vector-2 gravity-x gravity-y) sleep?])))))
(defmacro box-2d (defmacro box-2d
"Returns a [World](http://libgdx.badlogicgames.com/nightlies/docs/api/com/badlogic/gdx/physics/box2d/World.html). "Returns a [World](http://libgdx.badlogicgames.com/nightlies/docs/api/com/badlogic/gdx/physics/box2d/World.html).
(box-2d 0 0)" (box-2d 0 0)"
[gravity-x gravity-y & options] [gravity-x gravity-y & options]
`(let [^World object# (box-2d* ~gravity-x ~gravity-y)] `(let [object# (box-2d* ~gravity-x ~gravity-y)]
(u/calls! object# ~@options))) (u/calls! object# ~@options)))
(defmacro box-2d! (defmacro box-2d!
"Calls a single method on a `box-2d`." "Calls a single method on a `box-2d`."
[screen k & options] [screen k & options]
`(let [^World object# (u/get-obj ~screen :world)] `(let [object# (u/get-obj ~screen :world)]
(u/call! object# ~k ~@options))) (u/call! object# ~k ~@options)))
; bodies ; bodies
@@ -213,7 +220,7 @@ such as :on-begin-contact."
; misc ; misc
(defmethod c/contact-listener (defmethod c/contact-listener
World "com.badlogic.gdx.physics.box2d.World"
[screen [screen
{:keys [on-begin-contact on-end-contact on-post-solve on-pre-solve]} {:keys [on-begin-contact on-end-contact on-post-solve on-pre-solve]}
execute-fn!] execute-fn!]
@@ -228,8 +235,8 @@ such as :on-begin-contact."
(execute-fn! on-pre-solve :contact c :old-manifold m)))) (execute-fn! on-pre-solve :contact c :old-manifold m))))
(defmethod c/update-physics! (defmethod c/update-physics!
World "com.badlogic.gdx.physics.box2d.World"
[{:keys [^World world contact-listener]} & [entities]] [{:keys [world contact-listener]} & [entities]]
(.setContactListener world contact-listener) (.setContactListener world contact-listener)
(when (and entities (not (.isLocked world))) (when (and entities (not (.isLocked world)))
(let [arr (u/gdx-array [])] (let [arr (u/gdx-array [])]
@@ -248,7 +255,7 @@ such as :on-begin-contact."
(defn step! (defn step!
"Runs the physics simulations for a single frame and optionally returns the "Runs the physics simulations for a single frame and optionally returns the
`entities` with their positions updated." `entities` with their positions updated."
[{:keys [^World world time-step velocity-iterations position-iterations] [{:keys [world time-step velocity-iterations position-iterations]
:or {time-step (/ 1 60) velocity-iterations 10 position-iterations 10} :or {time-step (/ 1 60) velocity-iterations 10 position-iterations 10}
:as screen} :as screen}
& [entities]] & [entities]]

View File

@@ -1,5 +1,6 @@
(ns play-clj.g3d (ns play-clj.g3d
(:require [play-clj.utils :as u]) (:require [play-clj.entities]
[play-clj.utils :as u])
(:import [com.badlogic.gdx.graphics.g3d Environment Material Model ModelBatch (:import [com.badlogic.gdx.graphics.g3d Environment Material Model ModelBatch
ModelInstance] ModelInstance]
[com.badlogic.gdx.graphics.g3d.attributes BlendingAttribute [com.badlogic.gdx.graphics.g3d.attributes BlendingAttribute

View File

@@ -267,7 +267,7 @@ such as :on-begin-contact."
; misc ; misc
(defmethod c/contact-listener (defmethod c/contact-listener
World3D "play_clj.g3d_physics.World3D"
[screen [screen
{:keys [on-begin-contact on-end-contact]} {:keys [on-begin-contact on-end-contact]}
execute-fn!] execute-fn!]
@@ -284,7 +284,7 @@ such as :on-begin-contact."
(.at arr i)))) (.at arr i))))
(defmethod c/update-physics! (defmethod c/update-physics!
World3D "play_clj.g3d_physics.World3D"
[screen & [entities]] [screen & [entities]]
; initialize bodies if necessary ; initialize bodies if necessary
(doseq [e entities] (doseq [e entities]

View File

@@ -1,125 +1,123 @@
(ns play-clj.physics (ns play-clj.physics
(:require [play-clj.g2d-physics :as p2d] (:require [play-clj.g2d-physics :as p2d]
[play-clj.g3d-physics :as p3d] [play-clj.g3d-physics :as p3d]
[play-clj.utils :as u]) [play-clj.utils :as u]))
(:import [com.badlogic.gdx.physics.box2d Body World]
[play_clj.g3d_physics Body3D World3D]))
; this namespace is for internal use only. you should use the g2d-physics and ; this namespace is for internal use only. you should use the g2d-physics and
; g3d-physics namespaces directly, instead. ; g3d-physics namespaces directly, instead.
(defmulti add-body! (defmulti add-body!
(fn [screen body] (-> screen (u/get-obj :world) class))) (fn [screen body] (some-> screen (u/get-obj :world) class .getName)))
(defmethod add-body! (defmethod add-body!
World "com.badlogic.gdx.physics.box2d.World"
[screen b-def] [screen b-def]
(p2d/add-body! screen b-def)) (p2d/add-body! screen b-def))
(defmethod add-body! (defmethod add-body!
World3D "play_clj.g3d_physics.World3D"
[screen body] [screen body]
(p3d/add-body! screen body)) (p3d/add-body! screen body))
(defmulti body-position! (defmulti body-position!
(fn [entity a1 a2 a3] (-> entity (u/get-obj :body) class))) (fn [entity a1 a2 a3] (some-> entity (u/get-obj :body) class .getName)))
(defmethod body-position! (defmethod body-position!
Body "com.badlogic.gdx.physics.box2d.Body"
[entity x y angle] [entity x y angle]
(p2d/body-position! entity x y angle)) (p2d/body-position! entity x y angle))
(defmethod body-position! (defmethod body-position!
Body3D "play_clj.g3d_physics.Body3D"
[entity x y z] [entity x y z]
(p3d/body-position! entity x y z)) (p3d/body-position! entity x y z))
(defmulti body-x! (defmulti body-x!
(fn [entity x] (-> entity (u/get-obj :body) class))) (fn [entity x] (some-> entity (u/get-obj :body) class .getName)))
(defmethod body-x! (defmethod body-x!
Body "com.badlogic.gdx.physics.box2d.Body"
[entity x] [entity x]
(p2d/body-x! entity x)) (p2d/body-x! entity x))
(defmethod body-x! (defmethod body-x!
Body3D "play_clj.g3d_physics.Body3D"
[entity x] [entity x]
(p3d/body-x! entity x)) (p3d/body-x! entity x))
(defmulti body-y! (defmulti body-y!
(fn [entity y] (-> entity (u/get-obj :body) class))) (fn [entity y] (some-> entity (u/get-obj :body) class .getName)))
(defmethod body-y! (defmethod body-y!
Body "com.badlogic.gdx.physics.box2d.Body"
[entity y] [entity y]
(p2d/body-y! entity y)) (p2d/body-y! entity y))
(defmethod body-y! (defmethod body-y!
Body3D "play_clj.g3d_physics.Body3D"
[entity y] [entity y]
(p3d/body-y! entity y)) (p3d/body-y! entity y))
(defmulti body-z! (defmulti body-z!
(fn [entity z] (-> entity (u/get-obj :body) class))) (fn [entity z] (some-> entity (u/get-obj :body) class .getName)))
(defmethod body-z! (defmethod body-z!
Body3D "play_clj.g3d_physics.Body3D"
[entity z] [entity z]
(p3d/body-z! entity z)) (p3d/body-z! entity z))
(defmulti body-angle! (defmulti body-angle!
(fn [entity angle] (-> entity (u/get-obj :body) class))) (fn [entity angle] (some-> entity (u/get-obj :body) class .getName)))
(defmethod body-angle! (defmethod body-angle!
Body "com.badlogic.gdx.physics.box2d.Body"
[entity angle] [entity angle]
(p2d/body-angle! entity angle)) (p2d/body-angle! entity angle))
(defmulti first-entity (defmulti first-entity
(fn [screen entities] (-> screen (u/get-obj :world) class))) (fn [screen entities] (some-> screen (u/get-obj :world) class .getName)))
(defmethod first-entity (defmethod first-entity
World "com.badlogic.gdx.physics.box2d.World"
[screen entities] [screen entities]
(p2d/first-entity screen entities)) (p2d/first-entity screen entities))
(defmethod first-entity (defmethod first-entity
World3D "play_clj.g3d_physics.World3D"
[screen entities] [screen entities]
(p3d/first-entity screen entities)) (p3d/first-entity screen entities))
(defmulti second-entity (defmulti second-entity
(fn [screen entities] (-> screen (u/get-obj :world) class))) (fn [screen entities] (some-> screen (u/get-obj :world) class .getName)))
(defmethod second-entity (defmethod second-entity
World "com.badlogic.gdx.physics.box2d.World"
[screen entities] [screen entities]
(p2d/second-entity screen entities)) (p2d/second-entity screen entities))
(defmethod second-entity (defmethod second-entity
World3D "play_clj.g3d_physics.World3D"
[screen entities] [screen entities]
(p3d/second-entity screen entities)) (p3d/second-entity screen entities))
(defmulti add-joint! (defmulti add-joint!
(fn [screen joint] (-> screen (u/get-obj :world) class))) (fn [screen joint] (some-> screen (u/get-obj :world) class .getName)))
(defmethod add-joint! (defmethod add-joint!
World "com.badlogic.gdx.physics.box2d.World"
[screen j-def] [screen j-def]
(p2d/add-joint! screen j-def)) (p2d/add-joint! screen j-def))
(defmulti step! (defmulti step!
(fn [screen & [entities]] (-> screen (u/get-obj :world) class))) (fn [screen & [entities]] (some-> screen (u/get-obj :world) class .getName)))
(defmethod step! (defmethod step!
World "com.badlogic.gdx.physics.box2d.World"
[screen & [entities]] [screen & [entities]]
(p2d/step! screen entities)) (p2d/step! screen entities))
(defmethod step! (defmethod step!
World3D "play_clj.g3d_physics.World3D"
[screen & [entities]] [screen & [entities]]
(p3d/step! screen entities)) (p3d/step! screen entities))

View File

@@ -1,5 +1,6 @@
(ns play-clj.ui (ns play-clj.ui
(:require [play-clj.g2d :as g2d] (:require [play-clj.entities]
[play-clj.g2d :as g2d]
[play-clj.utils :as u]) [play-clj.utils :as u])
(:import [com.badlogic.gdx Files Gdx] (:import [com.badlogic.gdx Files Gdx]
[com.badlogic.gdx.graphics Color Texture] [com.badlogic.gdx.graphics Color Texture]