From e5323ecaf854924cdc6226a5db716d35ae347e9b Mon Sep 17 00:00:00 2001 From: Kristian Lyngstol Date: Sat, 28 May 2016 16:42:32 +0200 Subject: Fix numerous time-travel issues in front and API Fixes #69 #11 #5 Introduces nmsTime which unifies the time travel code a bit. It still needs some work, but this is much better. All conversion is now done by native JavaScript methods, freeing us from the hell that is parsing it ourself. One thing should be added: The backend should discard any now=values that are not 5-minute intervals. We don't want to kill the cache and the database by extension. Still need to re-implement the "replay event" shorthand, but that ties in to #54 --- web/js/nms-time.js | 150 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 150 insertions(+) create mode 100644 web/js/nms-time.js (limited to 'web/js/nms-time.js') diff --git a/web/js/nms-time.js b/web/js/nms-time.js new file mode 100644 index 0000000..e857956 --- /dev/null +++ b/web/js/nms-time.js @@ -0,0 +1,150 @@ +"use strict"; + +/* + * Deals with controlling time. + * + * More specifically: replaying of past events, fast forwarding, pausing, + * etc. + * + * The interface is a bit bloated at the moment, though. + */ +var nmsTime = nmsTime || { + _now: undefined, + _handle: undefined +} + +nmsTime.replayEvent = function() { + throw "Not yet implemented."; +} + +nmsTime.isRealTime = function() { + if (nmsTime._now == undefined && nmsTime._handle == undefined) + return true; + return false; +} + +nmsTime.startNowPicker = function () { + $.datetimepicker.setLocale('no'); + $('#nowPicker').datetimepicker('destroy'); + var now; + if (nmsTime._now == undefined) + now = new Date(); + else + now = nmsTime._now; + now.setSeconds(0); + now.setMilliseconds(0); + var datepicker = $('#nowPicker').datetimepicker({ + value: now, + step: 5, + mask:false, + inline:true, + todayButton: true, + validateOnBlur:false, + dayOfWeekStart:1, + maxDate:'+1970/01/01', + onSelectDate: function(ct,$i){ + document.getElementById('nowPicker').dataset.iso = new Date(ct.valueOf()); + }, + onSelectTime: function(ct,$i){ + document.getElementById('nowPicker').dataset.iso = new Date(ct.valueOf()); + }, + onGenerate: function(ct,$i){ + document.getElementById('nowPicker').dataset.iso = new Date(ct.valueOf()); + } + }); +} + +nmsTime.setNow = function(now) { + var newDate = new Date(now); + newDate.setSeconds(0); + newDate.setMilliseconds(0); + newDate.setMinutes(newDate.getMinutes() - newDate.getMinutes()%5); + nmsTime._now = newDate; +} + +nmsTime._updateData = function() { + nmsData.now = nmsTime._now.getTime() / 1000; +} + +nmsTime.realTime = function() { + nmsTime.stopPlayback(); + nmsTime._now = undefined; + nmsData.now = undefined; +} + +/* + * Step a fixed amount of time, measured in minutes. + * + * Try to align this to whole 5 minutes. It will be enforced in future + * backend versions to avoid bloating the cache and thus also stressing the + * database + */ +nmsTime.step = function(amount) { + if (nmsTime._now == null) + throw "Stepping without nmsTime._now"; + if (amount == 0 || amount == undefined) + throw "Invalid step"; + if (nmsTime._now.getTime() + (amount * 1000 * 60 ) > Date.now()) { + nmsTime.realTime(); + return; + } + nmsTime._now.setMinutes(nmsTime._now.getMinutes() + amount); + nmsTime._updateData(); +} + +/* + * Step based on key-press. Same as step() but stops playback if it's + * active and allows you to rewind from a "live" map. + */ +nmsTime.stepKey = function(amount) { + nmsTime.stopPlayback(); + if (nmsTime._now == undefined) { + nmsTime.setNow(Date.now()); + } + nmsTime.step(amount); +} + +/* + * Target of setInterval() when replaying. + */ +nmsTime._tick = function() { + nmsTime.step(nmsTime._speed); +} + +/* + * We now have a time (presumably), start playback. + * + * Aborts if the time provided is greater than real time. + * + * Gondul does not _yet_ support fast forwarding into the future. + */ +nmsTime.startPlayback = function(speed) { + if (nmsTime._handle) + nmsTime.stopPlayback(); + if (nmsTime._now.getTime() > Date.now()) { + nmsTime.stopPlayback(); + return; + } + nmsTime._speed = speed; + nmsTime._handle = setInterval(nmsTime._tick,1000); +} + +nmsTime.togglePause = function() { + if (nmsTime._handle) { + nmsTime.stopPlayback(); + } else { + if (nmsTime.isRealTime()) { + nmsTime.setNow(Date.now()); + nmsTime._updateData(); + } else { + nmsTime.startPlayback(nmsTime._speed ? nmsTime._speed : 5); + } + } +} + +nmsTime.stopPlayback = function() { + if (nmsTime._handle) + clearInterval(nmsTime._handle); + nmsTime._handle = undefined; +} + -- cgit v1.2.3