mirror of
https://github.com/codeninjasllc/codecombat.git
synced 2024-11-28 01:55:38 -05:00
This commit is contained in:
commit
b2ddde96cd
17 changed files with 342 additions and 43 deletions
|
@ -8,6 +8,8 @@ CocoView = require 'views/kinds/CocoView'
|
|||
preventBackspace = (event) ->
|
||||
if event.keyCode is 8 and not elementAcceptsKeystrokes(event.srcElement or event.target)
|
||||
event.preventDefault()
|
||||
else if (key.ctrl or key.command) and not key.alt and event.keyCode in [219, 221] # prevent Ctrl/Cmd + [ / ]
|
||||
event.preventDefault()
|
||||
|
||||
elementAcceptsKeystrokes = (el) ->
|
||||
# http://stackoverflow.com/questions/1495219/how-can-i-prevent-the-backspace-key-from-navigating-back
|
||||
|
|
|
@ -152,7 +152,7 @@ class Angel
|
|||
@ids[@lastID]
|
||||
|
||||
# https://github.com/codecombat/codecombat/issues/81 -- TODO: we need to wait for worker initialization first
|
||||
infiniteLoopIntervalDuration: 15000 # check this often (must be more than the others added)
|
||||
infiniteLoopIntervalDuration: 1500000 # check this often (must be more than the others added)
|
||||
infiniteLoopTimeoutDuration: 1500 # wait this long when we check
|
||||
abortTimeoutDuration: 500 # give in-process or dying workers this long to give up
|
||||
constructor: (@god) ->
|
||||
|
|
|
@ -140,7 +140,7 @@ module.exports = class Mark extends CocoClass
|
|||
worldZ = @sprite.thang.pos.z - @sprite.thang.depth / 2
|
||||
@mark.alpha = 0.451 / Math.sqrt(worldZ / 2 + 1)
|
||||
else
|
||||
pos ?= @sprite.displayObject
|
||||
pos ?= @sprite?.displayObject
|
||||
@mark.x = pos.x
|
||||
@mark.y = pos.y
|
||||
if @name is 'highlight'
|
||||
|
|
|
@ -259,6 +259,6 @@ module.exports = class SpriteBoss extends CocoClass
|
|||
target = thang?.target
|
||||
targetPos = thang?.targetPos
|
||||
targetPos = null if targetPos?.isZero?() # Null targetPos get serialized as (0, 0, 0)
|
||||
@targetMark.toggle target or targetPos
|
||||
@targetMark.setSprite if target then @sprites[target.id] else null
|
||||
@targetMark.toggle @targetMark.sprite or targetPos
|
||||
@targetMark.update if targetPos then @camera.worldToSurface targetPos else null
|
||||
|
|
|
@ -30,11 +30,13 @@
|
|||
color: white
|
||||
|
||||
#cast-button-view
|
||||
display: none
|
||||
|
||||
.cast-button-group
|
||||
position: absolute
|
||||
// Bottom/right margins must appear to scroll to size of any paper gashes
|
||||
top: 2%
|
||||
right: 4%
|
||||
top: 55px
|
||||
left: 20px
|
||||
z-index: 2
|
||||
@include opacity(77)
|
||||
|
||||
.button-progress-overlay
|
||||
|
|
|
@ -32,10 +32,11 @@
|
|||
|
||||
.ace_editor
|
||||
@include box-sizing(border-box)
|
||||
margin-top: 40px
|
||||
width: 100%
|
||||
height: 90%
|
||||
height: -webkit-calc(100% - 60px)
|
||||
height: calc(100% - 60px)
|
||||
height: 83%
|
||||
height: -webkit-calc(100% - 60px - 40px)
|
||||
height: calc(100% - 60px - 40px)
|
||||
position: relative
|
||||
background-color: transparent
|
||||
line-height: 20px
|
||||
|
@ -75,11 +76,10 @@
|
|||
background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAUCAYAAACNiR0NAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAA2hpVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADw/eHBhY2tldCBiZWdpbj0i77u/IiBpZD0iVzVNME1wQ2VoaUh6cmVTek5UY3prYzlkIj8+IDx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IkFkb2JlIFhNUCBDb3JlIDUuMC1jMDYxIDY0LjE0MDk0OSwgMjAxMC8xMi8wNy0xMDo1NzowMSAgICAgICAgIj4gPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4gPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIgeG1sbnM6eG1wTU09Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9tbS8iIHhtbG5zOnN0UmVmPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvc1R5cGUvUmVzb3VyY2VSZWYjIiB4bWxuczp4bXA9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC8iIHhtcE1NOk9yaWdpbmFsRG9jdW1lbnRJRD0ieG1wLmRpZDowMjgwMTE3NDA3MjA2ODExOEE2REU4Q0M1MTM1MkIxRiIgeG1wTU06RG9jdW1lbnRJRD0ieG1wLmRpZDpBQjVEQUNDMzQ4RUIxMUUxOEVGRUUyNzFENDM3RDVFMCIgeG1wTU06SW5zdGFuY2VJRD0ieG1wLmlpZDpBQjVEQUNDMjQ4RUIxMUUxOEVGRUUyNzFENDM3RDVFMCIgeG1wOkNyZWF0b3JUb29sPSJBZG9iZSBQaG90b3Nob3AgQ1M1LjEgTWFjaW50b3NoIj4gPHhtcE1NOkRlcml2ZWRGcm9tIHN0UmVmOmluc3RhbmNlSUQ9InhtcC5paWQ6QTU1MjE3RDIzMTIwNjgxMThEQkI4NTlBMjQ1QTEwOTUiIHN0UmVmOmRvY3VtZW50SUQ9InhtcC5kaWQ6MDI4MDExNzQwNzIwNjgxMThBNkRFOENDNTEzNTJCMUYiLz4gPC9yZGY6RGVzY3JpcHRpb24+IDwvcmRmOlJERj4gPC94OnhtcG1ldGE+IDw/eHBhY2tldCBlbmQ9InIiPz7SazaGAAAAiElEQVR42mL8//8/AzUBEwOVweA3kAWboI2jCyhgDwBx4ZH9ey5Qy4UOQHweaHg/EAtQ08sFUIMDqBmGCkC8HmgoCCtQM1ICoK5toGYsg8KzHmjo+UGbDj8AcSMwORkSnQ7xgA3QtPmApISNBTyAGrSBGl6eAMSGxBhGyIVkZT3G0fKQYgAQYACL+C2ZM6PC7AAAAABJRU5ErkJggg==)
|
||||
background-position: 0px center
|
||||
|
||||
//.user-code-problem
|
||||
//.ace_scroller
|
||||
// background-color: #470000
|
||||
|
||||
.ace_marker-layer
|
||||
.ace_bracket
|
||||
// Override faint gray
|
||||
border-color: #0FF
|
||||
border-color: #8FF
|
||||
|
||||
.ace_identifier
|
||||
background-color: rgba(255, 128, 128, 0.15)
|
||||
|
|
10
app/styles/play/level/tome/spell_debug.sass
Normal file
10
app/styles/play/level/tome/spell_debug.sass
Normal file
|
@ -0,0 +1,10 @@
|
|||
@import "../../../bootstrap/mixins"
|
||||
|
||||
.spell-debug-view
|
||||
position: absolute
|
||||
z-index: 9001
|
||||
max-width: 400px
|
||||
padding: 10px
|
||||
background: transparent url(/images/level/popover_background.png)
|
||||
background-size: 100% 100%
|
||||
|
54
app/styles/play/level/tome/spell_toolbar.sass
Normal file
54
app/styles/play/level/tome/spell_toolbar.sass
Normal file
|
@ -0,0 +1,54 @@
|
|||
@import "../../../bootstrap/mixins"
|
||||
|
||||
.spell-toolbar-view
|
||||
position: absolute
|
||||
z-index: 2
|
||||
top: 2px
|
||||
left: 5px
|
||||
box-sizing: border-box
|
||||
padding-left: 150px
|
||||
height: 36px
|
||||
width: 95%
|
||||
width: -webkit-calc(95% - 5px)
|
||||
width: calc(95% - 5px)
|
||||
background-color: rgba(100, 45, 210, 0.05)
|
||||
|
||||
.spell-progress
|
||||
position: relative
|
||||
height: 100%
|
||||
width: 50%
|
||||
display: inline-block
|
||||
|
||||
.progress
|
||||
position: absolute
|
||||
left: 0px
|
||||
top: 8px
|
||||
bottom: 0px
|
||||
width: 100%
|
||||
cursor: pointer
|
||||
overflow: visible
|
||||
|
||||
.bar
|
||||
@include transition(width .0s linear)
|
||||
position: relative
|
||||
pointer-events: none
|
||||
background-color: #67A4C8
|
||||
width: 50%
|
||||
|
||||
.scrubber-handle
|
||||
position: absolute
|
||||
pointer-events: none
|
||||
right: -16px
|
||||
top: -7px
|
||||
background: transparent url(/images/level/playback_thumb.png)
|
||||
width: 32px
|
||||
height: 32px
|
||||
|
||||
.btn-group
|
||||
// I don't know, I can figure this out for real later
|
||||
margin: -26px 0 0 18px
|
||||
|
||||
.metrics
|
||||
display: inline-block
|
||||
margin: -30px 0 0 10px
|
||||
vertical-align: middle
|
|
@ -1,4 +1,4 @@
|
|||
button.btn.btn-mini.btn-inverse#play-button.playing(title="Alt-P: Toggle level play/pause")
|
||||
button.btn.btn-mini.btn-inverse#play-button.playing(title="Ctrl/Cmd + P: Toggle level play/pause")
|
||||
i.icon-play.icon-white.big
|
||||
i.icon-pause.icon-white.big
|
||||
i.icon-repeat.icon-white.big
|
||||
|
@ -16,19 +16,19 @@ button.btn.btn-mini.btn-inverse#music-button(title="Toggle Music")
|
|||
.scrubber-handle
|
||||
|
||||
.btn-group.dropup#playback-settings
|
||||
button.btn.btn-mini.btn-inverse#zoom-in-button
|
||||
button.btn.btn-mini.btn-inverse#zoom-in-button(title="Zoom In (or scroll down)")
|
||||
i.icon-zoom-in.icon-white
|
||||
button.btn.btn-mini.btn-inverse#zoom-out-button
|
||||
button.btn.btn-mini.btn-inverse#zoom-out-button(title="Zoom Out (or scroll up)")
|
||||
i.icon-zoom-out.icon-white
|
||||
button.btn.btn-mini.btn-inverse.dropdown-toggle(data-toggle="dropdown")#settings-button
|
||||
i.icon-cog.icon-white.big
|
||||
ul.dropdown-menu
|
||||
if me.get('name') == "Nick"
|
||||
li(title="\\: Toggle debug display").selectable#debug-toggle
|
||||
li(title="Ctrl/Cmd + \\: Toggle debug display").selectable#debug-toggle
|
||||
i.icon-globe
|
||||
| Debug Mode
|
||||
i.icon-ok.hide
|
||||
li(title="G: Toggle grid display").selectable#grid-toggle
|
||||
li(title="Ctrl/Cmd + G: Toggle grid display").selectable#grid-toggle
|
||||
i.icon-th
|
||||
span(data-i18n="play_level.grid") Grid
|
||||
i.icon-ok.hide
|
||||
|
|
2
app/templates/play/level/tome/spell_debug.jade
Normal file
2
app/templates/play/level/tome/spell_debug.jade
Normal file
|
@ -0,0 +1,2 @@
|
|||
pre
|
||||
code
|
22
app/templates/play/level/tome/spell_toolbar.jade
Normal file
22
app/templates/play/level/tome/spell_toolbar.jade
Normal file
|
@ -0,0 +1,22 @@
|
|||
.spell-progress
|
||||
.progress
|
||||
.bar
|
||||
.scrubber-handle
|
||||
|
||||
.btn-group
|
||||
button.btn.btn-mini.btn-inverse.banner.step-backward(title="Ctrl/Cmd + Alt + [: Step Backward")
|
||||
i.icon-arrow-left.icon-white
|
||||
button.btn.btn-mini.btn-inverse.banner.step-forward(title="Ctrl/Cmd + Alt + ]: Step Forward")
|
||||
i.icon-arrow-right.icon-white
|
||||
|
||||
.metrics
|
||||
code.statements-metric
|
||||
span.metric.statement-index
|
||||
| /
|
||||
span.metric.statements-executed
|
||||
span.metric.statements-executed-total
|
||||
|
|
||||
code.calls-metric
|
||||
span.metric.call-index
|
||||
| /
|
||||
span.metric.calls-executed
|
|
@ -24,7 +24,6 @@ module.exports = class CastButtonView extends View
|
|||
context.castShortcutVerbose = @castShortcutVerbose
|
||||
context
|
||||
|
||||
|
||||
afterRender: ->
|
||||
super()
|
||||
# TODO: use a User setting instead of localStorage
|
||||
|
|
|
@ -64,7 +64,11 @@ module.exports = class Spell
|
|||
functionParameters: @parameters
|
||||
yieldConditionally: thang.plan?
|
||||
requiresThis: thang.requiresThis
|
||||
if @name is 'chooseAction' or not (me.team in @permissions.readwrite) or thang.id is 'Thoktar' # Gridmancer can't handle it
|
||||
includeFlow: true
|
||||
#callIndex: 0
|
||||
#timelessVariables: ['i']
|
||||
#statementIndex: 9001
|
||||
if not (me.team in @permissions.readwrite)# or @name is 'chooseAction' or thang.id is 'Thoktar' # Gridmancer can't handle it
|
||||
#console.log "Turning off includeFlow for", @spellKey
|
||||
aetherOptions.includeFlow = false
|
||||
aether = new Aether aetherOptions
|
||||
|
|
63
app/views/play/level/tome/spell_debug_view.coffee
Normal file
63
app/views/play/level/tome/spell_debug_view.coffee
Normal file
|
@ -0,0 +1,63 @@
|
|||
View = require 'views/kinds/CocoView'
|
||||
template = require 'templates/play/level/tome/spell_debug'
|
||||
Range = ace.require("ace/range").Range
|
||||
|
||||
module.exports = class DebugView extends View
|
||||
className: 'spell-debug-view'
|
||||
template: template
|
||||
subscriptions: {}
|
||||
events: {}
|
||||
|
||||
constructor: (options) ->
|
||||
super options
|
||||
@ace = options.ace
|
||||
@variableStates = {}
|
||||
|
||||
afterRender: ->
|
||||
super()
|
||||
@ace.on "mousemove", @onMouseMove
|
||||
#@ace.on "click", onClick # same ACE API as mousemove
|
||||
|
||||
setVariableStates: (@variableStates) ->
|
||||
@update()
|
||||
|
||||
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
|
||||
@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
|
||||
else
|
||||
@variable = @markerRange = null
|
||||
@update()
|
||||
|
||||
onMouseOut: (e) =>
|
||||
@variable = @markerRange = null
|
||||
@update()
|
||||
|
||||
update: ->
|
||||
if @variable
|
||||
value = @variableStates[@variable]
|
||||
@$el.find("code").text "#{@variable}: #{value}"
|
||||
@$el.show().css(@pos)
|
||||
else
|
||||
@$el.hide()
|
||||
@updateMarker()
|
||||
|
||||
updateMarker: ->
|
||||
if @marker
|
||||
@ace.getSession().removeMarker @marker
|
||||
@marker = null
|
||||
if @markerRange
|
||||
@marker = @ace.getSession().addMarker @markerRange, "ace_bracket", "text"
|
||||
|
||||
destroy: ->
|
||||
super()
|
||||
@ace?.removeEventListener "mousemove", @onMouseMove
|
94
app/views/play/level/tome/spell_toolbar_view.coffee
Normal file
94
app/views/play/level/tome/spell_toolbar_view.coffee
Normal file
|
@ -0,0 +1,94 @@
|
|||
View = require 'views/kinds/CocoView'
|
||||
template = require 'templates/play/level/tome/spell_toolbar'
|
||||
|
||||
module.exports = class SpellToolbarView extends View
|
||||
className: 'spell-toolbar-view'
|
||||
template: template
|
||||
|
||||
subscriptions:
|
||||
'spell-step-backward': 'onStepBackward'
|
||||
'spell-step-forward': 'onStepForward'
|
||||
|
||||
events:
|
||||
'mousemove .progress': 'onProgressHover'
|
||||
'mouseout .progress': 'onProgressMouseOut'
|
||||
'click .step-backward': 'onStepBackward'
|
||||
'click .step-forward': 'onStepForward'
|
||||
|
||||
constructor: (options) ->
|
||||
super options
|
||||
@ace = options.ace
|
||||
|
||||
afterRender: ->
|
||||
super()
|
||||
|
||||
setStatementIndex: (statementIndex) ->
|
||||
return unless total = @callState?.statementsExecuted
|
||||
@statementIndex = Math.min(total - 1, Math.max(0, statementIndex))
|
||||
@statementRatio = @statementIndex / (total - 1)
|
||||
@statementTime = @callState.statements[@statementIndex].userInfo.time
|
||||
@$el.find('.bar').css('width', 100 * @statementRatio + '%')
|
||||
Backbone.Mediator.publish 'tome:spell-statement-index-updated', statementIndex: @statementIndex, ace: @ace
|
||||
@$el.find('.step-backward').prop('disabled', @statementIndex is 0)
|
||||
@$el.find('.step-forward').prop('disabled', @statementIndex is total - 1)
|
||||
@updateMetrics()
|
||||
|
||||
updateMetrics: ->
|
||||
statementsExecuted = @callState.statementsExecuted
|
||||
$metrics = @$el.find('.metrics')
|
||||
if @metrics.callsExecuted > 1
|
||||
$metrics.find('.call-index').text @callIndex + 1
|
||||
$metrics.find('.calls-executed').text @metrics.callsExecuted
|
||||
$metrics.find('.calls-metric').show().attr('title', "Method call #{@callIndex + 1} of #{@metrics.callsExecuted} calls")
|
||||
else
|
||||
$metrics.find('.calls-metric').hide()
|
||||
if @metrics.statementsExecuted
|
||||
$metrics.find('.statement-index').text @statementIndex + 1
|
||||
$metrics.find('.statements-executed').text statementsExecuted
|
||||
if @metrics.statementsExecuted > statementsExecuted
|
||||
$metrics.find('.statements-executed-total').text " (#{@metrics.statementsExecuted})"
|
||||
titleSuffix = " (#{@metrics.statementsExecuted} statements total)"
|
||||
else
|
||||
$metrics.find('.statements-executed-total').text ""
|
||||
titleSuffix = ""
|
||||
$metrics.find('.statements-metric').show().attr('title', "Statement #{@statementIndex + 1} of #{statementsExecuted} this call#{titleSuffix}")
|
||||
else
|
||||
$metrics.find('.statements-metric').hide()
|
||||
|
||||
setStatementRatio: (ratio) ->
|
||||
return unless total = @callState?.statementsExecuted
|
||||
@setStatementIndex Math.floor ratio * total
|
||||
|
||||
onProgressHover: (e) ->
|
||||
@setStatementRatio e.offsetX / @$el.find('.progress').width()
|
||||
@updateTime()
|
||||
@maintainIndexHover = true
|
||||
|
||||
onProgressMouseOut: (e) ->
|
||||
@maintainIndexHover = false
|
||||
|
||||
onStepBackward: (e) -> @step -1
|
||||
onStepForward: (e) -> @step 1
|
||||
step: (delta) ->
|
||||
lastTime = @statementTime
|
||||
@setStatementIndex @statementIndex + delta
|
||||
@updateTime() if @statementIndex isnt lastTime
|
||||
|
||||
updateTime: ->
|
||||
@maintainIndexScrub = true
|
||||
clearTimeout @maintainIndexScrubTimeout if @maintainIndexScrubTimeout
|
||||
@maintainIndexScrubTimeout = _.delay (=> @maintainIndexScrub = false), 500
|
||||
Backbone.Mediator.publish 'level-set-time', time: @statementTime, scrubDuration: 500
|
||||
|
||||
setCallState: (callState, statementIndex, @callIndex, @metrics) ->
|
||||
return if callState is @callState and statementIndex is @statementIndex
|
||||
return unless @callState = callState
|
||||
if not @maintainIndexHover and not @maintainIndexScrub and statementIndex? and callState.statements[statementIndex].userInfo.time isnt @statementTime
|
||||
@setStatementIndex statementIndex
|
||||
else
|
||||
@setStatementRatio @statementRatio
|
||||
# Not sure yet whether it's better to maintain @statementIndex or @statementRatio
|
||||
#else if @statementRatio is 1 or not @statementIndex?
|
||||
# @setStatementRatio 1
|
||||
#else
|
||||
# @setStatementIndex @statementIndex
|
|
@ -4,6 +4,8 @@ template = require 'templates/play/level/tome/spell'
|
|||
filters = require 'lib/image_filter'
|
||||
Range = ace.require("ace/range").Range
|
||||
Problem = require './problem'
|
||||
SpellDebugView = require './spell_debug_view'
|
||||
SpellToolbarView = require './spell_toolbar_view'
|
||||
|
||||
module.exports = class SpellView extends View
|
||||
id: 'spell-view'
|
||||
|
@ -25,9 +27,10 @@ module.exports = class SpellView extends View
|
|||
'level:session-will-save': 'onSessionWillSave'
|
||||
'modal-closed': 'focus'
|
||||
'focus-editor': 'focus'
|
||||
'tome:spell-statement-index-updated': 'onStatementIndexUpdated'
|
||||
|
||||
events:
|
||||
'click .ace': -> console.log 'clicked ace', @
|
||||
'mouseout': 'onMouseOut'
|
||||
|
||||
constructor: (options) ->
|
||||
super options
|
||||
|
@ -48,6 +51,7 @@ 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
|
||||
|
@ -86,24 +90,30 @@ module.exports = class SpellView extends View
|
|||
name: 'end-all-scripts'
|
||||
bindKey: {win: 'Escape', mac: 'Escape'}
|
||||
exec: -> Backbone.Mediator.publish 'level:escape-pressed'
|
||||
|
||||
# TODO: These don't work on, for example, Danish keyboards. Figure out a more universal solution.
|
||||
# @ace.commands.addCommand
|
||||
# name: 'toggle-grid'
|
||||
# bindKey: {win: 'Alt-G', mac: 'Alt-G'}
|
||||
# exec: -> Backbone.Mediator.publish 'level-toggle-grid'
|
||||
# @ace.commands.addCommand
|
||||
# name: 'toggle-debug'
|
||||
# bindKey: {win: 'Alt-\\', mac: 'Alt-\\'}
|
||||
# exec: -> Backbone.Mediator.publish 'level-toggle-debug'
|
||||
# @ace.commands.addCommand
|
||||
# name: 'level-scrub-forward'
|
||||
# bindKey: {win: 'Alt-]', mac: 'Alt-]'}
|
||||
# exec: -> Backbone.Mediator.publish 'level-scrub-forward'
|
||||
# @ace.commands.addCommand
|
||||
# name: 'level-scrub-back'
|
||||
# bindKey: {win: 'Alt-[', mac: 'Alt-['}
|
||||
# exec: -> Backbone.Mediator.publish 'level-scrub-back'
|
||||
@ace.commands.addCommand
|
||||
name: 'toggle-grid'
|
||||
bindKey: {win: 'Ctrl-G', mac: 'Command-G|Ctrl-G'}
|
||||
exec: -> Backbone.Mediator.publish 'level-toggle-grid'
|
||||
@ace.commands.addCommand
|
||||
name: 'toggle-debug'
|
||||
bindKey: {win: 'Ctrl-\\', mac: 'Command-\\|Ctrl-\\'}
|
||||
exec: -> Backbone.Mediator.publish 'level-toggle-debug'
|
||||
@ace.commands.addCommand
|
||||
name: 'level-scrub-forward'
|
||||
bindKey: {win: 'Ctrl-]', mac: 'Command-]|Ctrl-]'}
|
||||
exec: -> Backbone.Mediator.publish 'level-scrub-forward'
|
||||
@ace.commands.addCommand
|
||||
name: 'level-scrub-back'
|
||||
bindKey: {win: 'Ctrl-[', mac: 'Command-[|Ctrl-]'}
|
||||
exec: -> Backbone.Mediator.publish 'level-scrub-back'
|
||||
@ace.commands.addCommand
|
||||
name: 'spell-step-forward'
|
||||
bindKey: {win: 'Ctrl-Alt-]', mac: 'Command-Alt-]|Ctrl-Alt-]'}
|
||||
exec: -> Backbone.Mediator.publish 'spell-step-forward'
|
||||
@ace.commands.addCommand
|
||||
name: 'spell-step-backward'
|
||||
bindKey: {win: 'Ctrl-Alt-[', mac: 'Command-Alt-[|Ctrl-Alt-]'}
|
||||
exec: -> Backbone.Mediator.publish 'spell-step-backward'
|
||||
|
||||
fillACE: ->
|
||||
@ace.setValue @spell.source
|
||||
|
@ -145,6 +155,17 @@ module.exports = class SpellView extends View
|
|||
Backbone.Mediator.publish 'tome:spell-loaded', spell: @spell
|
||||
@eventsSuppressed = false # Now that the initial change is in, we can start running any changed code
|
||||
|
||||
createDebugView: ->
|
||||
@debugView = new SpellDebugView ace: @ace
|
||||
@$el.append @debugView.render().$el.hide()
|
||||
|
||||
createToolbarView: ->
|
||||
@toolbarView = new SpellToolbarView ace: @ace
|
||||
@$el.prepend @toolbarView.render().$el
|
||||
|
||||
onMouseOut: (e) ->
|
||||
@debugView.onMouseOut e
|
||||
|
||||
getSource: ->
|
||||
@ace.getValue() # could also do @firepad.getText()
|
||||
|
||||
|
@ -368,22 +389,33 @@ module.exports = class SpellView extends View
|
|||
@thang = e.selectedThang # update our thang to the current version
|
||||
@highlightCurrentLine()
|
||||
|
||||
onStatementIndexUpdated: (e) ->
|
||||
return unless e.ace is @ace
|
||||
@highlightCurrentLine()
|
||||
|
||||
highlightCurrentLine: (flow) =>
|
||||
# TODO: move this whole thing into SpellDebugView or somewhere?
|
||||
flow ?= @spellThang?.castAether?.flow
|
||||
return unless flow
|
||||
executed = []
|
||||
matched = false
|
||||
for callState, callNumber in flow.states or []
|
||||
states = flow.states ? []
|
||||
currentCallIndex = null
|
||||
for callState, callNumber in states
|
||||
if not currentCallIndex? and callState.userInfo?.time > @thang.world.age
|
||||
currentCallIndex = callNumber - 1
|
||||
if matched
|
||||
executed.pop()
|
||||
break
|
||||
executed.push []
|
||||
for state, statementNumber in callState
|
||||
for state, statementNumber in callState.statements
|
||||
if state.userInfo?.time > @thang.world.age
|
||||
matched = true
|
||||
break
|
||||
_.last(executed).push state
|
||||
#state.executing = true if state.userInfo?.time is @thang.world.age # no work
|
||||
currentCallIndex ?= callNumber - 1
|
||||
#console.log "got call index", currentCallIndex, "for time", @thang.world.age, "out of", states.length
|
||||
|
||||
# TODO: don't redo the markers if they haven't actually changed
|
||||
text = @aceDoc.getValue()
|
||||
|
@ -397,11 +429,20 @@ module.exports = class SpellView extends View
|
|||
markerRange.end.detach()
|
||||
@aceSession.removeMarker markerRange.id
|
||||
@markerRanges = []
|
||||
@debugView.setVariableStates {}
|
||||
@aceSession.removeGutterDecoration row, 'executing' for row in [0 ... @aceSession.getLength()]
|
||||
$(@ace.container).find('.ace_gutter-cell.executing').removeClass('executing')
|
||||
return unless executed.length
|
||||
unless executed.length
|
||||
@toolbarView?.$el.hide()
|
||||
return
|
||||
unless @toolbarView or (@spell.name is "plan" and @spellThang.castAether.metrics.statementsExecuted < 20)
|
||||
@createToolbarView()
|
||||
lastExecuted = _.last executed
|
||||
@toolbarView?.$el.show()
|
||||
statementIndex = Math.max 0, lastExecuted.length - 1
|
||||
@toolbarView?.setCallState states[currentCallIndex], statementIndex, currentCallIndex, @spellThang.castAether.metrics
|
||||
marked = {}
|
||||
lastExecuted = lastExecuted[0 .. @toolbarView.statementIndex] if @toolbarView?.statementIndex?
|
||||
for state, i in lastExecuted
|
||||
#clazz = if state.executing then 'executing' else 'executed' # doesn't work
|
||||
clazz = if i is lastExecuted.length - 1 then 'executing' else 'executed'
|
||||
|
@ -410,6 +451,9 @@ module.exports = class SpellView extends View
|
|||
continue if marked[key] > 2 # don't allow more than three of the same marker
|
||||
marked[key] ?= 0
|
||||
++marked[key]
|
||||
else
|
||||
@debugView.setVariableStates state.variables
|
||||
#console.log "at", state.userInfo.time, "vars are now:", state.variables
|
||||
[start, end] = [offsetToPos(state.range[0]), offsetToPos(state.range[1])]
|
||||
markerRange = new Range(start.row, start.column, end.row, end.column)
|
||||
markerRange.start = @aceDoc.createAnchor markerRange.start
|
||||
|
@ -454,3 +498,4 @@ module.exports = class SpellView extends View
|
|||
super()
|
||||
@firepad?.dispose()
|
||||
@ace.destroy()
|
||||
@debugView.destroy()
|
||||
|
|
|
@ -114,6 +114,7 @@ module.exports = class TomeView extends View
|
|||
@spellTabView?.$el.after('<div id="' + @spellTabView.id + '"></div>').detach()
|
||||
@spellTabView = null
|
||||
@removeSubView @spellPaletteView if @spellPaletteView
|
||||
@castButton?.$el.hide()
|
||||
@thangList?.$el.show()
|
||||
|
||||
onSpriteSelected: (e) ->
|
||||
|
@ -137,6 +138,7 @@ module.exports = class TomeView extends View
|
|||
@$el.find('#' + @spellTabView.id).after(@spellTabView.el).remove()
|
||||
@spellView.setThang thang
|
||||
@spellTabView.setThang thang
|
||||
@castButton.$el.show()
|
||||
@thangList.$el.hide()
|
||||
@spellPaletteView = @insertSubView new SpellPaletteView thang: thang
|
||||
@spellPaletteView.toggleControls {}, @spellView.controlsEnabled # TODO: know when palette should have been disabled but didn't exist
|
||||
|
|
Loading…
Reference in a new issue