Simplified SAVE STATE events, added wrap method to easily build decorators

This commit is contained in:
juliandescottes 2014-04-20 13:15:30 +02:00
parent 8335c07519
commit c2a3ccc8d0
11 changed files with 119 additions and 201 deletions

View File

@ -56,6 +56,19 @@
return layer.getFrameAt(this.currentFrameIndex);
};
ns.PiskelController.prototype.getCurrentLayerIndex = function () {
return this.currentLayerIndex;
};
ns.PiskelController.prototype.getCurrentFrameIndex = function () {
return this.currentFrameIndex;
};
ns.PiskelController.prototype.getPiskel = function () {
return this.piskel;
};
ns.PiskelController.prototype.getFrameAt = function (index) {
var frames = this.getLayers().map(function (l) {
return l.getFrameAt(index);

View File

@ -3,6 +3,7 @@
ns.PublicPiskelController = function (piskelController) {
this.piskelController = piskelController;
pskl.utils.wrap(this, this.piskelController);
};
ns.PublicPiskelController.prototype.init = function () {
@ -32,22 +33,13 @@
ns.PublicPiskelController.prototype.addFrameAt = function (index) {
this.piskelController.addFrameAt(index);
$.publish(Events.PISKEL_SAVE_STATE, {
type : 'ADD_FRAME',
index : index
});
this.raiseSaveStateEvent_(this.piskelController.addFrameAt, [index]);
$.publish(Events.PISKEL_RESET);
};
ns.PublicPiskelController.prototype.removeFrameAt = function (index) {
this.piskelController.removeFrameAt(index);
$.publish(Events.PISKEL_SAVE_STATE, {
type : 'DELETE_FRAME',
index : index
});
this.raiseSaveStateEvent_(this.piskelController.removeFrameAt, [index]);
$.publish(Events.PISKEL_RESET);
};
@ -55,32 +47,33 @@
this.piskelController.duplicateFrameAt(this.getCurrentFrameIndex());
};
ns.PublicPiskelController.prototype.raiseSaveStateEvent_ = function (fn, args) {
$.publish(Events.PISKEL_SAVE_STATE, {
type : 'REPLAY',
scope : this,
replay : {
fn : fn,
args : args
}
});
};
ns.PublicPiskelController.prototype.replay = function (frame, replayData) {
replayData.fn.apply(this.piskelController, replayData.args);
};
ns.PublicPiskelController.prototype.duplicateFrameAt = function (index) {
this.piskelController.duplicateFrameAt(index);
$.publish(Events.PISKEL_SAVE_STATE, {
type : 'DUPLICATE_FRAME',
index : index
});
this.raiseSaveStateEvent_(this.piskelController.duplicateFrameAt, [index]);
$.publish(Events.PISKEL_RESET);
};
ns.PublicPiskelController.prototype.moveFrame = function (fromIndex, toIndex) {
this.piskelController.moveFrame(fromIndex, toIndex);
$.publish(Events.PISKEL_SAVE_STATE, {
type : 'MOVE_FRAME',
from : fromIndex,
to : toIndex
});
this.raiseSaveStateEvent_(this.piskelController.moveFrame, [fromIndex, toIndex]);
$.publish(Events.PISKEL_RESET);
};
ns.PublicPiskelController.prototype.getFrameCount = function () {
return this.piskelController.getFrameCount();
};
ns.PublicPiskelController.prototype.setCurrentFrameIndex = function (index) {
this.piskelController.setCurrentFrameIndex(index);
$.publish(Events.PISKEL_RESET);
@ -108,86 +101,37 @@
ns.PublicPiskelController.prototype.renameLayerAt = function (index, name) {
this.piskelController.renameLayerAt(index, name);
$.publish(Events.PISKEL_SAVE_STATE, {
type : 'RENAME_LAYER',
index : index,
name : name
});
};
ns.PublicPiskelController.prototype.getLayerByIndex = function (index) {
return this.piskelController.getLayerByIndex(index);
this.raiseSaveStateEvent_(this.piskelController.renameLayerAt, [index, name]);
};
ns.PublicPiskelController.prototype.createLayer = function (name) {
this.piskelController.createLayer(name);
$.publish(Events.PISKEL_SAVE_STATE, {
type : 'CREATE_LAYER',
name : name
});
this.raiseSaveStateEvent_(this.piskelController.createLayer, [name]);
$.publish(Events.PISKEL_RESET);
};
ns.PublicPiskelController.prototype.moveLayerUp = function () {
this.piskelController.moveLayerUp();
$.publish(Events.PISKEL_SAVE_STATE, {
type : 'LAYER_UP'
});
this.raiseSaveStateEvent_(this.piskelController.moveLayerUp, []);
$.publish(Events.PISKEL_RESET);
};
ns.PublicPiskelController.prototype.moveLayerDown = function () {
this.piskelController.moveLayerDown();
$.publish(Events.PISKEL_SAVE_STATE, {
type : 'LAYER_DOWN'
});
this.raiseSaveStateEvent_(this.piskelController.moveLayerDown, []);
$.publish(Events.PISKEL_RESET);
};
ns.PublicPiskelController.prototype.removeCurrentLayer = function () {
this.piskelController.removeCurrentLayer();
$.publish(Events.PISKEL_SAVE_STATE, {
type : 'REMOVE_LAYER'
});
this.raiseSaveStateEvent_(this.piskelController.removeCurrentLayer, []);
$.publish(Events.PISKEL_RESET);
};
ns.PublicPiskelController.prototype.serialize = function (compressed) {
return this.piskelController.serialize(compressed);
};
ns.PublicPiskelController.prototype.getHeight = function () {
return this.piskelController.getHeight();
};
ns.PublicPiskelController.prototype.getWidth = function () {
return this.piskelController.getWidth();
};
ns.PublicPiskelController.prototype.getFPS = function () {
return this.piskelController.getFPS();
};
ns.PublicPiskelController.prototype.getLayers = function () {
return this.piskelController.getLayers();
};
ns.PublicPiskelController.prototype.getCurrentLayer = function () {
return this.piskelController.getCurrentLayer();
};
ns.PublicPiskelController.prototype.getCurrentLayerIndex = function () {
return this.piskelController.currentLayerIndex;
};
ns.PublicPiskelController.prototype.getLayerAt = function (index) {
return this.piskelController.getLayerAt(index);
};
ns.PublicPiskelController.prototype.getCurrentFrame = function () {
return this.piskelController.getCurrentFrame();
};
ns.PublicPiskelController.prototype.getCurrentFrameIndex = function () {
return this.piskelController.currentFrameIndex;
};
@ -196,12 +140,4 @@
return this.piskelController.piskel;
};
ns.PublicPiskelController.prototype.getFrameAt = function (index) {
return this.piskelController.getFrameAt(index);
};
ns.PublicPiskelController.prototype.hasFrameAt = function (index) {
return this.piskelController.hasFrameAt(index);
};
})();

View File

@ -50,12 +50,12 @@
}
};
ns.BaseTool.prototype.raiseSaveStateEvent = function (args) {
var toolInfo = {
toolId : this.toolId,
args : args
};
$.publish(Events.PISKEL_SAVE_STATE, toolInfo);
ns.BaseTool.prototype.raiseSaveStateEvent = function (replayData) {
$.publish(Events.PISKEL_SAVE_STATE, {
type : 'REPLAY',
scope : this,
replay : replayData
});
};

View File

@ -53,13 +53,9 @@
ns.Move.prototype.releaseToolAt = function(col, row, color, frame, overlay, event) {
this.moveToolAt(col, row, color, frame, overlay);
$.publish(Events.PISKEL_SAVE_STATE, {
type : 'TOOL',
tool : this,
replay : {
this.raiseSaveStateEvent({
colDiff : col - this.startCol,
rowDiff : row - this.startRow
}
});
};

View File

@ -19,14 +19,10 @@
ns.PaintBucket.prototype.applyToolAt = function(col, row, color, frame, overlay, event) {
pskl.PixelUtils.paintSimilarConnectedPixelsFromFrame(frame, col, row, color);
$.publish(Events.PISKEL_SAVE_STATE, {
type : 'TOOL',
tool : this,
replay : {
this.raiseSaveStateEvent({
col : col,
row : row,
color : color
}
});
};

View File

@ -51,17 +51,12 @@
this.draw_(coords.col, coords.row, color, frame);
$.publish(Events.DRAG_END, [col, row]);
$.publish(Events.PISKEL_SAVE_STATE, {
type : 'TOOL',
tool : this,
replay : {
this.raiseSaveStateEvent({
col : col,
row : row,
startCol : this.startCol,
startRow : this.startRow,
color : color
}
});
};

View File

@ -55,13 +55,9 @@
ns.SimplePen.prototype.releaseToolAt = function(col, row, color, frame, overlay, event) {
$.publish(Events.PISKEL_SAVE_STATE, {
type : 'TOOL',
tool : this,
replay : {
this.raiseSaveStateEvent({
pixels : this.pixels.slice(0),
color : color
}
});
this.pixels = [];
};

View File

@ -73,13 +73,9 @@
// For now, we are done with the stroke tool and don't need an overlay anymore:
overlay.clear();
$.publish(Events.PISKEL_SAVE_STATE, {
type : 'TOOL',
tool : this,
replay : {
this.raiseSaveStateEvent({
pixels : strokePoints,
color : color
}
});
};

View File

@ -1,6 +1,11 @@
(function () {
var ns = $.namespace("pskl.selection");
var SELECTION_REPLAY = {
PASTE : 'REPLAY_PASTE',
ERASE : 'REPLAY_ERASE'
};
ns.SelectionManager = function (piskelController) {
this.piskelController = piskelController;
@ -55,10 +60,10 @@
}
$.publish(Events.PISKEL_SAVE_STATE, {
type : 'TOOL',
tool : this,
type : 'REPLAY',
scope : this,
replay : {
type : 'erase',
type : SELECTION_REPLAY.ERASE,
pixels : JSON.parse(JSON.stringify(pixels.slice(0)))
}
});
@ -81,10 +86,10 @@
var currentFrame = this.piskelController.getCurrentFrame();
$.publish(Events.PISKEL_SAVE_STATE, {
type : 'TOOL',
tool : this,
type : 'REPLAY',
scope : this,
replay : {
type : 'paste',
type : SELECTION_REPLAY.PASTE,
pixels : JSON.parse(JSON.stringify(pixels.slice(0)))
}
});
@ -98,7 +103,7 @@
ns.SelectionManager.prototype.replay = function (frame, replayData) {
var pixels = replayData.pixels;
pixels.forEach(function (pixel) {
var color = replayData.type === 'paste' ? pixel.color : Constants.TRANSPARENT_COLOR;
var color = replayData.type === SELECTION_REPLAY.PASTE ? pixel.color : Constants.TRANSPARENT_COLOR;
frame.setPixel(pixel.col, pixel.row, color);
});
};

View File

@ -2,6 +2,7 @@
var ns = $.namespace('pskl.service');
var SNAPSHOT_PERIOD = 50;
var LOAD_STATE_INTERVAL = 50;
ns.HistoryService = function (piskelController) {
this.piskelController = piskelController;
@ -9,7 +10,7 @@
this.currentIndex = -1;
this.saveState__b = this.saveState.bind(this);
this.lastEvent = -1;
this.lastLoadState = -1;
};
ns.HistoryService.prototype.init = function () {
@ -38,39 +39,23 @@
};
ns.HistoryService.prototype.undo = function () {
var now = Date.now();
if ((Date.now() - this.lastEvent) > 50 && this.currentIndex > 0) {
this.currentIndex = this.currentIndex - 1;
this.loadState(this.currentIndex);
this.lastEvent = Date.now();
}
this.loadState(this.currentIndex - 1);
};
ns.HistoryService.prototype.redo = function () {
var now = Date.now();
if ((Date.now() - this.lastEvent) > 50 && this.currentIndex < this.stateQueue.length - 1) {
this.currentIndex = this.currentIndex + 1;
this.loadState(this.currentIndex);
this.lastEvent = Date.now();
}
this.loadState(this.currentIndex + 1);
};
ns.HistoryService.prototype.loadState = function (index) {
// get nearest snaphot index
var snapshotIndex = -1;
for (var i = index ; i >= 0 ; i--) {
if (this.stateQueue[i].piskel) {
snapshotIndex = i;
break;
}
}
if (this.isLoadStateAllowed_(index)) {
this.lastLoadState = Date.now();
if (snapshotIndex === -1) {
var snapshotIndex = this.getPreviousSnapshotIndex_(index);
if (snapshotIndex < 0) {
throw 'Could not find previous SNAPSHOT saved in history stateQueue';
}
var serializedPiskel = this.stateQueue[snapshotIndex].piskel;
var targetState = this.stateQueue[index];
if (typeof serializedPiskel === "string") {
this.stateQueue[snapshotIndex].piskel = JSON.parse(serializedPiskel);
@ -78,6 +63,20 @@
}
this.loadPiskel(serializedPiskel, this.onPiskelLoadedCallback.bind(this, index, snapshotIndex));
}
};
ns.HistoryService.prototype.isLoadStateAllowed_ = function (index) {
var timeOk = (Date.now() - this.lastLoadState) > LOAD_STATE_INTERVAL;
var indexInRange = index >= 0 && index < this.stateQueue.length;
return timeOk && indexInRange;
};
ns.HistoryService.prototype.getPreviousSnapshotIndex_ = function (index) {
while (this.stateQueue[index] && !this.stateQueue[index].piskel) {
index = index - 1;
}
return index;
};
ns.HistoryService.prototype.onPiskelLoadedCallback = function (index, snapshotIndex, piskel) {
@ -89,7 +88,7 @@
var lastState = this.stateQueue[index];
this.setupState(lastState);
this.currentIndex = index;
$.publish(Events.PISKEL_RESET);
};
@ -108,33 +107,11 @@
};
ns.HistoryService.prototype.replayState = function (state) {
var type = state.action.type;
if (type === 'DELETE_FRAME') {
this.piskelController.removeFrameAt(state.action.index);
} else if (type === 'ADD_FRAME') {
this.piskelController.addFrameAt(state.action.index);
} else if (type === 'DUPLICATE_FRAME') {
this.piskelController.duplicateFrameAt(state.action.index);
} else if (type === 'CREATE_LAYER') {
this.piskelController.createLayer(state.action.name);
} else if (type === 'REMOVE_LAYER') {
this.piskelController.removeCurrentLayer();
} else if (type === 'LAYER_UP') {
this.piskelController.moveLayerUp();
} else if (type === 'LAYER_DOWN') {
this.piskelController.moveLayerUp();
} else if (type === 'RENAME_LAYER') {
this.piskelController.renameLayerAt(state.action.index, state.action.name);
} else if (type === 'MOVE_FRAME') {
this.piskelController.moveFrame(state.action.from, state.action.to);
} else if (type === 'CREATE_LAYER') {
this.piskelController.createLayer();
} else if (type === 'TOOL') {
var action = state.action;
var type = action.type;
var layer = this.piskelController.getLayerAt(state.layerIndex);
var frame = layer.getFrameAt(state.frameIndex);
action.tool.replay(frame, action.replay);
}
action.scope.replay(frame, action.replay);
};
})();

View File

@ -47,5 +47,13 @@ if (typeof Function.prototype.bind !== "function") {
extendedObject.prototype.superclass = inheritFrom.prototype;
};
ns.wrap = function (wrapper, wrappedObject) {
for (var prop in wrappedObject) {
if (typeof wrappedObject[prop] === 'function') {
wrapper[prop] = wrappedObject[prop].bind(wrappedObject);
}
}
};
})();