OK, this now works, more or less. The REST API is not yet used, and the

on-screen representation of the machine isn't nearly as pretty as I intend.
This commit is contained in:
simon 2016-11-24 16:05:59 +00:00
parent 78977d9fef
commit f8fe873bd4
3 changed files with 120 additions and 104 deletions

View file

@ -1,15 +1,53 @@
(ns vending.routes.home (ns vending.routes.home
(:use compojure.core) (:use compojure.core)
(:require [vending.views.layout :as layout] (:require [vending.views.layout :as layout]
[noir.session :as session]
[vending.core :as machine]
[vending.util :as util])) [vending.util :as util]))
(defn home-page []
(def button-actions
{"Coin return" machine/coin-return
"Add Merk" machine/add-merk
"Add Bawbee" machine/add-bawbee
"Add Plack" machine/add-plack
"Add Bodle" machine/add-bodle
"Request Caramel Wafer" machine/get-caramel-wafer
"Request Teacake" machine/get-teacake
"Request Snowball" machine/get-snowball
})
(defn- perform-action!
"Apply this function to the machine in the session, if there is one, or else to a new default
machine; cache the result in the session; and return a rendered page representation of the
state of the machine."
[function]
(let [machine (apply function (list (or (session/get :machine) (machine/make-default-machine))))]
(session/put! :machine machine)
(layout/render (layout/render
"home.html" {:content (util/md->html "/md/docs.md")})) "home.html" {:content (util/md->html "/md/docs.md")
:machine machine
:buttons (keys button-actions)})))
(defn home-page
"Render the home page with the default machine; in so doing, reset the machine in the session."
[]
(let [machine (machine/make-default-machine)]
(session/put! :machine machine)
(layout/render
"home.html" {:content (util/md->html "/md/docs.md")
:machine machine
:buttons (keys button-actions)})))
(defn about-page [] (defn about-page []
(layout/render "about.html")) (layout/render "about.html"))
(defroutes home-routes (defroutes home-routes
(GET "/" [] (home-page)) (GET "/" [] (home-page))
(GET "/about" [] (about-page))) (GET "/about" [] (about-page))
(POST "/update" [action] (perform-action! (button-actions action)))
)

View file

@ -8,75 +8,23 @@
[vending.util :as util])) [vending.util :as util]))
(defn- perform-action (defn- perform-action!
"Apply this function to the machine in the session, if there is one, or else to a new default "Apply this function to the machine in the session, if there is one, or else to a new default
machine; cache the result in the session; and return a JSON formatted representation of the result." machine; cache the result in the session; and return a JSON formatted representation of the state
of the machine."
[function] [function]
(let [machine (apply function (list (or (session/get :machine) (machine/make-default-machine))))] (let [machine (apply function (list (or (session/get :machine) (machine/make-default-machine))))]
(session/put! :machine machine) (session/put! :machine machine)
(json/write-str machine))) (json/write-str machine)))
;;; Each of these action functions perform an action on the machine in the session, if there is one,
;;; or on a new default machine if there is no machine in the session. They return (and cache in the
;;; session) the new state of the machine after the action; the machine returned is returned as a
;;; JSON string.
(defn coin-return-action
"Return all the coins that have been tendered since the last sale."
[]
(perform-action machine/coin-return))
(defn add-merk-action
"Insert one merk into the coin slot of the machine in the session."
[]
(perform-action machine/add-merk))
(defn add-bawbee-action
"Insert one bawbee into the coin slot of the machine in the session."
[]
(perform-action machine/add-bawbee))
(defn add-plack-action
"Insert one plack into the coin slot of the machine in the session."
[]
(perform-action machine/add-plack))
(defn add-bodle-action
"Insert one bodle into the coin slot of the machine in the session."
[]
(perform-action machine/add-bodle))
(defn select-caramel-wafer-action
"Request one caramel wafer from the machine in the session."
[]
(perform-action machine/get-caramel-wafer))
(defn select-teacake-action
"Request one teacake from the machine in the session."
[]
(perform-action machine/get-teacake))
(defn select-snowball-action
"Request one snowball from the machine in the session."
[]
(perform-action machine/get-snowball))
(defroutes json-routes (defroutes json-routes
(GET "/coin-return" [] (coin-return-action)) (GET "/json/coin-return" [] (perform-action! machine/coin-return))
(GET "/add-merk" [] (add-merk-action)) (GET "/json/add-merk" [] (perform-action! machine/add-merk))
(GET "/add-bawbee" [] (add-bawbee-action)) (GET "/json/add-bawbee" [] (perform-action! machine/add-bawbee))
(GET "/add-plack" [] (add-plack-action)) (GET "/json/add-plack" [] (perform-action! machine/add-plack))
(GET "/add-bodle" [] (add-bodle-action)) (GET "/json/add-bodle" [] (perform-action! machine/add-bodle))
(GET "/select-caramel-wafer" [] (select-caramel-wafer-action)) (GET "/json/select-caramel-wafer" [] (perform-action! machine/get-caramel-wafer))
(GET "/select-teacake" [] (select-teacake-action)) (GET "/json/select-teacake" [] (perform-action! machine/get-teacake))
(GET "/select-snowball" [] (select-snowball-action)) (GET "/json/select-snowball" [] (perform-action! machine/get-snowball))
) )

