able to load level editor.

This commit is contained in:
Ting-Kuan 2014-04-09 15:11:59 -04:00
parent 354e3570e2
commit 3ea4d1677c
3 changed files with 243 additions and 166 deletions

View file

@ -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

View file

@ -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

View file

@ -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()