Last active
November 18, 2016 03:18
-
-
Save nasser/f0b467a4deff1ded742b636d1d4b0890 to your computer and use it in GitHub Desktop.
Hiccup-inspired Unity Scene Graph DSL
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
(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