zorldo

Goofing around with Ebiten
git clone git://bsandro.tech/zorldo
Log | Files | Refs | README

lifecycler.go (2025B)


      1 // Copyright 2016 The Go Authors. All rights reserved.
      2 // Use of this source code is governed by a BSD-style
      3 // license that can be found in the LICENSE file.
      4 
      5 // Package lifecycler tracks a window's lifecycle state.
      6 //
      7 // It eliminates sending redundant lifecycle events, ones where the From and To
      8 // stages are equal. For example, moving a window from one part of the screen
      9 // to another should not send multiple events from StageVisible to
     10 // StageVisible, even though the underlying window system's message might only
     11 // hold the new position, and not whether the window was previously visible.
     12 package lifecycler // import "golang.org/x/exp/shiny/driver/internal/lifecycler"
     13 
     14 import (
     15 	"sync"
     16 
     17 	"golang.org/x/mobile/event/lifecycle"
     18 )
     19 
     20 // State is a window's lifecycle state.
     21 type State struct {
     22 	mu      sync.Mutex
     23 	stage   lifecycle.Stage
     24 	dead    bool
     25 	focused bool
     26 	visible bool
     27 }
     28 
     29 func (s *State) SetDead(b bool) {
     30 	s.mu.Lock()
     31 	s.dead = b
     32 	s.mu.Unlock()
     33 }
     34 
     35 func (s *State) SetFocused(b bool) {
     36 	s.mu.Lock()
     37 	s.focused = b
     38 	s.mu.Unlock()
     39 }
     40 
     41 func (s *State) SetVisible(b bool) {
     42 	s.mu.Lock()
     43 	s.visible = b
     44 	s.mu.Unlock()
     45 }
     46 
     47 func (s *State) SendEvent(r Sender, drawContext interface{}) {
     48 	s.mu.Lock()
     49 	from, to := s.stage, lifecycle.StageAlive
     50 	// The order of these if's is important. For example, once a window becomes
     51 	// StageDead, it should never change stage again.
     52 	//
     53 	// Similarly, focused trumps visible. It's hard to imagine a situation
     54 	// where a window is focused and not visible on screen, but in that
     55 	// unlikely case, StageFocused seems the most appropriate stage.
     56 	if s.dead {
     57 		to = lifecycle.StageDead
     58 	} else if s.focused {
     59 		to = lifecycle.StageFocused
     60 	} else if s.visible {
     61 		to = lifecycle.StageVisible
     62 	}
     63 	s.stage = to
     64 	s.mu.Unlock()
     65 
     66 	if from != to {
     67 		r.Send(lifecycle.Event{
     68 			From: from,
     69 			To:   to,
     70 
     71 			// TODO: does shiny use this at all?
     72 			DrawContext: drawContext,
     73 		})
     74 	}
     75 }
     76 
     77 // Sender is who to send the lifecycle event to.
     78 type Sender interface {
     79 	Send(event interface{})
     80 }