diff --git a/README-goreadme.md b/README-goreadme.md index fe9ce18..9336c80 100644 --- a/README-goreadme.md +++ b/README-goreadme.md @@ -123,20 +123,17 @@ Creates a window helpful for debugging this package `func ExampleCatcher(f func())` +### func [FindPlugin](/plugin.go#L64) + +`func FindPlugin(name string) *aplug` + +loads and initializes a toolkit (andlabs/ui, gocui, etc) +attempts to locate the .so file + ### func [Indent](/debug.go#L120) `func Indent(b bool, a ...interface{})` -### func [LoadPlugin](/main.go#L114) - -`func LoadPlugin(name string) bool` - -### func [LoadToolkit](/plugin.go#L68) - -`func LoadToolkit(name string) *aplug` - -loads and initializes a toolkit (andlabs/ui, gocui, etc) - ### func [SetDebug](/debug.go#L28) `func SetDebug(s bool)` @@ -149,7 +146,7 @@ loads and initializes a toolkit (andlabs/ui, gocui, etc) `func ShowDebugValues()` -### func [StandardExit](/main.go#L155) +### func [StandardExit](/main.go#L153) `func StandardExit()` @@ -190,7 +187,7 @@ var Config GuiConfig The Node is a binary tree. This is how all GUI elements are stored simply the name and the size of whatever GUI element exists -#### func [New](/main.go#L132) +#### func [New](/main.go#L126) `func New() *Node` diff --git a/cmds/buttonplugin/main.go b/cmds/buttonplugin/main.go index 3eb3b17..01ce1c8 100644 --- a/cmds/buttonplugin/main.go +++ b/cmds/buttonplugin/main.go @@ -18,7 +18,7 @@ func main() { // This will turn on all debugging // gui.SetDebug(true) - myGui = gui.New() + myGui = gui.New().LoadToolkit("gocui") buttonWindow() // This is just a optional goroutine to watch that things are alive @@ -55,11 +55,11 @@ func buttonWindow() { g.NewButton("Load 'gocui'", func () { // this set the xterm and mate-terminal window title. maybe works generally? fmt.Println("\033]0;" + title + "blah \007") - gui.LoadPlugin("gocui") + myGui.LoadToolkit("gocui") }) g.NewButton("Load 'andlabs'", func () { - gui.LoadPlugin("andlabs") + myGui.LoadToolkit("andlabs") }) g.NewButton("NewButton(more)", func () { diff --git a/debugWindow.go b/debugWindow.go index 1a97e2c..d7d7961 100644 --- a/debugWindow.go +++ b/debugWindow.go @@ -90,8 +90,8 @@ func (n *Node) DebugTab(title string) *Node { } }) - g2.NewButton("load plugin 'gocui'", func () { - LoadPlugin("gocui") + g2.NewButton("load toolkit 'gocui'", func () { + Config.rootNode.LoadToolkit("gocui") }) return newN diff --git a/main.go b/main.go index 9776401..68c14be 100644 --- a/main.go +++ b/main.go @@ -40,7 +40,7 @@ func init() { Config.flag = Config.rootNode.newNode("flag", 0, nil) Config.flag.WidgetType = toolkit.Flag - Config.guiChan = make(chan toolkit.Action) + Config.guiChan = make(chan toolkit.Action, 1) go watchCallback() } @@ -111,18 +111,12 @@ func (n *Node) doUserEvent(a toolkit.Action) { } } -func LoadPlugin(name string) bool { +func (n *Node) LoadToolkit(name string) *Node { log(logInfo, "Start() Main(f) for name =", name) - newPlugin := LoadToolkit(name) - if (newPlugin == nil) { - return false + if (FindPlugin(name) == nil) { + return n } - - sleep(1) // temp hack until chan communication is setup - - // TODO: find a new way to do this that is locking, safe and accurate - Config.rootNode.redraw(newPlugin) - return true + return n } // There should only be one of these per application @@ -130,18 +124,22 @@ func LoadPlugin(name string) bool { // some toolkit's on some operating systems don't support more than one // Keep things simple. Do the default expected thing whenever possible func New() *Node { - if (LoadPlugin("gocui")) { + return Config.rootNode +} + +func (n *Node) Default() *Node { + if (FindPlugin("gocui") == nil) { log(logError, "New() failed to load gocui") } // if DISPLAY isn't set, return since gtk can't load // TODO: figure out how to check what to do in macos and mswindows if (os.Getenv("DISPLAY") == "") { - return Config.rootNode + return n } - if (LoadPlugin("andlabs")) { + if (FindPlugin("andlabs") == nil) { log(logError, "New() failed to load andlabs") } - return Config.rootNode + return n } // The window is destroyed but the application does not quit @@ -157,9 +155,6 @@ func StandardExit() { log("StandardExit() attempt to exit each toolkit plugin") for i, aplug := range allPlugins { log("NewButton()", i, aplug) - if (aplug.Quit != nil) { - aplug.Quit() - } } exit(0) } diff --git a/plugin.go b/plugin.go index df661a1..de8dd76 100644 --- a/plugin.go +++ b/plugin.go @@ -21,10 +21,11 @@ type aplug struct { filename string plug *plugin.Plugin sym *plugin.Symbol - LoadOk bool + // LoadOk bool InitOk bool - MainOk bool + // MainOk bool + // startup whatever might need to be setup in the plugin Init func() // This passes the go channel to the plugin @@ -47,35 +48,30 @@ type aplug struct { // each toolkit has it's own goroutine and each one is sent this // add button request pluginChan chan toolkit.Action - PluginChannel func() chan toolkit.Action // deprecate all this // TODO: make Main() main() and never allow the user to call it // run plugin.Main() when the plugin is loaded - Main func(func ()) // this never returns. Each plugin must have it's own goroutine - Quit func() - - // simplifies passing to the plugin - // Send func(*toolkit.Widget, *toolkit.Widget) - // should replace Send() - // Action func(*toolkit.Action) + // Main func(func ()) // this never returns. Each plugin must have it's own goroutine + // Quit func() } var allPlugins []*aplug // loads and initializes a toolkit (andlabs/ui, gocui, etc) -func LoadToolkit(name string) *aplug { +// attempts to locate the .so file +func FindPlugin(name string) *aplug { var newPlug *aplug newPlug = new(aplug) - log(logInfo, "LoadToolkit() START") - newPlug.LoadOk = false + log(logInfo, "FindPlugin() START") + newPlug.InitOk = false for _, aplug := range allPlugins { - log(debugGui, "LoadToolkit() already loaded toolkit plugin =", aplug.name) + log(debugGui, "FindPlugin() already loaded toolkit plugin =", aplug.name) if (aplug.name == name) { - log(debugError, "LoadToolkit() SKIPPING", name, "as you can't load it twice") + log(debugError, "FindPlugin() SKIPPING", name, "as you can't load it twice") return aplug } } @@ -94,13 +90,13 @@ func LoadToolkit(name string) *aplug { newPlug.Init = loadFuncE(newPlug, "Init") // should make a goroutine that never exits - newPlug.Main = loadFuncF(newPlug, "Main") + // newPlug.Main = loadFuncF(newPlug, "Main") // should send things to the goroutine above // newPlug.Queue = loadFuncF(&newPlug, "Queue") // unload the plugin and restore state - newPlug.Quit = loadFuncE(newPlug, "Quit") + // newPlug.Quit = loadFuncE(newPlug, "Quit") // Sends instructions like "Add", "Delete", "Disable", etc // Sends a widget (button, checkbox, etc) and it's parent widget @@ -116,14 +112,20 @@ func LoadToolkit(name string) *aplug { allPlugins = append(allPlugins, newPlug) - log(debugPlugin, "LoadToolkit() END", newPlug.name, filename) + log(debugPlugin, "FindPlugin() END", newPlug.name, filename) newPlug.Init() // set the communication to the plugins newPlug.pluginChan = newPlug.PluginChannel() newPlug.Callback(Config.guiChan) - newPlug.LoadOk = true + newPlug.InitOk = true + + sleep(1) // temp hack until chan communication is setup + + // TODO: find a new way to do this that is locking, safe and accurate + Config.rootNode.redraw(newPlug) + return newPlug } diff --git a/toolkit/andlabs/add.go b/toolkit/andlabs/add.go index 2f35e99..6d4c7cd 100644 --- a/toolkit/andlabs/add.go +++ b/toolkit/andlabs/add.go @@ -15,21 +15,21 @@ func actionDump(b bool, a *toolkit.Action) { log(b, "actionDump() ParentId =", a.ParentId) } -func add(a *toolkit.Action) { +func add(a toolkit.Action) { if (andlabs[a.WidgetId] != nil) { log(debugError, "add() error. can't make a widget that already exists. id =", a.WidgetId) - actionDump(debugError, a) + actionDump(debugError, &a) return } if (a.WidgetId == 0) { log(debugError, "add() error. w.WidgetId == 0") - actionDump(debugError, a) + actionDump(debugError, &a) return } // for now, window gets handled without checking where == nil) if (a.WidgetType == toolkit.Window) { - newWindow(*a) + newWindow(a) return } @@ -44,49 +44,49 @@ func add(a *toolkit.Action) { switch a.WidgetType { case toolkit.Window: - newWindow(*a) + newWindow(a) return case toolkit.Tab: log(debugError, "add() CAME AT THIS FROM add() =", a.Name) log(debugError, "add() CAME AT THIS FROM add() =", a.Name) log(debugError, "add() CAME AT THIS FROM add() =", a.Name) - newTab(*a) + newTab(a) return case toolkit.Label: - newLabel(a) + newLabel(&a) return case toolkit.Button: - newButton(a) + newButton(&a) return case toolkit.Grid: - newGrid(a) + newGrid(&a) return case toolkit.Checkbox: - newCheckbox(a) + newCheckbox(&a) return case toolkit.Spinner: - newSpinner(a) + newSpinner(&a) return case toolkit.Slider: - newSlider(a) + newSlider(&a) return case toolkit.Dropdown: - newDropdown(a) + newDropdown(&a) return case toolkit.Combobox: - newCombobox(a) + newCombobox(&a) return case toolkit.Textbox: - newTextbox(a) + newTextbox(&a) return case toolkit.Group: - newGroup(a) + newGroup(&a) return case toolkit.Box: - newBox(a) + newBox(&a) return case toolkit.Image: - newImage(a) + newImage(&a) return default: log(debugError, "add() error TODO: ", a.WidgetType, a.Name) @@ -122,13 +122,14 @@ func place(a *toolkit.Action, t *andlabsT, newt *andlabsT) bool { // add the structure to the array if (andlabs[a.WidgetId] == nil) { - log(logInfo, "newTab() MAPPED", a.WidgetId, a.ParentId) + log(logInfo, "place() MAPPED", a.WidgetId, a.ParentId) andlabs[a.WidgetId] = newt newt.WidgetType = a.WidgetType } else { - log(debugError, "newTab() DO WHAT?", a.WidgetId, a.ParentId) - log(debugError, "THIS IS BAD") + log(debugError, "place() DO WHAT?", a.WidgetId, a.ParentId) + log(debugError, "place() THIS IS BAD") } + log(logInfo, "place() DONE MAPPED", a.WidgetId, a.ParentId) if (newt.uiControl == nil) { log(debugError, "place() ERROR uiControl == nil", a.ParentId) @@ -141,12 +142,13 @@ func place(a *toolkit.Action, t *andlabsT, newt *andlabsT) bool { return false } + log(logInfo, "place() switch", where.WidgetType) switch where.WidgetType { case toolkit.Grid: - log(debugGrid, "add() Grid try at Parent X,Y =", a.X, a.Y) + log(debugGrid, "place() Grid try at Parent X,Y =", a.X, a.Y) newt.gridX = a.X newt.gridY = a.Y - log(debugGrid, "add() Grid try at gridX,gridY", newt.gridX, newt.gridY) + log(debugGrid, "place() Grid try at gridX,gridY", newt.gridX, newt.gridY) // at the very end, subtract 1 from X & Y since andlabs/ui starts counting at zero t.uiGrid.Append(newt.uiControl, newt.gridY - 1, newt.gridX - 1, 1, 1, @@ -155,7 +157,7 @@ func place(a *toolkit.Action, t *andlabsT, newt *andlabsT) bool { case toolkit.Group: if (t.uiBox == nil) { t.uiGroup.SetChild(newt.uiControl) - log(debugGrid, "add() hack Group to use this as the box?", a.Name, a.WidgetType) + log(debugGrid, "place() hack Group to use this as the box?", a.Name, a.WidgetType) t.uiBox = newt.uiBox } else { t.uiBox.Append(newt.uiControl, stretchy) @@ -166,6 +168,8 @@ func place(a *toolkit.Action, t *andlabsT, newt *andlabsT) bool { t.boxC += 1 return true case toolkit.Box: + log(logInfo, "place() uiBox =", t.uiBox) + log(logInfo, "place() uiControl =", newt.uiControl) t.uiBox.Append(newt.uiControl, stretchy) t.boxC += 1 return true @@ -173,7 +177,7 @@ func place(a *toolkit.Action, t *andlabsT, newt *andlabsT) bool { t.uiWindow.SetChild(newt.uiControl) return true default: - log(debugError, "add() how?", a.ParentId) + log(debugError, "place() how?", a.ParentId) } return false } diff --git a/toolkit/andlabs/button.go b/toolkit/andlabs/button.go index bc58da2..f4032d0 100644 --- a/toolkit/andlabs/button.go +++ b/toolkit/andlabs/button.go @@ -24,7 +24,6 @@ func newButton(a *toolkit.Action) { newt.uiButton = b newt.uiControl = b newt.wId = a.WidgetId - // newt.tw = a.Widget newt.WidgetType = a.WidgetType newt.parent = t diff --git a/toolkit/andlabs/main.go b/toolkit/andlabs/main.go index e6befd2..5a99421 100644 --- a/toolkit/andlabs/main.go +++ b/toolkit/andlabs/main.go @@ -1,6 +1,7 @@ package main import ( + "sync" "embed" "git.wit.org/wit/gui/toolkit" @@ -16,14 +17,20 @@ var res embed.FS var pluginChan chan toolkit.Action var uiMainUndef bool = true +var uiMain sync.Once +var muAction sync.Mutex func catchActionChannel() { log(logNow, "catchActionChannel() START") for { log(logNow, "catchActionChannel() for loop") + uiMain.Do(func() { + go ui.Main(demoUI) + }) select { case a := <-pluginChan: log(logNow, "catchActionChannel() SELECT widget id =", a.WidgetId, a.Name) + /* // go Action(a) if (uiMainUndef) { log(logError,"catchActionChannel() main() was not run yet") @@ -34,7 +41,7 @@ func catchActionChannel() { log(logError,"catchActionChannel() ui.Main() START") log(logError,"catchActionChannel() ui.Main() START") sleep(1) - go ui.Main(demoUI) + // go ui.Main(demoUI) // go ui.Main( func() { // rawAction(a) // }) @@ -46,6 +53,12 @@ func catchActionChannel() { rawAction(a) log(logNow, "catchActionChannel() STUFF END", a.WidgetId, a.ActionType, a.WidgetType) } + */ + log(logNow, "catchActionChannel() STUFF", a.WidgetId, a.ActionType, a.WidgetType) + muAction.Lock() + rawAction(a) + muAction.Unlock() + log(logNow, "catchActionChannel() STUFF END", a.WidgetId, a.ActionType, a.WidgetType) } } } @@ -90,7 +103,7 @@ func Init() { setDefaultBehavior(true) andlabs = make(map[int]*andlabsT) - pluginChan = make(chan toolkit.Action) + pluginChan = make(chan toolkit.Action, 1) log(logNow, "Init() start channel reciever") go catchActionChannel() diff --git a/toolkit/andlabs/plugin.go b/toolkit/andlabs/plugin.go index f319add..15e9396 100644 --- a/toolkit/andlabs/plugin.go +++ b/toolkit/andlabs/plugin.go @@ -55,7 +55,7 @@ func rawAction(a toolkit.Action) { switch a.ActionType { case toolkit.Add: - add(&a) + add(a) case toolkit.Show: a.B = true show(&a) diff --git a/toolkit/andlabs/structs.go b/toolkit/andlabs/structs.go index 0216407..60047ef 100644 --- a/toolkit/andlabs/structs.go +++ b/toolkit/andlabs/structs.go @@ -22,6 +22,7 @@ type andlabsT struct { // tw *toolkit.Widget parent *andlabsT + a toolkit.Action uiControl ui.Control diff --git a/toolkit/widget.go b/toolkit/widget.go index f0fba0f..769bf09 100644 --- a/toolkit/widget.go +++ b/toolkit/widget.go @@ -127,6 +127,7 @@ const ( Append Move Dump + Quit ) func (s WidgetType) String() string { diff --git a/watchdog.go b/watchdog.go index af59439..5d18dcb 100644 --- a/watchdog.go +++ b/watchdog.go @@ -24,10 +24,10 @@ func Watchdog() { } } if (i == 2) { - LoadPlugin("gocui") + Config.rootNode.LoadToolkit("gocui") } // if (i == 3) { -// LoadPlugin("andlabs") +// Config.rootNode.LoadToolkit("andlabs") // } i += 1 time.Sleep(watchtime * time.Second / 10)