-
Notifications
You must be signed in to change notification settings - Fork 0
/
eventframework.go
226 lines (187 loc) · 5.16 KB
/
eventframework.go
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
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
package trygo
import (
"fmt"
"os"
"time"
)
///////////////////////////////////////////////////////////////////////////////
// A simple event callback framework by golang.
//
// $ go build eventframework.go
// $ ./eventframework
// --> OnloadForm1(): Form1 was loaded.
// form1 width=640, height=480 Title=This is main form of application
// --> OnoverCheckbox1(): Checkbox1 was overed.
// Interface function Tostring()=Checkbox
// checkbox1 at (20, 0) Checked=true
// --> OnclickButton1(): Button1 was overed.
// --> OnclickButton1(): Button1 was clicked.
// Interface function Tostring()=Button
// btn1 at (0, 0) Text=OK
///////////////////////////////////////////////////////////////////////////////
// User side code
// OnloadApplication user programming entry OnloadApplication()
func OnloadApplication(c Control) {
// using app access functions privid by framework
var app = c.(Application)
var obj Control
// create object
obj = Form{640, 480, "This is main form of application"}
// binding (objid, eventtype) with target function
app.Binding("frmMain", LOAD, OnloadForm1)
// add objects to gui
app.Add("frmMain", obj)
obj = Button{0, 0, "OK"}
app.Binding("btnOK", CLICK, OnclickButton1)
app.Binding("btnOK", OVER, OnoverButton1) // if commet binding, quiet
app.Add("btnOK", obj)
obj = Checkbox{20, 0, true}
app.Binding("ckbUpcase", OVER, OnoverCheckbox1)
app.Add("ckbUpcase", obj)
}
// OnclickButton1 user customized event callback functions
func OnclickButton1(c Control) {
// upcast Control to concrete type
var btn = c.(Button)
fmt.Println("--> OnclickButton1(): Button1 was clicked.")
// call method implemented the interface Control
fmt.Printf(" Interface function Tostring()=%s\n", btn.Tostring())
// access data/call method of concrete control
fmt.Printf(" btn1 at (%d, %d) Text=%s\n", btn.X, btn.Y, btn.Text)
os.Exit(0)
}
// OnoverButton1 func
func OnoverButton1(c Control) {
fmt.Println("--> OnclickButton1(): Button1 was overed.")
}
// OnloadForm1 func
func OnloadForm1(c Control) {
var frm = c.(Form)
fmt.Println("--> OnloadForm1(): Form1 was loaded.")
fmt.Printf(" form1 width=%d, height=%d Title=%s\n", frm.Width, frm.Height, frm.Text)
}
// OnoverCheckbox1 func
func OnoverCheckbox1(c Control) {
var ckb = c.(Checkbox)
fmt.Println("--> OnoverCheckbox1(): Checkbox1 was overed.")
fmt.Printf(" Interface function Tostring()=%s\n", ckb.Tostring())
fmt.Printf(" checkbox1 at (%d, %d) Checked=%v\n", ckb.X, ckb.Y, ckb.Checked)
}
///////////////////////////////////////////////////////////////////////////////
// Framework side code
// Control is the base interface of all control types
type Control interface {
Tostring() string
}
// Form control
type Form struct {
Width int
Height int
Text string
}
// Tostring func
func (f Form) Tostring() string {
return "Form"
}
// Button struct
type Button struct {
X int
Y int
Text string
}
// Tostring func
func (b Button) Tostring() string {
return "Button"
}
// Checkbox struct
type Checkbox struct {
X int
Y int
Checked bool
}
// Tostring func
func (c Checkbox) Tostring() string {
return "Checkbox"
}
// control Application, Yeah!!! Application is control too.
const (
CLICK = iota
DCLICK
EXIT
LOAD
OVER
)
type eventkey struct {
objid string
eventid int
}
// Application struct
type Application struct {
Text string
Objects map[string]Control
Bindings map[eventkey]func(Control)
}
// Tostring func
func (a Application) Tostring() string {
return "Application"
}
// Add target control to application, LOAD event generated either
func (a Application) Add(objid string, c Control) {
a.Objects[objid] = c
switch c.(type) {
case Application:
// create a application
case Form:
// create a form
case Button:
// create a button
case Checkbox:
// create a checkbox
}
// common events LOAD
a.Event(objid, LOAD)
}
// Binding (object, event) with process function
func (a Application) Binding(objid string, eventid int, op func(Control)) {
key := eventkey{objid, eventid}
a.Bindings[key] = op
}
// Event process event will cause callback function executed
func (a Application) Event(objid string, eventid int) {
key := eventkey{objid, eventid}
// do nothing if no function binding on this (object, event)
if a.Bindings[key] != nil {
a.Bindings[key](a.Objects[objid])
}
}
// emulate_events
type event struct {
objid string
eventid int
}
var events = make(chan event)
// emulate event generator will raise one event per-second
func generateEvents() {
time.Sleep(1000000000) // 1 second
events <- event{"ckbUpcase", OVER}
time.Sleep(1000000000)
events <- event{"btnOK", OVER}
time.Sleep(1000000000)
events <- event{"btnOK", CLICK}
}
// EventLoop framework's main event loop
func EventLoop() {
// create application and add to dictionary
// this will cause binding LOAD event raised
app := Application{"Application", make(map[string]Control), make(map[eventkey]func(Control))}
app.Binding("Application", LOAD, OnloadApplication)
app.Add("Application", app)
// generate events from go routine
go generateEvents()
// event process loop, receive events from goroutine
var e event
for {
e = <-events
app.Event(e.objid, e.eventid)
}
}