From e841075b0dbde552ab20f4d79402da54271c1375 Mon Sep 17 00:00:00 2001 From: Thomas FORGIONE Date: Wed, 20 May 2015 16:28:53 +0200 Subject: [PATCH] Added support of previous / next in replay --- controllers/prototype/index.js | 57 +++++++++++++++++++++++----- posts/previous-next-clicked/index.js | 33 ++++++++++++++++ posts/previous-next-clicked/urls.js | 3 ++ sql/backup.pgsql | 14 +++++++ static/js/Logger.js | 51 ++++++++++++++++++------- static/js/PointerCamera.js | 16 +++++++- static/js/ReplayCamera.js | 5 +++ 7 files changed, 154 insertions(+), 25 deletions(-) create mode 100644 posts/previous-next-clicked/index.js create mode 100644 posts/previous-next-clicked/urls.js diff --git a/controllers/prototype/index.js b/controllers/prototype/index.js index 44b9c1f..cf45b68 100644 --- a/controllers/prototype/index.js +++ b/controllers/prototype/index.js @@ -131,6 +131,43 @@ var addResetsFromId = function(client, req, res, callback, id) { ); } +var addPreviousNextFromId = function(client, req, res, callback, id) { + client.query( + "SELECT ((camera).position).x AS px, " + + "((camera).position).y AS py, " + + "((camera).position).z AS pz, " + + "((camera).target).x AS tx, " + + "((camera).target).y AS ty, " + + "((camera).target).z AS tz, " + + "time AS time " + + "FROM previousnextclicked;", + [], + function(err, result) { + res.locals.path = res.locals.path || []; + for (var i in result.rows) { + res.locals.path.push( + { + type: 'previousnext', + time: result.rows[i].time, + previous: result.rows[i].previousnext == 'p', + position : { + x: result.rows[i].px, + y: result.rows[i].py, + z: result.rows[i].pz + }, + target : { + x: result.rows[i].tx, + y: result.rows[i].ty, + z: result.rows[i].tz + } + } + ); + } + callback(); + } + ); +} + var getAllUsers = function(req, res, callback) { pg.connect(pgc.url, function(err, client, release) { client.query( @@ -200,15 +237,17 @@ module.exports.replay_info = function(req, res) { addCoinsFromId(client, req, res, function() { addArrowsFromId(client, req, res, function() { addResetsFromId(client, req, res, function() { - res.locals.path.sort(function(elt1, elt2) { - // Dates as string can be compared - if (elt1.time < elt2.time) - return -1; - if (elt1.time > elt2.time) - return 1; - return 0; - }); - res.send(JSON.stringify(res.locals.path)); + addPreviousNextFromId(client, req, res, function() { + res.locals.path.sort(function(elt1, elt2) { + // Dates as string can be compared + if (elt1.time < elt2.time) + return -1; + if (elt1.time > elt2.time) + return 1; + return 0; + }); + res.send(JSON.stringify(res.locals.path)); + }, id); }, id); }, id); }, id); diff --git a/posts/previous-next-clicked/index.js b/posts/previous-next-clicked/index.js new file mode 100644 index 0000000..0bb693d --- /dev/null +++ b/posts/previous-next-clicked/index.js @@ -0,0 +1,33 @@ +var pg = require('pg'); +var secret = require('../../private'); + +module.exports.index = function(req, res) { + + var user_id = req.session.user_id; + var camera = req.body.camera; + + pg.connect(secret.url, function(err, client, release) { + client.query( + "INSERT INTO previousnextclicked(user_id, previousnext, time, camera)" + + "VALUES($1, $2, to_timestamp($3), ROW(ROW($4,$5,$6), ROW($7,$8,$9)));" , + [ + user_id, + req.body.previous ? 'p' : 'n', + req.body.time, + camera.position.x, + camera.position.y, + camera.position.z, + camera.target.x, + camera.target.y, + camera.target.z + ], + function(err, result) { + release(); + } + ); + }); + + res.setHeader('Content-Type', 'text/html'); + res.send("user_id = " + user_id); + +} diff --git a/posts/previous-next-clicked/urls.js b/posts/previous-next-clicked/urls.js new file mode 100644 index 0000000..8499640 --- /dev/null +++ b/posts/previous-next-clicked/urls.js @@ -0,0 +1,3 @@ +module.exports = { + '/previous-next-clicked': 'index' +} diff --git a/sql/backup.pgsql b/sql/backup.pgsql index 0127872..6707b69 100644 --- a/sql/backup.pgsql +++ b/sql/backup.pgsql @@ -3,9 +3,15 @@ DROP TABLE IF EXISTS arrowclicked CASCADE; DROP TABLE IF EXISTS coinclicked CASCADE; DROP TABLE IF EXISTS keyboardevent CASCADE; DROP TABLE IF EXISTS resetclicked CASCADE; +DROP TABLE IF EXISTS previousnextclicked CASCADE; DROP TYPE IF EXISTS VECTOR3 CASCADE; DROP TYPE IF EXISTS CAMERA CASCADE; +DROP TYPE IF EXISTS PREVIOUSNEXT CASCADE; + +CREATE TYPE PREVIOUSNEXT AS ENUM( + 'p', 'n' +); CREATE TYPE VECTOR3 AS( x FLOAT, @@ -49,3 +55,11 @@ CREATE TABLE resetclicked( user_id SERIAL REFERENCES users (id), time TIMESTAMP DEFAULT NOW() ); + +CREATE TABLE previousnextclicked( + id SERIAL PRIMARY KEY, + user_id SERIAL REFERENCES users (id), + previousnext PREVIOUSNEXT NOT NULL, + time TIMESTAMP DEFAULT NOW(), + camera CAMERA +); diff --git a/static/js/Logger.js b/static/js/Logger.js index ed18926..b54c46d 100644 --- a/static/js/Logger.js +++ b/static/js/Logger.js @@ -8,9 +8,30 @@ BD.Private.sendData = function(url, data) { var xhr = new XMLHttpRequest(); xhr.open("POST", url, true); xhr.setRequestHeader("Content-type", "application/json;charset=UTF-8"); + + xhr.onreadystatechange = function() { + if(xhr.readyState == 4 && xhr.status == 200) { + console.log(xhr.responseText); + } + } xhr.send(JSON.stringify(data)); } +BD.Private.compactCamera = function(camera) { + return { + position: { + x: camera.position.x, + y: camera.position.y, + z: camera.position.z + }, + target: { + x: camera.target.x, + y: camera.target.y, + z: camera.target.z + } + }; +} + BD.Event = {}; BD.Event.ArrowClicked = function() {}; @@ -30,21 +51,11 @@ BD.Event.CoinClicked.prototype.send = function() { BD.Event.KeyboardEvent = function() {}; BD.Event.KeyboardEvent.prototype.send = function() { var url = "/keyboard-event"; + var data = { - camera: { - // Compact camera - position: { - x: this.camera.position.x, - y: this.camera.position.y, - z: this.camera.position.z - }, - target: { - x: this.camera.target.x, - y: this.camera.target.y, - z: this.camera.target.z - } - } - }; + camera: BD.Private.compactCamera(this.camera) + } + BD.Private.sendData(url, data); } @@ -54,3 +65,15 @@ BD.Event.ResetClicked.prototype.send = function() { var data = {}; BD.Private.sendData(url, data); } + +BD.Event.PreviousNextClicked = function() {}; +BD.Event.PreviousNextClicked.prototype.send = function() { + var url = "/previous-next-clicked"; + var data = { + // casts previous to boolean + previous: this.previous, + camera: BD.Private.compactCamera(this.camera) + }; + + BD.Private.sendData(url, data); +} diff --git a/static/js/PointerCamera.js b/static/js/PointerCamera.js index 170ef52..f3e9620 100644 --- a/static/js/PointerCamera.js +++ b/static/js/PointerCamera.js @@ -350,14 +350,26 @@ PointerCamera.prototype.save = function() { PointerCamera.prototype.undo = function() { var move = this.history.undo(); - if (move !== undefined) + if (move !== undefined) { + var event = new BD.Event.PreviousNextClicked(); + event.previous = true; + event.camera = move; + event.send(); + this.move(move, false); + } } PointerCamera.prototype.redo = function() { var move = this.history.redo(); - if (move !== undefined) + if (move !== undefined) { + var event = new BD.Event.PreviousNextClicked(); + event.previous = false; + event.camera = move; + event.send(); + this.move(move, false); + } } PointerCamera.prototype.undoable = function() { diff --git a/static/js/ReplayCamera.js b/static/js/ReplayCamera.js index bc84114..edcc854 100644 --- a/static/js/ReplayCamera.js +++ b/static/js/ReplayCamera.js @@ -45,11 +45,14 @@ ReplayCamera.prototype.update = function(time) { if (this.started) { if (this.event.type == 'camera') { this.linearMotion(time); + } else if (this.event.type == 'previousnext') { + this.linearMotion(time / 5); } else if (this.event.type == 'arrow') { this.hermiteMotion(time); } else if (this.event.type == 'coin') { // Nothing to do } else if (this.event.type == 'reset') { + // Nothing to do } } } @@ -112,6 +115,8 @@ ReplayCamera.prototype.nextEvent = function() { self.nextEvent(); },500); })(this); + } else if (this.event.type == 'previousnext') { + this.move(this.event); } }