From 37d2861352a32ebd894504073266edbf2f223d26 Mon Sep 17 00:00:00 2001 From: Julian Descottes Date: Tue, 13 Dec 2016 09:17:34 +0100 Subject: [PATCH 1/3] move fps info from preview controller to piskel model --- src/js/Events.js | 1 + src/js/app.js | 8 ++--- src/js/controller/piskel/PiskelController.js | 17 ++++++----- .../controller/preview/PreviewController.js | 29 +++++++------------ .../controller/settings/ImportController.js | 3 +- src/js/devtools/DrawingTestPlayer.js | 2 +- src/js/model/Piskel.js | 19 +++++------- src/js/service/BackupService.js | 6 ---- src/js/service/FileDropperService.js | 3 +- src/js/service/HistoryService.js | 2 ++ src/js/service/ImportService.js | 3 +- .../service/storage/DesktopStorageService.js | 3 +- src/js/utils/serialization/Deserializer.js | 4 +-- .../arraybuffer/ArrayBufferDeserializer.js | 4 +-- .../serialization/backward/Deserializer_v0.js | 2 +- .../serialization/backward/Deserializer_v1.js | 4 +-- test/js/service/HistoryServiceTest.js | 2 +- test/js/utils/serialization/SerializerTest.js | 2 +- 18 files changed, 47 insertions(+), 67 deletions(-) diff --git a/src/js/Events.js b/src/js/Events.js index 5241ce03..75c37067 100644 --- a/src/js/Events.js +++ b/src/js/Events.js @@ -59,6 +59,7 @@ var Events = { AFTER_SAVING_PISKEL: 'AFTER_SAVING_PISKEL', FRAME_SIZE_CHANGED : 'FRAME_SIZE_CHANGED', + FPS_CHANGED : 'FPS_CHANGED', SELECTION_CREATED: 'SELECTION_CREATED', SELECTION_MOVE_REQUEST: 'SELECTION_MOVE_REQUEST', diff --git a/src/js/app.js b/src/js/app.js index 489d6389..b30d430e 100644 --- a/src/js/app.js +++ b/src/js/app.js @@ -19,8 +19,9 @@ this.shortcutService.init(); var size = pskl.UserSettings.get(pskl.UserSettings.DEFAULT_SIZE); + var fps = Constants.DEFAULT.FPS; var descriptor = new pskl.model.piskel.Descriptor('New Piskel', ''); - var piskel = new pskl.model.Piskel(size.width, size.height, descriptor); + var piskel = new pskl.model.Piskel(size.width, size.height, fps, descriptor); var layer = new pskl.model.Layer('Layer 1'); var frame = new pskl.model.Frame(size.width, size.height); @@ -177,16 +178,13 @@ loadPiskel_ : function (piskelData) { var serializedPiskel = piskelData.piskel; - pskl.utils.serialization.Deserializer.deserialize(serializedPiskel, function (piskel, extra) { + pskl.utils.serialization.Deserializer.deserialize(serializedPiskel, function (piskel) { pskl.app.piskelController.setPiskel(piskel); $.publish(Events.PISKEL_SAVED); - var fps = extra.fps; if (piskelData.descriptor) { // Backward compatibility for v2 or older piskel.setDescriptor(piskelData.descriptor); - fps = piskelData.fps; } - pskl.app.previewController.setFPS(fps); }); }, diff --git a/src/js/controller/piskel/PiskelController.js b/src/js/controller/piskel/PiskelController.js index b03fb30a..f9e38171 100644 --- a/src/js/controller/piskel/PiskelController.js +++ b/src/js/controller/piskel/PiskelController.js @@ -35,15 +35,16 @@ return this.piskel.getWidth(); }; - /** - * TODO : this should be removed - * FPS should be stored in the Piskel model and not in the - * previewController - * Then piskelController should be able to return this information - * @return {Number} Frames per second for the current animation - */ ns.PiskelController.prototype.getFPS = function () { - return pskl.app.previewController.getFPS(); + return this.piskel.fps; + }; + + ns.PiskelController.prototype.setFPS = function (fps) { + if (typeof fps !== 'number') { + return; + } + this.piskel.fps = fps; + $.publish(Events.FPS_CHANGED); }; ns.PiskelController.prototype.getLayers = function () { diff --git a/src/js/controller/preview/PreviewController.js b/src/js/controller/preview/PreviewController.js index 96b701b7..c1619001 100644 --- a/src/js/controller/preview/PreviewController.js +++ b/src/js/controller/preview/PreviewController.js @@ -21,23 +21,12 @@ this.lastRenderTime = 0; this.renderFlag = true; - /** - * !! WARNING !! ALL THE INITIALISATION BELOW SHOULD BE MOVED TO INIT() - * IT WILL STAY HERE UNTIL WE CAN REMOVE SETFPS (see comment below) - */ this.fpsRangeInput = document.querySelector('#preview-fps'); this.fpsCounterDisplay = document.querySelector('#display-fps'); this.openPopupPreview = document.querySelector('.open-popup-preview-button'); this.originalSizeButton = document.querySelector('.original-size-button'); this.toggleOnionSkinButton = document.querySelector('.preview-toggle-onion-skin'); - /** - * !! WARNING !! THIS SHOULD REMAIN HERE UNTIL, BECAUSE THE PREVIEW CONTROLLER - * IS THE SOURCE OF TRUTH AT THE MOMENT WHEN IT COMES TO FPSs - * IT WILL BE QUERIED BY OTHER OBJECTS SO DEFINE IT AS SOON AS POSSIBLE - */ - this.setFPS(Constants.DEFAULT.FPS); - this.renderer = new pskl.rendering.frame.BackgroundImageFrameRenderer(this.container); this.popupPreviewController = new ns.PopupPreviewController(piskelController); }; @@ -58,7 +47,10 @@ $.subscribe(Events.FRAME_SIZE_CHANGED, this.onFrameSizeChange_.bind(this)); $.subscribe(Events.USER_SETTINGS_CHANGED, $.proxy(this.onUserSettingsChange_, this)); $.subscribe(Events.PISKEL_SAVE_STATE, this.setRenderFlag_.bind(this, true)); + $.subscribe(Events.FPS_CHANGED, this.updateFPS_.bind(this)); + // On PISKEL_RESET, set the render flag and update the FPS input $.subscribe(Events.PISKEL_RESET, this.setRenderFlag_.bind(this, true)); + $.subscribe(Events.PISKEL_RESET, this.updateFPS_.bind(this)); this.initTooltips_(); this.popupPreviewController.init(); @@ -66,6 +58,7 @@ this.updateZoom_(); this.updateOnionSkinPreview_(); this.updateOriginalSizeButton_(); + this.updateFPS_(); this.updateMaxFPS_(); this.updateContainerDimensions_(); }; @@ -113,7 +106,7 @@ ns.PreviewController.prototype.updateMaxFPS_ = function () { var maxFps = pskl.UserSettings.get(pskl.UserSettings.MAX_FPS); this.fpsRangeInput.setAttribute('max', maxFps); - this.setFPS(Math.min(this.fps, maxFps)); + this.piskelController.setFPS(Math.min(maxFps, this.piskelController.getFPS())); }; ns.PreviewController.prototype.updateZoom_ = function () { @@ -145,15 +138,17 @@ * Event handler triggered on 'input' or 'change' events. */ ns.PreviewController.prototype.onFpsRangeInputUpdate_ = function (evt) { - this.setFPS(parseInt(this.fpsRangeInput.value, 10)); + var fps = parseInt(this.fpsRangeInput.value, 10); + this.piskelController.setFPS(fps); // blur only on 'change' events, as blurring on 'input' breaks on Firefox if (evt.type === 'change') { this.fpsRangeInput.blur(); } }; - ns.PreviewController.prototype.setFPS = function (fps) { - if (typeof fps === 'number') { + ns.PreviewController.prototype.updateFPS_ = function () { + var fps = this.piskelController.getFPS(); + if (fps !== this.fps) { this.fps = fps; // reset this.fpsRangeInput.value = 0; @@ -163,10 +158,6 @@ } }; - ns.PreviewController.prototype.getFPS = function () { - return this.fps; - }; - ns.PreviewController.prototype.render = function (delta) { this.elapsedTime += delta; var index = this.getNextIndex_(delta); diff --git a/src/js/controller/settings/ImportController.js b/src/js/controller/settings/ImportController.js index fe960c8d..4909f397 100644 --- a/src/js/controller/settings/ImportController.js +++ b/src/js/controller/settings/ImportController.js @@ -79,9 +79,8 @@ ns.ImportController.prototype.openPiskelFile_ = function (file) { if (this.isPiskel_(file)) { - pskl.utils.PiskelFileUtils.loadFromFile(file, function (piskel, extra) { + pskl.utils.PiskelFileUtils.loadFromFile(file, function (piskel) { pskl.app.piskelController.setPiskel(piskel); - pskl.app.previewController.setFPS(extra.fps); }); this.closeDrawer_(); } diff --git a/src/js/devtools/DrawingTestPlayer.js b/src/js/devtools/DrawingTestPlayer.js index 2a0940c6..6add3321 100644 --- a/src/js/devtools/DrawingTestPlayer.js +++ b/src/js/devtools/DrawingTestPlayer.js @@ -46,7 +46,7 @@ ns.DrawingTestPlayer.prototype.createPiskel_ = function (width, height) { var descriptor = new pskl.model.piskel.Descriptor('TestPiskel', ''); - var piskel = new pskl.model.Piskel(width, height, descriptor); + var piskel = new pskl.model.Piskel(width, height, 12, descriptor); var layer = new pskl.model.Layer('Layer 1'); var frame = new pskl.model.Frame(width, height); diff --git a/src/js/model/Piskel.js b/src/js/model/Piskel.js index 2ff34e9e..ba091352 100644 --- a/src/js/model/Piskel.js +++ b/src/js/model/Piskel.js @@ -8,21 +8,14 @@ * @param {String} name * @param {String} description */ - ns.Piskel = function (width, height, descriptor) { + ns.Piskel = function (width, height, fps, descriptor) { if (width && height && descriptor) { - /** @type {Array} */ this.layers = []; - - /** @type {Number} */ this.width = width; - - /** @type {Number} */ this.height = height; - this.descriptor = descriptor; - - /** @type {String} */ this.savePath = null; + this.fps = fps; } else { throw 'Missing arguments in Piskel constructor : ' + Array.prototype.join.call(arguments, ','); @@ -35,11 +28,11 @@ * @param {Array} layers * @return {pskl.model.Piskel} */ - ns.Piskel.fromLayers = function (layers, descriptor) { + ns.Piskel.fromLayers = function (layers, fps, descriptor) { var piskel = null; if (layers.length > 0 && layers[0].size() > 0) { var sampleFrame = layers[0].getFrameAt(0); - piskel = new pskl.model.Piskel(sampleFrame.getWidth(), sampleFrame.getHeight(), descriptor); + piskel = new pskl.model.Piskel(sampleFrame.getWidth(), sampleFrame.getHeight(), fps, descriptor); layers.forEach(piskel.addLayer.bind(piskel)); } else { throw 'Piskel.fromLayers expects array of non empty pskl.model.Layer as first argument'; @@ -59,6 +52,10 @@ return this.width; }; + ns.Piskel.prototype.getFPS = function () { + return this.fps; + }; + ns.Piskel.prototype.getLayers = function () { return this.layers; }; diff --git a/src/js/service/BackupService.js b/src/js/service/BackupService.js index 5e39601f..7541a563 100644 --- a/src/js/service/BackupService.js +++ b/src/js/service/BackupService.js @@ -26,7 +26,6 @@ var info = { name : descriptor.name, description : descriptor.info, - fps : this.piskelController.getFPS(), date : Date.now(), hash : hash }; @@ -47,16 +46,11 @@ }; ns.BackupService.prototype.load = function() { - var previousPiskel = window.localStorage.getItem('bkp.prev.piskel'); - var previousInfo = window.localStorage.getItem('bkp.prev.info'); - previousPiskel = JSON.parse(previousPiskel); - previousInfo = JSON.parse(previousInfo); pskl.utils.serialization.Deserializer.deserialize(previousPiskel, function (piskel) { pskl.app.piskelController.setPiskel(piskel); - pskl.app.previewController.setFPS(previousInfo.fps); }); }; diff --git a/src/js/service/FileDropperService.js b/src/js/service/FileDropperService.js index 975aedb0..e42f364c 100644 --- a/src/js/service/FileDropperService.js +++ b/src/js/service/FileDropperService.js @@ -52,10 +52,9 @@ pskl.UserSettings.set(pskl.UserSettings.SELECTED_PALETTE, palette.id); }; - ns.FileDropperService.prototype.onPiskelFileLoaded_ = function (piskel, extra) { + ns.FileDropperService.prototype.onPiskelFileLoaded_ = function (piskel) { if (window.confirm('This will replace your current animation')) { pskl.app.piskelController.setPiskel(piskel); - pskl.app.previewController.setFPS(extra.fps); } }; diff --git a/src/js/service/HistoryService.js b/src/js/service/HistoryService.js index b15e410a..60f363f8 100644 --- a/src/js/service/HistoryService.js +++ b/src/js/service/HistoryService.js @@ -51,6 +51,7 @@ action : action, frameIndex : action.state ? action.state.frameIndex : this.piskelController.currentFrameIndex, layerIndex : action.state ? action.state.layerIndex : this.piskelController.currentLayerIndex, + fps : this.piskelController.getFPS(), uuid: pskl.utils.Uuid.generate() }; @@ -182,6 +183,7 @@ ns.HistoryService.prototype.setupState = function (state) { this.piskelController.setCurrentFrameIndex(state.frameIndex); this.piskelController.setCurrentLayerIndex(state.layerIndex); + this.piskelController.setFPS(state.fps); }; ns.HistoryService.prototype.replayState = function (state) { diff --git a/src/js/service/ImportService.js b/src/js/service/ImportService.js index 44d1513b..e1807d80 100644 --- a/src/js/service/ImportService.js +++ b/src/js/service/ImportService.js @@ -101,10 +101,9 @@ var frames = this.createFramesFromImages_(images, frameSizeX, frameSizeY, smoothing); var layer = pskl.model.Layer.fromFrames('Layer 1', frames); var descriptor = new pskl.model.piskel.Descriptor('Imported piskel', ''); - var piskel = pskl.model.Piskel.fromLayers([layer], descriptor); + var piskel = pskl.model.Piskel.fromLayers([layer], Constants.DEFAULT.FPS, descriptor); this.piskelController_.setPiskel(piskel); - this.previewController_.setFPS(Constants.DEFAULT.FPS); }; /** diff --git a/src/js/service/storage/DesktopStorageService.js b/src/js/service/storage/DesktopStorageService.js index 6ceab17c..aa6963a7 100644 --- a/src/js/service/storage/DesktopStorageService.js +++ b/src/js/service/storage/DesktopStorageService.js @@ -37,11 +37,10 @@ ns.DesktopStorageService.prototype.load = function (savePath) { pskl.utils.FileUtilsDesktop.readFile(savePath).then(function (content) { - pskl.utils.PiskelFileUtils.decodePiskelFile(content, function (piskel, extra) { + pskl.utils.PiskelFileUtils.decodePiskelFile(content, function (piskel) { // store save path so we can re-save without opening the save dialog piskel.savePath = savePath; pskl.app.piskelController.setPiskel(piskel); - pskl.app.previewController.setFPS(extra.fps); }); }); }; diff --git a/src/js/utils/serialization/Deserializer.js b/src/js/utils/serialization/Deserializer.js index 0a7769b6..583ca592 100644 --- a/src/js/utils/serialization/Deserializer.js +++ b/src/js/utils/serialization/Deserializer.js @@ -28,7 +28,7 @@ var description = piskelData.description || ''; var descriptor = new pskl.model.piskel.Descriptor(name, description); - this.piskel_ = new pskl.model.Piskel(piskelData.width, piskelData.height, descriptor); + this.piskel_ = new pskl.model.Piskel(piskelData.width, piskelData.height, piskelData.fps, descriptor); this.layersToLoad_ = piskelData.layers.length; if (piskelData.expanded) { @@ -85,7 +85,7 @@ this.layers_.forEach(function (layer) { this.piskel_.addLayer(layer); }.bind(this)); - this.callback_(this.piskel_, {fps: this.data_.piskel.fps}); + this.callback_(this.piskel_); } }; })(); diff --git a/src/js/utils/serialization/arraybuffer/ArrayBufferDeserializer.js b/src/js/utils/serialization/arraybuffer/ArrayBufferDeserializer.js index 12264f42..7fb77d51 100644 --- a/src/js/utils/serialization/arraybuffer/ArrayBufferDeserializer.js +++ b/src/js/utils/serialization/arraybuffer/ArrayBufferDeserializer.js @@ -90,7 +90,7 @@ } var descriptor = new pskl.model.piskel.Descriptor(descriptorName, descriptorDescription); - var piskel = new pskl.model.Piskel(width, height, descriptor); + var piskel = new pskl.model.Piskel(width, height, fps, descriptor); var loadedLayers = 0; var loadLayerImage = function(layer, cb) { @@ -103,7 +103,7 @@ loadedLayers++; if (loadedLayers == layerCount) { - cb(piskel, {fps: fps}); + cb(piskel); } }; image.src = layer.dataUri; diff --git a/src/js/utils/serialization/backward/Deserializer_v0.js b/src/js/utils/serialization/backward/Deserializer_v0.js index d1eec0c0..ee16265c 100644 --- a/src/js/utils/serialization/backward/Deserializer_v0.js +++ b/src/js/utils/serialization/backward/Deserializer_v0.js @@ -14,6 +14,6 @@ var descriptor = new pskl.model.piskel.Descriptor('Deserialized piskel', ''); var layer = pskl.model.Layer.fromFrames('Layer 1', frames); - this.callback_(pskl.model.Piskel.fromLayers([layer], descriptor), {fps: Constants.DEFAULTS.FPS}); + this.callback_(pskl.model.Piskel.fromLayers([layer], Constants.DEFAULTS.FPS, descriptor)); }; })(); diff --git a/src/js/utils/serialization/backward/Deserializer_v1.js b/src/js/utils/serialization/backward/Deserializer_v1.js index 7b777c62..6d5df3fd 100644 --- a/src/js/utils/serialization/backward/Deserializer_v1.js +++ b/src/js/utils/serialization/backward/Deserializer_v1.js @@ -9,14 +9,14 @@ ns.Deserializer_v1.prototype.deserialize = function () { var piskelData = this.data_.piskel; var descriptor = new pskl.model.piskel.Descriptor('Deserialized piskel', ''); - var piskel = new pskl.model.Piskel(piskelData.width, piskelData.height, descriptor); + var piskel = new pskl.model.Piskel(piskelData.width, piskelData.height, Constants.DEFAULTS.FPS, descriptor); piskelData.layers.forEach(function (serializedLayer) { var layer = this.deserializeLayer(serializedLayer); piskel.addLayer(layer); }.bind(this)); - this.callback_(piskel, {fps: Constants.DEFAULTS.FPS}); + this.callback_(piskel); }; ns.Deserializer_v1.prototype.deserializeLayer = function (layerString) { diff --git a/test/js/service/HistoryServiceTest.js b/test/js/service/HistoryServiceTest.js index 4e8c6aac..c85f6541 100644 --- a/test/js/service/HistoryServiceTest.js +++ b/test/js/service/HistoryServiceTest.js @@ -22,7 +22,7 @@ describe("History Service suite", function() { }; var createMockHistoryService = function () { - var mockPiskelController = { getPiskel : function () {} }; + var mockPiskelController = { getPiskel : function () {}, getFPS : function () { return 12; } }; var mockShortcutService = { registerShortcuts : function () {}, registerShortcut : function () {} diff --git a/test/js/utils/serialization/SerializerTest.js b/test/js/utils/serialization/SerializerTest.js index 44d21bf5..2798342d 100644 --- a/test/js/utils/serialization/SerializerTest.js +++ b/test/js/utils/serialization/SerializerTest.js @@ -13,7 +13,7 @@ describe("Serialization/Deserialization test", function() { it("serializes layer opacity", function(done) { var descriptor = new pskl.model.piskel.Descriptor('piskelName', 'piskelDesc'); - var piskel = new pskl.model.Piskel(1, 1, descriptor); + var piskel = new pskl.model.Piskel(1, 1, 1, descriptor); piskel.addLayer(new pskl.model.Layer('layer1')); piskel.addLayer(new pskl.model.Layer('layer2')); From 25ede9ffff9b98ed884d4a977aac3743d3c11be5 Mon Sep 17 00:00:00 2001 From: Julian Descottes Date: Tue, 13 Dec 2016 11:00:58 +0100 Subject: [PATCH 2/3] cleanup unused arguments in PiskelFileUtils --- src/js/utils/PiskelFileUtils.js | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/src/js/utils/PiskelFileUtils.js b/src/js/utils/PiskelFileUtils.js index f9e70284..4d7680e6 100644 --- a/src/js/utils/PiskelFileUtils.js +++ b/src/js/utils/PiskelFileUtils.js @@ -5,7 +5,7 @@ /** * Load a piskel from a piskel file. * After deserialization is successful, the provided success callback will be called. - * Success callback is expected to handle 3 arguments : (piskel:Piskel, descriptor:PiskelDescriptor, fps:Number) + * Success callback is expected to receive a single Piskel object argument * @param {File} file the .piskel file to load * @param {Function} onSuccess Called if the deserialization of the piskel is successful * @param {Function} onError NOT USED YET @@ -15,13 +15,13 @@ var rawPiskel = pskl.utils.Base64.toText(content); ns.PiskelFileUtils.decodePiskelFile( rawPiskel, - function (piskel, descriptor, fps) { + function (piskel) { // if using Node-Webkit, store the savePath on load // Note: the 'path' property is unique to Node-Webkit, and holds the full path if (pskl.utils.Environment.detectNodeWebkit()) { piskel.savePath = file.path; } - onSuccess(piskel, descriptor, fps); + onSuccess(piskel); }, onError ); @@ -30,11 +30,9 @@ decodePiskelFile : function (rawPiskel, onSuccess, onError) { var serializedPiskel = JSON.parse(rawPiskel); - var fps = serializedPiskel.piskel.fps; var piskel = serializedPiskel.piskel; - var descriptor = new pskl.model.piskel.Descriptor(piskel.name, piskel.description, true); pskl.utils.serialization.Deserializer.deserialize(serializedPiskel, function (piskel) { - onSuccess(piskel, descriptor, fps); + onSuccess(piskel); }); } }; From b21fc0490df4c77b05892809013e838351767d30 Mon Sep 17 00:00:00 2001 From: Julian Descottes Date: Tue, 13 Dec 2016 11:04:03 +0100 Subject: [PATCH 3/3] remove unused previewController member in ImportService --- src/js/app.js | 2 +- src/js/service/ImportService.js | 4 +--- src/js/service/storage/LocalStorageService.js | 3 +-- 3 files changed, 3 insertions(+), 6 deletions(-) diff --git a/src/js/app.js b/src/js/app.js index b30d430e..83ce44a4 100644 --- a/src/js/app.js +++ b/src/js/app.js @@ -125,7 +125,7 @@ this.storageService = new pskl.service.storage.StorageService(this.piskelController); this.storageService.init(); - this.importService = new pskl.service.ImportService(this.piskelController, this.previewController); + this.importService = new pskl.service.ImportService(this.piskelController); this.imageUploadService = new pskl.service.ImageUploadService(); this.imageUploadService.init(); diff --git a/src/js/service/ImportService.js b/src/js/service/ImportService.js index e1807d80..ac633a00 100644 --- a/src/js/service/ImportService.js +++ b/src/js/service/ImportService.js @@ -4,13 +4,11 @@ /** * Image an animation import service supporting the import dialog. * @param {!PiskelController} piskelController - * @param {!PreviewController} previewController * @constructor */ ns.ImportService = - function (piskelController, previewController) { + function (piskelController) { this.piskelController_ = piskelController; - this.previewController_ = previewController; }; /** diff --git a/src/js/service/storage/LocalStorageService.js b/src/js/service/storage/LocalStorageService.js index 8e6fe512..ccae7d96 100644 --- a/src/js/service/storage/LocalStorageService.js +++ b/src/js/service/storage/LocalStorageService.js @@ -36,9 +36,8 @@ var piskelString = this.getPiskel(name); var key = this.getKey_(name); - pskl.utils.serialization.Deserializer.deserialize(JSON.parse(piskelString), function (piskel, extra) { + pskl.utils.serialization.Deserializer.deserialize(JSON.parse(piskelString), function (piskel) { pskl.app.piskelController.setPiskel(piskel); - pskl.app.previewController.setFPS(extra.fps); }); };