Move history service to linked list with random UUID

Signed-off-by:Guillaume Martigny <guillaume.martigny@gmail.com>
This commit is contained in:
Guillaume Martigny 2016-04-19 14:50:37 +02:00 committed by Julian Descottes
parent da94e0c1fc
commit eb1320de11

View File

@ -7,7 +7,7 @@
this.deserializer = deserializer || pskl.utils.serialization.Deserializer;
this.stateQueue = [];
this.currentIndex = -1;
this.currentUUID = false;
this.lastLoadState = -1;
};
@ -40,42 +40,84 @@
};
ns.HistoryService.prototype.saveState = function (action) {
this.stateQueue = this.stateQueue.slice(0, this.currentIndex + 1);
this.currentIndex = this.currentIndex + 1;
var state = {
action : action,
frameIndex : action.state ? action.state.frameIndex : this.piskelController.currentFrameIndex,
layerIndex : action.state ? action.state.layerIndex : this.piskelController.currentLayerIndex
layerIndex : action.state ? action.state.layerIndex : this.piskelController.currentLayerIndex,
previousIndex: false,
nextIndex: false
};
var isSnapshot = action.type === ns.HistoryService.SNAPSHOT;
var isAtAutoSnapshotInterval = this.currentIndex % ns.HistoryService.SNAPSHOT_PERIOD === 0;
var isAtAutoSnapshotInterval = (this.stateQueue.length - 1) % ns.HistoryService.SNAPSHOT_PERIOD === 0;
if (isSnapshot || isAtAutoSnapshotInterval) {
state.piskel = this.piskelController.serialize(true);
}
this.stateQueue.push(state);
this.pushNewState_(state);
$.publish(Events.HISTORY_STATE_SAVED);
};
ns.HistoryService.prototype.getCurrentState = function(){
if(this.currentUUID){
return this.stateQueue[this.currentUUID];
}
else{
return false;
}
};
ns.HistoryService.prototype.pushNewState_ = function(state){
// Generate a random UUID (~1e28 combinations)
var uuid = 'xxxxxx'.replace(/x/g, function(){
return (Math.random() * 36 << 0).toString(36);
});
var currentState = this.getCurrentState();
if(currentState){
// Clear unlinked states
if(currentState.nextIndex){
this.clearBranchingQueue_(currentState.nextIndex);
}
currentState.nextIndex = uuid;
}
state.previousIndex = this.currentUUID;
this.stateQueue[uuid] = state;
this.currentUUID = uuid;
};
ns.HistoryService.prototype.clearBranchingQueue_ = function(index){
while(this.stateQueue[index]){
var next = this.stateQueue[index].nextIndex;
delete(this.stateQueue[index]);
index = next;
}
};
ns.HistoryService.prototype.undo = function () {
this.loadState(this.currentIndex - 1);
var currentState = this.getCurrentState();
if(currentState.previousIndex)
this.loadState(currentState.previousIndex);
};
ns.HistoryService.prototype.redo = function () {
this.loadState(this.currentIndex + 1);
var currentState = this.getCurrentState();
if(currentState.nextIndex)
this.loadState(currentState.nextIndex);
};
ns.HistoryService.prototype.isLoadStateAllowed_ = function (index) {
var timeOk = (Date.now() - this.lastLoadState) > ns.HistoryService.LOAD_STATE_INTERVAL;
var indexInRange = index >= 0 && index < this.stateQueue.length;
var indexInRange = index && this.stateQueue[index];
return timeOk && indexInRange;
};
ns.HistoryService.prototype.getPreviousSnapshotIndex_ = function (index) {
while (this.stateQueue[index] && !this.stateQueue[index].piskel) {
index = index - 1;
index = this.stateQueue[index].previousIndex;
}
return index;
};
@ -86,7 +128,7 @@
this.lastLoadState = Date.now();
var snapshotIndex = this.getPreviousSnapshotIndex_(index);
if (snapshotIndex < 0) {
if (!snapshotIndex) {
throw 'Could not find previous SNAPSHOT saved in history stateQueue';
}
var serializedPiskel = this.getSnapshotFromState_(snapshotIndex);
@ -97,7 +139,7 @@
console.error('[CRITICAL ERROR] : Unable to load a history state.');
this.logError_(error);
this.stateQueue = [];
this.currentIndex = -1;
this.currentUUID = false;
}
};
@ -132,19 +174,21 @@
piskel.savePath = this.piskelController.piskel.savePath;
this.piskelController.setPiskel(piskel);
for (var i = snapshotIndex + 1 ; i <= index ; i++) {
var state = this.stateQueue[i];
var walkingIndex = snapshotIndex;
do{
walkingIndex = this.stateQueue[walkingIndex].nextIndex;
var state = this.stateQueue[walkingIndex];
this.setupState(state);
this.replayState(state);
}
} while(walkingIndex && walkingIndex != index);
// Should only do this when going backwards
var lastState = this.stateQueue[index + 1];
if (lastState) {
this.setupState(lastState);
var next = this.stateQueue[index].nextIndex;
if (next) {
this.setupState(this.stateQueue[next]);
}
this.currentIndex = index;
this.currentUUID = index;
$.publish(Events.PISKEL_RESET);
$.publish(Events.HISTORY_STATE_LOADED);
if (originalSize !== this.getPiskelSize_()) {