game_sync/common/clock.go

277 lines
5.4 KiB
Go

package common
import (
"time"
"mongo.games.com/goserver/core/module"
)
/*
时钟
*/
func init() {
module.RegisteModule(ClockMgrSingleton, time.Millisecond*500, 0)
}
var ClockMgrSingleton = &ClockMgr{
LastHour: -1,
LastDay: -1,
Notifying: false,
}
const (
ClockEventSecond int = iota
ClockEventMinute
ClockEventHour
ClockEventDay
ClockEventWeek
ClockEventMonth
ClockEventShutdown
ClockEventMax
)
type ClockSinker interface {
InterestClockEvent() int
OnSecTimer()
OnMiniTimer()
OnHourTimer()
OnDayTimer()
OnWeekTimer()
OnMonthTimer()
OnShutdown()
}
type BaseClockSinker struct {
}
func (s *BaseClockSinker) InterestClockEvent() int { return (1 << ClockEventMax) - 1 }
func (s *BaseClockSinker) OnSecTimer() {}
func (s *BaseClockSinker) OnMiniTimer() {}
func (s *BaseClockSinker) OnHourTimer() {}
func (s *BaseClockSinker) OnDayTimer() {}
func (s *BaseClockSinker) OnWeekTimer() {}
func (s *BaseClockSinker) OnMonthTimer() {}
func (s *BaseClockSinker) OnShutdown() {}
type ClockMgr struct {
sinkers [ClockEventMax][]ClockSinker
LastTickTime time.Time
LastMonth time.Month
LastWeek int
LastDay int
LastHour int
LastMini int
LastSec int
Notifying bool
LastFiveMin int
}
func (this *ClockMgr) RegisterSinker(sinker ClockSinker) {
interest := sinker.InterestClockEvent()
for i := 0; i < ClockEventMax; i++ {
if (1<<i)&interest != 0 {
found := false
ss := this.sinkers[i]
for _, s := range ss {
if s == sinker {
found = true
break
}
}
if !found {
this.sinkers[i] = append(this.sinkers[i], sinker)
}
}
}
}
func (this *ClockMgr) ModuleName() string {
return "ClockMgr"
}
func (this *ClockMgr) Init() {
tNow := time.Now().Local()
this.LastTickTime = tNow
_, this.LastMonth, this.LastDay = tNow.Date()
this.LastHour, this.LastMini, this.LastSec = tNow.Hour(), tNow.Minute(), tNow.Second()
_, this.LastWeek = tNow.ISOWeek()
this.LastFiveMin = -1
}
func (this *ClockMgr) Update() {
tNow := time.Now().Local()
this.LastTickTime = tNow
sec := tNow.Second()
if sec != this.LastSec {
this.LastSec = sec
this.fireSecondEvent()
minute := tNow.Minute()
if minute != this.LastMini {
this.LastMini = minute
this.fireMinuteEvent()
hour := tNow.Hour()
if hour != this.LastHour {
this.LastHour = hour
this.fireHourEvent()
day := tNow.Day()
if day != this.LastDay {
this.LastDay = day
this.fireDayEvent()
week := GetWeekStartTs(tNow.Unix())
if week != int64(this.LastWeek) {
this.LastWeek = int(week)
this.fireWeekEvent()
}
month := tNow.Month()
if month != this.LastMonth {
this.LastMonth = month
this.fireMonthEvent()
}
}
}
}
}
}
func (this *ClockMgr) Shutdown() {
this.fireShutdownEvent()
module.UnregisteModule(this)
}
func (this *ClockMgr) fireSecondEvent() {
for _, s := range this.sinkers[ClockEventSecond] {
s.OnSecTimer()
}
}
func (this *ClockMgr) fireMinuteEvent() {
for _, s := range this.sinkers[ClockEventMinute] {
s.OnMiniTimer()
}
}
func (this *ClockMgr) fireHourEvent() {
for _, s := range this.sinkers[ClockEventHour] {
s.OnHourTimer()
}
}
func (this *ClockMgr) fireDayEvent() {
for _, s := range this.sinkers[ClockEventDay] {
s.OnDayTimer()
}
}
func (this *ClockMgr) fireWeekEvent() {
for _, s := range this.sinkers[ClockEventWeek] {
s.OnWeekTimer()
}
}
func (this *ClockMgr) fireMonthEvent() {
for _, s := range this.sinkers[ClockEventMonth] {
s.OnMonthTimer()
}
}
func (this *ClockMgr) fireShutdownEvent() {
for _, s := range this.sinkers[ClockEventShutdown] {
s.OnShutdown()
}
}
func (this *ClockMgr) GetLast() (int, int, int, int, int, int) {
return this.LastSec, this.LastMini, this.LastHour, this.LastDay, this.LastWeek, int(this.LastMonth)
}
type ClockFunc struct {
event int
OnSecTimerFunc func()
OnMiniTimerFunc func()
OnHourTimerFunc func()
OnDayTimerFunc func()
OnWeekTimerFunc func()
OnMonthTimerFunc func()
OnShutdownFunc func()
}
func (s *ClockFunc) InterestClockEvent() int { return s.event }
func (s *ClockFunc) OnSecTimer() {
if s.OnSecTimerFunc != nil {
s.OnSecTimerFunc()
}
}
func (s *ClockFunc) OnMiniTimer() {
if s.OnMiniTimerFunc != nil {
s.OnMiniTimerFunc()
}
}
func (s *ClockFunc) OnHourTimer() {
if s.OnHourTimerFunc != nil {
s.OnHourTimerFunc()
}
}
func (s *ClockFunc) OnDayTimer() {
if s.OnDayTimerFunc != nil {
s.OnDayTimerFunc()
}
}
func (s *ClockFunc) OnWeekTimer() {
if s.OnWeekTimerFunc != nil {
s.OnWeekTimerFunc()
}
}
func (s *ClockFunc) OnMonthTimer() {
if s.OnMonthTimerFunc != nil {
s.OnMonthTimerFunc()
}
}
func (s *ClockFunc) OnShutdown() {
if s.OnShutdownFunc != nil {
s.OnShutdownFunc()
}
}
// RegisterClockFunc 注册时钟事件
func RegisterClockFunc(fs *ClockFunc) {
if fs == nil {
return
}
if fs.OnSecTimerFunc != nil {
fs.event = fs.event | ClockEventSecond
}
if fs.OnMiniTimerFunc != nil {
fs.event = fs.event | ClockEventMinute
}
if fs.OnHourTimerFunc != nil {
fs.event = fs.event | ClockEventHour
}
if fs.OnDayTimerFunc != nil {
fs.event = fs.event | ClockEventDay
}
if fs.OnWeekTimerFunc != nil {
fs.event = fs.event | ClockEventWeek
}
if fs.OnMonthTimerFunc != nil {
fs.event = fs.event | ClockEventMonth
}
if fs.OnShutdownFunc != nil {
fs.event = fs.event | ClockEventShutdown
}
ClockMgrSingleton.RegisterSinker(fs)
}