Asynchronously building things again.

This commit is contained in:
Scott Erickson 2014-05-20 10:46:52 -07:00
parent a04130f26a
commit 93c6f72f07
7 changed files with 59 additions and 30 deletions

View file

@ -165,16 +165,25 @@ module.exports = class LevelLoader extends CocoClass
app.tracker.updatePlayState(@level, @session) unless @headless
buildLoop: =>
return if @lastBuilt and new Date().getTime() - @lastBuilt < 10
return clearInterval @buildLoopInterval unless @spriteSheetsToBuild.length
someLeft = false
for spriteSheetResource, i in @spriteSheetsToBuild
if spriteSheetResource.thangType.loaded
@buildSpriteSheetsForThangType spriteSheetResource.thangType
@spriteSheetsToBuild.splice i, 1
@lastBuilt = new Date().getTime()
spriteSheetResource.markLoaded()
return
continue if spriteSheetResource.spriteSheetKeys
someLeft = true
thangType = spriteSheetResource.thangType
if thangType.loaded and not thangType.loading
@listenTo spriteSheetResource.thangType, 'build-complete', @onBuildComplete
keys = @buildSpriteSheetsForThangType spriteSheetResource.thangType
spriteSheetResource.spriteSheetKeys = keys
spriteSheetResource.markLoaded() if keys.length is 0
clearInterval @buildLoopInterval unless someLeft
onBuildComplete: (e) ->
resource = null
for resource in @spriteSheetsToBuild
break if e.thangType is resource.thangType
resource.spriteSheetKeys = (k for k in resource.spriteSheetKeys when k isnt e.key)
resource.markLoaded() if resource.spriteSheetKeys.length is 0
denormalizeSession: ->
return if @headless or @sessionDenormalized or @spectateMode
@ -201,13 +210,16 @@ module.exports = class LevelLoader extends CocoClass
# queue = new createjs.LoadQueue()
# queue.loadFile('/file/'+f)
@grabThangTypeTeams() unless @thangTypeTeams
keys = []
for team in @thangTypeTeams[thangType.get('original')] ? [null]
spriteOptions = {resolutionFactor: SPRITE_RESOLUTION_FACTOR, async: false}
spriteOptions = {resolutionFactor: SPRITE_RESOLUTION_FACTOR, async: true}
if thangType.get('kind') is 'Floor'
spriteOptions.resolutionFactor = 2
if team and color = @teamConfigs[team]?.color
spriteOptions.colorConfig = team: color
@buildSpriteSheet thangType, spriteOptions
key = @buildSpriteSheet thangType, spriteOptions
if _.isString(key) then keys.push key
keys
grabThangTypeTeams: ->
@grabTeamConfigs()

View file

@ -33,6 +33,7 @@ module.exports = CocoSprite = class CocoSprite extends CocoClass
camera: null
spriteSheetCache: null
showInvisible: false
async: true
possessed: false
flipped: false
@ -75,28 +76,32 @@ module.exports = CocoSprite = class CocoSprite extends CocoClass
@ranges = []
@handledDisplayEvents = {}
@age = 0
@stillLoading = true
if @thangType.isFullyLoaded()
@setupSprite()
else
@stillLoading = true
@thangType.fetch()
@listenToOnce(@thangType, 'sync', @setupSprite)
setupSprite: ->
for trigger, sounds of @thangType.get('soundTriggers') or {} when trigger isnt 'say'
AudioPlayer.preloadSoundReference sound for sound in sounds
@stillLoading = false
if @thangType.get('raster')
@stillLoading = false
@actions = {}
@isRaster = true
@setUpRasterImage()
else
@actions = @thangType.getActions()
@buildFromSpriteSheet @buildSpriteSheet()
@createMarks()
result = @buildSpriteSheet()
if _.isString result # async build
@listenToOnce @thangType, 'build-complete', @setupSprite
else
@stillLoading = false
@actions = @thangType.getActions()
@buildFromSpriteSheet result
@createMarks()
finishSetup: ->
return unless @thang
@updateBaseScale()
@scaleFactor = @thang.scaleFactor if @thang?.scaleFactor
@update true # Reflect initial scale and other state
@ -120,7 +125,7 @@ module.exports = CocoSprite = class CocoSprite extends CocoClass
buildSpriteSheet: ->
options = _.extend @options, @thang?.getSpriteOptions?() ? {}
options.colorConfig = @options.colorConfig if @options.colorConfig
options.async = false
options.async = @options.async
@thangType.getSpriteSheet options
setImageObject: (newImageObject) ->
@ -677,6 +682,7 @@ module.exports = CocoSprite = class CocoSprite extends CocoClass
updateGold: ->
# TODO: eventually this should be moved into some sort of team-based update
# rather than an each-thang-that-shows-gold-per-team thing.
return unless @thang
return if @thang.gold is @lastGold
gold = Math.floor @thang.gold
if @thang.world.age is 0

