From 15100aad3ee4294fc22bbeb697e6c6b88228a0ca Mon Sep 17 00:00:00 2001 From: Jeff Carr Date: Wed, 5 Mar 2025 03:00:21 -0600 Subject: [PATCH] func shouldn't have been global --- action.go | 2 +- addNode.go | 21 +++++++++++-------- find.go | 59 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ plugin.go | 24 ---------------------- structs.go | 45 ++++++++++++++++++++--------------------- table.go | 4 ++-- 6 files changed, 97 insertions(+), 58 deletions(-) create mode 100644 find.go diff --git a/action.go b/action.go index f2ef7e3..c64dd49 100644 --- a/action.go +++ b/action.go @@ -15,7 +15,7 @@ func (me *TreeInfo) doAction(a widget.Action) { if a.ActionType == widget.ToolkitInit { log.Log(TREEWARN, "tree.doAction() trapped ToolkitInit finally!") a.WidgetType = widget.Root - n := AddNode(&a) + n := addNode(&a) me.Add(n) log.Log(TREEWARN, "tree.doAction() init() me.treeRoot") if me.ToolkitInit != nil { diff --git a/addNode.go b/addNode.go index 544792f..2f7ccea 100644 --- a/addNode.go +++ b/addNode.go @@ -11,10 +11,10 @@ func (me *TreeInfo) AddNode(a *widget.Action) *Node { } else { log.Info("TREE: mutex lock was already held before AddNode()") } - return AddNode(a) + return addNode(a) } -func AddNode(a *widget.Action) *Node { +func addNode(a *widget.Action) *Node { n := new(Node) n.WidgetType = a.WidgetType n.WidgetId = a.WidgetId @@ -60,18 +60,23 @@ func AddNode(a *widget.Action) *Node { } func (me *TreeInfo) DeleteNode(n *Node) { - me.Lock() - defer me.Unlock() + log.Log(TREEWARN, "DeleteNode() before lock n =", n.WidgetId, n.GetProgName()) + if me.TryLock() { + defer me.Unlock() + } else { + log.Info("TREE: mutex lock was already held before DeleteNode()") + } p := n.Parent + log.Log(TREEWARN, "DeleteNode() parent =", p.WidgetId, p.GetProgName()) for i, child := range p.children { - log.Log(TREE, "parent has child:", i, child.WidgetId, child.GetProgName()) + log.Log(TREEWARN, "parent has child:", i, child.WidgetId, child.GetProgName()) if n == child { - log.Log(TREE, "Found child ==", i, child.WidgetId, child.GetProgName()) - log.Log(TREE, "Found n ==", i, n.WidgetId, n.GetProgName()) + log.Log(TREEWARN, "Found child ==", i, child.WidgetId, child.GetProgName()) + log.Log(TREEWARN, "Found n ==", i, n.WidgetId, n.GetProgName()) p.children = append(p.children[:i], p.children[i+1:]...) } } for i, child := range p.children { - log.Log(TREE, "parent now has child:", i, child.WidgetId, child.GetProgName()) + log.Log(TREEWARN, "parent now has child:", i, child.WidgetId, child.GetProgName()) } } diff --git a/find.go b/find.go new file mode 100644 index 0000000..6b22ad3 --- /dev/null +++ b/find.go @@ -0,0 +1,59 @@ +package tree + +import "log" + +// find things in the tree +// also verify parent <-> child mappings aren't a lie + +// searches the binary tree for a WidgetId +func FindWidgetId(id int) *Node { + return treeRoot.FindWidgetId(id) +} + +// searches the binary tree for a WidgetId +func (n *Node) FindWidgetId(id int) *Node { + if n == nil { + return nil + } + + if n.WidgetId == id { + return n + } + + for _, child := range n.children { + newN := child.FindWidgetId(id) + if newN != nil { + return newN + } + } + return nil +} + +// used for debugging the 'gui' package +// to make sure things are valid +// fixes any errors along the way +func (me *Node) VerifyParentId() bool { + return me.verifyParentId(0) +} + +func (n *Node) verifyParentId(parentId int) bool { + if n == nil { + return false + } + var ok bool = true + + if n.ParentId != parentId { + log.Printf("fixed widgetId %d from %d to %d", n.WidgetId, n.ParentId, parentId) + n.ParentId = parentId + ok = false + } + + for _, child := range n.children { + if child.verifyParentId(n.WidgetId) { + // everything is ok + } else { + ok = false + } + } + return ok +} diff --git a/plugin.go b/plugin.go index 3df0607..3b1d741 100644 --- a/plugin.go +++ b/plugin.go @@ -16,30 +16,6 @@ import ( "go.wit.com/widget" ) -// searches the binary tree for a WidgetId -func FindWidgetId(id int) *Node { - return treeRoot.FindWidgetId(id) -} - -// searches the binary tree for a WidgetId -func (n *Node) FindWidgetId(id int) *Node { - if n == nil { - return nil - } - - if n.WidgetId == id { - return n - } - - for _, child := range n.children { - newN := child.FindWidgetId(id) - if newN != nil { - return newN - } - } - return nil -} - func (me *TreeInfo) InitOK() { me.ok = true } diff --git a/structs.go b/structs.go index 8e3bc19..708780c 100644 --- a/structs.go +++ b/structs.go @@ -20,29 +20,28 @@ import ( var treeRoot *Node type TreeInfo struct { - sync.Mutex // a lock around the tree to serialize access - ok bool // indicates the plugin actually initialized - PluginName string // used to identify the plugin - config *ToolkitConfigs // protobuf of plugin settings - callback chan widget.Action // mouse clicks or keyboard events back to the program - pluginChan chan widget.Action // this is the channel we get requests to make widgets - frozenChan chan widget.Action // expirement to get fyne to work - Add func(*Node) // add a new widget - AddText func(*Node, string) // add a string to a dropdown widget - SetText func(*Node, string) // set the text of a widget - SetTitle func(*Node, string) // update the title of a window or tab - SetLabel func(*Node, string) // update the "label" (aka "Name") for a widget - SetChecked func(*Node, bool) // set the state of a checkbox - ToolkitInit func() // init the plugin - ToolkitClose func() // shutdown and unload the plugin - Show func(*Node) // show a widget - Hide func(*Node) // hide a widget - Enable func(*Node) // enable a widget - Disable func(*Node) // disable a widget - ShowTable func(*guipb.Table) // attempt at sending a whole table - // NodeI interface{} // is an interface useful here? - // NodeAction func(*Node, widget.ActionType) // deprecate - currentTables []*guipb.Table + sync.Mutex // a lock around the tree to serialize access + ok bool // indicates the plugin actually initialized + PluginName string // used to identify the plugin + config *ToolkitConfigs // protobuf of plugin settings + callback chan widget.Action // mouse clicks or keyboard events back to the program + pluginChan chan widget.Action // this is the channel we get requests to make widgets + frozenChan chan widget.Action // expirement to get fyne to work + Add func(*Node) // add a new widget + AddText func(*Node, string) // add a string to a dropdown widget + SetText func(*Node, string) // set the text of a widget + SetTitle func(*Node, string) // update the title of a window or tab + SetLabel func(*Node, string) // update the "label" (aka "Name") for a widget + SetChecked func(*Node, bool) // set the state of a checkbox + ToolkitInit func() // init the plugin + ToolkitClose func() // shutdown and unload the plugin + Show func(*Node) // show a widget + Hide func(*Node) // hide a widget + Enable func(*Node) // enable a widget + Disable func(*Node) // disable a widget + ShowTable func(*guipb.Table) // attempt at sending a whole table + currentTables []*guipb.Table // track the list of tables? + Root *guipb.Tree // this is the future of this system } type Node struct { diff --git a/table.go b/table.go index 50e32f2..4b51509 100644 --- a/table.go +++ b/table.go @@ -86,7 +86,7 @@ func (grid *Node) makeGridLabel(pb *guipb.Widget, w int, h int) *Node { a.State.GridOffset.X = w a.State.GridOffset.Y = h // log.Info("makeGridLabel()", a.State) - return AddNode(a) + return addNode(a) } func (me *TreeInfo) updateTable(t *guipb.Table) { @@ -184,7 +184,7 @@ func (me *TreeInfo) makeTable(t *guipb.Table) { a.WidgetId = int(t.Grid.Id) a.ParentId = int(t.Parent.Id) a.State.Enable = true - grid = AddNode(a) + grid = addNode(a) } if grid == nil { log.Info("tree: makeTable() failed to make grid")