game_sync/common/clock.go

188 lines
3.8 KiB
Go

package common
import (
"time"
"mongo.games.com/goserver/core/module"
)
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()
min := tNow.Minute()
if min != this.LastMini {
this.LastMini = min
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)
}
func init() {
module.RegisteModule(ClockMgrSingleton, time.Millisecond*500, 0)
}