View file

@ -2,17 +2,10 @@
{% block content %} {% block content %}
<div class="jumbotron"> <div class="jumbotron">
<h1>Welcome to vending</h1> <h1>Welcome to vending</h1>
<p>Time to start building your site!</p>
<p><a class="btn btn-primary btn-lg" href="http://luminusweb.net">Learn more &raquo;</a></p>
</div> </div>
<div class="row-fluid"> <div class="row-fluid">
<div class="span8"> <div class="content span8">
{{content|safe}}
</div>
</div>
<div class="content">
<h2>OK, the Vending machine plan</h2>
<p>What this project is about is the <p>What this project is about is the
<a href="http://code.joejag.com/coding-dojo-vending-machine/">Vending Machine code kata</a>. <a href="http://code.joejag.com/coding-dojo-vending-machine/">Vending Machine code kata</a>.
Just at this point, I've added the whole of a <a href="http://www.luminusweb.net/">luminusweb</a> Just at this point, I've added the whole of a <a href="http://www.luminusweb.net/">luminusweb</a>
@ -24,33 +17,70 @@
but possibly later I'll move it client-side using ClojureScript.</p> but possibly later I'll move it client-side using ClojureScript.</p>
<p>At this stage in the project this page uses the <a href="https://github.com/yogthos/Selmer">Selmer</a> <p>At this stage in the project this page uses the <a href="https://github.com/yogthos/Selmer">Selmer</a>
templating system; later I intend that it should use <a href="https://github.com/cgrand/enlive">Enlive</a>.</p> templating system; later I intend that it should use <a href="https://github.com/cgrand/enlive">Enlive</a>.</p>
<form action="/update" method="post">
<table class="machine"> <table class="machine">
<tr> <tr>
<td colspan="8" id="tendered-coins">Tendered coins</td> <th colspan="2" id="tendered-coins-header">Tendered coins</th>
<td colspan="6" id="tendered-coins">{{machine.tendered}}</td>
</tr> </tr>
<tr> <tr>
<td id="teacake" class="items">Teacakes</td> <th colspan="3" id="stock-header">Stock</th>
<td id="caramel-wafer" class="items">Caramel wafers</td> <th colspan="4" id="coin-stack-header">Coin stacks</th>
<td id="snowballs" class="items">Snowballs</td> <th id="change-chute" rowspan="2"></th>
<td id="merk" class="coins">Merks</td>
<td id="plack" class="coins">Placks</td>
<td id="bawbee" class="coins">Bawbees</td>
<td id="bodle" class="coins">Bodles</td>
<td id="change-chute" rowspan="2"></td>
</tr> </tr>
<tr> <tr>
<td id="message">Last Message</td> <th id="teacake" class="item-header">Teacakes</th>
<th id="caramel-wafer" class="item-header">Caramel wafers</th>
<th id="snowballs" class="item-header">Snowballs</th>
<th id="merk" class="coin-header">Merks</th>
<th id="bawbee" class="coin-header">Bawbees</th>
<th id="plack" class="coin-header">Placks</th>
<th id="bodle" class="coin-header">Bodles</th>
</tr> </tr>
<tr> <tr>
<td colspan="3" id="output" class="hoppers">Output</td> <td id="caramel-wafers" class="item-stock">
<td colspan="5" id="change" class="hoppers">Change</td> {{machine.stock.caramel-wafer}}
</td>
<td id="teacakes" class="item-stock">
{{machine.stock.teacake}}
</td>
<td id="snowballs" class="item-stock">
{{machine.stock.snowball}}
</td>
<td id="merks" class="coin-stacks">{{machine.coins.merk}}</td>
<td id="bawbee" class="coin-stacks">{{machine.coins.bawbee}}</td>
<td id="plack" class="coin-stacks">{{machine.coins.plack}}</td>
<td id="bodle" class="coin-stacks">{{machine.coins.bodle}}</td>
</tr>
<tr>
<th id="message-header">Last Message</th>
</tr>
<tr>
<td id="message">{{machine.message}}</td>
</tr>
<tr>
<th colspan="3" id="output-header" class="hopper-headers">Output</th>
<th colspan="4" id="change-header" class="hopper-headers">Change</th>
</tr>
<tr>
<td colspan="3" id="output-hopper" class="hoppers">
{{machine.output}}
</td>
<td colspan="4" id="change-hopper" class="hoppers">
{% for coin in machine.change %}
{{coin}}
{% endfor %}
</td>
</tr> </tr>
<tr> <tr>
{% for button in buttons %} {% for button in buttons %}
<td class="button" id="{{ button }}-cell"> <td class="button" id="{{ button }}-cell">
<submit name="action" value="{{ button }}" id="{{ button }}-button"/> <input type="submit" name="action" value="{{ button }}" id="{{ button }}-button"/>
</td> </td>
{% endfor %} {% endfor %}
</tr> </tr>
</table> </table>
</form>
</div>
</div>
{% endblock %} {% endblock %}