down_time.go 3.4 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697
  1. // package down_time -- счётчик обратного времени в мсек
  2. package down_time
  3. import (
  4. "sync"
  5. "time"
  6. . "gitp78su.ipnodns.ru/svi/kern"
  7. . "gitp78su.ipnodns.ru/svi/kern/kc/helpers"
  8. . "gitp78su.ipnodns.ru/svi/kern/krn/ktypes"
  9. . "wartank/app/lev0/alias"
  10. . "wartank/app/lev0/types"
  11. "wartank/app/lev1/product/parser_time"
  12. )
  13. const (
  14. спатьИнтервал = time.Millisecond * 1000 // Малый интервал сна, в мсек
  15. )
  16. // ВремОбрат -- счётчик обратного времени для игровой зоны (анга, база, битва и т.п.)
  17. type ВремОбрат struct {
  18. конт ILocalCtx
  19. остатПарсер ИПарсерВремя // Парсер значения (мсек)
  20. времПорог ISafeInt // Целевое время срабатывания, мсек
  21. канВызов chan int // Канал для отправки сигналов (для верхнего уровня)
  22. блок sync.RWMutex
  23. }
  24. // НовВремОбрат -- возвращает новый *CountTime
  25. func НовВремОбрат(конт ILocalCtx, время АМилСек) *ВремОбрат {
  26. сам := &ВремОбрат{
  27. конт: конт,
  28. времПорог: NewSafeInt(),
  29. канВызов: make(chan int, 2),
  30. остатПарсер: parser_time.НовПарсерВремя(),
  31. }
  32. мСек := АМилСек(TimeNow()) + время
  33. сам.времПорог.Set(int(мСек))
  34. go сам.пуск()
  35. _ = ИВремяОстат(сам)
  36. return сам
  37. }
  38. // ПолучМилСек -- возвращает оставшееся хранимое время остатка
  39. func (сам *ВремОбрат) ПолучМилСек() АМилСек {
  40. return сам.остатПарсер.ПолучМилСек()
  41. }
  42. func (сам *ВремОбрат) ждать() {
  43. time.Sleep(спатьИнтервал)
  44. timeNow := TimeNow()
  45. if сам.времПорог.Get() > int(timeNow) {
  46. return
  47. }
  48. сам.канВызов <- 1
  49. // сам.времПорог.Set(int(timeNow) + int(сам.остатПарсер.ПолучМилСек()))
  50. }
  51. // Запускает тикер для интервалов сна (через каждые 1000 мСек)
  52. func (сам *ВремОбрат) пуск() {
  53. defer close(сам.канВызов)
  54. for {
  55. select {
  56. case <-сам.конт.Ctx().Done(): // Отмена контекста тикера (а может и сцены, может и бота)
  57. return
  58. default:
  59. сам.ждать()
  60. }
  61. }
  62. }
  63. // Уст -- устанавливает число оставшихся сек
  64. func (сам *ВремОбрат) Уст(время АВремя) {
  65. сам.блок.Lock()
  66. defer сам.блок.Unlock()
  67. сам.остатПарсер.Уст(время)
  68. _val := сам.остатПарсер.ПолучМилСек()
  69. сам.времПорог.Set(int(TimeNow()) + int(_val))
  70. }
  71. // String -- возвращает строковое представление оставшихся сек
  72. func (сам *ВремОбрат) String() string {
  73. сам.блок.RLock()
  74. defer сам.блок.RUnlock()
  75. цОстат := сам.времПорог.Get() - int(TimeNow())
  76. остат := time.Millisecond * time.Duration(цОстат)
  77. return остат.String()
  78. }
  79. // КаналСиг -- возвращает канал чтения тиков
  80. func (сам *ВремОбрат) КаналСиг() <-chan int {
  81. return сам.канВызов
  82. }