Almost working; rule editor doesn't save.

This commit is contained in:
Simon Brooke 2014-07-13 23:56:29 +01:00
parent 28da9555ba
commit 77cfb32bb2
7 changed files with 94 additions and 13 deletions

View file

@ -3055,12 +3055,18 @@ See <code>world.clj</code>.</p>
rules are applied in turn until one matches. Once one rule has matched no rules are applied in turn until one matches. Once one rule has matched no
further rules can be applied.</p> further rules can be applied.</p>
</td><td class="codes"></td></tr><tr><td class="docs"><p>Derive a cell from this cell of this world by applying these rules.</p> </td><td class="codes"></td></tr><tr><td class="docs"><p>Derive a cell from this cell of this world by applying these rules.</p>
</td><td class="codes"><pre class="brush: clojure">(defn- transform-cell </td><td class="codes"><pre class="brush: clojure">(defn- apply-rules
[cell world rules] [cell world rules]
(cond (empty? rules) cell (cond (empty? rules) cell
true (let [result (apply (eval (first rules)) (list cell world))] true (let [result (apply (eval (first rules)) (list cell world))]
(cond result result (cond result result
true (transform-cell cell world (rest rules))))))</pre></td></tr><tr><td class="docs"><p>Return a row derived from this row of this world by applying these rules to each cell.</p> true (apply-rules cell world (rest rules))))))</pre></td></tr><tr><td class="docs"><p>Derive a cell from this cell of this world by applying these rules. If an
exception is thrown, cache its message on the cell and set state to error</p>
</td><td class="codes"><pre class="brush: clojure">(defn- transform-cell
[cell world rules]
(try
(apply-rules cell world rules)
(catch Exception e (merge {:state :error :error (.getMessage e)} cell)))) </pre></td></tr><tr><td class="docs"><p>Return a row derived from this row of this world by applying these rules to each cell.</p>
</td><td class="codes"><pre class="brush: clojure">(defn- transform-world-row </td><td class="codes"><pre class="brush: clojure">(defn- transform-world-row
[row world rules] [row world rules]
(map #(transform-cell % world rules) row))</pre></td></tr><tr><td class="docs"><p>Return a world derived from this world by applying these rules to each cell.</p> (map #(transform-cell % world rules) row))</pre></td></tr><tr><td class="docs"><p>Return a world derived from this world by applying these rules to each cell.</p>

View file

@ -3053,7 +3053,7 @@ objective is to parse rules out of a block of text from a textarea</p>
function, and return the sequence of such functions.</p> function, and return the sequence of such functions.</p>
</td><td class="codes"><pre class="brush: clojure">(defn compile-string </td><td class="codes"><pre class="brush: clojure">(defn compile-string
[string] [string]
(map compile-rule (split string #&quot;\n&quot;)))</pre></td></tr><tr><td class="docs"><p>Compile each non-comment line of the file indicated by this <code>filename</code> into (map compile-rule (remove comment? (split string #&quot;\n&quot;))))</pre></td></tr><tr><td class="docs"><p>Compile each non-comment line of the file indicated by this <code>filename</code> into
an executable anonymous function, and return the sequence of such functions.</p> an executable anonymous function, and return the sequence of such functions.</p>
</td><td class="codes"><pre class="brush: clojure">(defn compile-file </td><td class="codes"><pre class="brush: clojure">(defn compile-file
[filename] [filename]
@ -3224,16 +3224,16 @@ front of the sequence of tokens it returns nil.</p>
(= have-or-are &quot;have&quot;) (= have-or-are &quot;have&quot;)
(let [[property comp1 comp2 value &amp; remainder] rest] (let [[property comp1 comp2 value &amp; remainder] rest]
(cond (and (= comp1 &quot;equal&quot;) (= comp2 &quot;to&quot;)) (cond (and (= comp1 &quot;equal&quot;) (= comp2 &quot;to&quot;))
(gen-neighbours-condition comparator quantity property value remainder =) (gen-neighbours-condition comparator quantity property value remainder '=)
(and (= comp1 &quot;more&quot;) (= comp2 &quot;than&quot;)) (and (= comp1 &quot;more&quot;) (= comp2 &quot;than&quot;))
(gen-neighbours-condition '&gt; quantity property value remainder &gt;) (gen-neighbours-condition '&gt; quantity property value remainder '&gt;)
(and (= comp1 &quot;less&quot;) (= comp2 &quot;than&quot;)) (and (= comp1 &quot;less&quot;) (= comp2 &quot;than&quot;))
(gen-neighbours-condition '&lt; quantity property value remainder &lt;)))))))</pre></td></tr><tr><td class="docs"> (gen-neighbours-condition '&lt; quantity property value remainder '&lt;)))))))</pre></td></tr><tr><td class="docs">
</td><td class="codes"><pre class="brush: clojure">(defn parse-some-neighbours-condition </td><td class="codes"><pre class="brush: clojure">(defn parse-some-neighbours-condition
[[SOME NEIGHBOURS &amp; rest]] [[SOME NEIGHBOURS &amp; rest]]
(cond (cond
(and (= SOME &quot;some&quot;) (= NEIGHBOURS &quot;neighbours&quot;)) (and (= SOME &quot;some&quot;) (= NEIGHBOURS &quot;neighbours&quot;))
(parse-comparator-neighbours-condition (concat '(&quot;more&quot; &quot;than&quot; &quot;0&quot; &quot;neighbours&quot;) rest))))</pre></td></tr><tr><td class="docs"><p>Parse conditions of the form '...6 neighbours are condition'</p> (parse-comparator-neighbours-condition (concat '(&quot;more&quot; &quot;than&quot; &quot;0&quot; &quot;neighbours&quot;) rest))))</pre></td></tr><tr><td class="docs"><p>Parse conditions of the form '...6 neighbours are [condition]'</p>
</td><td class="codes"><pre class="brush: clojure">(defn parse-simple-neighbours-condition </td><td class="codes"><pre class="brush: clojure">(defn parse-simple-neighbours-condition
[[n NEIGHBOURS have-or-are &amp; rest]] [[n NEIGHBOURS have-or-are &amp; rest]]
(let [quantity (first (parse-numeric-value (list n)))] (let [quantity (first (parse-numeric-value (list n)))]
@ -3247,10 +3247,10 @@ front of the sequence of tokens it returns nil.</p>
(let [[property comp1 comp2 value &amp; remainder] rest] (let [[property comp1 comp2 value &amp; remainder] rest]
(cond (and (= comp1 &quot;equal&quot;) (= comp2 &quot;to&quot;)) (cond (and (= comp1 &quot;equal&quot;) (= comp2 &quot;to&quot;))
(gen-neighbours-condition '= quantity property value remainder) (gen-neighbours-condition '= quantity property value remainder)
;; (and (= comp1 &quot;more&quot;) (= comp2 &quot;than&quot;)) (and (= comp1 &quot;more&quot;) (= comp2 &quot;than&quot;))
;; (gen-neighbours-condition '&gt; quantity property value remainder) (gen-neighbours-condition '&gt; quantity property value remainder '&gt;)
;; (and (= comp1 &quot;less&quot;) (= comp2 &quot;than&quot;)) (and (= comp1 &quot;less&quot;) (= comp2 &quot;than&quot;))
;; (gen-neighbours-condition '&lt; quantity property value remainder)))))))</pre></td></tr><tr><td class="docs"><p>Parse conditions referring to neighbours</p> (gen-neighbours-condition '&lt; quantity property value remainder '&lt;)))))))</pre></td></tr><tr><td class="docs"><p>Parse conditions referring to neighbours</p>
</td><td class="codes"><pre class="brush: clojure">(defn parse-neighbours-condition </td><td class="codes"><pre class="brush: clojure">(defn parse-neighbours-condition
[tokens] [tokens]
(or (or

View file

@ -3210,6 +3210,7 @@ net.brehaut.ClojureTools = (function (SH) {
</td><td class="codes"><pre class="brush: clojure">(ns mw-ui.routes.home </td><td class="codes"><pre class="brush: clojure">(ns mw-ui.routes.home
(:use compojure.core) (:use compojure.core)
(:require [hiccup.core :refer [html]] (:require [hiccup.core :refer [html]]
[mw-parser.bulk :as compiler]
[mw-ui.layout :as layout] [mw-ui.layout :as layout]
[mw-ui.util :as util] [mw-ui.util :as util]
[mw-ui.render-world :as world] [mw-ui.render-world :as world]
@ -3219,6 +3220,11 @@ net.brehaut.ClojureTools = (function (SH) {
:content (html (world/render-world-table)) :content (html (world/render-world-table))
:seconds (or (session/get :seconds) 5) :seconds (or (session/get :seconds) 5)
:maybe-refresh &quot;refresh&quot;}))</pre></td></tr><tr><td class="docs"> :maybe-refresh &quot;refresh&quot;}))</pre></td></tr><tr><td class="docs">
</td><td class="codes"><pre class="brush: clojure">(defn world-page []
(layout/render &quot;world.html&quot; {:title &quot;Watch your world grow&quot;
:content (html (world/render-world-table))
:seconds (or (session/get :seconds) 5)
:maybe-refresh &quot;refresh&quot;}))</pre></td></tr><tr><td class="docs">
</td><td class="codes"><pre class="brush: clojure">(defn about-page [] </td><td class="codes"><pre class="brush: clojure">(defn about-page []
(layout/render &quot;about.html&quot; {:title &quot;About MicroWorld&quot; :content (util/md-&gt;html &quot;/md/about.md&quot;)}))</pre></td></tr><tr><td class="docs"> (layout/render &quot;about.html&quot; {:title &quot;About MicroWorld&quot; :content (util/md-&gt;html &quot;/md/about.md&quot;)}))</pre></td></tr><tr><td class="docs">
</td><td class="codes"><pre class="brush: clojure">(defn list-states [] </td><td class="codes"><pre class="brush: clojure">(defn list-states []
@ -3231,10 +3237,29 @@ net.brehaut.ClojureTools = (function (SH) {
:parser (util/md-&gt;html &quot;/md/mw-parser.md&quot;) :parser (util/md-&gt;html &quot;/md/mw-parser.md&quot;)
:states (list-states) :states (list-states)
:components [&quot;mw-engine&quot; &quot;mw-parser&quot; &quot;mw-ui&quot;]}))</pre></td></tr><tr><td class="docs"> :components [&quot;mw-engine&quot; &quot;mw-parser&quot; &quot;mw-ui&quot;]}))</pre></td></tr><tr><td class="docs">
</td><td class="codes"><pre class="brush: clojure">(defn rules-page
([request]
(let [rule-text (:src request)
error
(try
(do
(if rule-text
(session/put! :rules (compiler/compile-string rule-text)))
(session/put! :rule-text rule-text)
nil)
(catch Exception e (.getMessage e)))]
(layout/render &quot;rules.html&quot; {:title &quot;Edit Rules&quot;
:rule-text (or (session/get :rule-text) (slurp &quot;resources/public/rulesets/basic.txt&quot;))
:error error})))
([]
(rules-page nil)))</pre></td></tr><tr><td class="docs">
</td><td class="codes"><pre class="brush: clojure">(defroutes home-routes </td><td class="codes"><pre class="brush: clojure">(defroutes home-routes
(GET &quot;/&quot; [] (home-page)) (GET &quot;/&quot; [] (home-page))
(GET &quot;/about&quot; [] (about-page)) (GET &quot;/about&quot; [] (about-page))
(GET &quot;/docs&quot; [] (docs-page)))</pre></td></tr><tr><td class="spacer docs">&nbsp;</td><td class="codes" /></tr><tr><td class="docs"><div class="docs-header"><a class="anchor" href="#mw-ui.util" name="mw-ui.util"><h1 class="project-name">mw-ui.util</h1><a class="toc-link" href="#toc">toc</a></a></div></td><td class="codes" /></tr><tr><td class="docs"> (GET &quot;/docs&quot; [] (docs-page))
(GET &quot;/world&quot; [] (world-page))
(GET &quot;/rules&quot; request (rules-page request))
(POST &quot;/rules&quot; request (rules-page request)))</pre></td></tr><tr><td class="spacer docs">&nbsp;</td><td class="codes" /></tr><tr><td class="docs"><div class="docs-header"><a class="anchor" href="#mw-ui.util" name="mw-ui.util"><h1 class="project-name">mw-ui.util</h1><a class="toc-link" href="#toc">toc</a></a></div></td><td class="codes" /></tr><tr><td class="docs">
</td><td class="codes"><pre class="brush: clojure">(ns mw-ui.util </td><td class="codes"><pre class="brush: clojure">(ns mw-ui.util
(:require [noir.io :as io] (:require [noir.io :as io]
[markdown.core :as md]))</pre></td></tr><tr><td class="docs"><p>reads a markdown file from public/md and returns an HTML string</p> [markdown.core :as md]))</pre></td></tr><tr><td class="docs"><p>reads a markdown file from public/md and returns an HTML string</p>

View file

@ -0,0 +1 @@
/home/simon/workspace/MicroWorld/mw-parser/resources/rules.txt

View file

@ -23,6 +23,8 @@
<div id="nav"> <div id="nav">
<ul class="nav"> <ul class="nav">
<li class="{{home-selected}}"><a href="{{servlet-context}}/">Home</a></li> <li class="{{home-selected}}"><a href="{{servlet-context}}/">Home</a></li>
<li class="{{rules-selected}}"><a href="{{servlet-context}}/rules">Rules</a></li>
<li class="{{world-selected}}"><a href="{{servlet-context}}/world">World</a></li>
<li class="{{about-selected}}"><a href="{{servlet-context}}/about">About</a></li> <li class="{{about-selected}}"><a href="{{servlet-context}}/about">About</a></li>
<li class="{{docs-selected}}"><a href="{{servlet-context}}/docs">Documentation</a></li> <li class="{{docs-selected}}"><a href="{{servlet-context}}/docs">Documentation</a></li>
</ul> </ul>
@ -31,6 +33,12 @@
</div> </div>
<div id="main-container" class="container"> <div id="main-container" class="container">
{% if error %}
<div id="announcement">
<p class="error">{{error}}</p>
</div>
{% endif %}
{% block content %} {% block content %}
{% endblock %} {% endblock %}
</div> </div>

View file

@ -0,0 +1,14 @@
{% extends "templates/base.html" %}
{% block content %}
<form action="{{servlet-context}}/rules" method="POST">
<textarea name="src" id="src" rows="10" cols="80">
{{rule-text}}
</textarea>
<p class="widget">
<label for="submit">When you have finished editing</label>
<input name="submit" id="submit" type="submit" value="Save your rules"/>
</p>
</form>
{% endblock %}

View file

@ -1,6 +1,7 @@
(ns mw-ui.routes.home (ns mw-ui.routes.home
(:use compojure.core) (:use compojure.core)
(:require [hiccup.core :refer [html]] (:require [hiccup.core :refer [html]]
[mw-parser.bulk :as compiler]
[mw-ui.layout :as layout] [mw-ui.layout :as layout]
[mw-ui.util :as util] [mw-ui.util :as util]
[mw-ui.render-world :as world] [mw-ui.render-world :as world]
@ -12,6 +13,12 @@
:seconds (or (session/get :seconds) 5) :seconds (or (session/get :seconds) 5)
:maybe-refresh "refresh"})) :maybe-refresh "refresh"}))
(defn world-page []
(layout/render "world.html" {:title "Watch your world grow"
:content (html (world/render-world-table))
:seconds (or (session/get :seconds) 5)
:maybe-refresh "refresh"}))
(defn about-page [] (defn about-page []
(layout/render "about.html" {:title "About MicroWorld" :content (util/md->html "/md/about.md")})) (layout/render "about.html" {:title "About MicroWorld" :content (util/md->html "/md/about.md")}))
@ -27,7 +34,27 @@
:states (list-states) :states (list-states)
:components ["mw-engine" "mw-parser" "mw-ui"]})) :components ["mw-engine" "mw-parser" "mw-ui"]}))
(defn rules-page
([request]
(let [rule-text (:src request)
error
(try
(do
(if rule-text
(session/put! :rules (compiler/compile-string rule-text)))
(session/put! :rule-text rule-text)
nil)
(catch Exception e (.getMessage e)))]
(layout/render "rules.html" {:title "Edit Rules"
:rule-text (or (session/get :rule-text) (slurp "resources/public/rulesets/basic.txt"))
:error error})))
([]
(rules-page nil)))
(defroutes home-routes (defroutes home-routes
(GET "/" [] (home-page)) (GET "/" [] (home-page))
(GET "/about" [] (about-page)) (GET "/about" [] (about-page))
(GET "/docs" [] (docs-page))) (GET "/docs" [] (docs-page))
(GET "/world" [] (world-page))
(GET "/rules" request (rules-page request))
(POST "/rules" request (rules-page request)))