mirror of
https://github.com/codeninjasllc/codecombat.git
synced 2025-03-14 07:00:01 -04:00
Several improvements to hover debugging.
This commit is contained in:
parent
9b9df12ea0
commit
6fa38bd889
8 changed files with 969 additions and 22 deletions
File diff suppressed because one or more lines are too long
|
@ -114,4 +114,7 @@ class Rectangle
|
|||
@deserialize: (o, world, classMap) ->
|
||||
new Rectangle o.x, o.y, o.w, o.h, o.r
|
||||
|
||||
serializeForAether: -> @serialize()
|
||||
@deserializeFromAether: (o) -> @deserialize o
|
||||
|
||||
module.exports = Rectangle
|
||||
|
|
|
@ -158,6 +158,9 @@ module.exports = class Thang
|
|||
t[prop] = val
|
||||
t
|
||||
|
||||
serializeForAether: ->
|
||||
{CN: @constructor.className, id: @id}
|
||||
|
||||
getSpriteOptions: ->
|
||||
colorConfigs = @world?.getTeamColors() or {}
|
||||
options = {}
|
||||
|
|
|
@ -119,4 +119,7 @@ class Vector
|
|||
@deserialize: (o, world, classMap) ->
|
||||
new Vector o.x, o.y, o.z
|
||||
|
||||
serializeForAether: -> @serialize()
|
||||
@deserializeFromAether: (o) -> @deserialize o
|
||||
|
||||
module.exports = Vector
|
||||
|
|
|
@ -61,9 +61,9 @@
|
|||
.executing, .executed, .problem-marker-info, .problem-marker-warning, .problem-marker-error
|
||||
position: absolute
|
||||
.executing
|
||||
background-color: rgba(216, 255, 255, 0.55)
|
||||
background-color: rgba(216, 255, 255, 0.85)
|
||||
.executed
|
||||
background-color: rgba(216, 255, 255, 0.25)
|
||||
background-color: rgba(200, 200, 255, 0.25)
|
||||
.problem-marker-info
|
||||
background-color: rgba(96, 63, 84, 0.25)
|
||||
.problem-marker-warning
|
||||
|
|
|
@ -1,16 +1,25 @@
|
|||
View = require 'views/kinds/CocoView'
|
||||
template = require 'templates/play/level/tome/spell_debug'
|
||||
Range = ace.require("ace/range").Range
|
||||
TokenIterator = ace.require("ace/token_iterator").TokenIterator
|
||||
serializedClasses =
|
||||
Thang: require "lib/world/thang"
|
||||
Vector: require "lib/world/vector"
|
||||
Rectangle: require "lib/world/rectangle"
|
||||
|
||||
module.exports = class DebugView extends View
|
||||
className: 'spell-debug-view'
|
||||
template: template
|
||||
subscriptions: {}
|
||||
|
||||
subscriptions:
|
||||
'god:new-world-created': 'onNewWorld'
|
||||
|
||||
events: {}
|
||||
|
||||
constructor: (options) ->
|
||||
super options
|
||||
@ace = options.ace
|
||||
@thang = options.thang
|
||||
@variableStates = {}
|
||||
|
||||
afterRender: ->
|
||||
|
@ -23,29 +32,44 @@ module.exports = class DebugView extends View
|
|||
|
||||
onMouseMove: (e) =>
|
||||
pos = e.getDocumentPosition()
|
||||
column = pos.column
|
||||
until column < 0
|
||||
if token = e.editor.session.getTokenAt pos.row, column
|
||||
break if token.type is 'identifier'
|
||||
column = token.start - 1
|
||||
else
|
||||
--column
|
||||
if token?.type is 'identifier' and token.value of @variableStates
|
||||
@variable = token.value
|
||||
it = new TokenIterator e.editor.session, pos.row, pos.column
|
||||
isIdentifier = (t) -> t and (t.type is 'identifier' or t.value is 'this')
|
||||
while it.getCurrentTokenRow() is pos.row and not isIdentifier(token = it.getCurrentToken())
|
||||
it.stepBackward()
|
||||
break unless token
|
||||
if isIdentifier token
|
||||
# This could be a property access, like "enemy.target.pos" or "this.spawnedRectangles".
|
||||
# We have to realize this and dig into the nesting of the objects.
|
||||
start = it.getCurrentTokenColumn()
|
||||
[chain, start, end] = [[token.value], start, start + token.value.length]
|
||||
while it.getCurrentTokenRow() is pos.row
|
||||
it.stepBackward()
|
||||
break unless it.getCurrentToken()?.value is "."
|
||||
it.stepBackward()
|
||||
token = null # If we're doing a complex access like this.getEnemies().length, then length isn't a valid var.
|
||||
break unless isIdentifier(prev = it.getCurrentToken())
|
||||
token = prev
|
||||
start = it.getCurrentTokenColumn()
|
||||
chain.unshift token.value
|
||||
if token and (token.value of @variableStates or token.value is "this")
|
||||
@variableChain = chain
|
||||
@pos = {left: e.domEvent.offsetX + 50, top: e.domEvent.offsetY + 50}
|
||||
@markerRange = new Range pos.row, token.start, pos.row, token.start + token.value.length
|
||||
@markerRange = new Range pos.row, start, pos.row, end
|
||||
else
|
||||
@variable = @markerRange = null
|
||||
@variableChain = @markerRange = null
|
||||
@update()
|
||||
|
||||
onMouseOut: (e) =>
|
||||
@variable = @markerRange = null
|
||||
@variableChain = @markerRange = null
|
||||
@update()
|
||||
|
||||
onNewWorld: (e) ->
|
||||
@thang = @options.thang = e.world.thangMap[@thang.id] if @thang
|
||||
|
||||
update: ->
|
||||
if @variable
|
||||
value = @variableStates[@variable]
|
||||
@$el.find("code").text "#{@variable}: #{value}"
|
||||
if @variableChain
|
||||
{key, value} = @deserializeVariableChain @variableChain
|
||||
@$el.find("code").text "#{key}: #{value}"
|
||||
@$el.show().css(@pos)
|
||||
else
|
||||
@$el.hide()
|
||||
|
@ -58,6 +82,28 @@ module.exports = class DebugView extends View
|
|||
if @markerRange
|
||||
@marker = @ace.getSession().addMarker @markerRange, "ace_bracket", "text"
|
||||
|
||||
deserializeVariableChain: (chain) ->
|
||||
keys = []
|
||||
for prop, i in chain
|
||||
if prop is "this"
|
||||
value = @thang
|
||||
else
|
||||
value = (if i is 0 then @variableStates else 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)
|
||||
if value and not _.isString value
|
||||
if value.constructor?.className is "Thang"
|
||||
value = "<#{value.spriteName} - #{value.id}, #{if value.pos then value.pos.toString() else 'non-physical'}>"
|
||||
else
|
||||
value = value.toString()
|
||||
key: keys.join("."), value: value
|
||||
|
||||
destroy: ->
|
||||
super()
|
||||
@ace?.removeEventListener "mousemove", @onMouseMove
|
||||
|
|
|
@ -51,7 +51,6 @@ module.exports = class SpellView extends View
|
|||
else
|
||||
# needs to happen after the code generating this view is complete
|
||||
setTimeout @onLoaded, 1
|
||||
@createDebugView()
|
||||
|
||||
createACE: ->
|
||||
# Test themes and settings here: http://ace.ajax.org/build/kitchen-sink.html
|
||||
|
@ -157,7 +156,7 @@ module.exports = class SpellView extends View
|
|||
@eventsSuppressed = false # Now that the initial change is in, we can start running any changed code
|
||||
|
||||
createDebugView: ->
|
||||
@debugView = new SpellDebugView ace: @ace
|
||||
@debugView = new SpellDebugView ace: @ace, thang: @thang
|
||||
@$el.append @debugView.render().$el.hide()
|
||||
|
||||
createToolbarView: ->
|
||||
|
@ -175,6 +174,8 @@ module.exports = class SpellView extends View
|
|||
return if thang.id is @thang?.id
|
||||
@thang = thang
|
||||
@spellThang = @spell.thangs[@thang.id]
|
||||
@createDebugView() unless @debugView
|
||||
@debugView.thang = @thang
|
||||
@updateAether false, true
|
||||
@highlightCurrentLine()
|
||||
|
||||
|
|
|
@ -32,7 +32,7 @@
|
|||
"firepad": "~0.1.2",
|
||||
"marked": "~0.3.0",
|
||||
"moment": "~2.5.0",
|
||||
"aether": "~0.0.5",
|
||||
"aether": "~0.0.7",
|
||||
"underscore.string": "~2.3.3",
|
||||
"firebase": "~1.0.2"
|
||||
},
|
||||
|
|
Loading…
Reference in a new issue