diff --git a/.vscode/launch.json b/.vscode/launch.json index a338036f..5d8277bb 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -35,6 +35,26 @@ "cwd": "${fileDirname}", "args": [] }, + { + "name": "GUI (FYNE) palette_gui.go", + "type": "go", + "request": "launch", + "mode": "auto", + "program": "${env:PALETTE_SOURCE}/cmd/palette_gui/palette_gui.go", + "env": { + "Path": "${env:Path};${workspaceFolder};c:/Users/me/Documents/github/vizicist/palette/SenselLib/x64;" }, + "args": [] + }, + { + "name": "FYNE DEMO", + "type": "go", + "request": "launch", + "mode": "auto", + "program": "${env:PALETTE_SOURCE}/cmd/fyne_demo/fyne_demo.go", + "env": { + "Path": "${env:Path};${workspaceFolder};c:/Users/me/Documents/github/vizicist/palette/SenselLib/x64;" }, + "args": [] + }, { "name": "ENGINE - palette_engine.go", "type": "go", diff --git a/cmd/palette/palette.go b/cmd/palette/palette.go index 96fdd9a3..fc6e5c9e 100644 --- a/cmd/palette/palette.go +++ b/cmd/palette/palette.go @@ -180,11 +180,11 @@ func CliCommand(args []string) (map[string]string, error) { case "test": switch arg1 { case "": - return kit.EngineRemoteApi("quadpro.test", "ntimes", "40") + return kit.EngineRemoteApi("quad.test", "ntimes", "40") case "long": - return kit.EngineRemoteApi("quadpro.test", "ntimes", "400") + return kit.EngineRemoteApi("quad.test", "ntimes", "400") case "center": - return kit.EngineRemoteApi("quadpro.test", "ntimes", "1000", "testtype","center") + return kit.EngineRemoteApi("quad.test", "ntimes", "1000", "testtype", "center") default: return nil, fmt.Errorf("unknown test type - %s", arg1) } @@ -223,63 +223,57 @@ func CliCommand(args []string) (map[string]string, error) { func StatusOutput() (statusOut string, numRunning int) { s := "" nrunning := 0 - if kit.MonitorIsRunning() { + running, err := kit.MonitorIsRunning() + if err == nil && running { s += "Monitor is running.\n" nrunning++ } - if kit.IsRunning("engine") { - s += "Engine is running.\n" - nrunning++ - } - - if kit.IsRunning("gui") { - s += "GUI is running.\n" - nrunning++ - } - - if kit.IsRunning("bidule") { - s += "Bidule is running.\n" - nrunning++ - } - - if kit.IsRunning("obs") { - s += "OBS is running.\n" - nrunning++ + type Runnable struct { + processName string + userName string } - - if kit.IsRunning("chat") { - s += "Chat monitor is running.\n" - nrunning++ + var Runnables = []Runnable{ + {"engine", "Engine"}, + {"gui", "GUI"}, + {"bidule", "Bidule"}, + {"obs", "OBS"}, + {"chat", "Chat monitor"}, + {"resolume", "Resolume"}, } - - if kit.IsRunning("resolume") { - s += "Resolume is running.\n" - nrunning++ + for _, r := range Runnables { + running, err = kit.IsRunning(r.processName) + if err == nil && running { + s += (r.userName + " is running.\n") + nrunning++ + } } /* - b, _ := kit.GetParamBool("global.keykitrun") - if b { - if kit.IsRunning("keykit") { - s += "Keykit is running.\n" - nrunning++ + b, _ := kit.GetParamBool("global.keykitrun") + if b { + if kit.IsRunning("keykit") { + s += "Keykit is running.\n" + nrunning++ + } } - } */ mmtt := os.Getenv("PALETTE_MMTT") if mmtt != "" { - if kit.IsRunning("mmtt") { + running, err := kit.IsRunning("mmtt") + if err == nil && running { s += "MMTT is running.\n" nrunning++ } } + return s, nrunning } func doStartEngine() error { - if kit.IsRunning("engine") { + running, err := kit.IsRunning("engine") + if err == nil && running { return fmt.Errorf("engine is already running") } fullexe := filepath.Join(kit.PaletteDir(), "bin", kit.EngineExe) @@ -288,7 +282,8 @@ func doStartEngine() error { } func doStartMonitor() error { - if kit.MonitorIsRunning() { + running, err := kit.MonitorIsRunning() + if err == nil && running { return fmt.Errorf("monitor is already running") } // palette_monitor.exe will restart the engine, diff --git a/cmd/palette_chat/palette_chat.go b/cmd/palette_chat/palette_chat.go index 14648605..c82c7df5 100644 --- a/cmd/palette_chat/palette_chat.go +++ b/cmd/palette_chat/palette_chat.go @@ -62,7 +62,7 @@ func StartTwitch() error { category = words[1] } kit.LogInfo("randomize message", "category", category) - vals, err := kit.EngineRemoteApi("quadpro.loadrand", "category", category) + vals, err := kit.EngineRemoteApi("quad.loadrand", "category", category) var reply string if err != nil { reply = fmt.Sprintf("err=%s", err.Error()) diff --git a/cmd/palette_gui/palette_gui.exe b/cmd/palette_gui/palette_gui.exe new file mode 100644 index 00000000..199e4b45 Binary files /dev/null and b/cmd/palette_gui/palette_gui.exe differ diff --git a/cmd/palette_gui/palette_gui.go b/cmd/palette_gui/palette_gui.go new file mode 100644 index 00000000..686fc233 --- /dev/null +++ b/cmd/palette_gui/palette_gui.go @@ -0,0 +1,32 @@ +package main + +import ( + "fyne.io/fyne/v2" // Import the base Fyne package + "fyne.io/fyne/v2/app" // Import the Fyne app package + "fyne.io/fyne/v2/container" // Import the Fyne container package for layouts + "fyne.io/fyne/v2/widget" // Import the Fyne widget package for widgets +) + +func main() { + myApp := app.New() // Create a new app + myWindow := myApp.NewWindow("Hello") // Create a new window + + myWindow.Resize(fyne.NewSize(300, 200)) // Resize the window + + // Create a label (widget) with initial text + label := widget.NewLabel("Hello, Fyne!") + + // Create a button (widget) + button := widget.NewButton("Click me!", func() { + label.SetText("Button clicked!") // Change the label text when the button is clicked + }) + + // Use a container to arrange the label and button vertically + content := container.NewVBox( + label, + button, + ) + + myWindow.SetContent(content) // Set the window content to be the container + myWindow.ShowAndRun() // Show and run the application +} diff --git a/cmd/palette_monitor/palette_monitor.go b/cmd/palette_monitor/palette_monitor.go index 63d269e8..4342a592 100644 --- a/cmd/palette_monitor/palette_monitor.go +++ b/cmd/palette_monitor/palette_monitor.go @@ -85,7 +85,8 @@ func scheduler() { func checkEngine() { tick := time.NewTicker(time.Second * 15) for { - if !kit.IsRunningExecutable(kit.EngineExe) { + running, err := kit.IsRunningExecutable(kit.EngineExe) + if err == nil && !running { kit.LogInfo("checkEngine: engine is not running, killing everything, monitor should restart engine.") kit.KillAllExceptMonitor() kit.LogInfo("checkEngine: restarting engine") diff --git a/data/config/paramenums.json b/data/config/paramenums.json index a55c579b..89bef3f6 100644 --- a/data/config/paramenums.json +++ b/data/config/paramenums.json @@ -1,6 +1,6 @@ { "resolumepath": ["C:/Program Files/Resolume Avenue/Avenue.exe", "C:/Program Files/Resolume Arena/Arena.exe"], - "plugins": [ "", "quadpro" ], + "plugins": [ "", "quad" ], "log": ["","cursor","midi","cursor,midi","cursor,midi,osc","osc","api","loop", "morph","mmtt", "quant", "transpose", "ffgl", "gesture"], "pitchset": ["","stylusrmx"], "guisize": ["small","medium","palette"], diff --git a/ffgl/source/lib/palette/LayerParams_types.h b/ffgl/source/lib/palette/LayerParams_types.h index 2ed759c0..55ce36b4 100644 --- a/ffgl/source/lib/palette/LayerParams_types.h +++ b/ffgl/source/lib/palette/LayerParams_types.h @@ -35,7 +35,7 @@ LayerParams_InitializeTypes() { LayerParams_resolumepathTypes.push_back("C:/Program Files/Resolume Arena/Arena.exe"); LayerParams_pluginsTypes.push_back(""); - LayerParams_pluginsTypes.push_back("quadpro"); + LayerParams_pluginsTypes.push_back("quad"); LayerParams_logTypes.push_back(""); LayerParams_logTypes.push_back("cursor"); diff --git a/go.mod b/go.mod index b53ebb42..1188d688 100644 --- a/go.mod +++ b/go.mod @@ -3,7 +3,7 @@ module github.com/vizicist/palette go 1.19 require ( - fyne.io/fyne/v2 v2.4.2 + fyne.io/fyne/v2 v2.4.3 github.com/0xcafed00d/joystick v1.0.1 github.com/andreykaipov/goobs v0.12.1 github.com/gempir/go-twitch-irc/v3 v3.3.0 @@ -57,7 +57,7 @@ require ( golang.org/x/exp/shiny v0.0.0-20230210204819-062eb4c674ab // indirect golang.org/x/mobile v0.0.0-20230531173138-3c911d8e3eda // indirect golang.org/x/net v0.17.0 // indirect - golang.org/x/sync v0.2.0 // indirect + golang.org/x/sync v0.3.0 // indirect golang.org/x/sys v0.15.0 // indirect golang.org/x/text v0.14.0 // indirect gopkg.in/alexcesaro/quotedprintable.v3 v3.0.0-20150716171945-2caba252f4dc // indirect diff --git a/go.sum b/go.sum index 858b2b34..0178d1fa 100644 --- a/go.sum +++ b/go.sum @@ -37,8 +37,8 @@ cloud.google.com/go/storage v1.6.0/go.mod h1:N7U0C8pVQ/+NIKOBQyamJIeKQKkZ+mxpohl cloud.google.com/go/storage v1.8.0/go.mod h1:Wv1Oy7z6Yz3DshWRJFhqM/UCfaWIRTdp0RXyy7KQOVs= cloud.google.com/go/storage v1.10.0/go.mod h1:FLPqc6j+Ki4BU591ie1oL6qBQGu2Bl/tZ9ullr3+Kg0= dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU= -fyne.io/fyne/v2 v2.4.2 h1:bt6/p/FTpcv0sZIN6msxto32JvKkgwKe/LzYxqv//B8= -fyne.io/fyne/v2 v2.4.2/go.mod h1:1h3BKxmQYRJlr2g+RGVxedzr6vLVQ/AJmFWcF9CJnoQ= +fyne.io/fyne/v2 v2.4.3 h1:v2wncjEAcwXZ8UNmTCWTGL9+sGyPc5RuzBvM96GcC78= +fyne.io/fyne/v2 v2.4.3/go.mod h1:1h3BKxmQYRJlr2g+RGVxedzr6vLVQ/AJmFWcF9CJnoQ= fyne.io/systray v1.10.1-0.20231115130155-104f5ef7839e h1:Hvs+kW2VwCzNToF3FmnIAzmivNgrclwPgoUdVSrjkP8= fyne.io/systray v1.10.1-0.20231115130155-104f5ef7839e/go.mod h1:oM2AQqGJ1AMo4nNqZFYU8xYygSBZkW2hmdJ7n4yjedE= github.com/0xcafed00d/joystick v1.0.1 h1:r4p2cRp4MHJWu1gArhGtumbkPxmr3tcOUTFqybEhplM= @@ -454,8 +454,8 @@ golang.org/x/sync v0.0.0-20200625203802-6e8e738ad208/go.mod h1:RxMgew5VJxzue5/jJ golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.2.0 h1:PUR+T4wwASmuSTYdKjYHI5TD22Wy5ogLU5qZCOLxBrI= -golang.org/x/sync v0.2.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.3.0 h1:ftCYgMx6zT/asHUrPw8BLLscYtGznsLAnjq5RH9P66E= +golang.org/x/sync v0.3.0/go.mod h1:FU7BRWz2tNW+3quACPkgCx/L+uEAv1htQ0V83Z9Rj+Y= golang.org/x/sys v0.0.0-20180823144017-11551d06cbcc/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20181026203630-95b1ffbd15a5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= diff --git a/kit/attract.go b/kit/attract.go index e89375a6..2b31b4ef 100644 --- a/kit/attract.go +++ b/kit/attract.go @@ -82,7 +82,7 @@ func (am *AttractManager) setAttractMode(onoff bool) { // am.attractMutex.Lock() am.attractModeIsOn.Store(onoff) - if TheQuadPro != nil { + if TheQuad != nil { for _, patch := range Patchs { patch.clearGraphics() patch.loopClear() @@ -161,10 +161,10 @@ func (am *AttractManager) doAttractAction() { dp := now.Sub(am.lastAttractChange).Seconds() if dp > am.attractChangeInterval { - if TheQuadPro == nil { - LogWarn("No QuadPro to change for attract mode") + if TheQuad == nil { + LogWarn("No Quad to change for attract mode") } else { - _, err := TheQuadPro.loadQuadRand("quad") + _, err := TheQuad.loadQuadRand("quad") LogIfError(err) } am.lastAttractChange = now diff --git a/kit/cursor.go b/kit/cursor.go index b12b99ca..bd325e61 100644 --- a/kit/cursor.go +++ b/kit/cursor.go @@ -91,7 +91,7 @@ func NewCursorClearEvent() CursorEvent { // An ActiveCursor can be for a Button or a Patch area. func NewActiveCursor(ce CursorEvent) *ActiveCursor { - patch, button := TheQuadPro.PatchForCursorEvent(ce) + patch, button := TheQuad.PatchForCursorEvent(ce) if patch == nil && button == "" { LogWarn("No Patch or Button for CursorEvent", "ce", ce) return nil diff --git a/kit/engine.go b/kit/engine.go index 8008d3d8..f7835a01 100644 --- a/kit/engine.go +++ b/kit/engine.go @@ -87,7 +87,7 @@ func InitEngine() { TheRouter = NewRouter() TheScheduler = NewScheduler() TheAttractManager = NewAttractManager() - TheQuadPro = NewQuadPro() + TheQuad = NewQuad() TheMidiIO = NewMidiIO() TheErae = NewErae() @@ -97,8 +97,8 @@ func InitEngine() { EngineSubscribeNats() - for name := range(ParamDefs) { - if strings.HasPrefix(name,"global.") { + for name := range ParamDefs { + if strings.HasPrefix(name, "global.") { ActivateGlobalParam(name) } } @@ -108,7 +108,7 @@ func EngineSubscribeNats() { err := TheNats.Connect() LogIfError(err) if err == nil { - subscribeTo := fmt.Sprintf("to_palette.%s.>",Hostname()) + subscribeTo := fmt.Sprintf("to_palette.%s.>", Hostname()) err = TheNats.Subscribe(subscribeTo, natsRequestHandler) LogIfError(err) } @@ -199,7 +199,7 @@ func (e *Engine) Start() { InitMidiIO() InitSynths() - TheQuadPro.Start() + TheQuad.Start() go e.StartOscListener(OscPort) go e.StartHttp(EngineHttpPort) diff --git a/kit/engineapi.go b/kit/engineapi.go index 54b1439e..0ec3ecbb 100644 --- a/kit/engineapi.go +++ b/kit/engineapi.go @@ -27,11 +27,11 @@ func ExecuteApi(api string, apiargs map[string]string) (result string, err error return ExecuteGlobalApi(apisuffix, apiargs) case "saved": return ExecuteSavedApi(apisuffix, apiargs) - case "quadpro": - if TheQuadPro != nil { - return TheQuadPro.Api(apisuffix, apiargs) + case "quad": + if TheQuad != nil { + return TheQuad.Api(apisuffix, apiargs) } - return "", fmt.Errorf("no quadpro") + return "", fmt.Errorf("no quad") case "patch": patchName := ExtractAndRemoveValueOf("patch", apiargs) if patchName == "" { @@ -91,7 +91,7 @@ func ExecuteGlobalApi(api string, apiargs map[string]string) (result string, err case "status": uptime := fmt.Sprintf("%f", Uptime()) attractmode := fmt.Sprintf("%v", TheAttractManager.AttractModeIsOn()) - if TheQuadPro == nil { + if TheQuad == nil { result = JsonObject( "uptime", uptime, "attractmode", attractmode, @@ -360,13 +360,13 @@ func ApplyGlobalParam(name string, value string) (err error) { } case "global.looping_override": - LogOfType("loop","global.looping_override needs handling") + LogOfType("loop", "global.looping_override needs handling") case "global.looping_fade": - LogOfType("loop","global.looping_fade needs handling") + LogOfType("loop", "global.looping_fade needs handling") case "global.looping_beats": - LogOfType("loop","global.looping_beats needs handling") + LogOfType("loop", "global.looping_beats needs handling") case "global.midithru": TheRouter.midithru = IsTrueValue(value) diff --git a/kit/log.go b/kit/log.go index 747133ee..87b0ca78 100644 --- a/kit/log.go +++ b/kit/log.go @@ -142,7 +142,7 @@ func SummarizeLog(fname string) error { startdate = "" } if nloaded > 0 { - fmt.Printf("%s :: Previous session nloaded=%d\n",startdate,nloaded) + fmt.Printf("%s :: Previous session nloaded=%d\n", startdate, nloaded) } fmt.Printf("%s :: Starting Engine\n", startdate) nloaded = 0 @@ -188,7 +188,7 @@ func SummarizeLog(fname string) error { userMode = true } } - } else if strings.HasPrefix(msg, "QuadPro.Load") { + } else if strings.HasPrefix(msg, "Quad.Load") { nloaded++ } } @@ -299,7 +299,7 @@ func LogWarn(msg string, keysAndValues ...any) { func LogRaw(loglevel string, msg string, keysAndValues ...any) { if (len(keysAndValues) % 2) != 0 { - LogWarn("LogRaw function given bad number of arguments","msg",msg) + LogWarn("LogRaw function given bad number of arguments", "msg", msg) } else { keysAndValues = appendExtraValues(keysAndValues) keysAndValues = append(keysAndValues, "loglevel") diff --git a/kit/patch.go b/kit/patch.go index 8a29e041..210d1609 100644 --- a/kit/patch.go +++ b/kit/patch.go @@ -309,7 +309,7 @@ func (patch *Patch) Api(api string, apiargs map[string]string) (string, error) { } func (patch *Patch) SaveQuadAndAlert() error { - return TheQuadPro.saveQuad("_Current") + return TheQuad.saveQuad("_Current") } func (patch *Patch) SetParam(paramName string, paramValue string) error { diff --git a/kit/process.go b/kit/process.go index 469980ae..f5c235a0 100644 --- a/kit/process.go +++ b/kit/process.go @@ -63,6 +63,7 @@ var GuiExe = "palette_gui.exe" var ChatExe = "palette_chat.exe" var BiduleExe = "bidule.exe" var ResolumeExe = "avenue.exe" + // var KeykitExe = "key.exe" var MmttExe = "mmtt_kinect.exe" var ObsExe = "obs64.exe" @@ -80,14 +81,14 @@ func KillAllExceptMonitor() { KillExecutable(ChatExe) } -func IsRunning(process string) bool { +func IsRunning(process string) (bool, error) { if process == "engine" { return IsRunningExecutable(EngineExe) } return TheProcessManager.IsRunning(process) } -func MonitorIsRunning() bool { +func MonitorIsRunning() (bool, error) { return IsRunningExecutable(MonitorExe) } @@ -145,7 +146,7 @@ func (pm *ProcessManager) CheckAutorestartProcesses() { defer pm.mutex.Unlock() for _, process := range ProcessList() { - if ! pm.IsAvailable(process) { + if !pm.IsAvailable(process) { continue } runit, err := GetParamBool("global.process." + process) @@ -153,20 +154,22 @@ func (pm *ProcessManager) CheckAutorestartProcesses() { LogError(err) continue } - isRunning := pm.IsRunning(process) - if runit { - if !isRunning { - LogInfo("CheckAutorestartProcesses: Restarting", "process", process) - err := pm.StartRunning(process) - LogIfError(err) - } - } else { - if isRunning { - LogInfo("CheckAutorestartProcesses: Stopping", "process", process) - err := pm.StopRunning(process) - LogIfError(err) + running, err := pm.IsRunning(process) + if err == nil { + if runit { + if !running { + LogInfo("CheckAutorestartProcesses: Restarting", "process", process) + err := pm.StartRunning(process) + LogIfError(err) + } + } else { + // If we're not supposed to be running it, stop it + if running { + LogInfo("CheckAutorestartProcesses: Stopping", "process", process) + err := pm.StopRunning(process) + LogIfError(err) + } } - } } } @@ -239,7 +242,11 @@ func (pm *ProcessManager) AddProcessBuiltIn(process string) { func (pm *ProcessManager) StartRunning(process string) error { - if pm.IsRunning(process) { + running, err := pm.IsRunning(process) + if err != nil { + return err + } + if running { LogInfo("StartRunning: already running", "process", process) return nil } @@ -293,15 +300,18 @@ func (pm *ProcessManager) StopRunning(process string) (err error) { return err } +/* func (pm *ProcessManager) ProcessStatus() string { s := "" for name := range pm.info { - if pm.IsRunning(name) { + running, err := pm.IsRunning(name) + if err == nil && running { s += fmt.Sprintf("%s is running\n", name) } } return s } +*/ func (pm *ProcessManager) GetProcessInfo(process string) (*ProcessInfo, error) { p, ok := pm.info[process] @@ -326,14 +336,13 @@ func (pm *ProcessManager) IsAvailable(process string) bool { return ok && p != nil && p.Exe != "" && p.FullPath != "" } -func (pm *ProcessManager) IsRunning(process string) bool { +func (pm *ProcessManager) IsRunning(process string) (bool, error) { pi, err := pm.GetProcessInfo(process) if err != nil { LogIfError(err) - return false + return false, err } - b := IsRunningExecutable(pi.Exe) - return b + return IsRunningExecutable(pi.Exe) } // Below here are functions that return ProcessInfo for various programs diff --git a/kit/quadpro.go b/kit/quad.go similarity index 68% rename from kit/quadpro.go rename to kit/quad.go index 9d813054..06c1d73e 100644 --- a/kit/quadpro.go +++ b/kit/quad.go @@ -11,9 +11,9 @@ import ( "time" ) -var TheQuadPro *QuadPro +var TheQuad *Quad -type QuadPro struct { +type Quad struct { // Per-patch things patch map[string]*Patch @@ -24,31 +24,31 @@ type QuadPro struct { randMutex sync.Mutex } -func NewQuadPro() *QuadPro { - quadpro := &QuadPro{ +func NewQuad() *Quad { + quad := &Quad{ patch: map[string]*Patch{}, patchLogic: map[string]*PatchLogic{}, rand: rand.New(rand.NewSource(1)), } - return quadpro + return quad } -func (quadpro *QuadPro) Stop() { - quadpro.started = false +func (quad *Quad) Stop() { + quad.started = false } -func (quadpro *QuadPro) Api(api string, apiargs map[string]string) (result string, err error) { +func (quad *Quad) Api(api string, apiargs map[string]string) (result string, err error) { switch api { case "get": - return quadpro.onGet(apiargs) + return quad.onGet(apiargs) case "event": return "", fmt.Errorf("event no longer handled in Quadpro.Api") case "ANO": - for _, patch := range quadpro.patch { + for _, patch := range quad.patch { patch.Synth().SendANO() } return "", nil @@ -71,14 +71,14 @@ func (quadpro *QuadPro) Api(api string, apiargs map[string]string) (result strin } // Loading a preset no longer turns off attract mode // TheAttractManager.SetAttractMode(false) - return "", quadpro.Load(category, filename) + return "", quad.Load(category, filename) case "loadrand": category, oksaved := apiargs["category"] if !oksaved { return "", fmt.Errorf("missing category parameter") } - return quadpro.loadQuadRand(category) + return quad.loadQuadRand(category) case "save": category, oksaved := apiargs["category"] @@ -89,7 +89,7 @@ func (quadpro *QuadPro) Api(api string, apiargs map[string]string) (result strin if !oksaved { return "", fmt.Errorf("missing filename parameter") } - return "", quadpro.save(category, filename) + return "", quad.save(category, filename) case "test": ntimes := ArgToInt("ntimes", apiargs) @@ -103,26 +103,26 @@ func (quadpro *QuadPro) Api(api string, apiargs map[string]string) (result strin testtype = "" } interval := time.Duration(intervalf * 1000000000) - LogInfo("QuadPro.ExecuteApi test start", "ntimes", ntimes, "interval", interval) - quadpro.doTest(testtype, ntimes, interval) - LogInfo("QuadPro.ExecuteApi test end", "ntimes", ntimes, "interval", interval) + LogInfo("Quad.ExecuteApi test start", "ntimes", ntimes, "interval", interval) + quad.doTest(testtype, ntimes, interval) + LogInfo("Quad.ExecuteApi test end", "ntimes", ntimes, "interval", interval) return "", nil default: - LogWarn("QuadPro.ExecuteApi api is not recognized\n", "api", api) - return "", fmt.Errorf("QuadPro.Api unrecognized api=%s", api) + LogWarn("Quad.ExecuteApi api is not recognized\n", "api", api) + return "", fmt.Errorf("Quad.Api unrecognized api=%s", api) } } var CursorSourceToQuadPreset ParamsMap -func (quadpro *QuadPro) Start() { +func (quad *Quad) Start() { - if quadpro.started { - LogInfo("QuadPro.Start: already started") + if quad.started { + LogInfo("Quad.Start: already started") return } - quadpro.started = true + quad.started = true buttonPath := ConfigFilePath("buttons.json") if fileExists(buttonPath) { @@ -145,25 +145,25 @@ func (quadpro *QuadPro) Start() { } } - TheCursorManager.AddCursorHandler("QuadPro", TheQuadPro, "A", "B", "C", "D") + TheCursorManager.AddCursorHandler("Quad", TheQuad, "A", "B", "C", "D") - _ = quadpro.addPatch("A") - _ = quadpro.addPatch("B") - _ = quadpro.addPatch("C") - _ = quadpro.addPatch("D") + _ = quad.addPatch("A") + _ = quad.addPatch("B") + _ = quad.addPatch("C") + _ = quad.addPatch("D") - err := quadpro.Load("quad", "_Current") + err := quad.Load("quad", "_Current") LogIfError(err) } -func (quadpro *QuadPro) Status(source string) string { +func (quad *Quad) Status(source string) string { return "status" + source } -func (quadpro *QuadPro) PatchForCursorEvent(ce CursorEvent) (patch *Patch, button string) { +func (quad *Quad) PatchForCursorEvent(ce CursorEvent) (patch *Patch, button string) { source := ce.Source() // If the source has some patchLogic... - patchLogic, ok := quadpro.patchLogic[source] + patchLogic, ok := quad.patchLogic[source] if !ok { patch = nil } else { @@ -177,7 +177,7 @@ func (quadpro *QuadPro) PatchForCursorEvent(ce CursorEvent) (patch *Patch, butto return patch, button } -func (quadpro *QuadPro) onCursorEvent(state ActiveCursor) error { +func (quad *Quad) onCursorEvent(state ActiveCursor) error { // Any non-attract-generated cursor or Button will turn attract mode off. if !state.Current.IsAttractGenerated() && TheAttractManager.AttractModeIsOn() { @@ -202,9 +202,9 @@ func (quadpro *QuadPro) onCursorEvent(state ActiveCursor) error { LogInfo("No Preset is attached to button", "button", state.Button) } else { preset := val.(string) - if TheQuadPro != nil { + if TheQuad != nil { LogOfType("cursor", "Button down", "z", state.Current.Pos.Z) - err := TheQuadPro.Load("quad", preset) + err := TheQuad.Load("quad", preset) if err != nil { return err } @@ -219,7 +219,7 @@ func (quadpro *QuadPro) onCursorEvent(state ActiveCursor) error { // For the moment, the cursor to patchLogic mapping is 1-to-1. // I.e. ce.Source of "A" maps to patchLogic "A" source := state.Current.Source() - patchLogic, ok := quadpro.patchLogic[source] + patchLogic, ok := quad.patchLogic[source] if !ok || patchLogic == nil { LogWarn("Source doesn't exist in patchLogic", "source", source) return nil @@ -248,38 +248,38 @@ func (quadpro *QuadPro) onCursorEvent(state ActiveCursor) error { return nil } -func (quadpro *QuadPro) onClientRestart(portnum int) { - LogOfType("resolume", "quadpro got clientrestart", "portnum", portnum) +func (quad *Quad) onClientRestart(portnum int) { + LogOfType("resolume", "quad got clientrestart", "portnum", portnum) // Refresh the patch that has that portnum - for _, patch := range quadpro.patch { + for _, patch := range quad.patch { patch.RefreshAllIfPortnumMatches(portnum) } } -func (quadpro *QuadPro) onGet(apiargs map[string]string) (result string, err error) { +func (quad *Quad) onGet(apiargs map[string]string) (result string, err error) { paramName, ok := apiargs["name"] if !ok { - return "", fmt.Errorf("QuadPro.onPatchGet: Missing name argument") + return "", fmt.Errorf("Quad.onPatchGet: Missing name argument") } if strings.HasPrefix(paramName, "global") { return GetParam(paramName) } else { - return "", fmt.Errorf("QuadPro.onGet: can't handle parameter %s", paramName) + return "", fmt.Errorf("Quad.onGet: can't handle parameter %s", paramName) } } -func (quadpro *QuadPro) onMidiEvent(me MidiEvent) error { - LogOfType("midi", "QuadPro.onMidiEvent", "me", me) +func (quad *Quad) onMidiEvent(me MidiEvent) error { + LogOfType("midi", "Quad.onMidiEvent", "me", me) return nil } -func (quadpro *QuadPro) RandomPatchName() string { - quadpro.randMutex.Lock() - defer quadpro.randMutex.Unlock() - return string("ABCD"[quadpro.rand.Intn(len(Patchs))]) +func (quad *Quad) RandomPatchName() string { + quad.randMutex.Lock() + defer quad.randMutex.Unlock() + return string("ABCD"[quad.rand.Intn(len(Patchs))]) } -func (quadpro *QuadPro) doTest(testtype string, ntimes int, interval time.Duration) { +func (quad *Quad) doTest(testtype string, ntimes int, interval time.Duration) { numsteps, err := GetParamInt("global.testgesturenumsteps") if err != nil { @@ -297,7 +297,7 @@ func (quadpro *QuadPro) doTest(testtype string, ntimes int, interval time.Durati switch testtype { case "": - randomPatchName := quadpro.RandomPatchName() + randomPatchName := quad.RandomPatchName() tag := randomPatchName + ",test" go TheCursorManager.GenerateRandomGesture(tag, numsteps, dur) @@ -311,30 +311,30 @@ func (quadpro *QuadPro) doTest(testtype string, ntimes int, interval time.Durati } } -func (quadpro *QuadPro) loadQuadRand(category string) (string, error) { +func (quad *Quad) loadQuadRand(category string) (string, error) { arr, err := SavedFileList(category) if err != nil { return "", err } - quadpro.randMutex.Lock() - rn := quadpro.rand.Uint64() % uint64(len(arr)) - quadpro.randMutex.Unlock() + quad.randMutex.Lock() + rn := quad.rand.Uint64() % uint64(len(arr)) + quad.randMutex.Unlock() - err = quadpro.Load(category, arr[rn]) + err = quad.Load(category, arr[rn]) if err != nil { LogIfError(err) return "", err } - for _, patch := range quadpro.patch { + for _, patch := range quad.patch { patch.RefreshAllPatchValues() } return arr[rn], err } -func (quadpro *QuadPro) Load(category string, filename string) error { +func (quad *Quad) Load(category string, filename string) error { paramsMap, err := LoadParamsMapOfCategory(category, filename) if err != nil { @@ -342,18 +342,18 @@ func (quadpro *QuadPro) Load(category string, filename string) error { return err } - LogInfo("QuadPro.Load", "category", category, "filename", filename) + LogInfo("Quad.Load", "category", category, "filename", filename) isOn := TheAttractManager.attractModeIsOn.Load() PublishFromEngine("quadro.load", fmt.Sprintf("category=%s filename=%s attractmode=%v", category, filename, isOn)) var lasterr error if category == "global" { - err := fmt.Errorf("HACK! quadpro.Load shouldn't load global parameters") + err := fmt.Errorf("HACK! quad.Load shouldn't load global parameters") LogError(err) lasterr = err } else { - for _, patch := range quadpro.patch { + for _, patch := range quad.patch { err := patch.Load(category, paramsMap) if err != nil { LogIfError(err) @@ -375,13 +375,13 @@ func (quadpro *QuadPro) Load(category string, filename string) error { } case "quad": if filename != "_Current" { - err = quadpro.saveQuad("_Current") + err = quad.saveQuad("_Current") } case "patch", "sound", "visual", "effect", "misc": // If we're loading a patch (or something inside a patch, like sound, visual, etc), // we save the entire quad, since that's our real persistent state if filename != "_Current" { - err = quadpro.saveQuad("_Current") + err = quad.saveQuad("_Current") } } if err != nil { @@ -391,17 +391,17 @@ func (quadpro *QuadPro) Load(category string, filename string) error { return lasterr } -func (quadpro *QuadPro) save(category string, filename string) (err error) { +func (quad *Quad) save(category string, filename string) (err error) { - LogOfType("saved", "QuadPro.save", "category", category, "filename", filename) + LogOfType("saved", "Quad.save", "category", category, "filename", filename) if category == "global" { - LogWarn("QuadPro.save: shouldn't be saving global?") - err = fmt.Errorf("QuadPro.save: global shouldn't be handled here") + LogWarn("quad.save: shouldn't be saving global?") + err = fmt.Errorf("quad.save: global shouldn't be handled here") } else if category == "quad" { - err = quadpro.saveQuad(filename) + err = quad.saveQuad(filename) } else { - err = fmt.Errorf("QuadPro.Api: unhandled save category %s", category) + err = fmt.Errorf("quad.save: unhandled save category %s", category) } if err != nil { LogIfError(err) @@ -409,7 +409,7 @@ func (quadpro *QuadPro) save(category string, filename string) (err error) { return err } -func (quadpro *QuadPro) saveQuad(quadName string) error { +func (quad *Quad) saveQuad(quadName string) error { category := "quad" path, err := WritableSavedFilePath(category, quadName, ".json") @@ -418,10 +418,10 @@ func (quadpro *QuadPro) saveQuad(quadName string) error { return err } - LogOfType("saved", "QuadPro.saveQuad", "quad", quadName) + LogOfType("saved", "Quad.saveQuad", "quad", quadName) sortedPatchNames := []string{} - for _, patch := range quadpro.patch { + for _, patch := range quad.patch { sortedPatchNames = append(sortedPatchNames, patch.Name()) } sort.Strings(sortedPatchNames) @@ -429,7 +429,7 @@ func (quadpro *QuadPro) saveQuad(quadName string) error { s := "{\n \"params\": {\n" sep := "" for _, patchName := range sortedPatchNames { - patch := quadpro.patch[patchName] + patch := quad.patch[patchName] sortedNames := patch.ParamNames() for _, fullName := range sortedNames { valstring := patch.Get(fullName) @@ -442,16 +442,16 @@ func (quadpro *QuadPro) saveQuad(quadName string) error { return os.WriteFile(path, data, 0644) } -func (quadpro *QuadPro) addPatch(name string) *Patch { +func (quad *Quad) addPatch(name string) *Patch { patch := NewPatch(name) - quadpro.patch[name] = patch - quadpro.patchLogic[name] = NewPatchLogic(patch) + quad.patch[name] = patch + quad.patchLogic[name] = NewPatchLogic(patch) return patch } /* -func (quadpro *QuadPro) scheduleNoteNow(dest string, pitch, velocity uint8, duration Clicks) { - LogInfo("QuadPro.scheculeNoteNow", "dest", dest, "pitch", pitch) +func (quad *Quad) scheduleNoteNow(dest string, pitch, velocity uint8, duration Clicks) { + LogInfo("Quad.scheculeNoteNow", "dest", dest, "pitch", pitch) pe := &PhraseElement{Value: NewNoteFull(0, pitch, velocity, duration)} phr := NewPhrase().InsertElement(pe) phr.Destination = dest diff --git a/kit/router.go b/kit/router.go index 4ca5aa17..9a22ef80 100644 --- a/kit/router.go +++ b/kit/router.go @@ -115,7 +115,7 @@ func (r *Router) HandleMidiEvent(me MidiEvent) { r.handleMIDISetScaleNote(me) } - err := TheQuadPro.onMidiEvent(me) + err := TheQuad.onMidiEvent(me) LogIfError(err) if TheErae.enabled { @@ -296,7 +296,7 @@ func (r *Router) oscHandleClientRestart(msg *osc.Message) error { if err != nil { return err } - TheQuadPro.onClientRestart(ffglportnum) + TheQuad.onClientRestart(ffglportnum) return nil } diff --git a/kit/windows.go b/kit/windows.go index 707a3796..6833bb72 100644 --- a/kit/windows.go +++ b/kit/windows.go @@ -81,15 +81,15 @@ func (writer *gatherWriter) Write(bytes []byte) (int, error) { return len(bytes), nil } -func IsRunningExecutable(exe string) bool { +func IsRunningExecutable(exe string) (bool,error) { // os.Stdout.WriteString("IsRunningExecutable exe=" + exe + "\n") stdout := &gatherWriter{} stderr := &NoWriter{} cmd, err := StartExecutableAndWait("c:\\windows\\system32\\tasklist.exe", stdout, stderr) if err != nil { - LogWarn("IsRunningExecutable tasklist.exe", "err", err) - LogOfType("process", "IsRunningExecutable", "exe", exe, "returning", "true") - return false + LogWarn("IsRunningExecutable of tasklist.exe", "err", err) + // Assume it's running, to avoid multiple instances + return true, err } _ = cmd.Wait() // ignore "Wait was already called" @@ -105,12 +105,12 @@ func IsRunningExecutable(exe string) bool { if strings.ToLower(words[0]) == exe { // os.Stdout.WriteString("IsRunningExecutable " + exe + " returning true\n") LogOfType("process", "IsRunningExecutable", "exe", exe, "returning", "true") - return true + return true, nil } } } LogOfType("process", "IsRunningExecutable", "exe", exe, "returning", "false") - return false + return false, nil } func isolateExe(exepath string) string { diff --git a/palette.code-workspace b/palette.code-workspace index 5e0fbd65..a45c6ed0 100644 --- a/palette.code-workspace +++ b/palette.code-workspace @@ -2,6 +2,9 @@ "folders": [ { "path": "." + }, + { + "path": "cmd/fyne_demo" } ], "settings": { diff --git a/python/palette.py b/python/palette.py index 6c71a962..d3065b99 100644 --- a/python/palette.py +++ b/python/palette.py @@ -60,11 +60,11 @@ def palette_patch_set(patch, name, value): ", \"name\": \"" + name + "\"" + \ ", \"value\": \"" + str(value) + "\"") -def palette_quadpro_api(api, params=""): - return palette_api("quadpro."+api,params) +def palette_quad_api(api, params=""): + return palette_api("quad."+api,params) -def palette_quadpro_set(name, value): - return palette_api("quadpro.set", +def palette_quad_set(name, value): + return palette_api("quad.set", "\"name\": \"" + name + "\"" + \ ", \"value\": \"" + str(value) + "\"") diff --git a/python/palette_gui.py b/python/palette_gui.py index c96d26ee..f16d8e42 100644 --- a/python/palette_gui.py +++ b/python/palette_gui.py @@ -940,7 +940,7 @@ def loadAndSend(self,category,filename): if category == "global": # log("Loading","category","global","filename",filename) - palette.palette_quadpro_api("load", + palette.palette_quad_api("load", "\"filename\": \"" + filename + "\"" ", \"category\": \"" + category + "\"") elif category == "quad": @@ -949,7 +949,7 @@ def loadAndSend(self,category,filename): # because in casual mode, the patch selectors aren't shown. # In non-casual mode (guiLevel>0) we do this if allPatchesSelected log("Loading","category","quad","filename",filename) - palette.palette_quadpro_api("load", + palette.palette_quad_api("load", "\"filename\": \"" + filename + "\"" ", \"category\": \"" + category + "\"") else: @@ -1334,7 +1334,7 @@ def setPerformIndex(self,name,index): self.performIndex[name] = index def sendANO(self): - palette.palette_quadpro_api("ANO") + palette.palette_quad_api("ANO") def clear(self): palette.palette_patch_api(self.name(), "clear", "") @@ -2018,7 +2018,7 @@ def saveOkCallback(self): def saveSaved(self,filename): if self.pagename == "quad": - result, err = palette.palette_quadpro_api("save", + result, err = palette.palette_quad_api("save", "\"category\": \"" + self.pagename + "\", " "\"filename\": \"" + filename + "\"") if err != None: diff --git a/scripts/apitest.bat b/scripts/apitest.bat index 65d1ab5f..a97fcc36 100644 --- a/scripts/apitest.bat +++ b/scripts/apitest.bat @@ -1 +1 @@ -palette quadpro.test ntimes 100 dt 0.5s +palette quad.test ntimes 100 dt 0.5s