Fixed I hope; at least, dramatically reduced memory leakage.

This commit is contained in:
Nick Winter 2014-01-15 13:04:48 -08:00
parent 2b30d50895
commit 172d97ed83
13 changed files with 45 additions and 26 deletions

View file

@ -18,6 +18,7 @@ module.exports = class God
@angels = []
@firstWorld = true
Backbone.Mediator.subscribe 'tome:cast-spells', @onTomeCast, @
console.log @id, "initialized with world", @world.id
onTomeCast: (e) ->
return if @dead
@ -92,6 +93,7 @@ module.exports = class God
for scriptNote in @world.scriptNotes
Backbone.Mediator.publish scriptNote.channel, scriptNote.event
@firstWorld = false
@testWorld = null
getUserCodeMap: ->
userCodeMap = {}

View file

@ -179,15 +179,11 @@ module.exports = class SpriteBoss extends CocoClass
wallSprites = (sprite for thangID, sprite of @sprites when sprite.thangType?.get('name') is 'Dungeon Wall')
walls = (sprite.thang for sprite in wallSprites)
@world.calculateBounds()
if @wallGrid and @wallGrid.width is @world.width and @wallGrid.height is @world.height
@wallGrid.update walls
else
@wallGrid = new Grid walls, @world.size()...
wallGrid = new Grid walls, @world.size()...
for wallSprite in wallSprites
wallSprite.updateActionDirection @wallGrid
wallSprite.updateActionDirection wallGrid
wallSprite.updateScale()
wallSprite.updatePosition()
# TODO: there's some bug whereby a new wall isn't drawn properly when cached the first time
#console.log @wallGrid.toString()
@spriteLayers["Obstacle"].uncache() if @spriteLayers["Obstacle"].cacheID # might have changed sizes
@spriteLayers["Obstacle"].cache()

View file

@ -28,6 +28,7 @@ module.exports = class World
@scriptNotes = []
@rand = new Rand 0
@frames = [new WorldFrame(@, 0)]
@id = Math.random()
age: 0
ended: false
@ -255,7 +256,7 @@ module.exports = class World
o = {name: @name, totalFrames: @totalFrames, maxTotalFrames: @maxTotalFrames, frameRate: @frameRate, dt: @dt, victory: @victory, userCodeMap: {}}
o[prop] = @[prop] for prop in @trackedProperties or []
for thangID, methods of @userCodeMap
serializedMethods = o.userCodeMap[thangID] = {}
for methodName, method of methods

View file

@ -280,10 +280,10 @@ module.exports = nativeDescription: "français", englishDescription: "French", t
and: "et"
about:
who_is_codecombat: "Qui est CodeCombat?"
why_codecombat: "Pourquoi CodeCombat?"
who_description_prefix: "avons commencé ensembles en 2013. Nous avons aussi créé "
who_description_suffix: "en 2008, qui a grandi jusqu'à devenir la première application web et iOS pour apprendre à écrire les caractères chinois et japonais."
who_is_codecombat: "Qui est CodeCombat?"
why_codecombat: "Pourquoi CodeCombat?"
who_description_prefix: "avons commencé ensembles en 2013. Nous avons aussi créé "
who_description_suffix: "en 2008, qui a grandi jusqu'à devenir la première application web et iOS pour apprendre à écrire les caractères chinois et japonais."
# who_description_ending: "Now it's time to teach people to write code."
# why_paragraph_1: "When making Skritter, George didn't know how to program and was constantly frustrated by his inability to implement his ideas. Afterwards, he tried learning, but the lessons were too slow. His housemate, wanting to reskill and stop teaching, tried Codecademy, but \"got bored.\" Each week another friend started Codecademy, then dropped off. We realized it was the same problem we'd solved with Skritter: people learning a skill via slow, intensive lessons when what they need is fast, extensive practice. We know how to fix that."
# why_paragraph_2: "Need to learn to code? You don't need lessons. You need to write a lot of code and have a great time doing it."
@ -293,7 +293,7 @@ module.exports = nativeDescription: "français", englishDescription: "French", t
# why_paragraph_3_italic_caps: "NO MOM I HAVE TO FINISH THE LEVEL!"
# why_paragraph_3_suffix: "That's why CodeCombat is a multiplayer game, not a gamified lesson course. We won't stop until you can't stop--but this time, that's a good thing."
# why_paragraph_4: "If you're going to get addicted to some game, get addicted to this one and become one of the wizards of the tech age."
why_ending: "Et au fait, c'est gratuit. "
why_ending: "Et au fait, c'est gratuit. "
# why_ending_url: "Start wizarding now!"
# george_description: "CEO, business guy, web designer, game designer, and champion of beginning programmers everywhere."
# scott_description: "Programmer extraordinaire, software architect, kitchen wizard, and master of finances. Scott is the reasonable one."

