mirror of
https://github.com/codeninjasllc/codecombat.git
synced 2024-12-11 00:02:19 -05:00
Merge pull request #992 from codecombat/master
Moved debug cache onto main thread
This commit is contained in:
commit
02830223a5
3 changed files with 53 additions and 98 deletions
|
@ -169,38 +169,8 @@ self.stringifyValue = function(value, depth) {
|
||||||
return "" + prefix + brackets[0] + sep + " " + (values.join(sep + ' ')) + sep + brackets[1];
|
return "" + prefix + brackets[0] + sep + " " + (values.join(sep + ' ')) + sep + brackets[1];
|
||||||
};
|
};
|
||||||
|
|
||||||
var cache = {};
|
|
||||||
|
|
||||||
self.invalidateCache = function () {
|
|
||||||
cache = {};
|
|
||||||
};
|
|
||||||
|
|
||||||
self.retrieveValueFromCache = function (thangID, spellID, variableChain, frame) {
|
|
||||||
var frameCache, thangCache, spellCache;
|
|
||||||
if ((frameCache = cache[frame]) && (thangCache = frameCache[thangID]) && (spellCache = thangCache[spellID]))
|
|
||||||
return spellCache[variableChain.join()];
|
|
||||||
return undefined;
|
|
||||||
};
|
|
||||||
self.updateCache = function (thangID, spellID, variableChain, frame, value) {
|
|
||||||
var key, keys, currentObject;
|
|
||||||
keys = [frame,thangID, spellID, variableChain.join()];
|
|
||||||
currentObject = cache;
|
|
||||||
|
|
||||||
for (var i = 0, len = keys.length - 1; i < len; i++)
|
|
||||||
{
|
|
||||||
key = keys[i];
|
|
||||||
if (!(key in currentObject))
|
|
||||||
currentObject[key] = {};
|
|
||||||
currentObject = currentObject[key];
|
|
||||||
}
|
|
||||||
currentObject[keys[keys.length - 1]] = value;
|
|
||||||
};
|
|
||||||
|
|
||||||
self.retrieveValueFromFrame = function retrieveValueFromFrame(args) {
|
self.retrieveValueFromFrame = function retrieveValueFromFrame(args) {
|
||||||
var cacheValue;
|
|
||||||
if (args.frame === self.currentDebugWorldFrame && (cacheValue = self.retrieveValueFromCache(args.currentThangID, args.currentSpellID, args.variableChain, args.frame)))
|
|
||||||
return self.postMessage({type: 'debug-value-return', serialized: {"key": args.variableChain.join("."), "value": cacheValue}});
|
|
||||||
|
|
||||||
|
|
||||||
var retrieveProperty = function retrieveProperty(currentThangID, currentSpellID, variableChain)
|
var retrieveProperty = function retrieveProperty(currentThangID, currentSpellID, variableChain)
|
||||||
{
|
{
|
||||||
|
@ -253,7 +223,6 @@ self.retrieveValueFromFrame = function retrieveValueFromFrame(args) {
|
||||||
"key": keys.join("."),
|
"key": keys.join("."),
|
||||||
"value": self.stringifyValue(value,0)
|
"value": self.stringifyValue(value,0)
|
||||||
};
|
};
|
||||||
self.updateCache(currentThangID,currentSpellID,variableChain, args.frame, serializedProperty.value);
|
|
||||||
self.postMessage({type: 'debug-value-return', serialized: serializedProperty});
|
self.postMessage({type: 'debug-value-return', serialized: serializedProperty});
|
||||||
};
|
};
|
||||||
self.enableFlowOnThangSpell(args.currentThangID, args.currentSpellID, args.userCodeMap);
|
self.enableFlowOnThangSpell(args.currentThangID, args.currentSpellID, args.userCodeMap);
|
||||||
|
@ -296,7 +265,6 @@ self.setupDebugWorldToRunUntilFrame = function (args) {
|
||||||
var stringifiedUserCodeMap = JSON.stringify(args.userCodeMap);
|
var stringifiedUserCodeMap = JSON.stringify(args.userCodeMap);
|
||||||
var userCodeMapHasChanged = ! _.isEqual(self.currentUserCodeMapCopy, stringifiedUserCodeMap);
|
var userCodeMapHasChanged = ! _.isEqual(self.currentUserCodeMapCopy, stringifiedUserCodeMap);
|
||||||
self.currentUserCodeMapCopy = stringifiedUserCodeMap;
|
self.currentUserCodeMapCopy = stringifiedUserCodeMap;
|
||||||
if (args.frame != self.currentDebugWorldFrame) self.invalidateCache();
|
|
||||||
if (!self.debugWorld || userCodeMapHasChanged || args.frame < self.currentDebugWorldFrame) {
|
if (!self.debugWorld || userCodeMapHasChanged || args.frame < self.currentDebugWorldFrame) {
|
||||||
try {
|
try {
|
||||||
self.debugWorld = new World(args.userCodeMap);
|
self.debugWorld = new World(args.userCodeMap);
|
||||||
|
@ -321,7 +289,7 @@ self.setupDebugWorldToRunUntilFrame = function (args) {
|
||||||
|
|
||||||
|
|
||||||
self.onDebugWorldLoaded = function onDebugWorldLoaded() {
|
self.onDebugWorldLoaded = function onDebugWorldLoaded() {
|
||||||
console.log("Debug world loaded!");
|
self.postMessage({type: 'debug-world-loaded'});
|
||||||
};
|
};
|
||||||
|
|
||||||
self.onDebugWorldError = function onDebugWorldError(error) {
|
self.onDebugWorldError = function onDebugWorldError(error) {
|
||||||
|
|
|
@ -93,7 +93,7 @@ module.exports = class God extends CocoClass
|
||||||
return unless args.thangID and args.spellID and args.variableChain
|
return unless args.thangID and args.spellID and args.variableChain
|
||||||
return console.error "Tried to retrieve debug value with no currentUserCodeMap" unless @currentUserCodeMap
|
return console.error "Tried to retrieve debug value with no currentUserCodeMap" unless @currentUserCodeMap
|
||||||
@debugWorker ?= @createDebugWorker()
|
@debugWorker ?= @createDebugWorker()
|
||||||
args.frame ?= @world.age / @world.dt
|
args.frame ?= @angelsShare.world.age / @angelsShare.world.dt
|
||||||
@debugWorker.postMessage
|
@debugWorker.postMessage
|
||||||
func: 'retrieveValueFromFrame'
|
func: 'retrieveValueFromFrame'
|
||||||
args:
|
args:
|
||||||
|
|
|
@ -15,6 +15,7 @@ module.exports = class DebugView extends View
|
||||||
'god:new-world-created': 'onNewWorld'
|
'god:new-world-created': 'onNewWorld'
|
||||||
'god:debug-value-return': 'handleDebugValue'
|
'god:debug-value-return': 'handleDebugValue'
|
||||||
'tome:spell-shown': 'changeCurrentThangAndSpell'
|
'tome:spell-shown': 'changeCurrentThangAndSpell'
|
||||||
|
'tome:cast-spells': 'onTomeCast'
|
||||||
'surface:frame-changed': 'onFrameChanged'
|
'surface:frame-changed': 'onFrameChanged'
|
||||||
|
|
||||||
events: {}
|
events: {}
|
||||||
|
@ -30,16 +31,50 @@ module.exports = class DebugView extends View
|
||||||
@globals[className] = serializedClass
|
@globals[className] = serializedClass
|
||||||
|
|
||||||
@onMouseMove = _.throttle @onMouseMove, 25
|
@onMouseMove = _.throttle @onMouseMove, 25
|
||||||
|
@cache = {}
|
||||||
|
@lastFrameRequested = -1
|
||||||
|
@workerIsSimulating = false
|
||||||
|
|
||||||
|
setTooltipKeyAndValue: (key, value) =>
|
||||||
|
@$el.find("code").text "#{key}: #{value}"
|
||||||
|
@$el.show().css(@pos)
|
||||||
|
|
||||||
|
setTooltipText: (text) =>
|
||||||
|
#perhaps changing styling here in the future
|
||||||
|
@$el.find("code").text text
|
||||||
|
@$el.show().css(@pos)
|
||||||
|
|
||||||
|
onTomeCast: ->
|
||||||
|
@invalidateCache()
|
||||||
|
|
||||||
|
invalidateCache: -> @cache = {}
|
||||||
|
|
||||||
|
retrieveValueFromCache: (thangID,spellID,variableChain,frame) ->
|
||||||
|
joinedVariableChain = variableChain.join()
|
||||||
|
value = @cache[frame]?[thangID]?[spellID]?[joinedVariableChain]
|
||||||
|
return value ? undefined
|
||||||
|
|
||||||
|
updateCache: (thangID, spellID, variableChain, frame, value) ->
|
||||||
|
currentObject = @cache
|
||||||
|
keys = [frame,thangID,spellID,variableChain.join()]
|
||||||
|
for keyIndex in [0...(keys.length - 1)]
|
||||||
|
key = keys[keyIndex]
|
||||||
|
unless key of currentObject
|
||||||
|
currentObject[key] = {}
|
||||||
|
currentObject = currentObject[key]
|
||||||
|
currentObject[keys[keys.length - 1]] = value
|
||||||
|
|
||||||
|
|
||||||
changeCurrentThangAndSpell: (thangAndSpellObject) ->
|
changeCurrentThangAndSpell: (thangAndSpellObject) ->
|
||||||
@thang = thangAndSpellObject.thang
|
@thang = thangAndSpellObject.thang
|
||||||
@spell = thangAndSpellObject.spell
|
@spell = thangAndSpellObject.spell
|
||||||
|
|
||||||
handleDebugValue: (returnObject) ->
|
handleDebugValue: (returnObject) ->
|
||||||
|
@workerIsSimulating = false
|
||||||
{key, value} = returnObject
|
{key, value} = returnObject
|
||||||
|
@updateCache(@thang.id,@spell.name,key.split("."),@lastFrameRequested,value)
|
||||||
if @variableChain and not key is @variableChain.join(".") then return
|
if @variableChain and not key is @variableChain.join(".") then return
|
||||||
@$el.find("code").text "#{key}: #{value}"
|
@setTooltipKeyAndValue(key,value)
|
||||||
@$el.show().css(@pos)
|
|
||||||
|
|
||||||
|
|
||||||
afterRender: ->
|
afterRender: ->
|
||||||
|
@ -99,13 +134,19 @@ module.exports = class DebugView extends View
|
||||||
|
|
||||||
update: ->
|
update: ->
|
||||||
if @variableChain
|
if @variableChain
|
||||||
|
if @workerIsSimulating
|
||||||
|
@setTooltipText("World is simulating, please wait...")
|
||||||
|
else if @currentFrame is @lastFrameRequested and (cacheValue = @retrieveValueFromCache(@thang.id, @spell.name, @variableChain, @currentFrame))
|
||||||
|
@setTooltipKeyAndValue(@variableChain.join("."),cacheValue)
|
||||||
|
else
|
||||||
Backbone.Mediator.publish 'tome:spell-debug-value-request',
|
Backbone.Mediator.publish 'tome:spell-debug-value-request',
|
||||||
thangID: @thang.id
|
thangID: @thang.id
|
||||||
spellID: @spell.name
|
spellID: @spell.name
|
||||||
variableChain: @variableChain
|
variableChain: @variableChain
|
||||||
frame: @currentFrame
|
frame: @currentFrame
|
||||||
@$el.find("code").text "Finding value..."
|
if @currentFrame isnt @lastFrameRequested then @workerIsSimulating = true
|
||||||
@$el.show().css(@pos)
|
@lastFrameRequested = @currentFrame
|
||||||
|
@setTooltipText("Finding value...")
|
||||||
else
|
else
|
||||||
@$el.hide()
|
@$el.hide()
|
||||||
if @variableChain?.length is 2
|
if @variableChain?.length is 2
|
||||||
|
@ -129,60 +170,6 @@ module.exports = class DebugView extends View
|
||||||
if @markerRange
|
if @markerRange
|
||||||
@marker = @ace.getSession().addMarker @markerRange, "ace_bracket", "text"
|
@marker = @ace.getSession().addMarker @markerRange, "ace_bracket", "text"
|
||||||
|
|
||||||
stringifyValue: (value, depth) ->
|
|
||||||
return value if not value or _.isString value
|
|
||||||
if _.isFunction value
|
|
||||||
return if depth is 2 then undefined else "<Function>"
|
|
||||||
return "<this #{value.id}>" if value is @thang and depth
|
|
||||||
if depth is 2
|
|
||||||
if value.constructor?.className is "Thang"
|
|
||||||
value = "<#{value.type or value.spriteName} - #{value.id}, #{if value.pos then value.pos.toString() else 'non-physical'}>"
|
|
||||||
else
|
|
||||||
value = value.toString()
|
|
||||||
return value
|
|
||||||
|
|
||||||
isArray = _.isArray value
|
|
||||||
isObject = _.isObject value
|
|
||||||
return value.toString() unless isArray or isObject
|
|
||||||
brackets = if isArray then ["[", "]"] else ["{", "}"]
|
|
||||||
size = _.size value
|
|
||||||
return brackets.join "" unless size
|
|
||||||
values = []
|
|
||||||
if isArray
|
|
||||||
for v in value
|
|
||||||
s = @stringifyValue(v, depth + 1)
|
|
||||||
values.push "" + s unless s is undefined
|
|
||||||
else
|
|
||||||
for key in value.apiProperties ? _.keys value
|
|
||||||
s = @stringifyValue(value[key], depth + 1)
|
|
||||||
values.push key + ": " + s unless s is undefined
|
|
||||||
sep = '\n' + (" " for i in [0 ... depth]).join('')
|
|
||||||
prefix = value.constructor?.className
|
|
||||||
prefix ?= "Array" if isArray
|
|
||||||
prefix ?= "Object" if isObject
|
|
||||||
prefix = if prefix then prefix + " " else ""
|
|
||||||
return "#{prefix}#{brackets[0]}#{sep} #{values.join(sep + ' ')}#{sep}#{brackets[1]}"
|
|
||||||
|
|
||||||
deserializeVariableChain: (chain) ->
|
|
||||||
keys = []
|
|
||||||
for prop, i in chain
|
|
||||||
if prop is "this"
|
|
||||||
value = @thang
|
|
||||||
else if i is 0
|
|
||||||
value = @variableStates[prop]
|
|
||||||
if typeof value is "undefined" then value = @globals[prop]
|
|
||||||
else
|
|
||||||
value = value[prop]
|
|
||||||
keys.push prop
|
|
||||||
break unless value
|
|
||||||
if theClass = serializedClasses[value.CN]
|
|
||||||
if value.CN is "Thang"
|
|
||||||
thang = @thang.world.thangMap[value.id]
|
|
||||||
value = thang or "<Thang #{value.id} (non-existent)>"
|
|
||||||
else
|
|
||||||
value = theClass.deserializeFromAether(value)
|
|
||||||
value = @stringifyValue value, 0
|
|
||||||
key: keys.join("."), value: value
|
|
||||||
|
|
||||||
destroy: ->
|
destroy: ->
|
||||||
@ace?.removeEventListener "mousemove", @onMouseMove
|
@ace?.removeEventListener "mousemove", @onMouseMove
|
||||||
|
|
Loading…
Reference in a new issue