           (cond (< r 0.5) (/ (fin (* 2 r)) 2)
                   :else (- 1 (/ (fout (* 2 (- 1 r))) 2))))})
 
+(def ^:private easeregistry
+  (into {}
+  (for [in [nil :pow2 :pow3 :pow4 :pow5]
+      out [nil :pow2 :pow3 :pow4 :pow5]
+      :let [infn (get easing in) 
+            outfn (get easing out)]]
+      (cond (= [in out] [nil nil]) {[in out] #(identity %)}
+        (= out nil) {[in out] (fn [r] ((:in easing) infn r))}
+        (= in nil) {[in out] #((:out easing) outfn %)}
+        :else {[in out] #((:inout easing) infn outfn %)}
+
+        ))))
+
 
 (deftype Tween [^System.MonoType component opts callbacks]
   clojure.lang.IObj

  clojure.lang.IFn
  (invoke [this go] 
    (let [pre-c (.GetComponent go component) 
        c (or pre-c (.AddComponent go component))
        uid (int (swap! UID inc))]
      (set! (.active c) true)
      (set! (.value c) (.target c))
      (if pre-c 
        (do (swap! REGISTRY dissoc (.uid c))
            (set! (.value c) (.target c)))
        (set! (.value c)  ((.getfn c) go)))
      (when @callbacks
        (swap! REGISTRY conj {uid @callbacks}))
      (set! (.uid c) uid)
      (set! (.start c) (float (UnityEngine.Time/time)))
      (set! (.duration c) (float (:duration opts)))
      
      
      (if (:+ opts) 
        (do ;(set! (.relative c) true)
            (set! (.target c) ((.addfn c) (.value c) (:target opts))))
        (set! (.target c) (:target opts)))
      (when-not (= (.easesig c) [(:in opts) (:out opts)]) 
        (set! (.easesig c) [(:in opts)(:out opts) ])
        (cond 
          (and (:in opts) (:out opts)) 
            (set! (.easefn c) #((:inout easing) (get easing (:in opts)) (get easing (:out opts)) %))
          (:in opts) 
            (set! (.easefn c) #((:in easing) (get easing (:in opts) ) %))
          (:out opts) 
            (set! (.easefn c) #((:out easing) (get easing (:out opts)) %))
          :else 
            (set! (.easefn c) (fn [r] r))))
      )
      go))

(defn make [c target & more]
  (let [args (conj {:target target :duration 1.0 :+ false :callback nil}
        (into {} (mapv 
          #(cond 
            (= :+ %) {:+ true}

(defmacro deftween [sym props & methods ] ;getter valuer & setter
  (let [{:keys [getter valuer setter adder]} (conj default-methods (into {} (map sort-methods methods)))
        compsym (symbol (str sym "_tween"))
        res-props (concat '[^boolean active ^System.Double delay ^System.Double start ^System.Double duration ^boolean relative ^float ratio ^int uid
                           getfn addfn easefn easesig] props)
        [[this] get-more] getter
        [[this-v] value-more] valuer
        getterfn (cons 'fn getter)
        set-more (or setter (list 'set! get-more value-more))]
`(do

  (arcadia.core/defcomponent ~compsym ~res-props
   (~'Awake [~this]
      (set! (.getfn ~this) ~getterfn)
      (set! (.addfn ~this) ~adder)
      (set! (.duration ~this) 5.0)
      (set! (.start ~this) (UnityEngine.Time/time))
      (set! (.value ~this) ~get-more)
      (set! (.target ~this) ~get-more))
   (~'Update [~this-v]

      (if (.active ~this-v)
            (if  (> (- (UnityEngine.Time/time) (.start ~this-v)) 
                    (.duration ~this-v))

              (do (set! (.ratio ~this-v) (float 1.0))
                ~set-more
                (set! (.active ~this-v) false)
                (set! (.delay ~this-v) 
                  (- (- (UnityEngine.Time/time) (.start ~this-v)) 
                     (.duration ~this-v)))
                (tween.core/finish (.uid ~this-v) (.gameObject ~this-v)))
              
              (do
                (set! (.ratio ~this-v) 
                  (float ((.easefn ~this)
                   (/ (- (UnityEngine.Time/time) (.start ~this-v)) 
                      (.duration ~this-v)) )))
                 ~set-more)) ))
  (~'OnDestroy [~'this]
      (swap! tween.core/REGISTRY dissoc (.uid ~'this))))

  (defn ~sym ~'[& more] (apply tween.core/make (cons ~compsym ~'more)))

)))

 
 

