flag.go 1.2 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485
  1. package chansync
  2. import (
  3. "sync"
  4. "github.com/anacrolix/chansync/events"
  5. )
  6. type ReadOnlyFlag interface {
  7. Bool() bool
  8. On() events.Active
  9. Off() events.Active
  10. }
  11. // Flag wraps a boolean value that starts as false (off). You can wait for it to be on or off, and
  12. // set the value as needed.
  13. type Flag struct {
  14. mu sync.Mutex
  15. on chan struct{}
  16. off chan struct{}
  17. state bool
  18. inited bool
  19. }
  20. func (me *Flag) Bool() bool {
  21. me.mu.Lock()
  22. defer me.mu.Unlock()
  23. return me.state
  24. }
  25. func (me *Flag) On() events.Active {
  26. me.mu.Lock()
  27. defer me.mu.Unlock()
  28. me.init()
  29. return me.on
  30. }
  31. func (me *Flag) Off() events.Active {
  32. me.mu.Lock()
  33. defer me.mu.Unlock()
  34. me.init()
  35. return me.off
  36. }
  37. func (me *Flag) init() {
  38. if me.inited {
  39. return
  40. }
  41. me.on = make(chan struct{})
  42. me.off = make(chan struct{})
  43. close(me.off)
  44. me.inited = true
  45. }
  46. func (me *Flag) SetBool(b bool) {
  47. if b {
  48. me.Set()
  49. } else {
  50. me.Clear()
  51. }
  52. }
  53. func (me *Flag) Set() {
  54. me.mu.Lock()
  55. defer me.mu.Unlock()
  56. me.init()
  57. if me.state {
  58. return
  59. }
  60. me.state = true
  61. close(me.on)
  62. me.off = make(chan struct{})
  63. }
  64. func (me *Flag) Clear() {
  65. me.mu.Lock()
  66. defer me.mu.Unlock()
  67. me.init()
  68. if !me.state {
  69. return
  70. }
  71. me.state = false
  72. close(me.off)
  73. me.on = make(chan struct{})
  74. }