From 08ee44a5c4c26dd754ef4c7a8993f98a1270b7cc Mon Sep 17 00:00:00 2001
From: Starbeamrainbowlabs <sbrl@starbeamrainbowlabs.com>
Date: Sun, 19 Feb 2017 11:57:42 +0000
Subject: [PATCH] Store client state updates sent by the server.

---
 Nibriboard/ClientFiles/BoardWindow.js    | 32 +++++++++++++-
 Nibriboard/ClientFiles/ViewportSyncer.js | 56 ++++++++++++++++++++++++
 2 files changed, 87 insertions(+), 1 deletion(-)
 create mode 100644 Nibriboard/ClientFiles/ViewportSyncer.js

diff --git a/Nibriboard/ClientFiles/BoardWindow.js b/Nibriboard/ClientFiles/BoardWindow.js
index 7595822..9fe6b7e 100644
--- a/Nibriboard/ClientFiles/BoardWindow.js
+++ b/Nibriboard/ClientFiles/BoardWindow.js
@@ -41,6 +41,8 @@ class BoardWindow extends EventEmitter
 		// Setup the input controls
 		window.panzoom(canvas, this.handleCanvasMovement.bind(this));
 		
+		// --~~~--
+		
 		// Fetch the RippleLink connection information and other settings from
 		// the server
 		get("/Settings.json").then(JSON.parse).then((function(settings) {
@@ -51,8 +53,15 @@ class BoardWindow extends EventEmitter
 			console.error(`Error: Failed to fetch settings from server! Response: ${errorMessage}`);
 		});
 		
+		// --~~~--
+		
+		// Setup a bunch of event listeners
+		// The ones that depend on the RippleLink will get setup later
+		
 		// Make the canvas track the window size
 		this.trackWindowSize();
+		
+		this.on("OtherClientUpdate", this.)
 	}
 	
 	/**
@@ -74,12 +83,16 @@ class BoardWindow extends EventEmitter
 				InitialAbsCursorPosition: this.cursorPosition
 			});
 		}).bind(this));
+		// Create a map to store information about other clients in
+		this.otherClients = new Map();
 		
-		// Track the mouse position
+		// Keep the server up to date on our viewport and cursor position
 		this.viewportSyncer = new ViewportSyncer(this.rippleLink, this.cursorUpdateFrequency)
 		
 		// RippleLink message bindings
 		
+		// Handle other clients' state updates
+		this.rippleLink.on("ClientStates", this.handlePeerUpdates.bind(this));
 	}
 	
 	/**
@@ -151,6 +164,23 @@ class BoardWindow extends EventEmitter
 	handleCanvasMovement(event) {
 		this.viewportState = event; // Store the viewport information for later
 	}
+	
+	handlePeerUpdates(message) {
+		// Update our knowledge about other clients
+		for (let otherClient of message) {
+			// If this client is new, emit an event about it
+			if(!this.otherClients.has(otherClient.Id))
+				this.emit("OtherClientConnect", otherClient);
+			else // If not, emit a normal update message about it
+				this.emit("OtherClientUpdate", otherClient);
+			// Store the information for later
+			this.otherClients.set(otherClient.Id, otherClient);
+		}
+	}
+	
+	handleOtherClientUpdate(otherClientData) {
+		
+	}
 }
 
 export default BoardWindow;
diff --git a/Nibriboard/ClientFiles/ViewportSyncer.js b/Nibriboard/ClientFiles/ViewportSyncer.js
new file mode 100644
index 0000000..4ceea18
--- /dev/null
+++ b/Nibriboard/ClientFiles/ViewportSyncer.js
@@ -0,0 +1,56 @@
+"use strict";
+
+class CursorSyncer
+{
+	constructor(inRippleLink, syncFrequency)
+	{
+		// The ripple link we should send the cursor updates down
+		this.rippleLink = inRippleLink;
+		// The target frequency in fps at we should send sursor updates.
+		this.cursorUpdateFrequency = syncFrequency;
+		
+		// Register ourselves to start sending cursor updates once the ripple
+		// link connects
+		this.rippleLink.on("connect", this.setup.bind(this));
+	}
+	
+	setup()
+	{
+		// The last time we sent a cursor update to the server.
+		this.lastCursorUpdate = 0;
+		
+		document.addEventListener("mousemove", (function(event) {
+			this.cursorPosition = {
+				X: event.clientX,
+				Y: event.clientY
+			};
+			
+			setTimeout((function() {
+			    // Throttle the cursor updates we send to the server - a high
+			    // update frequency here will just consume bandwidth and is only
+			    // noticable if you have a good connection
+				if(+new Date() - this.lastCursorUpdate < 1 / this.cursorUpdateFrequency)
+					return false;
+					
+				// Update the server on the mouse's position
+				this.sendCursorUpdate();
+				
+				this.lastFrameStart = +new Date();
+			}).bind(this), 1 / this.cursorUpdateFrequency);
+			
+		}).bind(this));
+		
+		this.sendCursorUpdate();
+	}
+	
+	sendCursorUpdate()
+	{
+		// Update the server on the mouse's position
+		this.rippleLink.send({
+			"event": "CursorPosition",
+			"AbsCursorPosition": this.cursorPosition
+		});
+	}
+}
+
+export default CursorSyncer;
