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() }