Repos / gorts / b40e2533e0
commit b40e2533e009863b5e2e0b4506e6d7aac9368547
Author: Nhân <hi@imnhan.com>
Date:   Fri Jun 16 16:56:55 2023 +0700

    draft Go backend

diff --git a/README.md b/README.md
new file mode 100644
index 0000000..00bac5d
--- /dev/null
+++ b/README.md
@@ -0,0 +1,4 @@
+# GORTS
+
+... is [orts](https://github.com/nhanb/orts) but in pure Go and pure Tcl/Tk
+purely talking via good ole pipes, the way Dennis Ritchie intended.
diff --git a/main.go b/main.go
index b690e69..e3673a3 100644
--- a/main.go
+++ b/main.go
@@ -1,7 +1,84 @@
 package main
 
-import "fmt"
+import (
+	"bufio"
+	_ "embed"
+	"io"
+	"log"
+	"os/exec"
+)
+
+//go:embed tcl/main.tcl
+var mainTcl string
 
 func main() {
-	fmt.Println("Heeey")
+	tcl := initTcl()
+	tcl.Connect()
+}
+
+type Tcl struct {
+	cmd *exec.Cmd
+}
+
+func initTcl() Tcl {
+	cmd := exec.Command("tclsh")
+	return Tcl{cmd}
+}
+
+func (t *Tcl) Connect() {
+	stdout, err := t.cmd.StdoutPipe()
+	if err != nil {
+		panic(err)
+	}
+
+	stdin, err := t.cmd.StdinPipe()
+	if err != nil {
+		panic(err)
+	}
+
+	err = t.cmd.Start()
+	if err != nil {
+		panic(err)
+	}
+
+	io.WriteString(stdin, mainTcl)
+	println("Loaded main tcl script.")
+
+	io.WriteString(stdin, "readvars\n")
+
+	reqscanner := bufio.NewScanner(stdout)
+	for reqscanner.Scan() {
+		req := reqscanner.Text()
+		println("=> " + req)
+		switch req {
+		case "readvars":
+			for _, line := range serveReadvars() {
+				println("<= " + line)
+				io.WriteString(stdin, line+"\n")
+			}
+		default:
+			println("Skipping bogus command: " + req)
+		}
+	}
+
+	println("Tcl process terminated.")
+
+	if err := reqscanner.Err(); err != nil {
+		log.Fatal(err)
+	}
+}
+
+func serveReadvars() []string {
+	return []string{
+		"description Saigon Cup 2023",
+		"p1name Diego Umejuarez",
+		"p1country jp",
+		"p1score 1",
+		"p1team Japan",
+		"p2name Chokido",
+		"p2country jp",
+		"p2score 2",
+		"p2team Japan2",
+		"end",
+	}
 }
diff --git a/tcl/main.tcl b/tcl/main.tcl
index 2f54050..0e4b9dc 100644
--- a/tcl/main.tcl
+++ b/tcl/main.tcl
@@ -12,28 +12,8 @@ if {$OS == "Windows"} {
     ttk::style theme use clam
 }
 
-# Very simple line-based RPC where Tcl client talks to Go server
-# via stdin/stdout.
-#
-# For this "readvars" method, the Go server returns multiple lines
-# where each line starts with variable name, followed by a space,
-# with the rest of the line being its value. When done, the server
-# sends a literal "end" line.
-#
-# => readvars
-# <= description Saigon Cup 2023
-# <= p1name BST Diego Umejuarez
-# <= p1score 0
-# [etc.]
-# <= end
-puts "readvars"
-set line [gets stdin]
-while {$line != "end"} {
-    set spaceindex [string first " " $line]
-    set key [string range $line 0 $spaceindex-1]
-    set val [string range $line $spaceindex+1 end]
-    set ${key} $val
-    set line [gets stdin]
+wm protocol . WM_DELETE_WINDOW {
+    exit 0
 }
 
 # GUI
@@ -94,3 +74,32 @@ grid .c.buttons.swap -row 0 -column 3
 grid columnconfigure .c.players 2 -pad 5
 grid columnconfigure .c.buttons 1 -pad 15
 grid columnconfigure .c.buttons 3 -pad 15
+
+
+# Very simple line-based IPC where Tcl client talks to Go server
+# via stdin/stdout.
+#
+# For this "readvars" method, the Go server returns multiple lines
+# where each line starts with variable name, followed by a space,
+# with the rest of the line being its value. When done, the server
+# sends a literal "end" line.
+#
+# => readvars
+# <= description Saigon Cup 2023
+# <= p1name BST Diego Umejuarez
+# <= p1score 0
+# [etc.]
+# <= end
+proc readvars {} {
+    puts "readvars"
+    set line [gets stdin]
+    while {$line != "end"} {
+        set spaceindex [string first " " $line]
+        set key [string range $line 0 $spaceindex-1]
+        set val [string range $line $spaceindex+1 end]
+        # this makes sure it sets the outer scope's variable:
+        variable ${key}
+        set ${key} $val
+        set line [gets stdin]
+    }
+}