diff --git a/driver/static.go b/driver/static.go index 3c0b1b0..a08b390 100644 --- a/driver/static.go +++ b/driver/static.go @@ -16,6 +16,8 @@ type StaticImage struct { pixelsClean [160][144][3]uint8 pixelLock sync.RWMutex + lastFrameIndex uint32 + inputStatus *byte inputQueue []*inputCommand queueLock sync.Mutex @@ -78,11 +80,19 @@ func (s *StaticImage) Run(drawSignal chan bool, f func()) { s.pixelLock.Lock() if s.pixelsDirty != nil { s.pixelsClean = *s.pixelsDirty + s.lastFrameIndex++ } s.pixelLock.Unlock() } } +func (s *StaticImage) LastFrameIndex() uint32 { + s.pixelLock.RLock() + lastFrameIndex := s.lastFrameIndex + s.pixelLock.RUnlock() + return lastFrameIndex +} + // Render raw pixels into images func (s *StaticImage) Render() *image.RGBA { scaleRatio := 4 diff --git a/go.mod b/go.mod index f94906c..1aced52 100644 --- a/go.mod +++ b/go.mod @@ -12,9 +12,7 @@ require ( github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1 // indirect github.com/go-gl/mathgl v0.0.0-20190416160123-c4601bc793c7 // indirect github.com/gorilla/websocket v1.4.2 - github.com/gosuri/uilive v0.0.2 github.com/logrusorgru/aurora v0.0.0-20190428105938-cea283e61946 - github.com/reiver/go-oi v0.0.0-20160325061615-431c83978379 // indirect - github.com/reiver/go-telnet v0.0.0-20180421082511-9ff0b2ab096e // indirect github.com/satori/go.uuid v1.2.0 + gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c // indirect ) diff --git a/static/server.go b/static/server.go index 29a39fd..69b2523 100644 --- a/static/server.go +++ b/static/server.go @@ -51,6 +51,10 @@ func (server *StaticServer) Run() { http.HandleFunc("/stream", streamImages(server)) http.HandleFunc("/svg", showSVG(server)) http.HandleFunc("/control", newInput(server)) + + http.HandleFunc("/controlWs", newInputWs(server)) + + log.Println(fmt.Sprintf("Serving on port %d", server.Port)) http.ListenAndServe(fmt.Sprintf(":%d", server.Port), nil) } @@ -82,18 +86,29 @@ func streamImages(server *StaticServer) func(http.ResponseWriter, *http.Request) server.driver.EnqueueInput(byte(buttonByte)) } }() + + var isFirstFrame bool + var lastFrameIndex uint32 + + isFirstFrame = true + lastFrameIndex = 0 + for { - img := server.driver.Render() - buf := new(bytes.Buffer) - err = png.Encode(buf, img) - if err != nil { - log.Println(err) - continue - } - err = c.WriteMessage(websocket.BinaryMessage, buf.Bytes()) - if err != nil { - log.Println("write error:", err) - break + if isFirstFrame || lastFrameIndex != server.driver.LastFrameIndex() { + isFirstFrame = false + lastFrameIndex = server.driver.LastFrameIndex() + img := server.driver.Render() + buf := new(bytes.Buffer) + err = png.Encode(buf, img) + if err != nil { + log.Println(err) + continue + } + err = c.WriteMessage(websocket.BinaryMessage, buf.Bytes()) + if err != nil { + log.Println("write error:", err) + break + } } } } @@ -166,3 +181,32 @@ func newInput(server *StaticServer) func(http.ResponseWriter, *http.Request) { http.Redirect(w, req, callback[0], http.StatusSeeOther) } } + +func newInputWs(server *StaticServer) func(http.ResponseWriter, *http.Request) { + return func(w http.ResponseWriter, req *http.Request) { + c, err := server.upgrader.Upgrade(w, req, nil) + if err != nil { + log.Print(":upgrade error: ", err) + return + } + defer c.Close() + for { + _, msg, err2 := c.ReadMessage() + stringMsg := string(msg) + if err2 != nil { + log.Println(err2) + break + } + buttonByte, err3 := strconv.ParseUint(stringMsg, 10, 32) + if err3 != nil { + log.Println(err3) + continue + } + if buttonByte > 7 { + log.Printf("Received input (%s) > 7", stringMsg) + continue + } + server.driver.EnqueueInput(byte(buttonByte)) + } + } +}