View file

@ -24,7 +24,7 @@ module.exports = class ThangType extends CocoModel
getActions: ->
return @actions or @buildActions()
buildActions: ->
@actions = _.cloneDeep(@get('actions'))
for name, action of @actions
@ -33,12 +33,12 @@ module.exports = class ThangType extends CocoModel
relatedAction.name = action.name + "_" + relatedName
@actions[relatedAction.name] = relatedAction
@actions
getSpriteSheet: (options) ->
options = @fillOptions options
key = @spriteSheetKey(options)
return @spriteSheets[key] or @buildSpriteSheet(options)
fillOptions: (options) ->
options ?= {}
options = _.clone options
@ -60,7 +60,7 @@ module.exports = class ThangType extends CocoModel
@builder = new createjs.SpriteSheetBuilder()
@builder.padding = 2
@frames = {}
addPortrait: ->
# The portrait is built very differently than the other animations, so it gets a separate function.
return unless @actions
@ -98,7 +98,7 @@ module.exports = class ThangType extends CocoModel
next = action.goesTo if action.goesTo
next = false if action.loops is false
@builder.addAnimation name, frames, next
for name, action of @actions when action.container and not action.animation
continue if name is 'portrait'
scale = @options.resolutionFactor * (action.scale or @get('scale') or 1)
@ -131,15 +131,17 @@ module.exports = class ThangType extends CocoModel
@builder.buildAsync()
@builder.on 'complete', @onBuildSpriteSheetComplete, @, true, key
return true
console.warn 'Building', @get('name'), 'and blocking the main thread. LevelLoader should have it built asynchronously instead.'
spriteSheet = @builder.build()
@spriteSheets[key] = spriteSheet
spriteSheet
onBuildSpriteSheetComplete: (e, key) ->
@spriteSheets[key] = e.target.spriteSheet
@trigger 'build-complete'
@builder = null
@vectorParser = null
spriteSheetKey: (options) ->
colorConfigs = []
@ -183,7 +185,7 @@ module.exports = class ThangType extends CocoModel
createjs.Ticker.removeEventListener 'tick', @tick
@tick = null
stage
uploadGenericPortrait: (callback) ->
src = @getPortraitSource()
return callback?() unless src
@ -198,4 +200,3 @@ module.exports = class ThangType extends CocoModel
onFileUploaded: =>
console.log 'Image uploaded'

View file

@ -21,6 +21,7 @@ module.exports = class HUDView extends View
'dialogue-sound-completed': 'onDialogueSoundCompleted'
'thang-began-talking': 'onThangBeganTalking'
'thang-finished-talking': 'onThangFinishedTalking'
'god:new-world-created': 'onNewWorld'
events:
'click': -> Backbone.Mediator.publish 'focus-editor'
@ -61,6 +62,9 @@ module.exports = class HUDView extends View
onSpriteClearDialogue: ->
@clearSpeaker()
onNewWorld: (e) ->
@thang = e.world.thangMap[@thang.id] if @thang
setThang: (thang, thangType) ->
unless @speaker
if not thang? and not @thang? then return

