mirror of https://github.com/Askill/r_place.git
saving periodically and loading state from file
This commit is contained in:
parent
d7a1421236
commit
14584c41a0
|
|
@ -131,3 +131,5 @@ dmypy.json
|
||||||
|
|
||||||
# Pyre type checker
|
# Pyre type checker
|
||||||
.pyre/
|
.pyre/
|
||||||
|
go/state.json
|
||||||
|
python/logo.png
|
||||||
|
|
|
||||||
57
go/server.go
57
go/server.go
|
|
@ -3,8 +3,11 @@ package main
|
||||||
import (
|
import (
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"flag"
|
"flag"
|
||||||
|
"fmt"
|
||||||
|
"io/ioutil"
|
||||||
"log"
|
"log"
|
||||||
"net/http"
|
"net/http"
|
||||||
|
"os"
|
||||||
"strconv"
|
"strconv"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
|
@ -44,17 +47,17 @@ func get(w http.ResponseWriter, r *http.Request) {
|
||||||
|
|
||||||
defer c.Close()
|
defer c.Close()
|
||||||
ticker := time.NewTicker(1 * time.Second)
|
ticker := time.NewTicker(1 * time.Second)
|
||||||
var tmpImage = GetImage(img.width, img.height)
|
var tmpImage = GetImage(img.Width, img.Height)
|
||||||
|
|
||||||
for range ticker.C {
|
for range ticker.C {
|
||||||
|
|
||||||
diff := tmpImage.GetDiff(&img)
|
diff := tmpImage.GetDiff(&img)
|
||||||
for i := 0; i < int(diff.width*diff.height); i++ {
|
for i := 0; i < int(diff.Width*diff.Height); i++ {
|
||||||
pix := diff.pixels[i]
|
pix := diff.Pixels[i]
|
||||||
if pix.pixel.UserID != 0 {
|
if pix.Pixel.UserID != 0 {
|
||||||
x := i / int(diff.width)
|
x := i / int(diff.Width)
|
||||||
y := i % int(diff.height)
|
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}
|
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)
|
marshalMsg, err := json.Marshal(msg)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Println("error while writing image", err)
|
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 {
|
if err := c.WriteMessage(websocket.PingMessage, []byte{}); err != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
copy(tmpImage.pixels, img.pixels)
|
copy(tmpImage.Pixels, img.Pixels)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -79,7 +82,6 @@ func set(w http.ResponseWriter, r *http.Request) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
c.SetReadLimit(maxMessageSize)
|
c.SetReadLimit(maxMessageSize)
|
||||||
|
|
||||||
c.SetPongHandler(func(string) error { c.SetReadDeadline(time.Now().Add(pongWait)); return nil })
|
c.SetPongHandler(func(string) error { c.SetReadDeadline(time.Now().Add(pongWait)); return nil })
|
||||||
|
|
||||||
defer c.Close()
|
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() {
|
func main() {
|
||||||
var addr = flag.String("addr", "localhost:8080", "http service address")
|
var addr = flag.String("addr", "localhost:8080", "http service address")
|
||||||
|
|
||||||
flag.Parse()
|
flag.Parse()
|
||||||
log.SetFlags(0)
|
log.SetFlags(0)
|
||||||
log.Println("starting server on", *addr)
|
log.Println("starting server on", *addr)
|
||||||
|
|
||||||
|
cachePath := "./state.json"
|
||||||
|
|
||||||
|
loadState(&img, cachePath)
|
||||||
|
go saveState(&img, cachePath)
|
||||||
|
|
||||||
http.HandleFunc("/get", get)
|
http.HandleFunc("/get", get)
|
||||||
http.HandleFunc("/set", set)
|
http.HandleFunc("/set", set)
|
||||||
|
|
||||||
|
|
|
||||||
46
go/util.go
46
go/util.go
|
|
@ -20,36 +20,36 @@ type pixel struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
type pixelContainer struct {
|
type pixelContainer struct {
|
||||||
pixel pixel
|
Pixel pixel `json:"pixel"`
|
||||||
Mutex sync.Mutex
|
Mutex sync.Mutex
|
||||||
}
|
}
|
||||||
|
|
||||||
type image struct {
|
type image struct {
|
||||||
width uint32
|
Width uint32 `json:"Width"`
|
||||||
height uint32
|
Height uint32 `json:"Height"`
|
||||||
pixels []pixelContainer
|
Pixels []pixelContainer `json:"Pixels"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func GetImage(w uint32, h uint32) image {
|
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++ {
|
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) {
|
func (p *pixelContainer) setColor(color uint8, timestamp int64, userid uint64) {
|
||||||
p.Mutex.Lock()
|
p.Mutex.Lock()
|
||||||
defer p.Mutex.Unlock()
|
defer p.Mutex.Unlock()
|
||||||
if timestamp > p.pixel.Timestamp {
|
if timestamp > p.Pixel.Timestamp {
|
||||||
p.pixel.Color = color
|
p.Pixel.Color = color
|
||||||
p.pixel.Timestamp = timestamp
|
p.Pixel.Timestamp = timestamp
|
||||||
p.pixel.UserID = userid
|
p.Pixel.UserID = userid
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (img *image) SetPixel(message Message) int {
|
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)
|
fmt.Printf("User %d tried accessing out of bounds \n", message.UserID)
|
||||||
return 1
|
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)
|
fmt.Printf("User %d tried setting non existent color \n", message.UserID)
|
||||||
return 1
|
return 1
|
||||||
}
|
}
|
||||||
pos := uint32(message.X)*uint32(img.width) + uint32(message.Y)
|
pos := uint32(message.X)*uint32(img.Width) + uint32(message.Y)
|
||||||
img.pixels[pos].setColor(message.Color, message.Timestamp, message.UserID)
|
img.Pixels[pos].setColor(message.Color, message.Timestamp, message.UserID)
|
||||||
return 0
|
return 0
|
||||||
}
|
}
|
||||||
|
|
||||||
func comparePixels(pixel1 *pixelContainer, pixel2 *pixelContainer) bool {
|
func comparePixels(pixel1 *pixelContainer, pixel2 *pixelContainer) bool {
|
||||||
return pixel1.pixel.Color == pixel2.pixel.Color &&
|
return pixel1.Pixel.Color == pixel2.Pixel.Color &&
|
||||||
pixel1.pixel.Timestamp == pixel2.pixel.Timestamp &&
|
pixel1.Pixel.Timestamp == pixel2.Pixel.Timestamp &&
|
||||||
pixel1.pixel.UserID == pixel2.pixel.UserID
|
pixel1.Pixel.UserID == pixel2.Pixel.UserID
|
||||||
}
|
}
|
||||||
|
|
||||||
func (img *image) GetDiff(img2 *image) image {
|
func (img *image) GetDiff(img2 *image) image {
|
||||||
diff := GetImage(img.width, img.height)
|
diff := GetImage(img.Width, img.Height)
|
||||||
for i := 0; i < int(img.width*img.height); i++ {
|
for i := 0; i < int(img.Width*img.Height); i++ {
|
||||||
if !comparePixels(&img.pixels[i], &img2.pixels[i]) {
|
if !comparePixels(&img.Pixels[i], &img2.Pixels[i]) {
|
||||||
diff.pixels[i].pixel.Color = img2.pixels[i].pixel.Color
|
diff.Pixels[i].Pixel.Color = img2.Pixels[i].Pixel.Color
|
||||||
diff.pixels[i].pixel.UserID = img2.pixels[i].pixel.UserID
|
diff.Pixels[i].Pixel.UserID = img2.Pixels[i].Pixel.UserID
|
||||||
diff.pixels[i].pixel.Timestamp = img2.pixels[i].pixel.Timestamp
|
diff.Pixels[i].Pixel.Timestamp = img2.Pixels[i].Pixel.Timestamp
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return diff
|
return diff
|
||||||
|
|
|
||||||
|
|
@ -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] = ([y*255 for y in colors[x.color]])
|
||||||
image[x.x][x.y] = ((x.color, x.color, x.color))
|
image[x.x][x.y] = ((x.color, x.color, x.color))
|
||||||
if i% 1000 == 0:
|
if i% 1000 == 0:
|
||||||
print("showing")
|
|
||||||
cv2.imshow("changes x", image)
|
cv2.imshow("changes x", image)
|
||||||
cv2.waitKey(10) & 0XFF
|
cv2.waitKey(10) & 0XFF
|
||||||
await websocket.send("1")
|
await websocket.send("1")
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue