diff options
| author | Sam Anthony <sam@samanthony.xyz> | 2024-08-24 15:04:33 -0400 |
|---|---|---|
| committer | Sam Anthony <sam@samanthony.xyz> | 2024-08-24 15:04:33 -0400 |
| commit | a8a38817d7bdd7505a7156e390460d48863a6bb3 (patch) | |
| tree | 77e0d50b01c0777789b72f4a59e2158352104a41 /env.go | |
| parent | eac0b4b31a1ae323222076dcb31dc7cd4d9402d5 (diff) | |
| download | gui-a8a38817d7bdd7505a7156e390460d48863a6bb3.zip | |
implement new layout design
Diffstat (limited to 'env.go')
| -rw-r--r-- | env.go | 102 |
1 files changed, 102 insertions, 0 deletions
@@ -28,3 +28,105 @@ type Env interface { killer } + +type env struct { + events <-chan Event + draw chan<- func(draw.Image) image.Rectangle + attachChan chan<- attachable + kill chan<- bool + dead <-chan bool + detachChan <-chan bool +} + +// newEnv makes an Env that receives Events from, and sends draw functions to, the parent. +// +// Each Event received from parent is passed to filterEvents() along with the Events() channel +// of the Env. Each draw function received from the Env's Draw() channel is passed to +// filterDraws() along with the Draw() channel of the parent Env. +// +// filterEvents() and filterDraws() can be used to, e.g., simply forward the Event or draw function +// to the channel, modify it before sending, not send it at all, or produce some other side-effects. +// +// shutdown() is called before the Env dies. +func newEnv(parent Env, + filterEvents func(Event, chan<- Event), + filterDraws func(func(draw.Image) image.Rectangle, chan<- func(draw.Image) image.Rectangle), + shutdown func(), +) Env { + eventsOut, eventsIn := makeEventsChan() + drawChan := make(chan func(draw.Image) image.Rectangle) + child := newAttachHandler() + kill := make(chan bool) + dead := make(chan bool) + detachFromParent := make(chan bool) + + go func() { + defer func() { + dead <- true + close(dead) + }() + defer func() { + detachFromParent <- true + close(detachFromParent) + }() + defer shutdown() + defer close(eventsIn) + defer close(drawChan) + defer close(kill) + defer func() { + go drain(drawChan) + child.kill <- true + <-child.dead + }() + + for { + select { + case e := <-parent.Events(): + filterEvents(e, eventsIn) + case d := <-drawChan: + filterDraws(d, parent.Draw()) + case <-kill: + return + } + } + }() + + e := env{ + events: eventsOut, + draw: drawChan, + attachChan: child.attach(), + kill: kill, + dead: dead, + detachChan: detachFromParent, + } + parent.attach() <- e + return e +} + +func (e env) Events() <-chan Event { + return e.events +} + +func (e env) Draw() chan<- func(draw.Image) image.Rectangle { + return e.draw +} + +func (e env) Kill() chan<- bool { + return e.kill +} + +func (e env) Dead() <-chan bool { + return e.dead +} + +func (e env) attach() chan<- attachable { + return e.attachChan +} + +func (e env) detach() <-chan bool { + return e.detachChan +} + +func send[T any](v T, c chan<- T) { + c <- v +} |