mirror of
https://github.com/codeninjasllc/codecombat.git
synced 2024-11-30 19:06:59 -05:00
Fixed a ton more leaks.
This commit is contained in:
parent
ad8a8e00e8
commit
5655084981
17 changed files with 162 additions and 113 deletions
|
@ -131,6 +131,8 @@ module.exports = class God
|
||||||
@dead = true
|
@dead = true
|
||||||
Backbone.Mediator.unsubscribe('tome:cast-spells', @onTomeCast, @)
|
Backbone.Mediator.unsubscribe('tome:cast-spells', @onTomeCast, @)
|
||||||
@goalManager = null
|
@goalManager = null
|
||||||
|
@fillWorkerPool = null
|
||||||
|
@simulateWorld = null
|
||||||
|
|
||||||
#### Bad code for running worlds on main thread (profiling / IE9) ####
|
#### Bad code for running worlds on main thread (profiling / IE9) ####
|
||||||
simulateWorld: =>
|
simulateWorld: =>
|
||||||
|
@ -207,6 +209,7 @@ class Angel
|
||||||
if @worker
|
if @worker
|
||||||
worker = @worker
|
worker = @worker
|
||||||
_.defer -> worker.terminate
|
_.defer -> worker.terminate
|
||||||
|
@worker.removeEventListener 'message', @onWorkerMessage
|
||||||
@worker = null
|
@worker = null
|
||||||
@
|
@
|
||||||
|
|
||||||
|
@ -217,6 +220,7 @@ class Angel
|
||||||
|
|
||||||
terminate: =>
|
terminate: =>
|
||||||
@worker?.terminate()
|
@worker?.terminate()
|
||||||
|
@worker?.removeEventListener 'message', @onWorkerMessage
|
||||||
@worker = null
|
@worker = null
|
||||||
return if @dead
|
return if @dead
|
||||||
@free()
|
@free()
|
||||||
|
@ -225,6 +229,10 @@ class Angel
|
||||||
destroy: ->
|
destroy: ->
|
||||||
@dead = true
|
@dead = true
|
||||||
@abort()
|
@abort()
|
||||||
|
@terminate = null
|
||||||
|
@testWorker = null
|
||||||
|
@condemnWorker = null
|
||||||
|
@onWorkerMessage = null
|
||||||
|
|
||||||
testWorker: =>
|
testWorker: =>
|
||||||
@worker.postMessage {func: 'reportIn'}
|
@worker.postMessage {func: 'reportIn'}
|
||||||
|
@ -235,7 +243,9 @@ class Angel
|
||||||
@abort()
|
@abort()
|
||||||
|
|
||||||
listen: ->
|
listen: ->
|
||||||
@worker.addEventListener 'message', (event) =>
|
@worker.addEventListener 'message', @onWorkerMessage
|
||||||
|
|
||||||
|
onWorkerMessage: (event) =>
|
||||||
switch event.data.type
|
switch event.data.type
|
||||||
when 'new-world'
|
when 'new-world'
|
||||||
@god.beholdWorld @, event.data.serialized, event.data.goalStates
|
@god.beholdWorld @, event.data.serialized, event.data.goalStates
|
||||||
|
|
|
@ -28,7 +28,7 @@ module.exports = class LevelLoader extends CocoClass
|
||||||
@loadLevelModels()
|
@loadLevelModels()
|
||||||
@loadAudio()
|
@loadAudio()
|
||||||
@playJingle()
|
@playJingle()
|
||||||
setTimeout (=> @update()), 1 # lets everything else resolve first
|
_.defer @update # Lets everything else resolve first
|
||||||
|
|
||||||
playJingle: ->
|
playJingle: ->
|
||||||
jingles = ["ident_1", "ident_2"]
|
jingles = ["ident_1", "ident_2"]
|
||||||
|
@ -80,7 +80,7 @@ module.exports = class LevelLoader extends CocoClass
|
||||||
# building = thangType.buildSpriteSheet options
|
# building = thangType.buildSpriteSheet options
|
||||||
# if building
|
# if building
|
||||||
# @spriteSheetsToBuild += 1
|
# @spriteSheetsToBuild += 1
|
||||||
# thangType.on 'build-complete', =>
|
# thangType.once 'build-complete', =>
|
||||||
# @spriteSheetsBuilt += 1
|
# @spriteSheetsBuilt += 1
|
||||||
# @notifyProgress()
|
# @notifyProgress()
|
||||||
|
|
||||||
|
@ -91,7 +91,7 @@ module.exports = class LevelLoader extends CocoClass
|
||||||
|
|
||||||
# Things to do when either the Session or Supermodel load
|
# Things to do when either the Session or Supermodel load
|
||||||
|
|
||||||
update: ->
|
update: =>
|
||||||
@notifyProgress()
|
@notifyProgress()
|
||||||
|
|
||||||
return if @updateCompleted
|
return if @updateCompleted
|
||||||
|
@ -153,7 +153,7 @@ module.exports = class LevelLoader extends CocoClass
|
||||||
return unless building
|
return unless building
|
||||||
console.log 'Building:', thangType.get('name'), options
|
console.log 'Building:', thangType.get('name'), options
|
||||||
@spriteSheetsToBuild += 1
|
@spriteSheetsToBuild += 1
|
||||||
thangType.on 'build-complete', =>
|
thangType.once 'build-complete', =>
|
||||||
@spriteSheetsBuilt += 1
|
@spriteSheetsBuilt += 1
|
||||||
@notifyProgress()
|
@notifyProgress()
|
||||||
|
|
||||||
|
@ -208,6 +208,11 @@ module.exports = class LevelLoader extends CocoClass
|
||||||
@trigger 'loaded-all' if @progress() is 1
|
@trigger 'loaded-all' if @progress() is 1
|
||||||
|
|
||||||
destroy: ->
|
destroy: ->
|
||||||
|
super()
|
||||||
@world = null # don't hold onto garbage
|
@world = null # don't hold onto garbage
|
||||||
@supermodel.off 'loaded-one', @onSupermodelLoadedOne
|
@supermodel.off 'loaded-one', @onSupermodelLoadedOne
|
||||||
super()
|
@onSessionLoaded = null
|
||||||
|
@onSupermodelError = null
|
||||||
|
@onSupermodelLoadedOne = null
|
||||||
|
@onSupermodelLoadedAll = null
|
||||||
|
@notifyProgress = null
|
||||||
|
|
|
@ -199,15 +199,13 @@ module.exports = class Camera extends CocoClass
|
||||||
@tweenProgress = 0.01
|
@tweenProgress = 0.01
|
||||||
createjs.Tween.get(@)
|
createjs.Tween.get(@)
|
||||||
.to({tweenProgress: 1.0}, time, createjs.Ease.getPowInOut(3))
|
.to({tweenProgress: 1.0}, time, createjs.Ease.getPowInOut(3))
|
||||||
.call @onTweenEnd
|
.call @finishTween
|
||||||
|
|
||||||
else
|
else
|
||||||
@target = newTarget
|
@target = newTarget
|
||||||
@zoom = newZoom
|
@zoom = newZoom
|
||||||
@updateZoom true
|
@updateZoom true
|
||||||
|
|
||||||
onTweenEnd: => @finishTween()
|
|
||||||
|
|
||||||
finishTween: (abort=false) =>
|
finishTween: (abort=false) =>
|
||||||
createjs.Tween.removeTweens(@)
|
createjs.Tween.removeTweens(@)
|
||||||
return unless @newTarget
|
return unless @newTarget
|
||||||
|
@ -263,4 +261,5 @@ module.exports = class Camera extends CocoClass
|
||||||
|
|
||||||
destroy: ->
|
destroy: ->
|
||||||
super()
|
super()
|
||||||
@onTweenEnd = null
|
createjs.Tween.removeTweens @
|
||||||
|
@finishTween = null
|
||||||
|
|
|
@ -80,6 +80,9 @@ module.exports = CocoSprite = class CocoSprite extends CocoClass
|
||||||
super()
|
super()
|
||||||
mark.destroy() for name, mark of @marks
|
mark.destroy() for name, mark of @marks
|
||||||
label.destroy() for name, label of @labels
|
label.destroy() for name, label of @labels
|
||||||
|
@imageObject?.off 'animationend', @playNextAction
|
||||||
|
@playNextAction = null
|
||||||
|
@displayObject?.off()
|
||||||
|
|
||||||
toString: -> "<CocoSprite: #{@thang?.id}>"
|
toString: -> "<CocoSprite: #{@thang?.id}>"
|
||||||
|
|
||||||
|
@ -108,7 +111,7 @@ module.exports = CocoSprite = class CocoSprite extends CocoClass
|
||||||
@displayObject.sprite = @
|
@displayObject.sprite = @
|
||||||
@displayObject.layerPriority = @thangType.get 'layerPriority'
|
@displayObject.layerPriority = @thangType.get 'layerPriority'
|
||||||
@displayObject.name = @thang?.spriteName or @thangType.get 'name'
|
@displayObject.name = @thang?.spriteName or @thangType.get 'name'
|
||||||
@imageObject.on 'animationend', @onActionEnd
|
@imageObject.on 'animationend', @playNextAction
|
||||||
|
|
||||||
##################################################
|
##################################################
|
||||||
# QUEUEING AND PLAYING ACTIONS
|
# QUEUEING AND PLAYING ACTIONS
|
||||||
|
@ -126,10 +129,9 @@ module.exports = CocoSprite = class CocoSprite extends CocoClass
|
||||||
@currentRootAction = action
|
@currentRootAction = action
|
||||||
@playNextAction()
|
@playNextAction()
|
||||||
|
|
||||||
onActionEnd: (e) => @playNextAction()
|
|
||||||
onSurfaceTicked: (e) -> @age += e.dt
|
onSurfaceTicked: (e) -> @age += e.dt
|
||||||
|
|
||||||
playNextAction: ->
|
playNextAction: =>
|
||||||
@playAction(@actionQueue.splice(0,1)[0]) if @actionQueue.length
|
@playAction(@actionQueue.splice(0,1)[0]) if @actionQueue.length
|
||||||
|
|
||||||
playAction: (action) ->
|
playAction: (action) ->
|
||||||
|
@ -411,7 +413,7 @@ module.exports = CocoSprite = class CocoSprite extends CocoClass
|
||||||
sound = e.sound ? AudioPlayer.soundForDialogue e.message, @thangType.get 'soundTriggers'
|
sound = e.sound ? AudioPlayer.soundForDialogue e.message, @thangType.get 'soundTriggers'
|
||||||
@instance?.stop()
|
@instance?.stop()
|
||||||
if @instance = @playSound sound, false
|
if @instance = @playSound sound, false
|
||||||
@instance.addEventListener "complete", => Backbone.Mediator.publish 'dialogue-sound-completed'
|
@instance.addEventListener "complete", -> Backbone.Mediator.publish 'dialogue-sound-completed'
|
||||||
@notifySpeechUpdated e
|
@notifySpeechUpdated e
|
||||||
|
|
||||||
onClearDialogue: (e) ->
|
onClearDialogue: (e) ->
|
||||||
|
|
|
@ -13,8 +13,8 @@ module.exports = class MusicPlayer extends CocoClass
|
||||||
'audio-player:loaded': 'onAudioLoaded'
|
'audio-player:loaded': 'onAudioLoaded'
|
||||||
|
|
||||||
constructor: ->
|
constructor: ->
|
||||||
super(arguments...)
|
super arguments...
|
||||||
me.on('change:music', @onMusicSettingChanged, @)
|
me.on 'change:music', @onMusicSettingChanged, @
|
||||||
|
|
||||||
onAudioLoaded: ->
|
onAudioLoaded: ->
|
||||||
@onPlayMusic(@standingBy) if @standingBy
|
@onPlayMusic(@standingBy) if @standingBy
|
||||||
|
@ -49,3 +49,6 @@ module.exports = class MusicPlayer extends CocoClass
|
||||||
createjs.Tween.removeTweens(@currentMusic)
|
createjs.Tween.removeTweens(@currentMusic)
|
||||||
@currentMusic.volume = if me.get('music') then 1.0 else 0.0
|
@currentMusic.volume = if me.get('music') then 1.0 else 0.0
|
||||||
|
|
||||||
|
destroy: ->
|
||||||
|
super()
|
||||||
|
me.off 'change:music', @onMusicSettingChanged, @
|
||||||
|
|
|
@ -90,13 +90,18 @@ module.exports = Surface = class Surface extends CocoClass
|
||||||
@dimmer?.destroy()
|
@dimmer?.destroy()
|
||||||
@stage.clear()
|
@stage.clear()
|
||||||
@musicPlayer?.destroy()
|
@musicPlayer?.destroy()
|
||||||
|
@stage.removeAllChildren()
|
||||||
@stage.removeEventListener 'stagemousemove', @onMouseMove
|
@stage.removeEventListener 'stagemousemove', @onMouseMove
|
||||||
@stage.removeEventListener 'stagemousedown', @onMouseDown
|
@stage.removeEventListener 'stagemousedown', @onMouseDown
|
||||||
@stage.removeAllEventListeners()
|
@stage.removeAllEventListeners()
|
||||||
|
@stage.enableDOMEvents false
|
||||||
|
@stage.enableMouseOver 0
|
||||||
@playScrubbedSounds = null
|
@playScrubbedSounds = null
|
||||||
@onMouseMove = null
|
@onMouseMove = null
|
||||||
@onMouseDown = null
|
@onMouseDown = null
|
||||||
@tick = null
|
@tick = null
|
||||||
|
@canvas.off 'mousewheel', @onMouseWheel
|
||||||
|
@onMouseWheel = null
|
||||||
|
|
||||||
setWorld: (@world) ->
|
setWorld: (@world) ->
|
||||||
@worldLoaded = true
|
@worldLoaded = true
|
||||||
|
@ -337,7 +342,7 @@ module.exports = Surface = class Surface extends CocoClass
|
||||||
@stage.enableMouseOver(10)
|
@stage.enableMouseOver(10)
|
||||||
@stage.addEventListener 'stagemousemove', @onMouseMove
|
@stage.addEventListener 'stagemousemove', @onMouseMove
|
||||||
@stage.addEventListener 'stagemousedown', @onMouseDown
|
@stage.addEventListener 'stagemousedown', @onMouseDown
|
||||||
@hookUpZoomControls()
|
@canvas.on 'mousewheel', @onMouseWheel
|
||||||
@hookUpChooseControls() if @options.choosing
|
@hookUpChooseControls() if @options.choosing
|
||||||
console.log "Setting fps", @world.frameRate unless @world.frameRate is 30
|
console.log "Setting fps", @world.frameRate unless @world.frameRate is 30
|
||||||
createjs.Ticker.setFPS @world.frameRate
|
createjs.Ticker.setFPS @world.frameRate
|
||||||
|
@ -436,8 +441,7 @@ module.exports = Surface = class Surface extends CocoClass
|
||||||
onBackground = not @stage.hitTest e.stageX, e.stageY
|
onBackground = not @stage.hitTest e.stageX, e.stageY
|
||||||
Backbone.Mediator.publish 'surface:stage-mouse-down', onBackground: onBackground, x: e.stageX, y: e.stageY, originalEvent: e
|
Backbone.Mediator.publish 'surface:stage-mouse-down', onBackground: onBackground, x: e.stageX, y: e.stageY, originalEvent: e
|
||||||
|
|
||||||
hookUpZoomControls: ->
|
onMouseWheel: (e) =>
|
||||||
@canvas.bind 'mousewheel', (e) =>
|
|
||||||
# https://github.com/brandonaaron/jquery-mousewheel
|
# https://github.com/brandonaaron/jquery-mousewheel
|
||||||
e.preventDefault()
|
e.preventDefault()
|
||||||
return if @disabled
|
return if @disabled
|
||||||
|
|
|
@ -55,7 +55,7 @@ class CocoModel extends Backbone.Model
|
||||||
@constructor.schema = new CocoSchema(@urlRoot)
|
@constructor.schema = new CocoSchema(@urlRoot)
|
||||||
@constructor.schema.fetch()
|
@constructor.schema.fetch()
|
||||||
|
|
||||||
@constructor.schema.on 'sync', =>
|
@constructor.schema.once 'sync', =>
|
||||||
@constructor.schema.loaded = true
|
@constructor.schema.loaded = true
|
||||||
@addSchemaDefaults()
|
@addSchemaDefaults()
|
||||||
@trigger 'schema-loaded'
|
@trigger 'schema-loaded'
|
||||||
|
|
|
@ -8,7 +8,7 @@ class SuperModel
|
||||||
@mustPopulate = model
|
@mustPopulate = model
|
||||||
model.saveBackups = @shouldSaveBackups(model)
|
model.saveBackups = @shouldSaveBackups(model)
|
||||||
model.fetch() unless model.loaded or model.loading
|
model.fetch() unless model.loaded or model.loading
|
||||||
model.on('sync', @modelLoaded) unless model.loaded
|
model.once('sync', @modelLoaded) unless model.loaded
|
||||||
model.once('error', @modelErrored) unless model.loaded
|
model.once('error', @modelErrored) unless model.loaded
|
||||||
url = model.url()
|
url = model.url()
|
||||||
@models[url] = model unless @models[url]?
|
@models[url] = model unless @models[url]?
|
||||||
|
@ -23,7 +23,7 @@ class SuperModel
|
||||||
|
|
||||||
modelLoaded: (model) =>
|
modelLoaded: (model) =>
|
||||||
schema = model.schema()
|
schema = model.schema()
|
||||||
return schema.on('sync', => @modelLoaded(model)) unless schema.loaded
|
return schema.once('sync', => @modelLoaded(model)) unless schema.loaded
|
||||||
refs = model.getReferencedModels(model.attributes, schema.attributes)
|
refs = model.getReferencedModels(model.attributes, schema.attributes)
|
||||||
refs = [] unless @mustPopulate is model or @shouldPopulate(model)
|
refs = [] unless @mustPopulate is model or @shouldPopulate(model)
|
||||||
# console.log 'Loaded', model.get('name')
|
# console.log 'Loaded', model.get('name')
|
||||||
|
@ -33,7 +33,7 @@ class SuperModel
|
||||||
continue if @models[refURL]
|
continue if @models[refURL]
|
||||||
@models[refURL] = ref
|
@models[refURL] = ref
|
||||||
ref.fetch()
|
ref.fetch()
|
||||||
ref.on 'sync', @modelLoaded
|
ref.once 'sync', @modelLoaded
|
||||||
|
|
||||||
@trigger 'loaded-one', model: model
|
@trigger 'loaded-one', model: model
|
||||||
@trigger 'loaded-all' if @finished()
|
@trigger 'loaded-all' if @finished()
|
||||||
|
|
|
@ -28,7 +28,6 @@ module.exports = class User extends CocoModel
|
||||||
profileUrl = "#{GRAVATAR_URL}#{emailHash}.json?callback=#{functionName}"
|
profileUrl = "#{GRAVATAR_URL}#{emailHash}.json?callback=#{functionName}"
|
||||||
script = $("<script src='#{profileUrl}' type='text/javascript'></script>")
|
script = $("<script src='#{profileUrl}' type='text/javascript'></script>")
|
||||||
$('head').append(script)
|
$('head').append(script)
|
||||||
$('body').on('load',(e)->console.log('we did it!', e))
|
|
||||||
window[functionName] = (profile) =>
|
window[functionName] = (profile) =>
|
||||||
@gravatarProfile = profile
|
@gravatarProfile = profile
|
||||||
@trigger('change', @)
|
@trigger('change', @)
|
||||||
|
|
|
@ -42,6 +42,7 @@ module.exports = class CocoView extends Backbone.View
|
||||||
@undelegateEvents() # removes both events and subs
|
@undelegateEvents() # removes both events and subs
|
||||||
view.destroy() for id, view of @subviews
|
view.destroy() for id, view of @subviews
|
||||||
@modalClosed = null
|
@modalClosed = null
|
||||||
|
$('#modal-wrapper .modal').off 'hidden.bs.modal', @modalClosed
|
||||||
|
|
||||||
afterInsert: ->
|
afterInsert: ->
|
||||||
|
|
||||||
|
@ -106,7 +107,7 @@ module.exports = class CocoView extends Backbone.View
|
||||||
modalView.afterInsert()
|
modalView.afterInsert()
|
||||||
visibleModal = modalView
|
visibleModal = modalView
|
||||||
modalOptions = {show: true, backdrop: if modalView.closesOnClickOutside then true else 'static'}
|
modalOptions = {show: true, backdrop: if modalView.closesOnClickOutside then true else 'static'}
|
||||||
$('#modal-wrapper .modal').modal(modalOptions).on('hidden.bs.modal', @modalClosed)
|
$('#modal-wrapper .modal').modal(modalOptions).on 'hidden.bs.modal', @modalClosed
|
||||||
window.currentModal = modalView
|
window.currentModal = modalView
|
||||||
@getRootView().stopListeningToShortcuts(true)
|
@getRootView().stopListeningToShortcuts(true)
|
||||||
|
|
||||||
|
@ -114,6 +115,7 @@ module.exports = class CocoView extends Backbone.View
|
||||||
visibleModal.willDisappear() if visibleModal
|
visibleModal.willDisappear() if visibleModal
|
||||||
visibleModal.destroy()
|
visibleModal.destroy()
|
||||||
visibleModal = null
|
visibleModal = null
|
||||||
|
$('#modal-wrapper .modal').off 'hidden.bs.modal', @modalClosed
|
||||||
if waitingModal
|
if waitingModal
|
||||||
wm = waitingModal
|
wm = waitingModal
|
||||||
waitingModal = null
|
waitingModal = null
|
||||||
|
|
|
@ -37,6 +37,7 @@ module.exports = class ControlBarView extends View
|
||||||
setBus: (@bus) ->
|
setBus: (@bus) ->
|
||||||
|
|
||||||
onPlayerStatesChanged: (e) ->
|
onPlayerStatesChanged: (e) ->
|
||||||
|
# TODO: this doesn't fire any more. Replacement?
|
||||||
return unless @bus is e.bus
|
return unless @bus is e.bus
|
||||||
numPlayers = _.keys(e.players).length
|
numPlayers = _.keys(e.players).length
|
||||||
return if numPlayers is @numPlayers
|
return if numPlayers is @numPlayers
|
||||||
|
|
|
@ -11,6 +11,8 @@ module.exports = class CastButtonView extends View
|
||||||
'tome:cast-spells': 'onCastSpells'
|
'tome:cast-spells': 'onCastSpells'
|
||||||
'god:world-load-progress-changed': 'onWorldLoadProgressChanged'
|
'god:world-load-progress-changed': 'onWorldLoadProgressChanged'
|
||||||
'god:new-world-created': 'onNewWorld'
|
'god:new-world-created': 'onNewWorld'
|
||||||
|
'click .cast-button': -> Backbone.Mediator.publish 'tome:manual-cast', {}
|
||||||
|
'click .cast-options a': 'onCastOptionsClick'
|
||||||
|
|
||||||
constructor: (options) ->
|
constructor: (options) ->
|
||||||
super options
|
super options
|
||||||
|
@ -26,8 +28,10 @@ module.exports = class CastButtonView extends View
|
||||||
|
|
||||||
afterRender: ->
|
afterRender: ->
|
||||||
super()
|
super()
|
||||||
|
@castButton = $('.cast-button', @$el)
|
||||||
|
@castButtonGroup = $('.cast-button-group', @$el)
|
||||||
|
@castOptions = $('.autocast-delays', @$el)
|
||||||
# TODO: use a User setting instead of localStorage
|
# TODO: use a User setting instead of localStorage
|
||||||
@hookUpButtons()
|
|
||||||
delay = localStorage.getItem 'autocastDelay'
|
delay = localStorage.getItem 'autocastDelay'
|
||||||
delay ?= 5000
|
delay ?= 5000
|
||||||
@setAutocastDelay delay
|
@setAutocastDelay delay
|
||||||
|
@ -35,15 +39,7 @@ module.exports = class CastButtonView extends View
|
||||||
attachTo: (spellView) ->
|
attachTo: (spellView) ->
|
||||||
@$el.detach().prependTo(spellView.toolbarView.$el).show()
|
@$el.detach().prependTo(spellView.toolbarView.$el).show()
|
||||||
|
|
||||||
hookUpButtons: ->
|
onCastOptionsClick: (e) ->
|
||||||
# hook up cast button callbacks
|
|
||||||
@castButton = $('.cast-button', @$el)
|
|
||||||
@castButtonGroup = $('.cast-button-group', @$el)
|
|
||||||
@castOptions = $('.autocast-delays', @$el)
|
|
||||||
|
|
||||||
@castButton.click (e) =>
|
|
||||||
Backbone.Mediator.publish 'tome:manual-cast', {}
|
|
||||||
@castOptions.find('a').click (e) =>
|
|
||||||
Backbone.Mediator.publish 'focus-editor'
|
Backbone.Mediator.publish 'focus-editor'
|
||||||
@castButtonGroup.removeClass 'open'
|
@castButtonGroup.removeClass 'open'
|
||||||
@setAutocastDelay $(e.target).attr 'data-delay'
|
@setAutocastDelay $(e.target).attr 'data-delay'
|
||||||
|
|
|
@ -60,7 +60,7 @@ module.exports = class DebugView extends View
|
||||||
@variableChain = @markerRange = null
|
@variableChain = @markerRange = null
|
||||||
@update()
|
@update()
|
||||||
|
|
||||||
onMouseOut: (e) =>
|
onMouseOut: (e) ->
|
||||||
@variableChain = @markerRange = null
|
@variableChain = @markerRange = null
|
||||||
@update()
|
@update()
|
||||||
|
|
||||||
|
@ -138,3 +138,4 @@ module.exports = class DebugView extends View
|
||||||
destroy: ->
|
destroy: ->
|
||||||
super()
|
super()
|
||||||
@ace?.removeEventListener "mousemove", @onMouseMove
|
@ace?.removeEventListener "mousemove", @onMouseMove
|
||||||
|
@onMouseMove = null
|
||||||
|
|
|
@ -60,3 +60,4 @@ module.exports = class SpellPaletteView extends View
|
||||||
destroy: ->
|
destroy: ->
|
||||||
super()
|
super()
|
||||||
entry.destroy() for entry in @entries
|
entry.destroy() for entry in @entries
|
||||||
|
@toggleBackground = null
|
||||||
|
|
|
@ -74,47 +74,51 @@ module.exports = class SpellView extends View
|
||||||
$(@ace.container).find('.ace_gutter').on 'click', '.ace_error, .ace_warning, .ace_info', @onAnnotationClick
|
$(@ace.container).find('.ace_gutter').on 'click', '.ace_error, .ace_warning, .ace_info', @onAnnotationClick
|
||||||
|
|
||||||
createACEShortcuts: ->
|
createACEShortcuts: ->
|
||||||
@ace.commands.addCommand
|
@aceCommands = []
|
||||||
|
addCommand = (c) =>
|
||||||
|
@ace.commands.addCommand c
|
||||||
|
@aceCommands.push c.name
|
||||||
|
addCommand
|
||||||
name: 'run-code'
|
name: 'run-code'
|
||||||
bindKey: {win: 'Shift-Enter|Ctrl-Enter|Ctrl-S', mac: 'Shift-Enter|Command-Enter|Ctrl-Enter|Command-S|Ctrl-S'}
|
bindKey: {win: 'Shift-Enter|Ctrl-Enter|Ctrl-S', mac: 'Shift-Enter|Command-Enter|Ctrl-Enter|Command-S|Ctrl-S'}
|
||||||
exec: (e) => @recompile()
|
exec: (e) => @recompile()
|
||||||
@ace.commands.addCommand
|
addCommand
|
||||||
name: 'toggle-playing'
|
name: 'toggle-playing'
|
||||||
bindKey: {win: 'Ctrl-P', mac: 'Command-P|Ctrl-P'}
|
bindKey: {win: 'Ctrl-P', mac: 'Command-P|Ctrl-P'}
|
||||||
exec: -> Backbone.Mediator.publish 'level-toggle-playing'
|
exec: -> Backbone.Mediator.publish 'level-toggle-playing'
|
||||||
@ace.commands.addCommand
|
addCommand
|
||||||
name: 'end-current-script'
|
name: 'end-current-script'
|
||||||
bindKey: {win: 'Shift-Space', mac: 'Shift-Space'}
|
bindKey: {win: 'Shift-Space', mac: 'Shift-Space'}
|
||||||
exec: -> Backbone.Mediator.publish 'level:shift-space-pressed'
|
exec: -> Backbone.Mediator.publish 'level:shift-space-pressed'
|
||||||
@ace.commands.addCommand
|
addCommand
|
||||||
name: 'end-all-scripts'
|
name: 'end-all-scripts'
|
||||||
bindKey: {win: 'Escape', mac: 'Escape'}
|
bindKey: {win: 'Escape', mac: 'Escape'}
|
||||||
exec: -> Backbone.Mediator.publish 'level:escape-pressed'
|
exec: -> Backbone.Mediator.publish 'level:escape-pressed'
|
||||||
@ace.commands.addCommand
|
addCommand
|
||||||
name: 'toggle-grid'
|
name: 'toggle-grid'
|
||||||
bindKey: {win: 'Ctrl-G', mac: 'Command-G|Ctrl-G'}
|
bindKey: {win: 'Ctrl-G', mac: 'Command-G|Ctrl-G'}
|
||||||
exec: -> Backbone.Mediator.publish 'level-toggle-grid'
|
exec: -> Backbone.Mediator.publish 'level-toggle-grid'
|
||||||
@ace.commands.addCommand
|
addCommand
|
||||||
name: 'toggle-debug'
|
name: 'toggle-debug'
|
||||||
bindKey: {win: 'Ctrl-\\', mac: 'Command-\\|Ctrl-\\'}
|
bindKey: {win: 'Ctrl-\\', mac: 'Command-\\|Ctrl-\\'}
|
||||||
exec: -> Backbone.Mediator.publish 'level-toggle-debug'
|
exec: -> Backbone.Mediator.publish 'level-toggle-debug'
|
||||||
@ace.commands.addCommand
|
addCommand
|
||||||
name: 'toggle-pathfinding'
|
name: 'toggle-pathfinding'
|
||||||
bindKey: {win: 'Ctrl-O', mac: 'Command-O|Ctrl-O'}
|
bindKey: {win: 'Ctrl-O', mac: 'Command-O|Ctrl-O'}
|
||||||
exec: -> Backbone.Mediator.publish 'level-toggle-pathfinding'
|
exec: -> Backbone.Mediator.publish 'level-toggle-pathfinding'
|
||||||
@ace.commands.addCommand
|
addCommand
|
||||||
name: 'level-scrub-forward'
|
name: 'level-scrub-forward'
|
||||||
bindKey: {win: 'Ctrl-]', mac: 'Command-]|Ctrl-]'}
|
bindKey: {win: 'Ctrl-]', mac: 'Command-]|Ctrl-]'}
|
||||||
exec: -> Backbone.Mediator.publish 'level-scrub-forward'
|
exec: -> Backbone.Mediator.publish 'level-scrub-forward'
|
||||||
@ace.commands.addCommand
|
addCommand
|
||||||
name: 'level-scrub-back'
|
name: 'level-scrub-back'
|
||||||
bindKey: {win: 'Ctrl-[', mac: 'Command-[|Ctrl-]'}
|
bindKey: {win: 'Ctrl-[', mac: 'Command-[|Ctrl-]'}
|
||||||
exec: -> Backbone.Mediator.publish 'level-scrub-back'
|
exec: -> Backbone.Mediator.publish 'level-scrub-back'
|
||||||
@ace.commands.addCommand
|
addCommand
|
||||||
name: 'spell-step-forward'
|
name: 'spell-step-forward'
|
||||||
bindKey: {win: 'Ctrl-Alt-]', mac: 'Command-Alt-]|Ctrl-Alt-]'}
|
bindKey: {win: 'Ctrl-Alt-]', mac: 'Command-Alt-]|Ctrl-Alt-]'}
|
||||||
exec: -> Backbone.Mediator.publish 'spell-step-forward'
|
exec: -> Backbone.Mediator.publish 'spell-step-forward'
|
||||||
@ace.commands.addCommand
|
addCommand
|
||||||
name: 'spell-step-backward'
|
name: 'spell-step-backward'
|
||||||
bindKey: {win: 'Ctrl-Alt-[', mac: 'Command-Alt-[|Ctrl-Alt-]'}
|
bindKey: {win: 'Ctrl-Alt-[', mac: 'Command-Alt-[|Ctrl-Alt-]'}
|
||||||
exec: -> Backbone.Mediator.publish 'spell-step-backward'
|
exec: -> Backbone.Mediator.publish 'spell-step-backward'
|
||||||
|
@ -212,6 +216,9 @@ module.exports = class SpellView extends View
|
||||||
@updateACEText @spell.originalSource
|
@updateACEText @spell.originalSource
|
||||||
@recompile cast
|
@recompile cast
|
||||||
|
|
||||||
|
recompileIfNeeded: =>
|
||||||
|
@recompile() if @recompileNeeded
|
||||||
|
|
||||||
recompile: (cast=true) =>
|
recompile: (cast=true) =>
|
||||||
@setRecompileNeeded false
|
@setRecompileNeeded false
|
||||||
return if @spell.source is @getSource()
|
return if @spell.source is @getSource()
|
||||||
|
@ -238,7 +245,7 @@ module.exports = class SpellView extends View
|
||||||
autocastDelay = @autocastDelay ? 3000
|
autocastDelay = @autocastDelay ? 3000
|
||||||
onSignificantChange = [
|
onSignificantChange = [
|
||||||
_.debounce @setRecompileNeeded, autocastDelay - 100
|
_.debounce @setRecompileNeeded, autocastDelay - 100
|
||||||
@currentAutocastHandler = _.debounce (=> @recompile() if @recompileNeeded), autocastDelay
|
@currentAutocastHandler = _.debounce @recompileIfNeeded, autocastDelay
|
||||||
]
|
]
|
||||||
onAnyChange = [
|
onAnyChange = [
|
||||||
_.debounce @updateAether, 500
|
_.debounce @updateAether, 500
|
||||||
|
@ -500,9 +507,17 @@ module.exports = class SpellView extends View
|
||||||
|
|
||||||
destroy: ->
|
destroy: ->
|
||||||
super()
|
super()
|
||||||
|
$(@ace?.container).find('.ace_gutter').off 'click', '.ace_error, .ace_warning, .ace_info', @onAnnotationClick
|
||||||
@firepad?.dispose()
|
@firepad?.dispose()
|
||||||
@ace.destroy()
|
@ace?.commands.removeCommand command for command in @aceCommands
|
||||||
|
@ace?.destroy()
|
||||||
@ace = null
|
@ace = null
|
||||||
|
@aceDoc?.off 'change', @onCodeChangeMetaHandler
|
||||||
|
@aceDoc = null
|
||||||
|
@aceSession?.selection.off 'changeCursor', @onCursorActivity
|
||||||
|
@aceSession = null
|
||||||
@debugView?.destroy()
|
@debugView?.destroy()
|
||||||
@spell = null
|
@spell = null
|
||||||
@session.off 'change:multiplayer', @onMultiplayerChanged, @
|
@session.off 'change:multiplayer', @onMultiplayerChanged, @
|
||||||
|
for fat in ['notifySpellChanged', 'notifyEditingEnded', 'notifyEditingBegan', 'onFirepadLoaded', 'onLoaded', 'recompile', 'toggleBackground', 'setRecompileNeeded', 'onCursorActivity', 'highlightCurrentLine', 'updateAether', 'onCodeChangeMetaHandler', 'recompileIfNeeded', 'currentAutocastHandler']
|
||||||
|
@[fat] = null
|
||||||
|
|
|
@ -97,12 +97,12 @@ module.exports = class ThangListEntryView extends View
|
||||||
@$el.popover('setContent').popover('show')
|
@$el.popover('setContent').popover('show')
|
||||||
@$el.parent().parent().parent().i18n()
|
@$el.parent().parent().parent().i18n()
|
||||||
clearTimeout @hideSpellsTimeout if @hideSpellsTimeout
|
clearTimeout @hideSpellsTimeout if @hideSpellsTimeout
|
||||||
popover = @$el.parent().parent().parent().find('.popover')
|
@popover = @$el.parent().parent().parent().find('.popover')
|
||||||
popover.off 'mouseenter mouseleave'
|
@popover.off 'mouseenter mouseleave'
|
||||||
popover.mouseenter (e) => @onMouseEnter()
|
@popover.mouseenter (e) => @onMouseEnter()
|
||||||
popover.mouseleave (e) => @onMouseLeave()
|
@popover.mouseleave (e) => @onMouseLeave()
|
||||||
thangID = @thang.id
|
thangID = @thang.id
|
||||||
popover.find('code').click (e) ->
|
@popover.find('code').click (e) ->
|
||||||
Backbone.Mediator.publish "level-select-sprite", thangID: thangID, spellName: $(@).data 'spell-name'
|
Backbone.Mediator.publish "level-select-sprite", thangID: thangID, spellName: $(@).data 'spell-name'
|
||||||
|
|
||||||
hideSpells: =>
|
hideSpells: =>
|
||||||
|
@ -139,3 +139,5 @@ module.exports = class ThangListEntryView extends View
|
||||||
destroy: ->
|
destroy: ->
|
||||||
super()
|
super()
|
||||||
@avatar?.destroy()
|
@avatar?.destroy()
|
||||||
|
@popover?.off 'mouseenter mouseleave'
|
||||||
|
@popover?.find('code').off 'click'
|
||||||
|
|
|
@ -76,9 +76,7 @@ module.exports = class PlayLevelView extends View
|
||||||
@sessionID = @getQueryVariable 'session'
|
@sessionID = @getQueryVariable 'session'
|
||||||
|
|
||||||
$(window).on('resize', @onWindowResize)
|
$(window).on('resize', @onWindowResize)
|
||||||
@supermodel.once 'error', =>
|
@supermodel.once 'error', @onLevelLoadError
|
||||||
msg = $.i18n.t('play_level.level_load_error', defaultValue: "Level could not be loaded.")
|
|
||||||
@$el.html('<div class="alert">' + msg + '</div>')
|
|
||||||
@saveScreenshot = _.throttle @saveScreenshot, 30000
|
@saveScreenshot = _.throttle @saveScreenshot, 30000
|
||||||
|
|
||||||
if @isEditorPreview
|
if @isEditorPreview
|
||||||
|
@ -94,6 +92,10 @@ module.exports = class PlayLevelView extends View
|
||||||
if localStorage?
|
if localStorage?
|
||||||
localStorage["lastLevel"] = @levelID
|
localStorage["lastLevel"] = @levelID
|
||||||
|
|
||||||
|
onLevelLoadError: (e) =>
|
||||||
|
msg = $.i18n.t('play_level.level_load_error', defaultValue: "Level could not be loaded.")
|
||||||
|
@$el.html('<div class="alert">' + msg + '</div>')
|
||||||
|
|
||||||
setLevel: (@level, @supermodel) ->
|
setLevel: (@level, @supermodel) ->
|
||||||
@god?.level = @level.serialize @supermodel
|
@god?.level = @level.serialize @supermodel
|
||||||
if @world
|
if @world
|
||||||
|
@ -181,21 +183,21 @@ module.exports = class PlayLevelView extends View
|
||||||
onWindowResize: (s...) ->
|
onWindowResize: (s...) ->
|
||||||
$('#pointer').css('opacity', 0.0)
|
$('#pointer').css('opacity', 0.0)
|
||||||
|
|
||||||
onDisableControls: (e) =>
|
onDisableControls: (e) ->
|
||||||
return if e.controls and not ('level' in e.controls)
|
return if e.controls and not ('level' in e.controls)
|
||||||
@shortcutsEnabled = false
|
@shortcutsEnabled = false
|
||||||
@wasFocusedOn = document.activeElement
|
@wasFocusedOn = document.activeElement
|
||||||
$('body').focus()
|
$('body').focus()
|
||||||
|
|
||||||
onEnableControls: (e) =>
|
onEnableControls: (e) ->
|
||||||
return if e.controls? and not ('level' in e.controls)
|
return if e.controls? and not ('level' in e.controls)
|
||||||
@shortcutsEnabled = true
|
@shortcutsEnabled = true
|
||||||
$(@wasFocusedOn).focus() if @wasFocusedOn
|
$(@wasFocusedOn).focus() if @wasFocusedOn
|
||||||
@wasFocusedOn = null
|
@wasFocusedOn = null
|
||||||
|
|
||||||
onDonePressed: => @showVictory()
|
onDonePressed: -> @showVictory()
|
||||||
|
|
||||||
onShowVictory: (e) =>
|
onShowVictory: (e) ->
|
||||||
console.log 'show vict', e
|
console.log 'show vict', e
|
||||||
$('#level-done-button').show()
|
$('#level-done-button').show()
|
||||||
@showVictory() if e.showModal
|
@showVictory() if e.showModal
|
||||||
|
@ -221,7 +223,7 @@ module.exports = class PlayLevelView extends View
|
||||||
@openModalView new InfiniteLoopModal()
|
@openModalView new InfiniteLoopModal()
|
||||||
window.tracker?.trackEvent 'Saw Initial Infinite Loop', level: @world.name, label: @world.name
|
window.tracker?.trackEvent 'Saw Initial Infinite Loop', level: @world.name, label: @world.name
|
||||||
|
|
||||||
onPlayNextLevel: =>
|
onPlayNextLevel: ->
|
||||||
nextLevel = @getNextLevel()
|
nextLevel = @getNextLevel()
|
||||||
nextLevelID = nextLevel.get('slug') or nextLevel.id
|
nextLevelID = nextLevel.get('slug') or nextLevel.id
|
||||||
url = "/play/level/#{nextLevelID}"
|
url = "/play/level/#{nextLevelID}"
|
||||||
|
@ -235,7 +237,7 @@ module.exports = class PlayLevelView extends View
|
||||||
levels = @supermodel.getModels(Level)
|
levels = @supermodel.getModels(Level)
|
||||||
return l for l in levels when l.get('original') is nextLevelOriginal
|
return l for l in levels when l.get('original') is nextLevelOriginal
|
||||||
|
|
||||||
onHighlightDom: (e) =>
|
onHighlightDom: (e) ->
|
||||||
if e.delay
|
if e.delay
|
||||||
delay = e.delay
|
delay = e.delay
|
||||||
delete e.delay
|
delete e.delay
|
||||||
|
@ -289,16 +291,16 @@ module.exports = class PlayLevelView extends View
|
||||||
), 1)
|
), 1)
|
||||||
|
|
||||||
|
|
||||||
animatePointer: =>
|
animatePointer: ->
|
||||||
pointer = $('#pointer')
|
pointer = $('#pointer')
|
||||||
pointer.css('transition', 'all 0.6s ease-out')
|
pointer.css('transition', 'all 0.6s ease-out')
|
||||||
pointer.css('transform', "rotate(#{@pointerRotation}rad) translate(-3px, #{@pointerRadialDistance-50}px)")
|
pointer.css('transform', "rotate(#{@pointerRotation}rad) translate(-3px, #{@pointerRadialDistance-50}px)")
|
||||||
setTimeout((=>
|
setTimeout((=>
|
||||||
pointer.css('transform', "rotate(#{@pointerRotation}rad) translate(-3px, #{@pointerRadialDistance}px)").css('transition', 'all 0.4s ease-in')), 800)
|
pointer.css('transform', "rotate(#{@pointerRotation}rad) translate(-3px, #{@pointerRadialDistance}px)").css('transition', 'all 0.4s ease-in')), 800)
|
||||||
|
|
||||||
onFocusDom: (e) => $(e.selector).focus()
|
onFocusDom: (e) -> $(e.selector).focus()
|
||||||
|
|
||||||
onEndHighlight: =>
|
onEndHighlight: ->
|
||||||
$('#pointer').css('opacity', 0.0)
|
$('#pointer').css('opacity', 0.0)
|
||||||
clearInterval(@pointerInterval)
|
clearInterval(@pointerInterval)
|
||||||
|
|
||||||
|
@ -380,6 +382,8 @@ module.exports = class PlayLevelView extends View
|
||||||
|
|
||||||
destroy: ->
|
destroy: ->
|
||||||
super()
|
super()
|
||||||
|
@supermodel.off 'error', @onLevelLoadError
|
||||||
|
@levelLoader?.off 'loaded-all', @onLevelLoaderLoaded
|
||||||
@levelLoader?.destroy()
|
@levelLoader?.destroy()
|
||||||
@surface?.destroy()
|
@surface?.destroy()
|
||||||
@god?.destroy()
|
@god?.destroy()
|
||||||
|
@ -393,3 +397,8 @@ module.exports = class PlayLevelView extends View
|
||||||
#@instance.save() unless @instance.loading
|
#@instance.save() unless @instance.loading
|
||||||
console.profileEnd?() if PROFILE_ME
|
console.profileEnd?() if PROFILE_ME
|
||||||
@session.off 'change:multiplayer', @onMultiplayerChanged, @
|
@session.off 'change:multiplayer', @onMultiplayerChanged, @
|
||||||
|
@onLevelLoadError = null
|
||||||
|
@onLevelLoaderLoaded = null
|
||||||
|
@onSupermodelLoadedOne = null
|
||||||
|
@preloadNextLevel = null
|
||||||
|
@saveScreenshot = null
|
||||||
|
|
Loading…
Reference in a new issue