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
|
package ethui
import (
"fmt"
"github.com/ethereum/eth-go/ethchain"
"github.com/ethereum/eth-go/ethpub"
"github.com/ethereum/eth-go/ethutil"
"github.com/go-qml/qml"
"math/big"
)
type AppContainer interface {
Create() error
Destroy()
Window() *qml.Window
Engine() *qml.Engine
NewBlock(*ethchain.Block)
ObjectChanged(*ethchain.StateObject)
StorageChanged(*ethchain.StateObject, []byte, *big.Int)
}
type ExtApplication struct {
*ethpub.PEthereum
blockChan chan ethutil.React
changeChan chan ethutil.React
quitChan chan bool
container AppContainer
lib *UiLib
registeredEvents []string
}
func NewExtApplication(container AppContainer, lib *UiLib) *ExtApplication {
app := &ExtApplication{
ethpub.NewPEthereum(lib.eth),
make(chan ethutil.React, 1),
make(chan ethutil.React, 1),
make(chan bool),
container,
lib,
nil,
}
return app
}
func (app *ExtApplication) run() {
// Set the "eth" api on to the containers context
context := app.container.Engine().Context()
context.SetVar("eth", app)
context.SetVar("ui", app.lib)
err := app.container.Create()
if err != nil {
fmt.Println(err)
return
}
// Call the main loop
go app.mainLoop()
// Subscribe to events
reactor := app.lib.eth.Reactor()
reactor.Subscribe("newBlock", app.blockChan)
win := app.container.Window()
win.Show()
win.Wait()
app.stop()
}
func (app *ExtApplication) stop() {
// Clean up
reactor := app.lib.eth.Reactor()
reactor.Unsubscribe("newBlock", app.blockChan)
for _, event := range app.registeredEvents {
reactor.Unsubscribe(event, app.changeChan)
}
// Kill the main loop
app.quitChan <- true
close(app.blockChan)
close(app.quitChan)
close(app.changeChan)
app.container.Destroy()
}
func (app *ExtApplication) mainLoop() {
out:
for {
select {
case <-app.quitChan:
break out
case block := <-app.blockChan:
if block, ok := block.Resource.(*ethchain.Block); ok {
app.container.NewBlock(block)
}
case object := <-app.changeChan:
if stateObject, ok := object.Resource.(*ethchain.StateObject); ok {
app.container.ObjectChanged(stateObject)
} else if _, ok := object.Resource.(*big.Int); ok {
//
}
}
}
}
func (app *ExtApplication) Watch(addr, storageAddr string) {
var event string
if len(storageAddr) == 0 {
event = "object:" + string(ethutil.FromHex(addr))
app.lib.eth.Reactor().Subscribe(event, app.changeChan)
} else {
event = "storage:" + string(ethutil.FromHex(addr)) + ":" + string(ethutil.FromHex(storageAddr))
app.lib.eth.Reactor().Subscribe(event, app.changeChan)
}
app.registeredEvents = append(app.registeredEvents, event)
}
|