- View — интерфейс Fyne-слоя: колбэки на все доменные события + логи. - Controller подписывается на доменную и логовую шины (через events.Hub) и диспатчит события в View; колбэки выполняются в горутинах Hub, поэтому реализация Fyne обязана обновлять виджеты через fyne.Do (спец 12.4). - Close отписывает контроллер (сворачивание окна) без остановки Core. - NilView — no-op для headless (--noui) и тестов. - Юнит-тесты: доставка доменных/логовых событий, остановка после Close.
52 lines
2.2 KiB
Go
52 lines
2.2 KiB
Go
package ui
|
||
|
||
import (
|
||
"github.com/kamelion/ratatoskr-go/internal/events"
|
||
)
|
||
|
||
// Controller — подписчик шин событий, мост к Fyne-представлению.
|
||
//
|
||
// Регистрирует Hub'ы на доменной и логовой шинах и диспатчит события в View
|
||
// (см. спец 12.4): колбэки View выполняются в горутинах Hub, поэтому
|
||
// реализация Fyne должна вызывать fyne.Do, чтобы обновить виджеты на главной
|
||
// горутине окна.
|
||
//
|
||
// Жизненный цикл независим от ядра: Close только отписывает Controller от шин
|
||
// (например, при сворачивании окна), но Core/worker продолжают работать.
|
||
type Controller struct {
|
||
domain *events.Hub
|
||
logs *events.Hub
|
||
view View
|
||
}
|
||
|
||
// New создаёт Controller, подписанный на доменную (domainBus) и логовую
|
||
// (logBus) шины, с представлением view.
|
||
func New(domainBus *events.Bus, logBus *events.LogBus, view View) *Controller {
|
||
c := &Controller{view: view}
|
||
|
||
c.domain = events.NewHub(domainBus)
|
||
events.On(c.domain, func(e events.TaskCreated) { view.OnTaskCreated(e) })
|
||
events.On(c.domain, func(e events.TaskUpdated) { view.OnTaskUpdated(e) })
|
||
events.On(c.domain, func(e events.TaskDeleted) { view.OnTaskDeleted(e) })
|
||
events.On(c.domain, func(e events.TaskStatusChanged) { view.OnTaskStatusChanged(e) })
|
||
events.On(c.domain, func(e events.HistoryAppended) { view.OnHistoryAppended(e) })
|
||
events.On(c.domain, func(e events.TraceAppended) { view.OnTraceAppended(e) })
|
||
events.On(c.domain, func(e events.AgentActivity) { view.OnAgentActivity(e) })
|
||
|
||
c.logs = events.NewHub(logBus.Bus)
|
||
events.On(c.logs, func(e events.LogLine) { view.OnLog(e) })
|
||
|
||
return c
|
||
}
|
||
|
||
// Start запускает подписку на обе шины.
|
||
func (c *Controller) Start() {
|
||
c.domain.Start()
|
||
c.logs.Start()
|
||
}
|
||
|
||
// Close останавливает подписки. Идемпотентен.
|
||
func (c *Controller) Close() {
|
||
c.domain.Close()
|
||
c.logs.Close()
|
||
} |