feat: gamemaster
This commit is contained in:
@@ -0,0 +1,59 @@
|
||||
// Package schedule wraps `pkg/cronutil` with the force-next-turn skip
|
||||
// rule used by Game Master's scheduler.
|
||||
//
|
||||
// The wrapper is pure: callers pass the current `skip_next_tick` flag
|
||||
// and the wrapper returns both the next firing time and a boolean that
|
||||
// reports whether the flag was consumed. The runtime-record store is
|
||||
// responsible for persisting the cleared flag; this package never
|
||||
// touches it.
|
||||
//
|
||||
// `gamemaster/README.md §Force-next-turn` describes the rule:
|
||||
//
|
||||
// If `skip_next_tick=true`, advance by one extra cron step and clear
|
||||
// the flag.
|
||||
package schedule
|
||||
|
||||
import (
|
||||
"time"
|
||||
|
||||
"galaxy/cronutil"
|
||||
)
|
||||
|
||||
// Schedule wraps `cronutil.Schedule` with the GM-specific
|
||||
// skip-next-tick semantics. The zero value is not usable; callers
|
||||
// obtain a Schedule from Parse.
|
||||
type Schedule struct {
|
||||
inner cronutil.Schedule
|
||||
}
|
||||
|
||||
// Parse parses expr as a five-field cron expression and returns the
|
||||
// resulting Schedule. Parse returns an error if expr is rejected by the
|
||||
// underlying cronutil parser.
|
||||
func Parse(expr string) (Schedule, error) {
|
||||
inner, err := cronutil.Parse(expr)
|
||||
if err != nil {
|
||||
return Schedule{}, err
|
||||
}
|
||||
return Schedule{inner: inner}, nil
|
||||
}
|
||||
|
||||
// Next returns the next firing time strictly after `after`, honouring
|
||||
// the skip flag.
|
||||
//
|
||||
// When `skip` is false, Next returns `cronutil.Schedule.Next(after)`
|
||||
// and reports `skipConsumed=false`.
|
||||
//
|
||||
// When `skip` is true, Next computes the cron step immediately after
|
||||
// `after`, then advances by one further cron step and returns that
|
||||
// time with `skipConsumed=true`. The caller is responsible for
|
||||
// persisting the cleared flag after observing `skipConsumed`.
|
||||
//
|
||||
// All returned times are in UTC; cronutil.Schedule already enforces
|
||||
// UTC normalisation on its inputs and outputs.
|
||||
func (s Schedule) Next(after time.Time, skip bool) (time.Time, bool) {
|
||||
first := s.inner.Next(after)
|
||||
if !skip {
|
||||
return first, false
|
||||
}
|
||||
return s.inner.Next(first), true
|
||||
}
|
||||
Reference in New Issue
Block a user