reactive gui implemented in clojure

Post on 16-Jul-2015

220 Views

Category:

Software

0 Downloads

Preview:

Click to see full reader

TRANSCRIPT

Reactive GUI Implemented in Clojure

Denys Lebediev

Quick background

Traditional approach

• Event Listener pattern

• Widget model is mutable

– Example: isPressed/setPressed

• Widget state is mutable

– Example: isEnabled/setEnabled

Traditional approach: problems

• Complicated GUI containers (dialogs, wizards, etc) are often difficult to implement, support and extend. Why?

Traditional approach: problems

• Obscuring the logic

Traditional approach: problems

• Obscuring the logic

– It may be unclear why the button is enabled and when it becomes enabled

Traditional approach: problems

• Obscuring the logic

– It may be unclear why the button is enabled and when it becomes enabled

• Spreading the logic

Traditional approach: problems

• Obscuring the logic

– It may be unclear why the button is enabled and when it becomes enabled

• Spreading the logic

– The reasons for the button to be enabled tend to be spread across the application code

Traditional approach: problems

• Obscuring the logic

– It may be unclear why the button is enabled and when it becomes enabled

• Spreading the logic

– The reasons for the button to be enabled tend to be spread across the application code

– Moreover with time

Traditional approach: problems

• Incidental complexity

– In fact, non-essential code has to be written

– Developer has to bother deciding when

– And spend time investigating another developer’s decisions

• Automated testing is tricky

– Robot-based testing

There is another way

• The framework takes care of routine

– It is already implemented and tested

– Developer concentrates on essential application logic

There is another way

• The framework takes care of routine

– It is already implemented and tested

– Developer concentrates on essential application logic

• All logic about a single property in a single place

There is another way

• The framework takes care of routine

– It is already implemented and tested

– Developer concentrates on essential application logic

• All logic about a single property in a single place

• Unit tests for code that manages widget model and state

Hello world with FlatGUI

(defcomponent checkbox :say-hello {:text "Greeting"})

(def nogreeting-text "Greeting not provided")

(def greeting-text "Hello, world!")

(defevolverfn greeting-evolver :text

(if (get-property [:say-hello] :pressed)

greeting-text

nogreeting-text))

(defcomponent label :greeting-label

{:text nogreeting-text

:evolvers {:text greeting-evolver}})

Hello world with FlatGUI

(defcomponent checkbox :say-hello {:text "Greeting"})

(def nogreeting-text "Greeting not provided")

(def greeting-text "Hello, world!")

(defevolverfn greeting-evolver :text

(if (get-property [:say-hello] :pressed)

greeting-text

nogreeting-text))

(defcomponent label :greeting-label

{:text nogreeting-text

:evolvers {:text greeting-evolver}})

Hello world with FlatGUI

(defcomponent checkbox :say-hello {:text "Greeting"})

(def nogreeting-text "Greeting not provided")

(def greeting-text "Hello, world!")

(defevolverfn greeting-evolver :text

(if (get-property [:say-hello] :pressed)

greeting-text

nogreeting-text))

(defcomponent label :greeting-label

{:text nogreeting-text

:evolvers {:text greeting-evolver}})

What’s the difference?

• greeting-evolver is a single place for the logic of

label’s :text property

What’s the difference?

• greeting-evolver is a single place for the logic of

label’s :text property

• It contains the logic, not routine

What’s the difference?

• greeting-evolver is a single place for the logic of

label’s :text property

• It contains the logic, not routine

• It’s easy to troubleshoot

What’s the difference?

• greeting-evolver is a single place for the logic of

label’s :text property

• It contains the logic, not routine

• It’s easy to troubleshoot

• It’s easy to cover with unit tests

What’s the difference?

• greeting-evolver is a single place for the logic of

label’s :text property

• It contains the logic, not routine

• It’s easy to troubleshoot

• It’s easy to cover with unit tests

• Developer does not have to decide when to call it

What’s the difference?

• greeting-evolver is a single place for the logic of

label’s :text property

• It contains the logic, not routine

• It’s easy to troubleshoot

• It’s easy to cover with unit tests

• Developer does not have to decide when to call it

• Developer does not have to call it

What’s the difference?

• Reactive framework takes care of these routine things

– Implemented once, no need to solve similar problems again

– Tested

FlatGUI architecture

Engine performs state transition

Option to run as RIA

Setup collaboration sessions

Clojure usage

• Macros are nice

– defining widget types and instances, property evolvers

– Layout management, like “below” “to the right of”

– Though IDE capabilities are still not enough

• Had fun with profiler to tune engine performance

– Introduced some non-idiomatic code

Current state of the project

• This is a poof-of-concept implementation

• What’s next

– Publish sources

– Prepare documentation and examples

– Launch the website

– Finalize the engine and basic widgets

– Optimize network solution

info@flatgui.org

top related