From 694d63448c61cbc41674e6e00119e99016c7a0a6 Mon Sep 17 00:00:00 2001 From: oakes Date: Sun, 20 Apr 2014 17:56:00 -0400 Subject: [PATCH] Use reflection to avoid static initializer in g2d-physics --- src/play_clj/core_listeners.clj | 4 +-- src/play_clj/g2d.clj | 3 +- src/play_clj/g2d_physics.clj | 25 +++++++++----- src/play_clj/g3d.clj | 3 +- src/play_clj/g3d_physics.clj | 4 +-- src/play_clj/physics.clj | 58 ++++++++++++++++----------------- src/play_clj/ui.clj | 3 +- 7 files changed, 54 insertions(+), 46 deletions(-) diff --git a/src/play_clj/core_listeners.clj b/src/play_clj/core_listeners.clj index e4c6606..460e8f5 100644 --- a/src/play_clj/core_listeners.clj +++ b/src/play_clj/core_listeners.clj @@ -173,7 +173,7 @@ (focus-listener options execute-fn!)]) (defmulti contact-listener - (fn [screen options execute-fn!] (-> screen :world class)) + (fn [screen options execute-fn!] (some-> screen :world class .getName)) :default nil) (defmethod contact-listener nil [_ _ _]) @@ -199,7 +199,7 @@ (add-input! renderer))) (defmulti update-physics! - (fn [screen & [entities]] (-> screen :world class)) + (fn [screen & [entities]] (some-> screen :world class .getName)) :default nil) (defmethod update-physics! nil [_ & _]) diff --git a/src/play_clj/g2d.clj b/src/play_clj/g2d.clj index 83d5b1d..658f55f 100644 --- a/src/play_clj/g2d.clj +++ b/src/play_clj/g2d.clj @@ -1,5 +1,6 @@ (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] [com.badlogic.gdx.graphics.g2d Animation BitmapFont NinePatch ParticleEffect TextureAtlas TextureRegion] diff --git a/src/play_clj/g2d_physics.clj b/src/play_clj/g2d_physics.clj index b095584..eb1c213 100644 --- a/src/play_clj/g2d_physics.clj +++ b/src/play_clj/g2d_physics.clj @@ -2,9 +2,10 @@ (:require [play-clj.core :as c] [play-clj.math :as m] [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 - PolygonShape Transform World])) + PolygonShape Transform])) ; world @@ -14,20 +15,26 @@ ([gravity-x gravity-y] (box-2d* gravity-x gravity-y true)) ([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 "Returns a [World](http://libgdx.badlogicgames.com/nightlies/docs/api/com/badlogic/gdx/physics/box2d/World.html). (box-2d 0 0)" [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))) (defmacro box-2d! "Calls a single method on a `box-2d`." [screen k & options] - `(let [^World object# (u/get-obj ~screen :world)] + `(let [object# (u/get-obj ~screen :world)] (u/call! object# ~k ~@options))) ; bodies @@ -213,7 +220,7 @@ such as :on-begin-contact." ; misc (defmethod c/contact-listener - World + "com.badlogic.gdx.physics.box2d.World" [screen {:keys [on-begin-contact on-end-contact on-post-solve on-pre-solve]} execute-fn!] @@ -228,8 +235,8 @@ such as :on-begin-contact." (execute-fn! on-pre-solve :contact c :old-manifold m)))) (defmethod c/update-physics! - World - [{:keys [^World world contact-listener]} & [entities]] + "com.badlogic.gdx.physics.box2d.World" + [{:keys [world contact-listener]} & [entities]] (.setContactListener world contact-listener) (when (and entities (not (.isLocked world))) (let [arr (u/gdx-array [])] @@ -248,7 +255,7 @@ such as :on-begin-contact." (defn step! "Runs the physics simulations for a single frame and optionally returns the `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} :as screen} & [entities]] diff --git a/src/play_clj/g3d.clj b/src/play_clj/g3d.clj index 78ca427..b5caf2e 100644 --- a/src/play_clj/g3d.clj +++ b/src/play_clj/g3d.clj @@ -1,5 +1,6 @@ (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 ModelInstance] [com.badlogic.gdx.graphics.g3d.attributes BlendingAttribute diff --git a/src/play_clj/g3d_physics.clj b/src/play_clj/g3d_physics.clj index 14005df..6ee3084 100644 --- a/src/play_clj/g3d_physics.clj +++ b/src/play_clj/g3d_physics.clj @@ -267,7 +267,7 @@ such as :on-begin-contact." ; misc (defmethod c/contact-listener - World3D + "play_clj.g3d_physics.World3D" [screen {:keys [on-begin-contact on-end-contact]} execute-fn!] @@ -284,7 +284,7 @@ such as :on-begin-contact." (.at arr i)))) (defmethod c/update-physics! - World3D + "play_clj.g3d_physics.World3D" [screen & [entities]] ; initialize bodies if necessary (doseq [e entities] diff --git a/src/play_clj/physics.clj b/src/play_clj/physics.clj index 03cfc36..8d48b5d 100644 --- a/src/play_clj/physics.clj +++ b/src/play_clj/physics.clj @@ -1,125 +1,123 @@ (ns play-clj.physics (:require [play-clj.g2d-physics :as p2d] [play-clj.g3d-physics :as p3d] - [play-clj.utils :as u]) - (:import [com.badlogic.gdx.physics.box2d Body World] - [play_clj.g3d_physics Body3D World3D])) + [play-clj.utils :as u])) ; this namespace is for internal use only. you should use the g2d-physics and ; g3d-physics namespaces directly, instead. (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! - World + "com.badlogic.gdx.physics.box2d.World" [screen b-def] (p2d/add-body! screen b-def)) (defmethod add-body! - World3D + "play_clj.g3d_physics.World3D" [screen body] (p3d/add-body! screen body)) (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! - Body + "com.badlogic.gdx.physics.box2d.Body" [entity x y angle] (p2d/body-position! entity x y angle)) (defmethod body-position! - Body3D + "play_clj.g3d_physics.Body3D" [entity x y z] (p3d/body-position! entity x y z)) (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! - Body + "com.badlogic.gdx.physics.box2d.Body" [entity x] (p2d/body-x! entity x)) (defmethod body-x! - Body3D + "play_clj.g3d_physics.Body3D" [entity x] (p3d/body-x! entity x)) (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! - Body + "com.badlogic.gdx.physics.box2d.Body" [entity y] (p2d/body-y! entity y)) (defmethod body-y! - Body3D + "play_clj.g3d_physics.Body3D" [entity y] (p3d/body-y! entity y)) (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! - Body3D + "play_clj.g3d_physics.Body3D" [entity z] (p3d/body-z! entity z)) (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! - Body + "com.badlogic.gdx.physics.box2d.Body" [entity angle] (p2d/body-angle! entity angle)) (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 - World + "com.badlogic.gdx.physics.box2d.World" [screen entities] (p2d/first-entity screen entities)) (defmethod first-entity - World3D + "play_clj.g3d_physics.World3D" [screen entities] (p3d/first-entity screen entities)) (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 - World + "com.badlogic.gdx.physics.box2d.World" [screen entities] (p2d/second-entity screen entities)) (defmethod second-entity - World3D + "play_clj.g3d_physics.World3D" [screen entities] (p3d/second-entity screen entities)) (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! - World + "com.badlogic.gdx.physics.box2d.World" [screen j-def] (p2d/add-joint! screen j-def)) (defmulti step! - (fn [screen & [entities]] (-> screen (u/get-obj :world) class))) + (fn [screen & [entities]] (some-> screen (u/get-obj :world) class .getName))) (defmethod step! - World + "com.badlogic.gdx.physics.box2d.World" [screen & [entities]] (p2d/step! screen entities)) (defmethod step! - World3D + "play_clj.g3d_physics.World3D" [screen & [entities]] (p3d/step! screen entities)) diff --git a/src/play_clj/ui.clj b/src/play_clj/ui.clj index 9e60778..c5a5cf7 100644 --- a/src/play_clj/ui.clj +++ b/src/play_clj/ui.clj @@ -1,5 +1,6 @@ (ns play-clj.ui - (:require [play-clj.g2d :as g2d] + (:require [play-clj.entities] + [play-clj.g2d :as g2d] [play-clj.utils :as u]) (:import [com.badlogic.gdx Files Gdx] [com.badlogic.gdx.graphics Color Texture]