package gui /* This is where the communication to the toolkit plugin happens. We copy the current values from the widget node of the binary tree and send an "action" to the toolkit over a channel. TODO: use protobuf */ import ( "errors" "go.wit.com/log" "go.wit.com/widget" ) // 2024/01/11 finally moving to type any. simplify to just 'value' // 2023/05/09 pretty clean // 2023/04/06 Queue() is also being used and channels are being used. func sendAction(n *Node, atype widget.ActionType) { if n == nil { log.Error(errors.New("Sending Action on n = nil")) log.Warn("Sending Action on n = nil") return } n.mu.Lock() defer n.mu.Unlock() log.Warn("SENDING ACTION STRINGS n.Strings", n.strings) // if the widget is hidden, don't send actions to the plugin if n.hidden { if atype == widget.Hide { // well, unless this is a Hide action, then inform the toolkit log.Warn("SENDING HIDDEN ACTION. IS THIS A WINDOW?", n.GetProgName(), atype) } else { log.Warn("NOT SENDING HIDDEN ACTION", n.GetProgName(), atype) // return } } var a widget.Action a.ActionType = atype // These should be "stable" at this point (2024/01/13) a.WidgetId = n.id // set state a.State.ProgName = n.progname a.State.Label = n.label a.State.Value = n.value a.State.Direction = n.direction for s, _ := range n.strings { a.State.Strings = append(a.State.Strings, s) } log.Warn("SENDING ACTION STRINGS a.Strings", a.Strings) a.State.Range.Low = n.X a.State.Range.High = n.Y a.ProgName = n.progname a.Value = n.value a.Direction = n.direction // These should be improved/deprecated based on the gui/widget docs a.X = n.X a.Y = n.Y a.State.GridOffset.X = n.AtW a.State.GridOffset.Y = n.AtH if n.parent != nil { a.ParentId = n.parent.id } a.WidgetType = n.WidgetType sendActionToPlugin(&a) } // sends the action/event to each toolkit via a golang plugin channel func sendActionToPlugin(a *widget.Action) { for _, aplug := range allPlugins { log.Log(PLUG, "Action() aplug =", aplug.name, "Action type=", a.ActionType) if aplug.pluginChan == nil { log.Warn("Action() retrieving the aplug.PluginChannel()", aplug.name) aplug.pluginChan = aplug.PluginChannel() log.Warn("Action() retrieved", aplug.pluginChan) } log.Verbose("Action() SEND to pluginChan", aplug.name, a.ActionType, a.WidgetType, a.WidgetId, a.ProgName) aplug.pluginChan <- *a // added during debugging. might be a good idea in general for a tactile experience // start playing with this if a.ActionType == widget.Hide { // log.Sleep(.001) // this delay makes it so SetText() works on initial widget creation } else { // 2024/12/16 still leaving this as I'm not sure binary tree access is actually // safe (thread safe, correct locking, etc). I think it is. Things seem stable // sync.Mutex() locks don't appear to work somehow in a way I don't understand // it's probably due to []string use. use map[] instead log.Sleep(.000001) // this delay makes it so SetText() works on initial widget creation // log.Sleep(.002) // this delay makes it so SetText() works on initial widget creation } } }