Created
February 10, 2011 01:14
-
-
Save kig/819732 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
DrawHistorySerializer = Klass({ | |
magic: 'SRBL', | |
majorVersion: 0, | |
minorVersion: 0, | |
getVersionTag : function() { | |
return [this.magic, this.majorVersion, this.minorVersion, ''].join(",") | |
}, | |
serialize : function(history) { | |
return [this.getVersionTag(), this.serializeBody(history)].join(""); | |
}, | |
deserialize : function(string) { | |
var t = this.getVersionTag(); | |
if (string.substring(0, t.length) != t) | |
throw (new Error("Unknown version tag")) | |
return this.deserializeBody(string.substring(t.length)); | |
}, | |
serializeBody : function(history) { | |
return JSON.stringify(history); | |
}, | |
deserializeBody : function(history) { | |
return JSON.parse(history); | |
} | |
}); | |
// sketch of a binary serializer. lacking parser and binary encoder funcs. | |
// dunno if i should throw some crazy entropy encoder there as well | |
// (arithmetic-encode brushstroke coord deltas) | |
CompressedDrawHistorySerializer = Klass(DrawHistorySerializer, { | |
commands : [ | |
'drawPoint', | |
'drawLine', | |
'clear', | |
'setColor', | |
'setBackground', | |
'setLineCap', | |
'setLineWidth', | |
'setOpacity' | |
], | |
collapsible : { | |
'clear' : true, | |
'setColor' : true, | |
'setBackground' : true, | |
'setLineCap' : true, | |
'setLineWidth' : true, | |
'setOpacity' : true | |
}, | |
majorVersion: 1, | |
minorVersion: 0, | |
initialize : function() { | |
this.commandCodes = {}; | |
for (var i=0; i<this.commands.length; i++) { | |
this.commandCodes[this.commands[i]] = i; | |
} | |
}, | |
serializeBody : function(history) { | |
var output = []; | |
for (var i=0; i<history.length; i++) { | |
var e = history[i]; | |
if (this.collapsible[e.methodName] && history[i+1] | |
&& history[i+1].methodName == e.methodName) { | |
// only the last element matters in a string of collapsible actions | |
// (a = 1; a = 2; a = 3; a = 4) <=> (a = 4) | |
continue; | |
} | |
var cmd = this.commandCodes[e.methodName]; | |
if (e.methodName == 'drawLine') { | |
// delta-encode a string of drawLine actions | |
var coords = [e.args[0], e.args[1]]; | |
e = history[i+1]; | |
while (e && e.methodName == 'drawLine') { | |
if (this.canDeltaEncode(coords, e.args)) | |
coords.push(e.args[1]); | |
else | |
break; | |
i++; | |
e = history[i+1]; | |
} | |
var deltaString = this.deltaEncode(coords); | |
output.push(cmd + this.encodeInt16(deltaString.length) + deltaString); | |
continue; | |
} else { | |
var args = this.encodeArgs(e.args); | |
output.push(cmd + args); | |
} | |
} | |
return output.join(""); | |
}, | |
deserializeBody : function(string) { | |
var output = []; | |
var obj = {}; | |
for (var i=0; i<string.length;) { | |
i += this.readCommand(string, obj); | |
if (obj.methodName == 'drawLine') { | |
var coords = this.decodeDeltas(obj.args); | |
for (var j=0; j<coords.length; j++) | |
output.push({methodName: 'drawLine', args: coords[j]}); | |
} else { | |
var o = {methodName: obj.methodName, args: obj.args}; | |
if (this.breakpointMethod[obj.methodName]) | |
o.breakpoint = true; | |
output.push(o); | |
} | |
} | |
return output; | |
}, | |
canDeltaEncode : function(coords, args) { | |
var l = coords.last(); | |
return ( | |
coords.length < 30000 && | |
(l.x == args[0].x && l.y == args[0].y) && | |
(Math.abs(l.x-args[1].x) < 127 && Math.abs(l.y-args[1].y) < 127) | |
); | |
}, | |
deltaEncode : function(coords) { | |
var base = coords[0]; | |
var deltas = [this.encodeInt16(base.x),this.encodeInt16(base.y)]; | |
for (var i=1; i<coords.length-1; i++) { | |
var prev = coords[i-1]; | |
var cur = coords[i]; | |
deltas.push(this.encodeInt8(cur.x-prev.x), this.encodeInt8(cur.y-prev.y)); | |
} | |
return deltas.join(""); | |
} | |
}); | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment