May 23, 2015

Tetris in clojurescript and re-frame Part 3 - App State

App State

There is a big conceptual difference between javasrcipt and clojurescript (especially in re-frame). Whereas in javascript you can have as much global state as you want it is discouraged to do so in the cljs-sphere. It is generally advised to have one to a few atoms containing your global application state.
In re-frame it is even more better, you don't declare an atom or global state at all, it is managed by re-frame completely.

In re-frame there is data flowing in events, this is the general idea, for a very complete documentation, please look here: re-frame

First we will initialize the app state. As you saw in part 2 there is already a call to the dispatch function doing that: (rf/dispatch [:initialise-db]).

Now we will add a new file handlers.cljs with the following content:

(defn get-clean-db-state []
  {:ctx            (.getContext (h/get-elem "tetris-canv") "2d")
   :grid-state     [[] []]
   :initialized?   true
   :started?       false
   :grid-h         20
   :grid-w         10
   :start-timestep 1000
   :timestep-dim   0.1})

(register-handler
  :initialise-db
  (fn [_ _]
    (get-clean-db-state)))
    
The first function returns a map which is the app state of the application after the initialization. This is where westore our global and local data. Also you can see that we finally initialize the canvas and also store thatin the app state.
The second function register-handler registers a handler for the :initialize-db event. This will be calledwhenever we call (re-frame/dispatch [:initialise-db]) and for now it returns the app state from get-clean-db-state.

A register-handler function will always have to return the app state, no matter if it was manipulated or not.

  • :ctx is a reference to the canvas element
  • :grid-state is a 2-dimensional vector which represents the tetris field. Each entry will represent a tetriminio(1 - 7) or nothing (0).
  • :started? indicates whether the game was started or not
  • :grid-w and :grid-h are the respective width and height entries
  • :start-timestep is the time for the ticker at which the game will run.
  • :timestep-dim is the percentage at that the ticker speed will be reduced after each level up
Tags: tetris clojuresrcipt