View file

@ -181,7 +181,8 @@ module.exports = class Mark extends CocoClass
return @listenToOnce(@thangType, 'sync', @onLoadedThangType) if not @thangType.loaded
CocoSprite = require './CocoSprite'
markSprite = new CocoSprite @thangType, @thangType.spriteOptions
# don't bother with making these render async for now, but maybe later for fun and more complexity of code
markSprite = new CocoSprite @thangType, {async: false}
markSprite.queueAction 'idle'
@mark = markSprite.imageObject
@markSprite = markSprite

View file

@ -39,8 +39,6 @@ module.exports = class WizardSprite extends IndieSprite
else if options.name
@setNameLabel options.name
finishSetup: -> # No initial setup update needed.
makeIndieThang: (thangType, thangID, pos) ->
thang = super thangType, thangID, pos
thang.isSelectable = false

View file

@ -62,7 +62,7 @@ module.exports = class ThangType extends CocoModel
@options = @fillOptions options
key = @spriteSheetKey(@options)
if ss = @spriteSheets[key] then return ss
return if @building[key]
return key if @building[key]
@t0 = new Date().getTime()
@initBuild(options)
@addGeneralFrames() unless @options.portraitOnly
@ -151,25 +151,34 @@ module.exports = class ThangType extends CocoModel
buildQueue.push @builder
@builder.t0 = new Date().getTime()
@builder.buildAsync() unless buildQueue.length > 1
@builder.on 'complete', @onBuildSpriteSheetComplete, @, true, key
return true
@builder.on 'complete', @onBuildSpriteSheetComplete, @, true, [@builder, key, @options]
@builder = null
return key
spriteSheet = @builder.build()
console.debug "Built #{@get('name')}#{if @options.portraitOnly then ' portrait' else ''} in #{new Date().getTime() - @t0}ms."
@logBuild @t0, false, @options.portraitOnly
@spriteSheets[key] = spriteSheet
delete @building[key]
@builder = null
spriteSheet
onBuildSpriteSheetComplete: (e, key) ->
console.log "Built #{@get('name')}#{if @options.portraitOnly then ' portrait' else ''} async in #{new Date().getTime() - @builder.t0}ms." if @builder
onBuildSpriteSheetComplete: (e, data) ->
[builder, key, options] = data
@logBuild builder.t0, true, options.portraitOnly
buildQueue = buildQueue.slice(1)
buildQueue[0].t0 = new Date().getTime() if buildQueue[0]
buildQueue[0]?.buildAsync()
@spriteSheets[key] = e.target.spriteSheet
delete @building[key]
@trigger 'build-complete'
@builder = null
@trigger 'build-complete', {key:key, thangType:@}
@vectorParser = null
logBuild: (startTime, async, portrait) ->
kind = if async then 'Async' else 'Sync '
portrait = if portrait then '(Portrait)' else ''
name = _.string.rpad @get('name'), 20
time = _.string.lpad '' + new Date().getTime() - startTime, 6
console.debug "Built sheet: #{name} #{time}ms #{kind} #{portrait}"
spriteSheetKey: (options) ->
colorConfigs = []
for groupName, config of options.colorConfig or {}
@ -196,6 +205,7 @@ module.exports = class ThangType extends CocoModel
options = if _.isPlainObject spriteOptionsOrKey then spriteOptionsOrKey else {}
options.portraitOnly = true
spriteSheet = @buildSpriteSheet(options)
return if _.isString spriteSheet
return unless spriteSheet
canvas = $("<canvas width='#{size}' height='#{size}'></canvas>")
stage = new createjs.Stage(canvas[0])

View file

@ -25,6 +25,7 @@ module.exports = class ThangAvatarView extends View
# couldn't get the level view to load properly through the supermodel
# so just doing it manually this time.
@listenTo @thangType, 'sync', @render
@listenTo @thangType, 'build-complete', @render
getSpriteThangType: ->
thangs = @supermodel.getModels(ThangType)
@ -36,7 +37,7 @@ module.exports = class ThangAvatarView extends View
context = super context
context.thang = @thang
options = @thang?.getSpriteOptions() or {}
options.async = false
options.async = true
context.avatarURL = @thangType.getPortraitSource(options) unless @thangType.loading
context.includeName = @includeName
context

View file

@ -290,6 +290,7 @@ module.exports = class PlayLevelView extends View
unless @isEditorPreview
@loadEndTime = new Date()
loadDuration = @loadEndTime - @loadStartTime
console.debug "Level unveiled after #{(loadDuration / 1000).toFixed(2)}s"
application.tracker?.trackEvent 'Finished Level Load', level: @levelID, label: @levelID, loadDuration: loadDuration
application.tracker?.trackTiming loadDuration, 'Level Load Time', @levelID, @levelID