// package down_time -- счётчик обратного времени в мсек package down_time import ( "sync" "time" . "gitp78su.ipnodns.ru/svi/kern" . "gitp78su.ipnodns.ru/svi/kern/kc/helpers" . "gitp78su.ipnodns.ru/svi/kern/krn/ktypes" . "wartank/app/lev0/alias" . "wartank/app/lev0/types" "wartank/app/lev1/product/parser_time" ) const ( спатьИнтервал = time.Millisecond * 1000 // Малый интервал сна, в мсек ) // ВремОбрат -- счётчик обратного времени для игровой зоны (анга, база, битва и т.п.) type ВремОбрат struct { конт ILocalCtx остатПарсер ИПарсерВремя // Парсер значения (мсек) времПорог ISafeInt // Целевое время срабатывания, мсек канВызов chan int // Канал для отправки сигналов (для верхнего уровня) блок sync.RWMutex } // НовВремОбрат -- возвращает новый *CountTime func НовВремОбрат(конт ILocalCtx, время АМилСек) *ВремОбрат { сам := &ВремОбрат{ конт: конт, времПорог: NewSafeInt(), канВызов: make(chan int, 2), остатПарсер: parser_time.НовПарсерВремя(), } мСек := АМилСек(TimeNow()) + время сам.времПорог.Set(int(мСек)) go сам.пуск() _ = ИВремяОстат(сам) return сам } // ПолучМилСек -- возвращает оставшееся хранимое время остатка func (сам *ВремОбрат) ПолучМилСек() АМилСек { return сам.остатПарсер.ПолучМилСек() } func (сам *ВремОбрат) ждать() { time.Sleep(спатьИнтервал) timeNow := TimeNow() if сам.времПорог.Get() > int(timeNow) { return } сам.канВызов <- 1 // сам.времПорог.Set(int(timeNow) + int(сам.остатПарсер.ПолучМилСек())) } // Запускает тикер для интервалов сна (через каждые 1000 мСек) func (сам *ВремОбрат) пуск() { defer close(сам.канВызов) for { select { case <-сам.конт.Ctx().Done(): // Отмена контекста тикера (а может и сцены, может и бота) return default: сам.ждать() } } } // Уст -- устанавливает число оставшихся сек func (сам *ВремОбрат) Уст(время АВремя) { сам.блок.Lock() defer сам.блок.Unlock() сам.остатПарсер.Уст(время) _val := сам.остатПарсер.ПолучМилСек() сам.времПорог.Set(int(TimeNow()) + int(_val)) } // String -- возвращает строковое представление оставшихся сек func (сам *ВремОбрат) String() string { сам.блок.RLock() defer сам.блок.RUnlock() цОстат := сам.времПорог.Get() - int(TimeNow()) остат := time.Millisecond * time.Duration(цОстат) return остат.String() } // КаналСиг -- возвращает канал чтения тиков func (сам *ВремОбрат) КаналСиг() <-chan int { return сам.канВызов }