From f3f79a425119f6e8dd161645447f668d25cd9626 Mon Sep 17 00:00:00 2001 From: Sam Anthony Date: Thu, 22 Aug 2024 00:29:35 -0400 Subject: simplify killer interface --- kill.go | 46 +++++++++++++++++++--------------------------- mux.go | 42 ++++++++++++++++++++++++------------------ mux_test.go | 4 ++-- 3 files changed, 45 insertions(+), 47 deletions(-) diff --git a/kill.go b/kill.go index 8f91035..2d2022b 100644 --- a/kill.go +++ b/kill.go @@ -7,21 +7,20 @@ type Killable interface { Dead() <-chan bool } -// A killer can kill the object that is attached to it. -// The victim can attach itself to the killer by sending an attachMsg via the provided attach() channel. -// The attachMsg contains the victim itself and a `detach' channel. -// The victim can detatch itself from the killer by signalling over the `detach' channel. +type attachable interface { + Killable + // Sending to detach() will detach the object from the killer it is attached to. + detach() <-chan bool +} + +// A killer can kill the `victim' that is attached to it. +// The victim can attach itself to the killer by sending itself via the killer's attach() channel. +// The victim can detach itself by sending a signal via its own detach() channel. // // Only one victim can be attached to the killer at a time. // Further messages sent on the attach() channel will block until the current victim is detached. type killer interface { - attach() chan<- attachMsg -} - -// attachMsg is sent to a killer to attach the victim. -type attachMsg struct { - victim Killable - detach <-chan bool + attach() chan<- attachable } // attachHandler implements killer. It allows victims to attach themselves via the attach channel. @@ -29,13 +28,13 @@ type attachMsg struct { // If attachHandler is killed while a victim is attached, it kills the victim. // When killed, the victim must detach itself before dying. type attachHandler struct { - attach chan<- attachMsg + attach chan<- attachable kill chan<- bool dead <-chan bool } func newAttachHandler() attachHandler { - attach := make(chan attachMsg) + attach := make(chan attachable) kill := make(chan bool) dead := make(chan bool) @@ -48,25 +47,18 @@ func newAttachHandler() attachHandler { defer close(attach) for { - var attached attachMsg - select { - case attached = <-attach: - case <-kill: - return - } - - Attached: - for { + case victim := <-attach: select { - case <-attached.detach: - break Attached + case <-victim.detach(): case <-kill: - attached.victim.Kill() <- true - <-attached.detach - <-attached.victim.Dead() + victim.Kill() <- true + <-victim.detach() + <-victim.Dead() return } + case <-kill: + return } } }() diff --git a/mux.go b/mux.go index e482a3a..26f220a 100644 --- a/mux.go +++ b/mux.go @@ -18,6 +18,7 @@ type Mux struct { removeChild chan<- muxEnv kill chan<- bool dead <-chan bool + detachChan <-chan bool } func NewMux(parent Env) Mux { @@ -88,8 +89,9 @@ func NewMux(parent Env) Mux { removeChild: removeChild, kill: kill, dead: dead, + detachChan: detachFromParent, } - parent.attach() <- attachMsg{mux, detachFromParent} + parent.attach() <- mux return mux } @@ -101,31 +103,36 @@ func (mux Mux) Dead() <-chan bool { return mux.dead } +func (mux Mux) detach() <-chan bool { + return mux.detachChan +} + type muxEnv struct { - eventsIn chan<- Event - eventsOut <-chan Event - draw chan<- func(draw.Image) image.Rectangle - attachChan chan<- attachMsg - kill chan<- bool - dead <-chan bool + eventsIn chan<- Event + eventsOut <-chan Event + draw chan<- func(draw.Image) image.Rectangle + attachChan chan<- attachable + kill chan<- bool + dead <-chan bool + detachFromMux <-chan bool } func (mux Mux) MakeEnv() Env { eventsOut, eventsIn := MakeEventsChan() drawChan := make(chan func(draw.Image) image.Rectangle) - victimChan := make(chan Killable) + attached := newAttachHandler() kill := make(chan bool) dead := make(chan bool) - - attached := newAttachHandler() + detachFromMux := make(chan bool) env := muxEnv{ - eventsIn: eventsIn, - eventsOut: eventsOut, - draw: drawChan, - attachChan: attached.attach, - kill: kill, - dead: dead, + eventsIn: eventsIn, + eventsOut: eventsOut, + draw: drawChan, + attachChan: attached.attach, + kill: kill, + dead: dead, + detachFromMux: detachFromMux, } mux.addChild <- env // make sure to always send a resize event to a new Env @@ -137,7 +144,6 @@ func (mux Mux) MakeEnv() Env { close(dead) }() defer close(kill) - defer close(victimChan) defer close(drawChan) defer close(eventsIn) // eventsOut closed automatically by MakeEventsChan() @@ -183,7 +189,7 @@ func (env muxEnv) Dead() <-chan bool { return env.dead } -func (env muxEnv) attach() chan<- attachMsg { +func (env muxEnv) attach() chan<- attachable { return env.attachChan } diff --git a/mux_test.go b/mux_test.go index 9ffca83..95fe4ae 100644 --- a/mux_test.go +++ b/mux_test.go @@ -152,7 +152,7 @@ type dummyEnv struct { kill chan<- bool dead <-chan bool - attachChan chan<- attachMsg + attachChan chan<- attachable } func newDummyEnv(size image.Rectangle) dummyEnv { @@ -212,7 +212,7 @@ func (de dummyEnv) Dead() <-chan bool { return de.dead } -func (de dummyEnv) attach() chan<- attachMsg { +func (de dummyEnv) attach() chan<- attachable { return de.attachChan } -- cgit v1.2.3