mirror of
https://github.com/codeninjasllc/codecombat.git
synced 2025-03-22 10:55:19 -04:00
able to load level editor.
This commit is contained in:
parent
354e3570e2
commit
3ea4d1677c
3 changed files with 243 additions and 166 deletions
app
|
@ -1,159 +0,0 @@
|
|||
module.exports = class ResourceManager extends Backbone.Model
|
||||
num: 0
|
||||
denom: 0
|
||||
showing: false
|
||||
resources:{} # models and collections
|
||||
progress: 0
|
||||
|
||||
constructor: ()->
|
||||
|
||||
addModelResource: (modelOrCollection, name, fetchOptions, value=1)->
|
||||
@checkName(name)
|
||||
res = new ModelResource(modelOrCollection, name, fetchOptions)
|
||||
storeResource: (name, res, value)
|
||||
return res
|
||||
|
||||
addRequestResource: (name, jqxhrOptions, value=1)->
|
||||
@checkName(name)
|
||||
res = new RequestResource(name, jqxhrOptions)
|
||||
storeResource: (name, res, value)
|
||||
return res
|
||||
|
||||
addSomethingResource: (name, value=1)->
|
||||
@checkName(name)
|
||||
res = new SomethingResource(name)
|
||||
storeResource: (name, res, value)
|
||||
return res
|
||||
|
||||
checkName: (name)->
|
||||
if name in resources
|
||||
throw new Error('Resource name has been used.')
|
||||
|
||||
storeResource: (name, resource, value)->
|
||||
@resources[name] = res
|
||||
@listenToOnce(res, 'resource:loaded', @updateProgress)
|
||||
@listenToOnce(res, 'resource:failed', @onResourceFailed)
|
||||
@denom += value
|
||||
|
||||
loadResources: ()->
|
||||
for name, res of @resources
|
||||
res.load()
|
||||
|
||||
updateProgress: (r)->
|
||||
@num += r.value if r.isLoaded
|
||||
@progress = if denom then num / denom else 0
|
||||
@trigger('resourceManager:updateProgress', @progress)
|
||||
|
||||
onResourceFailed: (r)->
|
||||
|
||||
getResource: (name)->
|
||||
return @resources[name]
|
||||
|
||||
|
||||
|
||||
class Resource
|
||||
dependencies: []
|
||||
name: null
|
||||
isLoading: false
|
||||
isLoaded: false
|
||||
model: null
|
||||
|
||||
addDependency: (resource)->
|
||||
@dependecies.push(resource)
|
||||
|
||||
markLoaded: ()->
|
||||
@isLoaded = true
|
||||
@trigger('resource:loaded', @) if @isLoading
|
||||
@isLoading = false
|
||||
|
||||
markFailed: ()->
|
||||
@isloaded = false
|
||||
@trigger('resource:failed', @) if @isLoading
|
||||
@isLoading = false
|
||||
|
||||
load: ()->
|
||||
getModel: ()-> @model
|
||||
|
||||
|
||||
|
||||
class ModelResource extends Resource
|
||||
constructor: (modelOrCollection, name, fetchOptions)->
|
||||
@model = modelOrCollection
|
||||
@name = name
|
||||
@fetchOptions = fetchOptions
|
||||
@loadDeferred = null
|
||||
|
||||
load: ()->
|
||||
return @loadDeferred.promise() if @isLoading
|
||||
|
||||
@isLoading = true
|
||||
@loadDeferred = $.Deferred()
|
||||
$.when.apply($, @loadDependencies())
|
||||
.then(onLoadDependenciesSuccess, onLoadDependenciesFailed)
|
||||
.always(()=> @isLoading = false)
|
||||
|
||||
return @loadDeferred.promise()
|
||||
|
||||
loadDependencies: ()->
|
||||
promises = []
|
||||
for dep in @dependecies
|
||||
continue if dep.isLoaded
|
||||
promises.push(dep.load())
|
||||
|
||||
return promises
|
||||
|
||||
onLoadDependenciesSuccess: ()->
|
||||
@model.fetch(@fetchOptions)
|
||||
|
||||
@listenToOnce(@model, 'sync' ()=>
|
||||
@markLoaded()
|
||||
@loadDeferred.resolve(@)
|
||||
)
|
||||
|
||||
@listenToOnce(@model, 'error', ()=>
|
||||
@markFailed()
|
||||
@loadDeferred.reject(@)
|
||||
)
|
||||
|
||||
onLoadDependenciesFailed: ()->
|
||||
@markFailed()
|
||||
@loadDeferred.reject(@)
|
||||
|
||||
|
||||
|
||||
class RequestResource extends Resource
|
||||
constructor: (name, jqxhrOptions)->
|
||||
@model = null
|
||||
@name = name
|
||||
@jqxhrOptions = jqxhrOptions
|
||||
|
||||
load: ()->
|
||||
return @model.promise() if @isLoading
|
||||
|
||||
@isLoading = true
|
||||
$.when.apply($, @loadDependencies())
|
||||
.then(onLoadDependenciesSuccess, onLoadDependenciesFailed)
|
||||
.always(()=> @isLoading = false)
|
||||
|
||||
return @model.promise()
|
||||
|
||||
loadDependencies: ()->
|
||||
promises = []
|
||||
for dep in @dependecies
|
||||
continue if dep.isLoaded
|
||||
promises.push(dep.load())
|
||||
|
||||
return promises
|
||||
|
||||
onLoadDependenciesSuccess: ()->
|
||||
@model = $.ajax(@jqxhrOptions)
|
||||
@model.done(()=> @markLoaded()).failed(()=> @markFailed())
|
||||
|
||||
onLoadDependenciesFailed: ()->
|
||||
@markFailed()
|
||||
|
||||
|
||||
|
||||
class SomethingResource extends Resource
|
||||
constructor: (name)->
|
||||
@name = name
|
|
@ -4,6 +4,7 @@ class CocoSchema extends Backbone.Model
|
|||
constructor: (path, args...) ->
|
||||
super(args...)
|
||||
@urlRoot = path + '/schema'
|
||||
console.debug 'gintau', 'schema-urlRoot', @urlRoot
|
||||
|
||||
window.CocoSchema = CocoSchema
|
||||
|
||||
|
|
|
@ -1,20 +1,33 @@
|
|||
class SuperModel
|
||||
module.exports = class SuperModel extends Backbone.Model
|
||||
constructor: ->
|
||||
@models = {}
|
||||
@collections = {}
|
||||
@schemas = {}
|
||||
_.extend(@, Backbone.Events)
|
||||
@num = 0
|
||||
@denom = 0
|
||||
@showing = false
|
||||
@progress = 0
|
||||
|
||||
populateModel: (model) ->
|
||||
console.debug 'gintau', 'SuperModel-populateModel', model
|
||||
|
||||
@mustPopulate = model
|
||||
model.saveBackups = @shouldSaveBackups(model)
|
||||
model.fetch() unless model.loaded or model.loading
|
||||
# model.fetch() unless model.loaded or model.loading
|
||||
@listenToOnce(model, 'sync', @modelLoaded) unless model.loaded
|
||||
@listenToOnce(model, 'error', @modelErrored) unless model.loaded
|
||||
url = model.url()
|
||||
@models[url] = model unless @models[url]?
|
||||
@modelLoaded(model) if model.loaded
|
||||
|
||||
modelRes = @addModelResource(model, url)
|
||||
schema = model.schema()
|
||||
schemaRes = @addModelResource(schema, schema.urlRoot)
|
||||
@schemas[schema.urlRoot] = schema
|
||||
modelRes.addDependency(schemaRes.name)
|
||||
|
||||
modelRes.load()
|
||||
|
||||
# replace or overwrite
|
||||
shouldLoadReference: (model) -> true
|
||||
shouldLoadProjection: (model) -> false
|
||||
|
@ -26,6 +39,8 @@ class SuperModel
|
|||
@removeEventsFromModel(model)
|
||||
|
||||
modelLoaded: (model) ->
|
||||
###
|
||||
|
||||
model.loadSchema()
|
||||
schema = model.schema()
|
||||
|
||||
|
@ -37,7 +52,7 @@ class SuperModel
|
|||
refs = model.getReferencedModels(model.attributes, schema.attributes, '/', @shouldLoadProjection)
|
||||
refs = [] unless @mustPopulate is model or @shouldPopulate(model)
|
||||
|
||||
console.debug 'gintau', 'superModel-refs', model, refs
|
||||
# console.debug 'gintau', 'superModel-refs', model, refs
|
||||
|
||||
# load references.
|
||||
for ref, i in refs when @shouldLoadReference ref
|
||||
|
@ -48,8 +63,10 @@ class SuperModel
|
|||
ref.fetch()
|
||||
@listenToOnce(ref, 'sync', @modelLoaded)
|
||||
|
||||
###
|
||||
|
||||
@trigger 'loaded-one', model: model
|
||||
@trigger 'loaded-all' if @finished()
|
||||
# @trigger 'loaded-all' if @finished()
|
||||
@removeEventsFromModel(model)
|
||||
|
||||
removeEventsFromModel: (model) ->
|
||||
|
@ -102,6 +119,7 @@ class SuperModel
|
|||
@addModel(model)
|
||||
collection
|
||||
|
||||
###
|
||||
progress: ->
|
||||
total = 0
|
||||
loaded = 0
|
||||
|
@ -115,8 +133,225 @@ class SuperModel
|
|||
|
||||
return 1.0 unless total
|
||||
return loaded / total
|
||||
###
|
||||
|
||||
finished: ->
|
||||
return @progress() == 1.0
|
||||
console.debug 'gintau', 'trigger-loaded-all' if @progress == 1.0
|
||||
return @progress == 1.0
|
||||
|
||||
module.exports = SuperModel
|
||||
|
||||
|
||||
addModelResource: (modelOrCollection, name, fetchOptions, value=1)->
|
||||
@checkName(name)
|
||||
res = new ModelResource(modelOrCollection, name, fetchOptions, value)
|
||||
@storeResource(name, res, value)
|
||||
return res
|
||||
|
||||
addRequestResource: (name, jqxhrOptions, value=1)->
|
||||
@checkName(name)
|
||||
res = new RequestResource(name, jqxhrOptions, value)
|
||||
@storeResource(name, res, value)
|
||||
return res
|
||||
|
||||
addSomethingResource: (name, value=1)->
|
||||
@checkName(name)
|
||||
res = new SomethingResource(name, value)
|
||||
@storeResource(name, res, value)
|
||||
return res
|
||||
|
||||
checkName: (name)->
|
||||
if not name
|
||||
throw new Error('Resource name should not be empty.')
|
||||
if name in ResourceManager.resources
|
||||
throw new Error('Resource name has been used.')
|
||||
|
||||
storeResource: (name, resource, value)->
|
||||
ResourceManager.resources[name] = resource
|
||||
@listenToOnce(resource, 'resource:loaded', @onResourceLoaded)
|
||||
@listenToOnce(resource, 'resource:failed', @onResourceFailed)
|
||||
@denom += value
|
||||
|
||||
loadResources: ()->
|
||||
for name, res of ResourceManager.resources
|
||||
res.load()
|
||||
|
||||
onResourceLoaded: (r)=>
|
||||
# Check if the model has references
|
||||
console.debug 'gintau', 'updateProgress', r.constructor.name
|
||||
if r.constructor.name == 'ModelResource'
|
||||
model = r.model
|
||||
@addModelRefencesToLoad(model)
|
||||
@updateProgress(r)
|
||||
else
|
||||
console.debug 'gintau', 'updateProgressWithoutAddReferences'
|
||||
@updateProgress(r)
|
||||
|
||||
onResourceFailed: (r)=>
|
||||
|
||||
addModelRefencesToLoad: (model)->
|
||||
schema = model.schema?()
|
||||
return unless schema
|
||||
|
||||
refs = model.getReferencedModels(model.attributes, schema.attributes, '/', @shouldLoadProjection)
|
||||
refs = [] unless @mustPopulate is model or @shouldPopulate(model)
|
||||
|
||||
console.debug 'gintau', 'superModel-refs', model, refs
|
||||
for ref, i in refs when @shouldLoadReference ref
|
||||
ref.saveBackups = @shouldSaveBackups(ref)
|
||||
refURL = ref.url()
|
||||
|
||||
continue if @models[refURL]
|
||||
|
||||
@models[refURL] = ref
|
||||
res = @addModelResource(ref, refURL)
|
||||
res.load()
|
||||
|
||||
updateProgress: (r)=>
|
||||
@num += r.value
|
||||
@progress = @num / @denom
|
||||
|
||||
console.debug 'gintau', 'updateProgress', @num, @denom, @progress
|
||||
@trigger('superModel:updateProgress', @progress)
|
||||
@trigger 'loaded-all' if @finished()
|
||||
|
||||
getResource: (name)->
|
||||
return ResourceManager.resources[name]
|
||||
|
||||
# Both SuperModel and Resource access this class.
|
||||
class ResourceManager
|
||||
@resources: {}
|
||||
|
||||
class Resource extends Backbone.Model
|
||||
constructor: (name, value=1)->
|
||||
@name = name
|
||||
@value = value
|
||||
@dependencies = []
|
||||
@isLoading = false
|
||||
@isLoaded = false
|
||||
@model = null
|
||||
@loadDeferred = null
|
||||
@value = 1
|
||||
|
||||
addDependency: (name)->
|
||||
depRes = ResourceManager.resources[name]
|
||||
throw new Error('Resource not found') unless depRes
|
||||
return if (depRes.isLoaded or name == @name)
|
||||
@dependencies.push(name)
|
||||
|
||||
markLoaded: ()->
|
||||
console.debug 'gintau', 'markLoaded', @model
|
||||
@trigger('resource:loaded', @) if not @isLoaded
|
||||
@isLoaded = true
|
||||
@isLoading = false
|
||||
|
||||
markFailed: ()->
|
||||
console.debug 'gintau', 'markLoaded', @model
|
||||
@trigger('resource:failed', @) if not @isLoaded
|
||||
@isLoaded = false
|
||||
@isLoading = false
|
||||
|
||||
load: ()->
|
||||
isReadyForLoad: ()-> return not (@isloaded and @isLoading)
|
||||
getModel: ()-> @model
|
||||
|
||||
class ModelResource extends Resource
|
||||
constructor: (modelOrCollection, name, fetchOptions, value)->
|
||||
super(name, value)
|
||||
@model = modelOrCollection
|
||||
@fetchOptions = fetchOptions
|
||||
|
||||
load: ()->
|
||||
return @loadDeferred.promise() if @isLoading or @isLoaded
|
||||
console.debug 'gintau', 'startLoading', @model
|
||||
|
||||
@isLoading = true
|
||||
@loadDeferred = $.Deferred()
|
||||
$.when.apply($, @loadDependencies())
|
||||
.then(@onLoadDependenciesSuccess, @onLoadDependenciesFailed)
|
||||
.always(()=> @isLoading = false)
|
||||
|
||||
return @loadDeferred.promise()
|
||||
|
||||
loadDependencies: ()->
|
||||
promises = []
|
||||
console.debug 'gintau', 'loadDependencies-Dependencies', @name, @dependencies
|
||||
|
||||
for resName in @dependencies
|
||||
dep = ResourceManager.resources[resName]
|
||||
console.debug 'gintau', 'loadDependencies-name', resName, @name
|
||||
continue if not dep.isReadyForLoad()
|
||||
promises.push(dep.load())
|
||||
|
||||
console.debug 'gintau', 'loadDependencies-promises', promises, @name
|
||||
return promises
|
||||
|
||||
onLoadDependenciesSuccess: ()=>
|
||||
console.debug 'gintau', 'onLoadDependenciesSuccess', 'startFetch', @model
|
||||
@model.fetch(@fetchOptions)
|
||||
|
||||
@listenToOnce(@model, 'sync', ()=>
|
||||
@markLoaded()
|
||||
@loadDeferred.resolve(@)
|
||||
)
|
||||
|
||||
@listenToOnce(@model, 'error', ()=>
|
||||
@markFailed()
|
||||
@loadDeferred.reject(@)
|
||||
)
|
||||
|
||||
onLoadDependenciesFailed: ()=>
|
||||
console.debug 'gintau', 'onLoadDependenciesFailed', model
|
||||
@markFailed()
|
||||
@loadDeferred.reject(@)
|
||||
|
||||
|
||||
class RequestResource extends Resource
|
||||
constructor: (name, jqxhrOptions, value)->
|
||||
super(name, value)
|
||||
@model = $.ajax(jqxhrOptions)
|
||||
@jqxhrOptions = jqxhrOptions
|
||||
@loadDeferred = @model
|
||||
|
||||
load: ()->
|
||||
return @loadDeferred.promise() if @isLoading or @isLoaded
|
||||
|
||||
@isLoading = true
|
||||
$.when.apply($, @loadDependencies())
|
||||
.then(@onLoadDependenciesSuccess, @onLoadDependenciesFailed)
|
||||
.always(()=> @isLoading = false)
|
||||
|
||||
return @loadDeferred.promise()
|
||||
|
||||
loadDependencies: ()->
|
||||
promises = []
|
||||
for depName in @dependecies
|
||||
dep = ResourceManager.resources[depName]
|
||||
continue if not dep.isReadyForLoad()
|
||||
promises.push(dep.load())
|
||||
|
||||
return promises
|
||||
|
||||
onLoadDependenciesSuccess: ()->
|
||||
@model = $.ajax(@jqxhrOptions)
|
||||
@model.done(()=> @markLoaded()).failed(()=> @markFailed())
|
||||
|
||||
onLoadDependenciesFailed: ()->
|
||||
@markFailed()
|
||||
|
||||
|
||||
class SomethingResource extends Resource
|
||||
constructor: (name, value)->
|
||||
super(value)
|
||||
@name = name
|
||||
@loadDeferred = $.Deferred()
|
||||
|
||||
load: ()->
|
||||
return @loadDeferred.promise()
|
||||
|
||||
markLoaded: ()->
|
||||
@loadDeferred.resolve()
|
||||
super()
|
||||
|
||||
markFailed: ()->
|
||||
@loadDeferred.reject()
|
||||
super()
|
Loading…
Reference in a new issue