View file

@ -8,6 +8,7 @@ module.exports = class ThangAvatarView extends View
subscriptions:
'tome:problems-updated': "onProblemsUpdated"
'god:new-world-created': 'onNewWorld'
constructor: (options) ->
super options
@ -50,3 +51,6 @@ module.exports = class ThangAvatarView extends View
worstLevel = level
break
@setProblems myProblems.length, worstLevel
onNewWorld: (e) ->
@options.thang = @thang = e.world.thangMap[@thang.id] if @thang

View file

@ -17,7 +17,6 @@ module.exports = class Spell
@thangs = {}
@view = new SpellView {spell: @, session: @session}
@view.render() # Get it ready and code loaded in advance
console.log 'spell creates tab entry view', @supermodel
@tabView = new SpellListTabEntryView spell: @, supermodel: @supermodel
@tabView.render()

View file

@ -15,6 +15,7 @@ module.exports = class SpellListEntryView extends View
'tome:problems-updated': "onProblemsUpdated"
'level-disable-controls': 'onDisableControls'
'level-enable-controls': 'onEnableControls'
'god:new-world-created': 'onNewWorld'
events:
'click': 'onClick'
@ -96,3 +97,6 @@ module.exports = class SpellListEntryView extends View
# Should refactor the disabling list so we can target the spell list separately?
# Should not call it 'editor' any more?
@$el.toggleClass('disabled', disabled).find('*').prop('disabled', disabled)
onNewWorld: (e) ->
@lastSelectedThang = e.world.thangMap[@lastSelectedThang.id] if @lastSelectedThang

View file

@ -10,6 +10,7 @@ module.exports = class SpellListTabEntryView extends SpellListEntryView
subscriptions:
'tome:spell-loaded': "onSpellLoaded"
'tome:spell-changed': "onSpellChanged"
'god:new-world-created': 'onNewWorld'
events:
'click .spell-list-button': 'onDropdownClick'
@ -26,6 +27,9 @@ module.exports = class SpellListTabEntryView extends SpellListEntryView
super()
@$el.addClass 'spell-tab'
onNewWorld: (e) ->
@thang = e.world.thangMap[@thang.id] if @thang
setThang: (thang) ->
return if thang.id is @thang?.id
@thang = thang

View file

@ -14,7 +14,8 @@ module.exports = class SpellListView extends View
id: 'spell-list-view'
template: template
subscriptions: {}
subscriptions:
'god:new-world-created': 'onNewWorld'
constructor: (options) ->
super options
@ -64,6 +65,9 @@ module.exports = class SpellListView extends View
@$el.append entry.el
entry.render() # Render after appending so that we can access parent container for popover
onNewWorld: (e) ->
@thang = e.world.thangMap[@thang.id] if @thang
setThangAndSpell: (@thang, @spell) ->
@entries[0]?.setSelected false
@sortSpells()

View file

@ -51,6 +51,6 @@ module.exports = class SpellPaletteEntryView extends View
onFrameChanged: (e) ->
return unless e.selectedThang?.id is @thang.id
@thang = e.selectedThang # Update our thang to the current version
@doc = Docs.getDocsFor(@thang, [@doc.prop])[0]
@options.thang = @thang = e.selectedThang # Update our thang to the current version
@options.doc = @doc = Docs.getDocsFor(@thang, [@doc.prop])[0]
@$el.find("code.current-value").text(@doc.formatValue()) # Don't call any functions. (?? What does this mean?)

View file

@ -55,7 +55,7 @@ module.exports = class SpellPaletteView extends View
onFrameChanged: (e) ->
return unless e.selectedThang?.id is @thang.id
@thang = e.selectedThang # Update our thang to the current version
@options.thang = @thang = e.selectedThang # Update our thang to the current version
destroy: ->
super()