diff options
| author | Pietro Gagliardi <[email protected]> | 2014-07-19 09:57:01 -0400 |
|---|---|---|
| committer | Pietro Gagliardi <[email protected]> | 2014-07-19 09:57:01 -0400 |
| commit | 104337188f1d7bcdb0774748f41cb91a06216122 (patch) | |
| tree | 21da8ff026a6a82547294b005d6e2b59869575c1 /redo/uitask.go | |
| parent | 48c5055eb960d6db3d3b997bdc859670f473a277 (diff) | |
Removed Request completely, also updating the uitask files. Also renamed xperform to doissue for consistency.
Diffstat (limited to 'redo/uitask.go')
| -rw-r--r-- | redo/uitask.go | 93 |
1 files changed, 25 insertions, 68 deletions
diff --git a/redo/uitask.go b/redo/uitask.go index 42006fe..8b5e523 100644 --- a/redo/uitask.go +++ b/redo/uitask.go @@ -14,53 +14,32 @@ func Go() error { if err := uiinit(); err != nil { return err } - go uitask(Do) uimsgloop() return nil } -// Stop issues a Request for package ui to stop and returns immediately. -// Some time after this request is received, Go() will return without performing any final cleanup. -// Stop is internally issued to Do, so it will not be registered until any event handlers and dialog boxes return. -func Stop() { - go func() { - c := make(chan interface{}) - Do <- &Request{ - op: func() { - uistop() - c <- struct{}{} - }, - resp: c, - } - <-c - }() +// Do performs f on the main loop, as if it were an event handler. +// It waits for f to execute before returning. +// Do cannot be called within event handlers or within Do itself. +func Do(f func()) { + done := make(chan struct{}) + defer close(done) + issue(func() { + f() + done <- struct{}{} + }) + <-done } -// This is the ui main loop. -// It is spawned by Go as a goroutine. -// It can also be called recursively using the recur/unrecur chain. -func uitask(doer Doer) { - for { - select { - case req := <-doer: - // TODO foreign event - issue(req) - case rec := <-recur: // want to perform event - c := make(Doer) - rec <- c - uitask(c) - case <-unrecur: // finished with event - close(doer) - return - } - } +// Stop informs package ui that it should stop. +// Stop then returns immediately. +// Some time after this request is received, Go() will return without performing any final cleanup. +// Stop will not have an effect until any event handlers or dialog boxes presently active return. +// (TODO make sure this is the case for dialog boxes) +func Stop() { + issue(uistop) } -// Send a channel over recur to have uitask() above enter a recursive loop in which the Doer sent back becomes the active request handler. -// Pulse unrecur when finished. -var recur = make(chan chan Doer) -var unrecur = make(chan struct{}) - type event struct { // All events internally return bool; those that don't will be wrapped around to return a dummy value. do func(c Doer) bool @@ -105,38 +84,16 @@ func (e *event) setbool(f func(Doer) bool) { // This is the common code for running an event. // It runs on the main thread without a message pump; it provides its own. func (e *event) fire() bool { - cc := make(chan Doer) - recur <- cc - c := <-cc - close(cc) - result := false - finished := make(chan struct{}) - go func() { - e.lock.Lock() - defer e.lock.Unlock() + e.lock.Lock() + defer e.lock.Unlock() - result = e.do(c) - finished <- struct{}{} - }() - <-finished - close(finished) - // leave the event handler; leave it only after returning from the OS-side event handler so we must issue it like a normal Request - issue(&Request{ - op: func() { - unrecur <- struct{}{} - }, - // unfortunately, closing a nil channel causes a panic - // therefore, we have to make a dummy channel - // TODO add conditional checks to the request handler instead? - resp: make(chan interface{}), - }) - return result + return e.do(c) } -// Common code for performing a Request. +// Common code for performing a requested action (ui.Do() or ui.Stop()). // This should run on the main thread. // Implementations of issue() should call this. -func perform(req *Request) { - req.op() - close(req.resp) +func perform(fp unsafe.Pointer) { + f := (*func())(fp) + (*f)() } |
