From 5d032e68ebb7a889de8c548d9d03fa4a6ad2e5f9 Mon Sep 17 00:00:00 2001
From: Jeff Carr <jcarr@wit.com>
Date: Fri, 7 Apr 2023 21:22:51 -0500
Subject: [PATCH] start work on a plugin channel

Signed-off-by: Jeff Carr <jcarr@wit.com>
---
 README-goreadme.md      | 14 +++++++-------
 main.go                 | 28 +++++++++++++++-------------
 plugin.go               | 32 ++++++++++++++++++++++++--------
 structs.go              |  1 +
 toolkit/andlabs/main.go |  2 +-
 5 files changed, 48 insertions(+), 29 deletions(-)

diff --git a/README-goreadme.md b/README-goreadme.md
index 156c030..e83340f 100644
--- a/README-goreadme.md
+++ b/README-goreadme.md
@@ -127,20 +127,20 @@ Creates a window helpful for debugging this package
 
 `func Indent(b bool, a ...interface{})`
 
-### func [InitPlugins](/main.go#L61)
+### func [InitPlugins](/main.go#L64)
 
 `func InitPlugins(names []string) []string`
 
 TODO: add logic to just load the 1st 'most common' gui toolkit
 and allow the 'go-arg' command line args to override the defaults
 
-### func [LoadToolkit](/plugin.go#L50)
+### func [LoadToolkit](/plugin.go#L66)
 
 `func LoadToolkit(name string) *aplug`
 
 loads and initializes a toolkit (andlabs/ui, gocui, etc)
 
-### func [Main](/main.go#L194)
+### func [Main](/main.go#L197)
 
 `func Main(f func())`
 
@@ -162,7 +162,7 @@ This should not pass a function
 
 `func ShowDebugValues()`
 
-### func [StandardExit](/main.go#L262)
+### func [StandardExit](/main.go#L264)
 
 `func StandardExit()`
 
@@ -196,7 +196,7 @@ This struct can be used with the go-arg package
 var Config GuiConfig
 ```
 
-### type [Node](/structs.go#L60)
+### type [Node](/structs.go#L61)
 
 `type Node struct { ... }`
 
@@ -251,11 +251,11 @@ func main() {
 You get a window
 ```
 
-#### func [Start](/main.go#L97)
+#### func [Start](/main.go#L100)
 
 `func Start() *Node`
 
-#### func [StartS](/main.go#L178)
+#### func [StartS](/main.go#L181)
 
 `func StartS(name string) *Node`
 
