Skip to content

Instantly share code, notes, and snippets.

@nasser
Last active November 18, 2016 03:18
Show Gist options
  • Star 3 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save nasser/f0b467a4deff1ded742b636d1d4b0890 to your computer and use it in GitHub Desktop.
Save nasser/f0b467a4deff1ded742b636d1d4b0890 to your computer and use it in GitHub Desktop.
Hiccup-inspired Unity Scene Graph DSL
(ns realize.core
(:use arcadia.core)
(:require [clojure.string :as string]))
(defn- reflective-set! [obj field value]
(if-let [^System.Reflection.FieldInfo info (.GetField (type obj) (str field))]
(.SetValue info obj value)
(if-let [^System.Reflection.PropertyInfo info (.GetProperty (type obj) (str field))]
(.SetValue info obj value nil)
(throw (Exception. (str "No field or property '" field "' on object of type " (type obj)))))))
(defn- hyphens-to-camels [s]
(string/replace s #"-([a-z])" #(string/upper-case (last %))))
(defn- predicate-to-is [s]
(if-let [match (re-find #"(.*)\?$" s)]
(str "is-" (last match))
s))
(defn- unity-name [n]
(-> n name predicate-to-is hyphens-to-camels))
(defn- populate [obj attrs]
(reduce-kv
(fn [o k v]
(reflective-set! o (unity-name k) v)
o)
obj
attrs))
(defn- realize-gameobject [parent attrs]
(let [go (populate
(UnityEngine.GameObject.)
attrs)]
(when parent (child+ parent go false))
go))
(defn- realize-component [parent typ attrs]
(populate
(cmpt+ parent typ)
attrs)
parent)
(defn- realize-transform [parent attrs]
(populate
(.. parent transform)
attrs)
parent)
(defn realize
([spec] (realize spec nil))
([spec parent]
(let [[tag attributes & children] spec]
(cond
(= tag UnityEngine.GameObject)
(let [go (realize-gameobject parent attributes)]
(doseq [child children]
(realize child go)))
(= tag UnityEngine.Transform)
(realize-transform parent attributes)
(fn? tag)
(let [res (apply tag attributes children)]
(when (vector? res)
(realize res parent)))
(every? coll? spec)
(doseq [child spec]
(log child)
(realize child parent))
:else
(realize-component parent tag attributes)))))
(defn replace! [spec parent]
(doseq [child (children parent)]
(UnityEngine.Object/DestroyImmediate child))
(realize spec parent))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment