diff --git a/.gitignore b/.gitignore index fd7dca5..e6536b1 100644 --- a/.gitignore +++ b/.gitignore @@ -131,3 +131,5 @@ dmypy.json # Pyre type checker .pyre/ +go/state.json +python/logo.png diff --git a/go/server.go b/go/server.go index 95c1e33..c037d7c 100644 --- a/go/server.go +++ b/go/server.go @@ -3,8 +3,11 @@ package main import ( "encoding/json" "flag" + "fmt" + "io/ioutil" "log" "net/http" + "os" "strconv" "time" @@ -44,17 +47,17 @@ func get(w http.ResponseWriter, r *http.Request) { defer c.Close() ticker := time.NewTicker(1 * time.Second) - var tmpImage = GetImage(img.width, img.height) + var tmpImage = GetImage(img.Width, img.Height) for range ticker.C { diff := tmpImage.GetDiff(&img) - for i := 0; i < int(diff.width*diff.height); i++ { - pix := diff.pixels[i] - if pix.pixel.UserID != 0 { - x := i / int(diff.width) - y := i % int(diff.height) - msg := Message{X: uint32(x), Y: uint32(y), Timestamp: pix.pixel.Timestamp, UserID: pix.pixel.UserID, Color: pix.pixel.Color} + for i := 0; i < int(diff.Width*diff.Height); i++ { + pix := diff.Pixels[i] + if pix.Pixel.UserID != 0 { + x := i / int(diff.Width) + y := i % int(diff.Height) + msg := Message{X: uint32(x), Y: uint32(y), Timestamp: pix.Pixel.Timestamp, UserID: pix.Pixel.UserID, Color: pix.Pixel.Color} marshalMsg, err := json.Marshal(msg) if err != nil { log.Println("error while writing image", err) @@ -68,7 +71,7 @@ func get(w http.ResponseWriter, r *http.Request) { if err := c.WriteMessage(websocket.PingMessage, []byte{}); err != nil { return } - copy(tmpImage.pixels, img.pixels) + copy(tmpImage.Pixels, img.Pixels) } } @@ -79,7 +82,6 @@ func set(w http.ResponseWriter, r *http.Request) { return } c.SetReadLimit(maxMessageSize) - c.SetPongHandler(func(string) error { c.SetReadDeadline(time.Now().Add(pongWait)); return nil }) defer c.Close() @@ -100,12 +102,49 @@ func set(w http.ResponseWriter, r *http.Request) { } } +func loadState(img *image, path string) { + stateJSON, err := os.Open(path) + if err != nil { + fmt.Println(err) + return + } + defer stateJSON.Close() + byteValue, _ := ioutil.ReadAll(stateJSON) + + json.Unmarshal(byteValue, &img) +} + +func saveState(img *image, path string) { + ticker := time.NewTicker(1 * time.Second) + + for range ticker.C { + imgJSON, _ := json.Marshal(img) + file, err := os.Create(path) + + if err != nil { + return + } + defer file.Close() + file.WriteString(string(imgJSON)) + if err != nil { + fmt.Println("Could not save state") + fmt.Println(err) + } + } +} + func main() { var addr = flag.String("addr", "localhost:8080", "http service address") flag.Parse() log.SetFlags(0) log.Println("starting server on", *addr) + + cachePath := "./state.json" + + loadState(&img, cachePath) + go saveState(&img, cachePath) + http.HandleFunc("/get", get) http.HandleFunc("/set", set) diff --git a/go/util.go b/go/util.go index f7bd4db..903b6a3 100644 --- a/go/util.go +++ b/go/util.go @@ -20,36 +20,36 @@ type pixel struct { } type pixelContainer struct { - pixel pixel + Pixel pixel `json:"pixel"` Mutex sync.Mutex } type image struct { - width uint32 - height uint32 - pixels []pixelContainer + Width uint32 `json:"Width"` + Height uint32 `json:"Height"` + Pixels []pixelContainer `json:"Pixels"` } func GetImage(w uint32, h uint32) image { - pixels := make([]pixelContainer, w*h) + Pixels := make([]pixelContainer, w*h) for i := 0; i < int(w*h); i++ { - pixels[i] = pixelContainer{pixel: pixel{Color: 0, Timestamp: 0, UserID: 0}, Mutex: sync.Mutex{}} + Pixels[i] = pixelContainer{Pixel: pixel{Color: 0, Timestamp: 0, UserID: 0}, Mutex: sync.Mutex{}} } - return image{width: w, height: h, pixels: pixels} + return image{Width: w, Height: h, Pixels: Pixels} } func (p *pixelContainer) setColor(color uint8, timestamp int64, userid uint64) { p.Mutex.Lock() defer p.Mutex.Unlock() - if timestamp > p.pixel.Timestamp { - p.pixel.Color = color - p.pixel.Timestamp = timestamp - p.pixel.UserID = userid + if timestamp > p.Pixel.Timestamp { + p.Pixel.Color = color + p.Pixel.Timestamp = timestamp + p.Pixel.UserID = userid } } func (img *image) SetPixel(message Message) int { - if message.X >= img.width || message.Y >= img.height || message.X < 0 || message.Y < 0 { + if message.X >= img.Width || message.Y >= img.Height || message.X < 0 || message.Y < 0 { fmt.Printf("User %d tried accessing out of bounds \n", message.UserID) return 1 } @@ -57,24 +57,24 @@ func (img *image) SetPixel(message Message) int { fmt.Printf("User %d tried setting non existent color \n", message.UserID) return 1 } - pos := uint32(message.X)*uint32(img.width) + uint32(message.Y) - img.pixels[pos].setColor(message.Color, message.Timestamp, message.UserID) + pos := uint32(message.X)*uint32(img.Width) + uint32(message.Y) + img.Pixels[pos].setColor(message.Color, message.Timestamp, message.UserID) return 0 } func comparePixels(pixel1 *pixelContainer, pixel2 *pixelContainer) bool { - return pixel1.pixel.Color == pixel2.pixel.Color && - pixel1.pixel.Timestamp == pixel2.pixel.Timestamp && - pixel1.pixel.UserID == pixel2.pixel.UserID + return pixel1.Pixel.Color == pixel2.Pixel.Color && + pixel1.Pixel.Timestamp == pixel2.Pixel.Timestamp && + pixel1.Pixel.UserID == pixel2.Pixel.UserID } func (img *image) GetDiff(img2 *image) image { - diff := GetImage(img.width, img.height) - for i := 0; i < int(img.width*img.height); i++ { - if !comparePixels(&img.pixels[i], &img2.pixels[i]) { - diff.pixels[i].pixel.Color = img2.pixels[i].pixel.Color - diff.pixels[i].pixel.UserID = img2.pixels[i].pixel.UserID - diff.pixels[i].pixel.Timestamp = img2.pixels[i].pixel.Timestamp + diff := GetImage(img.Width, img.Height) + for i := 0; i < int(img.Width*img.Height); i++ { + if !comparePixels(&img.Pixels[i], &img2.Pixels[i]) { + diff.Pixels[i].Pixel.Color = img2.Pixels[i].Pixel.Color + diff.Pixels[i].Pixel.UserID = img2.Pixels[i].Pixel.UserID + diff.Pixels[i].Pixel.Timestamp = img2.Pixels[i].Pixel.Timestamp } } return diff diff --git a/python/clients.py b/python/clients.py index 06504ba..2a44497 100644 --- a/python/clients.py +++ b/python/clients.py @@ -57,7 +57,6 @@ async def client(): #image[x.x][x.y] = ([y*255 for y in colors[x.color]]) image[x.x][x.y] = ((x.color, x.color, x.color)) if i% 1000 == 0: - print("showing") cv2.imshow("changes x", image) cv2.waitKey(10) & 0XFF await websocket.send("1")