diff --git a/main.go b/main.go
index e489e25..65c184a 100644
--- a/main.go
+++ b/main.go
@@ -38,6 +38,9 @@ func init() {
 	// used to pass debugging flags to the toolkit plugins
 	Config.flag = Config.rootNode.New("flag", 0, nil)
 	Config.flag.WidgetType = toolkit.Flag
+
+	Config.guiChan = make(chan toolkit.Action)
+	go watchCallback()
 }
 
 func doGuiChan() {
@@ -200,26 +203,25 @@ func Main(f func()) {
 	if (os.Getenv("DISPLAY") == "") {
 		InitPlugins([]string{"gocui"})
 	} else {
-		InitPlugins([]string{"andlabs", "gocui"})
-	}
-
-	if (Config.guiChan == nil) {
-		Config.guiChan = make(chan toolkit.Action)
-		go watchCallback()
+		InitPlugins([]string{"gocui", "andlabs"})
 	}
 
 	for _, aplug := range allPlugins {
-		log(debugGui, "gui.Node.NewButton() toolkit plugin =", aplug.name)
+		log(debugGui, "NewButton() toolkit plugin =", aplug.name)
 		if (aplug.MainOk) {
-			log(debugGui, "gui.Node.Main() Already Ran Main()", aplug.name)
+			log(debugGui, "Main() Already Ran Main()", aplug.name)
 			continue
 		}
 		if (aplug.Main == nil) {
-			log(debugGui, "gui.Node.Main() Main == nil", aplug.name)
+			log(debugGui, "Main() Main == nil", aplug.name)
 			continue
 		}
 		aplug.MainOk = true
-		if (aplug.Callback != nil) {
+		if (aplug.Callback == nil) {
+			// TODO: don't load the module if this failed
+			// if Callback() isn't set in the plugin, no information can be sent to it!
+			log(debugError, "SERIOUS ERROR: Callback() == nil. nothing will work for plugin", aplug.name)
+		} else {
 			aplug.Callback(Config.guiChan)
 		}
 		aplug.Main(f)
@@ -242,7 +244,7 @@ func Queue(f func()) {
 	log(debugGui, "Sending function to gui.Main() (using gtk via andlabs/ui)")
 	// toolkit.Queue(f)
 	for _, aplug := range allPlugins {
-		log(debugGui, "gui.Node.NewButton() toolkit plugin =", aplug.name)
+		log(debugGui, "NewButton() toolkit plugin =", aplug.name)
 		if (aplug.Queue == nil) {
 			continue
 		}
@@ -261,9 +263,9 @@ func (n *Node) StandardClose() {
 // TODO: properly exit the plugin since Quit() doesn't do it
 func StandardExit() {
 	log("wit/gui Standard Window Exit. running os.Exit()")
-	log("gui.Node.StandardExit() attempt to exit each toolkit plugin")
+	log("StandardExit() attempt to exit each toolkit plugin")
 	for i, aplug := range allPlugins {
-		log("gui.Node.NewButton()", i, aplug)
+		log("NewButton()", i, aplug)
 		if (aplug.Quit != nil) {
 			aplug.Quit()
 		}
diff --git a/plugin.go b/plugin.go
index 051f9c7..ada310d 100644
--- a/plugin.go
+++ b/plugin.go
@@ -26,20 +26,36 @@ type aplug struct {
 	MainOk bool
 
 	Init func()
+
+	// This passes the go channel to the plugin
+	// the plugin then passes actions back to
+	// here where they are processed. If you wit/gui this is how
+	// you are passed information like a user clicking a button
+	// or a user changing a dropdown menu or a checkbox
+	//
+	// from this channel, the information is then passed into your
+	// Custom() function
+	//
+	// the custom functions are run from inside of your own goroutine
+	// where you initialize the gui
+	Callback func(chan toolkit.Action)
+
+	// This is how actions are sent to the plugin
+	//
+	// for example, when you you create a new button, it sends
+	// a structure to the goroutine that is handling the gui
+	// each toolkit has it's own goroutine and each one is sent this
+	// add button request
+	pluginChan 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
-	// Queue func(func ())	// Should this return right away? Should it wait (can it wait?)
 	Quit func()
-	// NewWindow func(*toolkit.Widget)
-
-	// sets the chan for the plugin to call back too
-	Callback func(chan toolkit.Action)
-	// NewWindow func(*toolkit.Widget)
 
 	// simplifies passing to the plugin
 	// Send func(*toolkit.Widget, *toolkit.Widget)
-
 	// should replace Send()
 	Action func(*toolkit.Action)
 }
@@ -57,7 +73,7 @@ func LoadToolkit(name string) *aplug {
 	for _, aplug := range allPlugins {
 		log(debugGui, "gui.LoadToolkit() already loaded toolkit plugin =", aplug.name)
 		if (aplug.name == name) {
-			log(debugGui, "gui.LoadToolkit() SKIPPING")
+			log(debugError, "gui.LoadToolkit() SKIPPING", name, "as you can't load it twice")
 			return aplug
 		}
 	}
diff --git a/structs.go b/structs.go
index eec3ccb..b6dcaff 100644
--- a/structs.go
+++ b/structs.go
@@ -52,6 +52,7 @@ type GuiConfig struct {
 	ActionCh1 chan int
 	ActionCh2 chan int
 
+	// sets the chan for the plugins to call back too
 	guiChan chan toolkit.Action
 }
 
diff --git a/toolkit/andlabs/main.go b/toolkit/andlabs/main.go
index 137af04..bf13746 100644
--- a/toolkit/andlabs/main.go
+++ b/toolkit/andlabs/main.go
@@ -40,7 +40,7 @@ func catchActionChannel() {
 				*/
 				log(logNow, "makeCallback() STUFF END")
 			}
-			sleep(.1)
+			// sleep(.1)
 		}
 	}
 }