Skip to content

Commit 914a10d

Browse files
committed
AsyncPath improvments
fixed occasional data race in Close() function. added Destroy() interface to window manager
1 parent a84ee10 commit 914a10d

File tree

5 files changed

+63
-45
lines changed

5 files changed

+63
-45
lines changed

archivefs/async.go

Lines changed: 39 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -24,14 +24,18 @@ type FilenameSetter interface {
2424
type AsyncResults struct {
2525
Entries []Node
2626
Selected string
27+
IsDir bool
2728
Dir string
2829
Base string
2930
}
3031

3132
// AsyncPath provides asynchronous access to an archivefs
3233
type AsyncPath struct {
3334
setter FilenameSetter
34-
afs Path
35+
36+
Set chan string
37+
Close chan bool
38+
Destroy chan bool
3539

3640
results chan AsyncResults
3741
err chan error
@@ -42,40 +46,48 @@ type AsyncPath struct {
4246

4347
// NewAsyncPath is the preferred method of initialisation for the AsyncPath type
4448
func NewAsyncPath(setter FilenameSetter) AsyncPath {
45-
return AsyncPath{
49+
pth := AsyncPath{
4650
setter: setter,
51+
Set: make(chan string, 1),
52+
Close: make(chan bool, 1),
53+
Destroy: make(chan bool, 1),
4754
results: make(chan AsyncResults, 1),
4855
err: make(chan error, 1),
4956
}
50-
}
5157

52-
// Close any open zip files and reset path
53-
func (pth *AsyncPath) Close() {
54-
// not sure how safe this is if it is called when the Set() goroutine is running
55-
pth.afs.Close()
56-
}
57-
58-
// Set archivefs path. Process() must be called in order to retreive the results
59-
// of the Set()
60-
func (pth *AsyncPath) Set(path string) error {
6158
go func() {
62-
pth.afs.Set(path)
63-
64-
entries, err := pth.afs.List()
65-
if err != nil {
66-
pth.err <- err
67-
return
68-
}
69-
70-
pth.results <- AsyncResults{
71-
Entries: entries,
72-
Selected: pth.afs.String(),
73-
Dir: pth.afs.Dir(),
74-
Base: pth.afs.Base(),
59+
var afs Path
60+
var done bool
61+
62+
for !done {
63+
select {
64+
case <-pth.Destroy:
65+
done = true
66+
67+
case <-pth.Close:
68+
afs.Close()
69+
70+
case path := <-pth.Set:
71+
afs.Set(path)
72+
73+
entries, err := afs.List()
74+
if err != nil {
75+
pth.err <- err
76+
return
77+
}
78+
79+
pth.results <- AsyncResults{
80+
Entries: entries,
81+
Selected: afs.String(),
82+
IsDir: afs.IsDir(),
83+
Dir: afs.Dir(),
84+
Base: afs.Base(),
85+
}
86+
}
7587
}
7688
}()
7789

78-
return nil
90+
return pth
7991
}
8092

8193
// Process asynchronous requests. Must be called in order to receive the results
@@ -89,7 +101,7 @@ func (pth *AsyncPath) Process() error {
89101
pth.Results = results
90102

91103
if pth.setter != nil {
92-
if pth.afs.IsDir() {
104+
if pth.Results.IsDir {
93105
pth.setter.SetSelectedFilename("")
94106
} else {
95107
pth.setter.SetSelectedFilename(pth.Results.Selected)

gui/sdlimgui/manager.go

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -138,6 +138,14 @@ func newManager(img *SdlImgui) (*manager, error) {
138138
return wm, nil
139139
}
140140

141+
func (wm *manager) destroy() {
142+
for _, w := range wm.windows {
143+
if c, ok := w.(windowDestroy); ok {
144+
c.destroy()
145+
}
146+
}
147+
}
148+
141149
func (wm *manager) draw() {
142150
// there's no good place to call the managedWindow.init() function except
143151
// here when we know everything else has been initialised

gui/sdlimgui/manager_window.go

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,11 @@ type window interface {
3232
id() string
3333
}
3434

35+
// windows that require special destruction implement the windowDestroy interface
36+
type windowDestroy interface {
37+
destroy()
38+
}
39+
3540
// information about the window, including window geometry
3641
//
3742
// is embedded in playmodeWin and debuggerWin interfaces. for window type that

gui/sdlimgui/sdlimgui.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -276,6 +276,8 @@ func (img *SdlImgui) Destroy() {
276276
logger.Log("sdlimgui", err.Error())
277277
}
278278

279+
img.wm.destroy()
280+
279281
err = img.plt.destroy()
280282
if err != nil {
281283
logger.Log("sdlimgui", err.Error())

gui/sdlimgui/win_rom_select.go

Lines changed: 9 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -137,22 +137,22 @@ func newSelectROM(img *SdlImgui) (window, error) {
137137
func (win *winSelectROM) init() {
138138
}
139139

140+
func (win *winSelectROM) destroy() {
141+
win.path.Destroy <- true
142+
}
143+
140144
func (win winSelectROM) id() string {
141145
return winSelectROMID
142146
}
143147

144148
func (win *winSelectROM) setOpen(open bool) {
145149
if !open {
146-
win.path.Close()
150+
win.path.Close <- true
147151
return
148152
}
149153

150154
// open at the most recently selected ROM
151-
recent := win.img.dbg.Prefs.RecentROM.String()
152-
err := win.path.Set(recent)
153-
if err != nil {
154-
logger.Logf("sdlimgui", err.Error())
155-
}
155+
win.path.Set <- win.img.dbg.Prefs.RecentROM.String()
156156
}
157157

158158
func (win *winSelectROM) playmodeSetOpen(open bool) {
@@ -285,10 +285,7 @@ func (win *winSelectROM) draw() {
285285
}()
286286

287287
if imgui.Button("Parent") {
288-
err := win.path.Set(filepath.Dir(win.path.Results.Dir))
289-
if err != nil {
290-
logger.Logf("sdlimgui", err.Error())
291-
}
288+
win.path.Set <- filepath.Dir(win.path.Results.Dir)
292289
win.scrollToTop = true
293290
}
294291

@@ -331,10 +328,7 @@ func (win *winSelectROM) draw() {
331328
}
332329

333330
if imgui.Selectable(s.String()) {
334-
err := win.path.Set(filepath.Join(win.path.Results.Dir, e.Name))
335-
if err != nil {
336-
logger.Logf("sdlimgui", err.Error())
337-
}
331+
win.path.Set <- filepath.Join(win.path.Results.Dir, e.Name)
338332
win.scrollToTop = true
339333
}
340334
}
@@ -380,10 +374,7 @@ func (win *winSelectROM) draw() {
380374
}
381375

382376
if imgui.SelectableV(e.Name, selected, 0, imgui.Vec2{0, 0}) {
383-
err := win.path.Set(filepath.Join(win.path.Results.Dir, e.Name))
384-
if err != nil {
385-
logger.Logf("sdlimgui", err.Error())
386-
}
377+
win.path.Set <- filepath.Join(win.path.Results.Dir, e.Name)
387378
}
388379
if imgui.IsItemHovered() && imgui.IsMouseDoubleClicked(0) {
389380
win.insertCartridge()

0 commit comments

Comments
 (0)