-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathcells.tex
128 lines (96 loc) · 3.92 KB
/
cells.tex
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
\chapter{Cells}\label{cells}
Factor has a Cells like mechanism for propagating changes in models to
their GUI representation (called Gadgets). It's like a lightweight
functional reactive programming system.
\section{Models}
To have a gadget dynamically updated it must reference a `model' which
wraps the value to be displayed. Whenever the data wrapped by the
model is changed, a sequence of connected objects are notified of the
change.
To create a model, use the \verb|<model>| word, with the value it is wrapping
on the top of the stack.
\wordtable{
\vocabulary{models}
\ordinaryword{<model>}{<model>~( value -- model )}
}
\begin{alltt}
USE: models
42 <model> value>> .
\textbf{42}
\end{alltt}
New models can be created based on the value of existing models. The \verb|<arrow>| word creates a new model, with its value being the result of a quotation applied to the original models value. Its value changes whenever the original model is changed.
\wordtable{
\vocabulary{models.arrow}
\ordinaryword{<arrow>}{<arrow>~( model quot -- arrow )}
}
\begin{alltt}
USE: models
USE: models.arrow
SYMBOL: a
SYMBOL: b
42 <model> a set
a get [ 2 * ] <arrow> b set
b get activate-model
b get value>> .
\textbf{84}
10 a get set-model
b get value>> .
\textbf{20}
\end{alltt}
You'll notice the call to the word \verb|activate-model|. An active model is one that gets updated when the models it depends on change. There is a corresponding \verb|deactivate-model| that can be called to stop changes from propagating.
\wordtable{
\vocabulary{models}
\ordinaryword{activate-model}{activate-model~( model -- )}
}
\wordtable{
\vocabulary{models}
\ordinaryword{deactivate-model}{deactivate-model~( model -- )}
}
\section{Gadgets and Models}
Gadgets can use models as their underlying data to be displayed. The gadget will automatically be updated when the underlying data changes.
\begin{verbatim}
USE: ui.gadgets.labels
USE: ui.gadgets.panes
"hello" <model>
dup <label-control> gadget.
"world" over set-model
"!" over set-model
\end{verbatim}
Here we create a model containing the text ``hello''. A label-control gadget is created with this model as the data, and the gadget is printed in the listener with \verb|gadget.|. The label will show ``hello'' as the text. When the model is updated with new text using \verb|set-model|, the label control displays the new text immediately.
\section{Updating time example}
In this example I create a global value called `time' that holds a
model wrapping the current date and time:
\begin{verbatim}
USING: calendar models ;
SYMBOL: time
now <model> time set-global
\end{verbatim}
The model here wraps the current date and time produced by
\verb|now|. To have the value change regularly I start a background
thread which sets the value every second:
\begin{verbatim}
USE: timers
: update-time ( -- )
now time get-global set-model ;
[ update-time ] 1 seconds every drop
\end{verbatim}
The \verb|update-time| words gets the current date and time (using \verb|now|)
and sets the model's value to it. A timer is created to do this every second.
We can confirm that this value is updating by getting the value of
the `time' variable and see that it changes between calls:
\begin{alltt}
USE: calendar.format
time get-global value>> timestamp>http-string .
\textbf{"Sun, 20 Jan 2008, 02:02:02 GMT"}
time get-global value>> timestamp>http-string .
\textbf{"Sun, 20 Jan 2008, 02:04:02 GMT" }
\end{alltt}
A label gadget that displays this value, and is updated as it changes,
can be created and displayed with:
\begin{verbatim}
USING: ui.gadgets.labels ui.gadgets.panes calendar.format ;
time get-global
[ timestamp>http-string ] <arrow> <label-control>
gadget.
\end{verbatim}
Notice I'm using \verb|<arrow>| to take the time value and convert it into a string. A \verb|<label-control>| can only display strings, so it has the filtered value as its data. The gadget displayed on the listener will update automatically as the time changes every second.