Refactor PlayGameDevLevelView to use promises

This commit is contained in:
Scott Erickson 2016-07-13 13:28:54 -07:00
parent 1b7ac76b9f
commit d7a2219b16
4 changed files with 62 additions and 38 deletions

View file

@ -52,6 +52,15 @@ module.exports = class LevelLoader extends CocoClass
@listenToOnce @supermodel, 'loaded-all', @onSupermodelLoaded
# Supermodel (Level) Loading
loadWorldNecessities: ->
# TODO: Actually trigger loading, instead of in the constructor
new Promise((resolve, reject) =>
@once 'world-necessities-loaded', => resolve(@)
@once 'world-necessity-load-failed', ({resource}) ->
{ jqxhr } = resource
reject({message: jqxhr.responseJSON?.message or jqxhr.responseText or 'Unknown Error'})
)
loadLevel: ->
@level = @supermodel.getModel(Level, @levelID) or new Level _id: @levelID
@ -332,8 +341,8 @@ module.exports = class LevelLoader extends CocoClass
@worldNecessities = (r for r in @worldNecessities when r?)
@onWorldNecessitiesLoaded() if @checkAllWorldNecessitiesRegisteredAndLoaded()
onWorldNecessityLoadFailed: (resource) ->
@trigger('world-necessity-load-failed', resource: resource)
onWorldNecessityLoadFailed: (event) ->
@trigger('world-necessity-load-failed', event)
checkAllWorldNecessitiesRegisteredAndLoaded: ->
return false unless _.filter(@worldNecessities).length is 0
@ -373,6 +382,7 @@ module.exports = class LevelLoader extends CocoClass
onSupermodelLoaded: ->
return if @destroyed
console.log 'SuperModel for Level loaded in', new Date().getTime() - @t0, 'ms' if LOG
console.log 'supermodel loaded'
@loadLevelSounds()
@denormalizeSession()

View file

@ -247,6 +247,15 @@ module.exports = class SuperModel extends Backbone.Model
getResource: (rid) ->
return @resources[rid]
# Promises
finishLoading: ->
new Promise (resolve, reject) =>
return resolve(@) if @finished()
@once 'failed', ({resource}) ->
jqxhr = resource.jqxhr
reject({message: jqxhr.responseJSON?.message or jqxhr.responseText or 'Unknown Error'})
@once 'loaded-all', => resolve(@)
class Resource extends Backbone.Model
constructor: (name, value=1) ->

View file

@ -6,8 +6,13 @@
canvas(width=924, height=589)#normal-surface
.col-xs-3#info-col.style-flat
if view.state.get('loading')
if view.state.get('errorMessage')
.alert.alert-danger= view.state.get('errorMessage')
else if view.state.get('loading')
h1.m-y-1 Loading...
.progress
.progress-bar(style="width: #{view.state.get('progress')}")
else
h1.m-y-1 Info

View file

@ -23,51 +23,51 @@ module.exports = class PlayGameDevLevelView extends RootView
initialize: (@options, @levelID, @sessionID) ->
@state = new State({
loading: true
progress: 0
})
@supermodel.on 'update-progress', (progress) =>
@state.set({progress: (progress*100).toFixed(1)+'%'})
@level = new Level()
@session = new LevelSession()
@gameUIState = new GameUIState()
@god = new God({ @gameUIState })
@levelLoader = new LevelLoader({ @supermodel, @levelID, @sessionID, observing: true, team: TEAM })
@listenToOnce @levelLoader, 'world-necessities-loaded', @onWorldNecessitiesLoaded
@listenTo @levelLoader, 'world-necessity-load-failed', @onWorldNecessityLoadFailed
@listenTo @state, 'change', _.debounce(-> @renderSelectors('#info-col'))
onWorldNecessitiesLoaded: ->
{ @level, @session, @world, @classMap } = @levelLoader
levelObject = @level.serialize(@supermodel, @session)
@god.setLevel(levelObject)
@god.setWorldClassMap(@world.classMap)
@goalManager = new GoalManager(@world, @level.get('goals'), @team)
@god.setGoalManager(@goalManager)
me.team = TEAM
@session.set 'team', TEAM
@levelLoader.loadWorldNecessities()
onWorldNecessityLoadFailed: ->
# TODO: handle these and other failures with Promises
.then (levelLoader) => # grabbing from the levelLoader
{ @level, @session, @world } = levelLoader
@god.setLevel(@level.serialize(@supermodel, @session))
@god.setWorldClassMap(@world.classMap)
@goalManager = new GoalManager(@world, @level.get('goals'), @team)
@god.setGoalManager(@goalManager)
me.team = TEAM
@session.set 'team', TEAM
return @supermodel.finishLoading()
.then (supermodel) =>
@levelLoader.destroy()
@levelLoader = null
webGLSurface = @$('canvas#webgl-surface')
normalSurface = @$('canvas#normal-surface')
@surface = new Surface(@world, normalSurface, webGLSurface, {
thangTypes: @supermodel.getModels(ThangType)
levelType: @level.get('type', true)
@gameUIState
})
worldBounds = @world.getBounds()
bounds = [{x: worldBounds.left, y: worldBounds.top}, {x: worldBounds.right, y: worldBounds.bottom}]
@surface.camera.setBounds(bounds)
@surface.camera.zoomTo({x: 0, y: 0}, 0.1, 0)
@surface.setWorld(@world)
@renderSelectors '#info-col'
@spells = @session.generateSpellsObject()
@state.set('loading', false)
onLoaded: ->
_.defer => @onLevelLoaderLoaded()
onLevelLoaderLoaded: ->
return unless @levelLoader.progress() is 1 # double check, since closing the guide may trigger this early
@levelLoader.destroy()
@levelLoader = null
webGLSurface = @$('canvas#webgl-surface')
normalSurface = @$('canvas#normal-surface')
@surface = new Surface(@world, normalSurface, webGLSurface, {
thangTypes: @supermodel.getModels(ThangType)
levelType: @level.get('type', true)
@gameUIState
})
worldBounds = @world.getBounds()
bounds = [{x: worldBounds.left, y: worldBounds.top}, {x: worldBounds.right, y: worldBounds.bottom}]
@surface.camera.setBounds(bounds)
@surface.camera.zoomTo({x: 0, y: 0}, 0.1, 0)
@surface.setWorld(@world)
@renderSelectors '#info-col'
@spells = @session.generateSpellsObject()
@state.set('loading', false)
.catch ({message}) =>
@state.set('errorMessage', message)
onClickPlayButton: ->
@god.createWorld(@spells, false, true)