From e0deae642aac6c0cc263f4f6b64eacd943963102 Mon Sep 17 00:00:00 2001 From: oakes Date: Sat, 10 May 2014 12:37:55 -0400 Subject: [PATCH] Store all listeners in the screen atom and add macros to call methods on them --- doclet/resources/classes.edn | 9 +++- src/play_clj/core.clj | 9 ++-- src/play_clj/core_listeners.clj | 95 ++++++++++++++++++++++++++------- 3 files changed, 89 insertions(+), 24 deletions(-) diff --git a/doclet/resources/classes.edn b/doclet/resources/classes.edn index 627ced4..8556554 100644 --- a/doclet/resources/classes.edn +++ b/doclet/resources/classes.edn @@ -1,4 +1,5 @@ -{"Align" {"align" :static-fields} +{"ActorGestureListener" {"actor-gesture-listener!" :methods} + "Align" {"align" :static-fields} "com.badlogic.gdx.graphics.g2d.Animation" {"animation" :methods "animation!" :methods} "Animation.PlayMode" {"play-mode" :static-fields} @@ -35,6 +36,8 @@ "Circle" {"circle" :methods "circle!" :methods} "CircleMapObject" {"map-object :circle" :methods} + "ChangeListener" {"change-listener!" :methods} + "ClickListener" {"click-listener!" :methods} "Color" {"color" :static-fields "color!" :methods} "ColorAttribute" {"attribute :color" :constructors @@ -60,6 +63,7 @@ "Dialog" {"dialog" :methods "dialog!" :methods} "DistanceJointDef" {"joint-def :distance" :fields} + "DragListener" {"drag-listener!" :methods} "EarClippingTriangulator" {"ear-clipping-triangulator" :methods "ear-clipping-triangulator!" :methods} "EdgeShape" {"edge-shape" :methods @@ -77,12 +81,14 @@ "attribute! :float" :static-methods} "FloatCounter" {"float-counter" :methods "float-counter!" :methods} + "FocusListener" {"focus-listener!" :methods} "FrictionJointDef" {"joint-def :friction" :fields} "Frustum" {"frustum" :methods "frustum!" :methods} "G3dModelLoader" {"loader! :g3d-model" :methods} "GearJointDef" {"joint-def :gear" :fields} "GeometryUtils" {"geometry!" :static-methods} + "GestureDetector" {"gesture-detector!" :methods} "Graphics" {"graphics!" :methods} "GridPoint2" {"grid-point-2" :methods "grid-point-2!" :methods} @@ -106,6 +112,7 @@ "key-pressed?" :static-fields} "Input.Buttons" {"button-code" :static-fields "button-pressed?" :static-fields} + "InputProcessor" {"input-processor!" :methods} "Interpolation" {"interpolation" :static-classes} "Intersector" {"intersector!" :static-methods} "IntAttribute" {"attribute :int" :constructors diff --git a/src/play_clj/core.clj b/src/play_clj/core.clj index 0d163a0..ee05778 100644 --- a/src/play_clj/core.clj +++ b/src/play_clj/core.clj @@ -69,6 +69,8 @@ (normalize (func screen-map old-entities))) (wrapper screen) (reset-changed! entities old-entities)))))] + ; add the input listeners to the screen atom + (swap! screen assoc :input-listeners (input-listeners options execute-fn!)) ; update screen when either the screen or entities are changed (add-watch screen :changed (fn [_ _ _ new-screen] (update-screen! new-screen))) @@ -94,8 +96,7 @@ :hide #(execute-fn! on-hide) :pause #(execute-fn! on-pause) :resize #(execute-fn! on-resize :width %1 :height %2) - :resume #(execute-fn! on-resume) - :input-listeners (global-listeners options execute-fn!)})) + :resume #(execute-fn! on-resume)})) (defmacro defscreen "Defines a screen, and creates vars for all the functions inside of it. All @@ -432,8 +433,8 @@ via the screen map. [^Game game & screens] (let [add-inputs! (fn [] (input! :set-input-processor (InputMultiplexer.)) - (doseq [{:keys [input-listeners]} screens] - (doseq [listener input-listeners] + (doseq [{:keys [screen]} screens] + (doseq [[_ listener] (:input-listeners @screen)] (add-input! listener)))) run-fn! (fn [k & args] (doseq [screen screens] diff --git a/src/play_clj/core_listeners.clj b/src/play_clj/core_listeners.clj index f76e482..8690cff 100644 --- a/src/play_clj/core_listeners.clj +++ b/src/play_clj/core_listeners.clj @@ -32,44 +32,60 @@ (execute-fn! on-touch-up :input-x sx :input-y sy :pointer p :button b) false))) +(defmacro input-processor! + "Calls a single method on the [InputProcessor](http://libgdx.badlogicgames.com/nightlies/docs/api/com/badlogic/gdx/InputProcessor.html) +in the `screen`." + [screen k & options] + `(let [listeners# (u/get-obj ~screen :input-listeners) + ^InputProcessor object# (u/get-obj listeners# :input-processor)] + (u/call! object# ~k ~@options))) + (defn ^:private gesture-listener [{:keys [on-fling on-long-press on-pan on-pan-stop on-pinch on-tap on-zoom]} execute-fn!] (reify GestureDetector$GestureListener (fling [this vx vy b] (execute-fn! on-fling :velocity-x vx :velocity-y vy :button b) - false) + (some? on-fling)) (longPress [this x y] (execute-fn! on-long-press :input-x x :input-y y) - false) + (some? on-long-press)) (pan [this x y dx dy] (execute-fn! on-pan :input-x x :input-y y :delta-x dx :delta-y dy) - false) + (some? on-pan)) (panStop [this x y p b] (execute-fn! on-pan-stop :input-x x :input-y y :pointer p :button b) - false) + (some? on-pan-stop)) (pinch [this ip1 ip2 p1 p2] (execute-fn! on-pinch :initial-pointer-1 ip1 :initial-pointer-2 ip2 :pointer-1 p1 :pointer-2 p2) - false) + (some? on-pinch)) (tap [this x y c b] (execute-fn! on-tap :input-x x :input-y y :count c :button b) - false) + (some? on-tap)) (touchDown [this x y p b] false) (zoom [this id d] (execute-fn! on-zoom :initial-distance id :distance d) - false))) + (some? on-zoom)))) (defn ^:private gesture-detector [options execute-fn!] (proxy [GestureDetector] [(gesture-listener options execute-fn!)])) -(defn ^:private global-listeners +(defmacro gesture-detector! + "Calls a single method on the [GestureDetector](http://libgdx.badlogicgames.com/nightlies/docs/api/com/badlogic/gdx/input/GestureDetector.html) +in the `screen`." + [screen k & options] + `(let [listeners# (u/get-obj ~screen :input-listeners) + ^GestureDetector object# (u/get-obj listeners# :gesture-detector)] + (u/call! object# ~k ~@options))) + +(defn ^:private input-listeners [options execute-fn!] - [(input-processor options execute-fn!) - (gesture-detector options execute-fn!)]) + {:input-processor (input-processor options execute-fn!) + :gesture-detector (gesture-detector options execute-fn!)}) ; ui @@ -83,7 +99,7 @@ :event e :velocity-x vx :velocity-y vy :button b)) (longPress [a x y] (execute-fn! on-ui-long-press :actor a :input-x x :input-y y) - false) + (some? on-ui-long-press)) (pan [e x y dx dy] (execute-fn! on-ui-pan :event e :input-x x :input-y y :delta-x dx :delta-y dy)) @@ -103,12 +119,29 @@ (zoom [e id d] (execute-fn! on-ui-zoom :event e :initial-distance id :distance d)))) +(defmacro actor-gesture-listener! + "Calls a single method on the [ActorGestureListener](http://libgdx.badlogicgames.com/nightlies/docs/api/com/badlogic/gdx/scenes/scene2d/utils/ActorGestureListener.html) +in the `screen`." + [screen k & options] + `(let [listeners# (u/get-obj ~screen :ui-listeners) + ^ActorGestureListener object# + (u/get-obj listeners# :actor-gesture-listener)] + (u/call! object# ~k ~@options))) + (defn ^:private change-listener [{:keys [on-ui-changed]} execute-fn!] (proxy [ChangeListener] [] (changed [e a] (execute-fn! on-ui-changed :event e :actor a)))) +(defmacro change-listener! + "Calls a single method on the [ChangeListener](http://libgdx.badlogicgames.com/nightlies/docs/api/com/badlogic/gdx/scenes/scene2d/utils/ChangeListener.html) +in the `screen`." + [screen k & options] + `(let [listeners# (u/get-obj ~screen :ui-listeners) + ^ChangeListener object# (u/get-obj listeners# :change-listener)] + (u/call! object# ~k ~@options))) + (defn ^:private click-listener [{:keys [on-ui-clicked on-ui-enter on-ui-exit on-ui-touch-down on-ui-touch-dragged on-ui-touch-up]} @@ -125,7 +158,7 @@ (touchDown [e x y p b] (execute-fn! on-ui-touch-down :event e :input-x x :input-y y :pointer p :button b) - false) + (some? on-ui-touch-down)) (touchDragged [e x y p] (execute-fn! on-ui-touch-dragged :event e :input-x x :input-y y :pointer p)) @@ -133,6 +166,14 @@ (execute-fn! on-ui-touch-up :event e :input-x x :input-y y :pointer p :button b)))) +(defmacro click-listener! + "Calls a single method on the [ClickListener](http://libgdx.badlogicgames.com/nightlies/docs/api/com/badlogic/gdx/scenes/scene2d/utils/ClickListener.html) +in the `screen`." + [screen k & options] + `(let [listeners# (u/get-obj ~screen :ui-listeners) + ^ClickListener object# (u/get-obj listeners# :click-listener)] + (u/call! object# ~k ~@options))) + (defn ^:private drag-listener [{:keys [on-ui-drag on-ui-drag-start on-ui-drag-stop on-ui-touch-down on-ui-touch-dragged on-ui-touch-up]} @@ -141,7 +182,7 @@ (touchDown [e x y p b] (execute-fn! on-ui-touch-down :event e :input-x x :input-y y :pointer p :button b) - false) + (some? on-ui-touch-down)) (touchDragged [e x y p] (execute-fn! on-ui-touch-dragged :event e :input-x x :input-y y :pointer p)) @@ -155,6 +196,14 @@ (dragStop [e x y p] (execute-fn! on-ui-drag-stop :event e :input-x x :input-y y :pointer p)))) +(defmacro drag-listener! + "Calls a single method on the [DragListener](http://libgdx.badlogicgames.com/nightlies/docs/api/com/badlogic/gdx/scenes/scene2d/utils/DragListener.html) +in the `screen`." + [screen k & options] + `(let [listeners# (u/get-obj ~screen :ui-listeners) + ^DragListener object# (u/get-obj listeners# :drag-listener)] + (u/call! object# ~k ~@options))) + (defn ^:private focus-listener [{:keys [on-ui-keyboard-focus-changed on-ui-scroll-focus-changed]} execute-fn!] @@ -164,13 +213,21 @@ (scrollFocusChanged [e a f] (execute-fn! on-ui-scroll-focus-changed :event e :actor a :focused? f)))) +(defmacro focus-listener! + "Calls a single method on the [FocusListener](http://libgdx.badlogicgames.com/nightlies/docs/api/com/badlogic/gdx/scenes/scene2d/utils/FocusListener.html) +in the `screen`." + [screen k & options] + `(let [listeners# (u/get-obj ~screen :ui-listeners) + ^FocusListener object# (u/get-obj listeners# :focus-listener)] + (u/call! object# ~k ~@options))) + (defn ^:private ui-listeners [options execute-fn!] - [(actor-gesture-listener options execute-fn!) - (change-listener options execute-fn!) - (click-listener options execute-fn!) - (drag-listener options execute-fn!) - (focus-listener options execute-fn!)]) + {:actor-gesture-listener (actor-gesture-listener options execute-fn!) + :change-listener (change-listener options execute-fn!) + :click-listener (click-listener options execute-fn!) + :drag-listener (drag-listener options execute-fn!) + :focus-listener (focus-listener options execute-fn!)}) (defmulti contact-listener (fn [screen options execute-fn!] (some-> screen :world class .getName)) @@ -193,7 +250,7 @@ (doseq [{:keys [object]} entities] (when (isa? (type object) Actor) (.addActor renderer object) - (doseq [listener ui-listeners] + (doseq [[_ listener] ui-listeners] (.addListener ^Actor object listener)))) (remove-input! renderer) (add-input! renderer)))