send moves

master
Jordan Orelli 4 years ago
parent 950aeda87e
commit 07791b0752

@ -2,6 +2,7 @@ package main
import (
"context"
"encoding/json"
"fmt"
"net/url"
"strings"
@ -15,9 +16,14 @@ type client struct {
*blammo.Log
host string
port int
lastSeq int
conn *websocket.Conn
outbox chan request
}
func (c *client) run(ctx context.Context) {
c.outbox = make(chan request)
dialer := websocket.Dialer{
HandshakeTimeout: 3 * time.Second,
ReadBufferSize: 32 * 1024,
@ -36,6 +42,7 @@ func (c *client) run(ctx context.Context) {
c.Error("dial error: %v", err)
return
}
c.conn = conn
c.Debug("dial response status: %d", res.StatusCode)
for k, vals := range res.Header {
@ -47,6 +54,29 @@ func (c *client) run(ctx context.Context) {
for {
select {
case req := <-c.outbox:
payload, err := json.Marshal(req)
if err != nil {
c.Error("unable to marshal a request: %v", err)
break
}
w, err := conn.NextWriter(websocket.TextMessage)
if err != nil {
c.Error("unable to get a websocket frame writer: %v", err)
break
}
n, err := w.Write(payload)
if err != nil {
c.Error("failed to write payload of length %d: %v", len(payload), err)
break
}
c.Info("wrote %d bytes for payload of length %d", n, len(payload))
if err := w.Close(); err != nil {
c.Error("failed to close websocket write frame: %v", err)
}
case <-tick.C:
w, err := conn.NextWriter(websocket.TextMessage)
if err != nil {
@ -67,7 +97,27 @@ func (c *client) run(ctx context.Context) {
c.Error("failed to close connection: %v", err)
}
c.Info("connection closed")
c.conn = nil
return
}
}
}
func (c *client) send(cmd string, args map[string]interface{}) {
eargs := make(map[string]json.RawMessage, len(args))
for k, v := range args {
b, err := json.Marshal(v)
if err != nil {
c.Error("failed to marshal an argument: %v", err)
return
}
eargs[k] = json.RawMessage(b)
}
c.lastSeq++
req := request{
Seq: c.lastSeq,
Command: cmd,
Args: eargs,
}
c.outbox <- req
}

@ -0,0 +1,17 @@
package main
import "encoding/json"
type request struct {
// client-side sequence number. Clients are expected to send requests with
// a monotonically-incrementing sequence number.
Seq int `json:"seq"`
// command represents the command to be executed on the server. Command
// names are globally unique.
Command string `json:"cmd"`
// args are the arguments passed to the command for parameterized commands
// executed on the server.
Args map[string]json.RawMessage `json:"args"`
}

@ -0,0 +1,8 @@
package main
// room represents a rectangular space in the world state
type room struct {
name string
width int
height int
}

@ -13,6 +13,7 @@ type server struct {
*blammo.Log
host string
port int
world *room
}
func (s *server) listen() error {

@ -102,7 +102,7 @@ func (ui *ui) menu() {
}
}
ui.mode.HandleEvent(e)
ui.mode.handleEvent(ui, e)
ui.screen.Clear()
ui.mode.draw(ui)
ui.screen.Show()

@ -5,7 +5,7 @@ import (
)
type uiMode interface {
HandleEvent(tcell.Event) bool
handleEvent(*ui, tcell.Event) bool
draw(*ui)
}
@ -15,19 +15,23 @@ type boxWalker struct {
position point
}
func (m *boxWalker) HandleEvent(e tcell.Event) bool {
func (m *boxWalker) handleEvent(ui *ui, e tcell.Event) bool {
switch v := e.(type) {
case *tcell.EventKey:
key := v.Key()
if key == tcell.KeyRune {
switch v.Rune() {
case 'w':
ui.client.send("self/move", map[string]interface{}{"delta": []int{0, -1}})
m.move(0, -1)
case 'a':
ui.client.send("self/move", map[string]interface{}{"delta": []int{-1, 0}})
m.move(-1, 0)
case 's':
ui.client.send("self/move", map[string]interface{}{"delta": []int{0, 1}})
m.move(0, 1)
case 'd':
ui.client.send("self/move", map[string]interface{}{"delta": []int{1, 0}})
m.move(1, 0)
}
}

Loading…
Cancel
Save