README
¶
Oxo3d for web with WASM
This is a version of Oxo3d with a web interface.
The Go code is compiled into WASM using Go 1.11 so all the code runs in your browser - there is no server component.
You can see it in action here: https://www.craig-wood.com/nick/oxo3dwasm/
See also: the gopherjs version.
Testing
Build the code with:
./build
Run a webserver to serve it:
./serve &
Then go to http://localhost:3000/
Notes on converting gopherjs -> go/wasm
The original of this program was written in gopherjs. It was then ported to go/wasm.
This is a very similar experience to gopherjs. Most of the calls from
gopherjs work just fine with go/wasm after changing *js.Object
to
js.Value
.
The calling convention of the callbacks are a bit different and in some ways a little bit more awkward in go/wasm. However it isn't necessary to expose code to javascript which makes things a bit simpler.
Here are some things that need changing from gopherjs -> go/wasm
@@ -3,9 +3,10 @@
import (
"fmt"
"math/rand"
"strconv"
+ "syscall/js"
"time"
- "github.com/gopherjs/gopherjs/js"
"github.com/ncw/oxo3d/oxo3d"
)
*js.Object
-> js.Value
@@ -14,11 +15,11 @@
board = oxo3d.NewOxo3d(true)
player = oxo3d.NewOxo3dHeuristic(board, 0)
symbols = [3]string{"O", "", "X"}
- square [64]*js.Object
+ square [64]js.Value
viewMap [64]int // mapping for the view
- document *js.Object
- messageP *js.Object
- helpSpan *js.Object
+ document js.Value
+ messageP js.Value
+ helpSpan js.Value
)
func init() {
Global
is now a function call as is Undefined
.
@@ -28,14 +29,14 @@
// Exit with the message
func fatalf(message string, args ...interface{}) {
text := fmt.Sprintf(message, args...)
- js.Global.Call("alert", text)
+ js.Global().Call("alert", text)
panic(text)
}
// getElementById gets the element with the ID passed in or panics
-func getElementById(ID string) *js.Object {
+func getElementById(ID string) js.Value {
obj := document.Call("getElementById", ID)
- if obj == js.Undefined {
+ if obj == js.Undefined() {
fatalf("couldn't find ID %q", ID)
}
return obj
@@ -79,26 +80,39 @@
}
Callback calling convention has changed. Now you have to hook event
handlers properly. The arg []js.Value
calling arguments are a
little awkward.
@@ -128,10 +142,21 @@
}
// Called when an orientation is clicked
-func clickOrientation(orientation int) bool {
+func clickOrientation(arg []js.Value) {
+ event := arg[0]
+ this := event.Get("target")
+ id := this.Get("id").String()
+ orientation := 0
+ switch id {
+ case "orientation1":
+ orientation = 1
+ case "orientation2":
+ orientation = 2
+ }
fmt.Printf("orientation = %q\n", id)
setOrientation(orientation)
draw()
- return false
}
const helpMessage = `
Now use addEventListener
rather than setAttribute
@@ -218,45 +244,39 @@
message("")
// attach handler for new game
- getElementById("newGame").Call("setAttribute", "onclick", "oxo3dweb.newGame(); return false;")
+ getElementById("newGame").Call("addEventListener", "click", js.NewCallback(newGame))
// attach handler for orientation changes
No need to expose functions to Javascript.
// main entry point
func main() {
- // expose functions to javascript
- js.Global.Set("oxo3dweb", map[string]interface{}{
- "clickSquare": clickSquare,
- "clickOrientation": clickOrientation,
- "clickHelp": clickHelp,
- "newGame": newGame,
- })
-
Need to sleep at the end of main()
otherwise the Go program quits
and the callbacks become invalid.
initialise(nil)
+ // Wait forever - everything is done on callbacks now
+ fmt.Printf("wait\n")
+ select {}
}
References
Documentation
¶
There is no documentation for this package.