Store all listeners in the screen atom and add macros to call methods on them

This commit is contained in:
oakes
2014-05-10 12:37:55 -04:00
parent 7e5b8738f0
commit e0deae642a
3 changed files with 89 additions and 24 deletions

View File

@@ -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 "com.badlogic.gdx.graphics.g2d.Animation" {"animation" :methods
"animation!" :methods} "animation!" :methods}
"Animation.PlayMode" {"play-mode" :static-fields} "Animation.PlayMode" {"play-mode" :static-fields}
@@ -35,6 +36,8 @@
"Circle" {"circle" :methods "Circle" {"circle" :methods
"circle!" :methods} "circle!" :methods}
"CircleMapObject" {"map-object :circle" :methods} "CircleMapObject" {"map-object :circle" :methods}
"ChangeListener" {"change-listener!" :methods}
"ClickListener" {"click-listener!" :methods}
"Color" {"color" :static-fields "Color" {"color" :static-fields
"color!" :methods} "color!" :methods}
"ColorAttribute" {"attribute :color" :constructors "ColorAttribute" {"attribute :color" :constructors
@@ -60,6 +63,7 @@
"Dialog" {"dialog" :methods "Dialog" {"dialog" :methods
"dialog!" :methods} "dialog!" :methods}
"DistanceJointDef" {"joint-def :distance" :fields} "DistanceJointDef" {"joint-def :distance" :fields}
"DragListener" {"drag-listener!" :methods}
"EarClippingTriangulator" {"ear-clipping-triangulator" :methods "EarClippingTriangulator" {"ear-clipping-triangulator" :methods
"ear-clipping-triangulator!" :methods} "ear-clipping-triangulator!" :methods}
"EdgeShape" {"edge-shape" :methods "EdgeShape" {"edge-shape" :methods
@@ -77,12 +81,14 @@
"attribute! :float" :static-methods} "attribute! :float" :static-methods}
"FloatCounter" {"float-counter" :methods "FloatCounter" {"float-counter" :methods
"float-counter!" :methods} "float-counter!" :methods}
"FocusListener" {"focus-listener!" :methods}
"FrictionJointDef" {"joint-def :friction" :fields} "FrictionJointDef" {"joint-def :friction" :fields}
"Frustum" {"frustum" :methods "Frustum" {"frustum" :methods
"frustum!" :methods} "frustum!" :methods}
"G3dModelLoader" {"loader! :g3d-model" :methods} "G3dModelLoader" {"loader! :g3d-model" :methods}
"GearJointDef" {"joint-def :gear" :fields} "GearJointDef" {"joint-def :gear" :fields}
"GeometryUtils" {"geometry!" :static-methods} "GeometryUtils" {"geometry!" :static-methods}
"GestureDetector" {"gesture-detector!" :methods}
"Graphics" {"graphics!" :methods} "Graphics" {"graphics!" :methods}
"GridPoint2" {"grid-point-2" :methods "GridPoint2" {"grid-point-2" :methods
"grid-point-2!" :methods} "grid-point-2!" :methods}
@@ -106,6 +112,7 @@
"key-pressed?" :static-fields} "key-pressed?" :static-fields}
"Input.Buttons" {"button-code" :static-fields "Input.Buttons" {"button-code" :static-fields
"button-pressed?" :static-fields} "button-pressed?" :static-fields}
"InputProcessor" {"input-processor!" :methods}
"Interpolation" {"interpolation" :static-classes} "Interpolation" {"interpolation" :static-classes}
"Intersector" {"intersector!" :static-methods} "Intersector" {"intersector!" :static-methods}
"IntAttribute" {"attribute :int" :constructors "IntAttribute" {"attribute :int" :constructors

View File

@@ -69,6 +69,8 @@
(normalize (func screen-map old-entities))) (normalize (func screen-map old-entities)))
(wrapper screen) (wrapper screen)
(reset-changed! entities old-entities)))))] (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 ; update screen when either the screen or entities are changed
(add-watch screen :changed (fn [_ _ _ new-screen] (add-watch screen :changed (fn [_ _ _ new-screen]
(update-screen! new-screen))) (update-screen! new-screen)))
@@ -94,8 +96,7 @@
:hide #(execute-fn! on-hide) :hide #(execute-fn! on-hide)
:pause #(execute-fn! on-pause) :pause #(execute-fn! on-pause)
:resize #(execute-fn! on-resize :width %1 :height %2) :resize #(execute-fn! on-resize :width %1 :height %2)
:resume #(execute-fn! on-resume) :resume #(execute-fn! on-resume)}))
:input-listeners (global-listeners options execute-fn!)}))
(defmacro defscreen (defmacro defscreen
"Defines a screen, and creates vars for all the functions inside of it. All "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] [^Game game & screens]
(let [add-inputs! (fn [] (let [add-inputs! (fn []
(input! :set-input-processor (InputMultiplexer.)) (input! :set-input-processor (InputMultiplexer.))
(doseq [{:keys [input-listeners]} screens] (doseq [{:keys [screen]} screens]
(doseq [listener input-listeners] (doseq [[_ listener] (:input-listeners @screen)]
(add-input! listener)))) (add-input! listener))))
run-fn! (fn [k & args] run-fn! (fn [k & args]
(doseq [screen screens] (doseq [screen screens]

View File

@@ -32,44 +32,60 @@
(execute-fn! on-touch-up :input-x sx :input-y sy :pointer p :button b) (execute-fn! on-touch-up :input-x sx :input-y sy :pointer p :button b)
false))) 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 (defn ^:private gesture-listener
[{:keys [on-fling on-long-press on-pan on-pan-stop on-pinch on-tap on-zoom]} [{:keys [on-fling on-long-press on-pan on-pan-stop on-pinch on-tap on-zoom]}
execute-fn!] execute-fn!]
(reify GestureDetector$GestureListener (reify GestureDetector$GestureListener
(fling [this vx vy b] (fling [this vx vy b]
(execute-fn! on-fling :velocity-x vx :velocity-y vy :button b) (execute-fn! on-fling :velocity-x vx :velocity-y vy :button b)
false) (some? on-fling))
(longPress [this x y] (longPress [this x y]
(execute-fn! on-long-press :input-x x :input-y y) (execute-fn! on-long-press :input-x x :input-y y)
false) (some? on-long-press))
(pan [this x y dx dy] (pan [this x y dx dy]
(execute-fn! on-pan :input-x x :input-y y :delta-x dx :delta-y 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] (panStop [this x y p b]
(execute-fn! on-pan-stop :input-x x :input-y y :pointer p :button 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] (pinch [this ip1 ip2 p1 p2]
(execute-fn! on-pinch (execute-fn! on-pinch
:initial-pointer-1 ip1 :initial-pointer-2 ip2 :initial-pointer-1 ip1 :initial-pointer-2 ip2
:pointer-1 p1 :pointer-2 p2) :pointer-1 p1 :pointer-2 p2)
false) (some? on-pinch))
(tap [this x y c b] (tap [this x y c b]
(execute-fn! on-tap :input-x x :input-y y :count c :button 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] (touchDown [this x y p b]
false) false)
(zoom [this id d] (zoom [this id d]
(execute-fn! on-zoom :initial-distance id :distance d) (execute-fn! on-zoom :initial-distance id :distance d)
false))) (some? on-zoom))))
(defn ^:private gesture-detector (defn ^:private gesture-detector
[options execute-fn!] [options execute-fn!]
(proxy [GestureDetector] [(gesture-listener 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!] [options execute-fn!]
[(input-processor options execute-fn!) {:input-processor (input-processor options execute-fn!)
(gesture-detector options execute-fn!)]) :gesture-detector (gesture-detector options execute-fn!)})
; ui ; ui
@@ -83,7 +99,7 @@
:event e :velocity-x vx :velocity-y vy :button b)) :event e :velocity-x vx :velocity-y vy :button b))
(longPress [a x y] (longPress [a x y]
(execute-fn! on-ui-long-press :actor a :input-x x :input-y 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] (pan [e x y dx dy]
(execute-fn! on-ui-pan (execute-fn! on-ui-pan
:event e :input-x x :input-y y :delta-x dx :delta-y dy)) :event e :input-x x :input-y y :delta-x dx :delta-y dy))
@@ -103,12 +119,29 @@
(zoom [e id d] (zoom [e id d]
(execute-fn! on-ui-zoom :event e :initial-distance id :distance 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 (defn ^:private change-listener
[{:keys [on-ui-changed]} execute-fn!] [{:keys [on-ui-changed]} execute-fn!]
(proxy [ChangeListener] [] (proxy [ChangeListener] []
(changed [e a] (changed [e a]
(execute-fn! on-ui-changed :event e :actor 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 (defn ^:private click-listener
[{:keys [on-ui-clicked on-ui-enter on-ui-exit [{:keys [on-ui-clicked on-ui-enter on-ui-exit
on-ui-touch-down on-ui-touch-dragged on-ui-touch-up]} on-ui-touch-down on-ui-touch-dragged on-ui-touch-up]}
@@ -125,7 +158,7 @@
(touchDown [e x y p b] (touchDown [e x y p b]
(execute-fn! on-ui-touch-down (execute-fn! on-ui-touch-down
:event e :input-x x :input-y y :pointer p :button b) :event e :input-x x :input-y y :pointer p :button b)
false) (some? on-ui-touch-down))
(touchDragged [e x y p] (touchDragged [e x y p]
(execute-fn! on-ui-touch-dragged (execute-fn! on-ui-touch-dragged
:event e :input-x x :input-y y :pointer p)) :event e :input-x x :input-y y :pointer p))
@@ -133,6 +166,14 @@
(execute-fn! on-ui-touch-up (execute-fn! on-ui-touch-up
:event e :input-x x :input-y y :pointer p :button b)))) :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 (defn ^:private drag-listener
[{:keys [on-ui-drag on-ui-drag-start on-ui-drag-stop [{:keys [on-ui-drag on-ui-drag-start on-ui-drag-stop
on-ui-touch-down on-ui-touch-dragged on-ui-touch-up]} on-ui-touch-down on-ui-touch-dragged on-ui-touch-up]}
@@ -141,7 +182,7 @@
(touchDown [e x y p b] (touchDown [e x y p b]
(execute-fn! on-ui-touch-down (execute-fn! on-ui-touch-down
:event e :input-x x :input-y y :pointer p :button b) :event e :input-x x :input-y y :pointer p :button b)
false) (some? on-ui-touch-down))
(touchDragged [e x y p] (touchDragged [e x y p]
(execute-fn! on-ui-touch-dragged (execute-fn! on-ui-touch-dragged
:event e :input-x x :input-y y :pointer p)) :event e :input-x x :input-y y :pointer p))
@@ -155,6 +196,14 @@
(dragStop [e x y p] (dragStop [e x y p]
(execute-fn! on-ui-drag-stop :event e :input-x x :input-y y :pointer 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 (defn ^:private focus-listener
[{:keys [on-ui-keyboard-focus-changed on-ui-scroll-focus-changed]} [{:keys [on-ui-keyboard-focus-changed on-ui-scroll-focus-changed]}
execute-fn!] execute-fn!]
@@ -164,13 +213,21 @@
(scrollFocusChanged [e a f] (scrollFocusChanged [e a f]
(execute-fn! on-ui-scroll-focus-changed :event e :actor a :focused? 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 (defn ^:private ui-listeners
[options execute-fn!] [options execute-fn!]
[(actor-gesture-listener options execute-fn!) {:actor-gesture-listener (actor-gesture-listener options execute-fn!)
(change-listener options execute-fn!) :change-listener (change-listener options execute-fn!)
(click-listener options execute-fn!) :click-listener (click-listener options execute-fn!)
(drag-listener options execute-fn!) :drag-listener (drag-listener options execute-fn!)
(focus-listener options execute-fn!)]) :focus-listener (focus-listener options execute-fn!)})
(defmulti contact-listener (defmulti contact-listener
(fn [screen options execute-fn!] (some-> screen :world class .getName)) (fn [screen options execute-fn!] (some-> screen :world class .getName))
@@ -193,7 +250,7 @@
(doseq [{:keys [object]} entities] (doseq [{:keys [object]} entities]
(when (isa? (type object) Actor) (when (isa? (type object) Actor)
(.addActor renderer object) (.addActor renderer object)
(doseq [listener ui-listeners] (doseq [[_ listener] ui-listeners]
(.addListener ^Actor object listener)))) (.addListener ^Actor object listener))))
(remove-input! renderer) (remove-input! renderer)
(add-input! renderer))) (add-input! renderer)))