Skip to content

Commit

Permalink
Add Screen.ChannelEvents v2 (#465)
Browse files Browse the repository at this point in the history
  • Loading branch information
eNV25 committed Jun 12, 2021
1 parent 7946eb8 commit b60a903
Show file tree
Hide file tree
Showing 5 changed files with 112 additions and 2 deletions.
20 changes: 20 additions & 0 deletions console_win.go
Expand Up @@ -343,6 +343,26 @@ func (s *cScreen) PostEvent(ev Event) error {
}
}

func (s *cScreen) ChannelEvents(ch chan<- Event, quit <-chan struct{}) {
defer close(ch)
for {
select {
case <-quit:
return
case <-s.stopQ:
return
case ev := <-s.evch:
select {
case <-quit:
return
case <-s.stopQ:
return
case ch <- ev:
}
}
}
}

func (s *cScreen) PollEvent() Event {
select {
case <-s.stopQ:
Expand Down
39 changes: 39 additions & 0 deletions event_test.go
Expand Up @@ -68,3 +68,42 @@ func TestMouseEvents(t *testing.T) {
t.Errorf("Modifiers should be control")
}
}

func TestChannelMouseEvents(t *testing.T) {

s := mkTestScreen(t, "")
defer s.Fini()

s.EnableMouse()
s.InjectMouse(4, 9, Button1, ModCtrl)
evch := make(chan Event)
quit := make(chan struct{})
em := new(EventMouse)
go s.ChannelEvents(evch, quit)

loop:
for {
select {
case ev := <-evch:
if evm, ok := ev.(*EventMouse); ok {
em = evm
close(quit)
break loop
}
continue
case <-time.After(time.Second):
close(quit)
break loop
}
}

if x, y := em.Position(); x != 4 || y != 9 {
t.Errorf("Mouse position wrong (%v, %v)", x, y)
}
if em.Buttons() != Button1 {
t.Errorf("Should be Button1")
}
if em.Modifiers() != ModCtrl {
t.Errorf("Modifiers should be control")
}
}
11 changes: 11 additions & 0 deletions screen.go
Expand Up @@ -78,6 +78,17 @@ type Screen interface {
// response to a call to Clear or Flush.
Size() (int, int)

// ChannelEvents is an infinite loop that waits for an event and
// channels it into the user provided channel ch. Closing the
// quit channel and calling the Fini method are cancellation
// signals. When a cancellation signal is received the method
// returns after closing ch.
//
// This method should be used as a goroutine.
//
// NOTE: PollEvent should not be called while this method is running.
ChannelEvents(ch chan<- Event, quit <-chan struct{})

// PollEvent waits for events to arrive. Main application loops
// must spin on this to prevent the application from stalling.
// Furthermore, this will return nil if the Screen is finalized.
Expand Down
22 changes: 21 additions & 1 deletion simulation.go
Expand Up @@ -351,6 +351,26 @@ func (s *simscreen) Colors() int {
return 256
}

func (s *simscreen) ChannelEvents(ch chan<- Event, quit <-chan struct{}) {
defer close(ch)
for {
select {
case <-quit:
return
case <-s.quit:
return
case ev := <-s.evch:
select {
case <-quit:
return
case <-s.quit:
return
case ch <- ev:
}
}
}
}

func (s *simscreen) PollEvent() Event {
select {
case <-s.quit:
Expand Down Expand Up @@ -531,4 +551,4 @@ func (s *simscreen) Suspend() error {

func (s *simscreen) Resume() error {
return nil
}
}
22 changes: 21 additions & 1 deletion tscreen.go
Expand Up @@ -638,7 +638,7 @@ func (t *tScreen) drawCell(x, y int) int {
t.TPuts(ti.TGoto(x-1, y))
t.TPuts(ti.InsertChar)
t.cy = y
t.cx = x-1
t.cx = x - 1
t.cells.SetDirty(x-1, y, true)
_ = t.drawCell(x-1, y)
t.TPuts(t.ti.TGoto(0, 0))
Expand Down Expand Up @@ -941,6 +941,26 @@ func (t *tScreen) nColors() int {
return t.ti.Colors
}

func (t *tScreen) ChannelEvents(ch chan<- Event, quit <-chan struct{}) {
defer close(ch)
for {
select {
case <-quit:
return
case <-t.quit:
return
case ev := <-t.evch:
select {
case <-quit:
return
case <-t.quit:
return
case ch <- ev:
}
}
}
}

func (t *tScreen) PollEvent() Event {
select {
case <-t.quit:
Expand Down

0 comments on commit b60a903

Please sign in to comment.