aboutsummaryrefslogtreecommitdiff
path: root/internal/engine/tick.go
diff options
context:
space:
mode:
authorhistoria <[not public]>2026-06-09 05:59:20 -0400
committerhistoria <[not public]>2026-06-09 05:59:20 -0400
commit9eb5ab1818b6b19501fd7209db1987c9e06cc919 (patch)
tree76e046b0bf611dfe939a8c8f6507467de2e9e20f /internal/engine/tick.go
downloadthehouseoficarus-9eb5ab1818b6b19501fd7209db1987c9e06cc919.tar.gz
first commit
Diffstat (limited to 'internal/engine/tick.go')
-rw-r--r--internal/engine/tick.go105
1 files changed, 105 insertions, 0 deletions
diff --git a/internal/engine/tick.go b/internal/engine/tick.go
new file mode 100644
index 0000000..d6d470a
--- /dev/null
+++ b/internal/engine/tick.go
@@ -0,0 +1,105 @@
+package engine
+
+import (
+ "sync"
+ "time"
+)
+
+const TickDuration = 600 * time.Millisecond
+
+type Callback func() bool
+
+type subscriber struct {
+ id uint64
+ interval int
+ callback Callback
+ ticks int
+}
+
+type Engine struct {
+ mu sync.Mutex
+ subscribers map[uint64]*subscriber
+ nextID uint64
+ ticker *time.Ticker
+ running bool
+ stopCh chan struct{}
+}
+
+func New() *Engine {
+ return &Engine{
+ subscribers: make(map[uint64]*subscriber),
+ }
+}
+
+func (e *Engine) Subscribe(interval int, cb Callback) uint64 {
+ e.mu.Lock()
+ defer e.mu.Unlock()
+ e.nextID++
+ e.subscribers[e.nextID] = &subscriber{
+ id: e.nextID,
+ interval: interval,
+ callback: cb,
+ }
+ return e.nextID
+}
+
+func (e *Engine) Unsubscribe(id uint64) {
+ e.mu.Lock()
+ defer e.mu.Unlock()
+ delete(e.subscribers, id)
+}
+
+func (e *Engine) Start() {
+ e.mu.Lock()
+ defer e.mu.Unlock()
+ if e.running {
+ return
+ }
+ e.running = true
+ e.ticker = time.NewTicker(TickDuration)
+ e.stopCh = make(chan struct{})
+
+ go func() {
+ for {
+ select {
+ case <-e.ticker.C:
+ e.processTick()
+ case <-e.stopCh:
+ return
+ }
+ }
+ }()
+}
+
+func (e *Engine) Stop() {
+ e.mu.Lock()
+ defer e.mu.Unlock()
+ if e.ticker != nil {
+ e.ticker.Stop()
+ }
+ e.running = false
+ if e.stopCh != nil {
+ close(e.stopCh)
+ }
+}
+
+func (e *Engine) processTick() {
+ e.mu.Lock()
+ snapshot := make(map[uint64]*subscriber, len(e.subscribers))
+ for id, sub := range e.subscribers {
+ snapshot[id] = sub
+ }
+ e.mu.Unlock()
+
+ for id, sub := range snapshot {
+ sub.ticks++
+ if sub.ticks >= sub.interval {
+ sub.ticks = 0
+ if !sub.callback() {
+ e.mu.Lock()
+ delete(e.subscribers, id)
+ e.mu.Unlock()
+ }
+ }
+ }
+}