codecombat/app/models/SuperModel.coffee

110 lines
3.5 KiB
CoffeeScript
Raw Normal View History

2014-01-03 13:32:13 -05:00
class SuperModel
constructor: ->
@models = {}
@collections = {}
_.extend(@, Backbone.Events)
populateModel: (model) ->
@mustPopulate = model
model.saveBackups = @shouldSaveBackups(model)
2014-01-03 13:32:13 -05:00
model.fetch() unless model.loaded or model.loading
2014-02-12 16:10:58 -05:00
model.once('sync', @modelLoaded, @) unless model.loaded
2014-02-11 19:09:44 -05:00
model.once('error', @modelErrored, @) unless model.loaded
2014-01-03 13:32:13 -05:00
url = model.url()
@models[url] = model unless @models[url]?
@modelLoaded(model) if model.loaded
# replace or overwrite
2014-02-15 18:44:45 -05:00
shouldLoadReference: (model) -> true
shouldLoadProjection: (model) -> false
2014-02-15 18:44:45 -05:00
shouldPopulate: (url) -> true
shouldSaveBackups: (model) -> false
2014-01-03 13:32:13 -05:00
2014-02-11 19:09:44 -05:00
modelErrored: (model) ->
2014-01-03 13:32:13 -05:00
@trigger 'error'
2014-02-11 19:09:44 -05:00
@removeEventsFromModel(model)
2014-01-03 13:32:13 -05:00
2014-02-11 19:09:44 -05:00
modelLoaded: (model) ->
2014-01-03 13:32:13 -05:00
schema = model.schema()
2014-02-12 15:41:41 -05:00
return schema.once('sync', => @modelLoaded(model)) unless schema.loaded
refs = model.getReferencedModels(model.attributes, schema.attributes, '/', @shouldLoadProjection)
2014-01-03 13:32:13 -05:00
refs = [] unless @mustPopulate is model or @shouldPopulate(model)
# console.log 'Loaded', model.get('name')
2014-02-15 18:44:45 -05:00
for ref, i in refs when @shouldLoadReference ref
ref.saveBackups = @shouldSaveBackups(ref)
2014-01-03 13:32:13 -05:00
refURL = ref.url()
continue if @models[refURL]
@models[refURL] = ref
ref.fetch()
2014-02-12 16:10:58 -05:00
ref.once 'sync', @modelLoaded, @
2014-01-03 13:32:13 -05:00
@trigger 'loaded-one', model: model
@trigger 'loaded-all' if @finished()
2014-02-11 19:09:44 -05:00
@removeEventsFromModel(model)
2014-02-12 16:10:58 -05:00
2014-02-11 19:09:44 -05:00
removeEventsFromModel: (model) ->
model.off 'sync', @modelLoaded, @
model.off 'error', @modelErrored, @
2014-01-03 13:32:13 -05:00
getModel: (ModelClass_or_url, id) ->
return @getModelByURL(ModelClass_or_url) if _.isString(ModelClass_or_url)
m = new ModelClass_or_url(_id: id)
return @getModelByURL(m.url())
getModelByURL: (modelURL) ->
return @models[modelURL] or null
getModelByOriginalAndMajorVersion: (ModelClass, original, majorVersion=0) ->
_.find @models, (m) ->
m.get('original') is original and m.get('version').major is majorVersion and m.constructor.className is ModelClass.className
getModels: (ModelClass) ->
# can't use instanceof. SuperModel gets passed between windows, and one window
# will have different class objects than another window.
# So compare className instead.
return (m for key, m of @models when m.constructor.className is ModelClass.className) if ModelClass
return _.values @models
addModel: (model) ->
url = model.url()
return console.warn "Tried to add Model '#{url}' to SuperModel, but it wasn't loaded." unless model.loaded
#return console.warn "Tried to add Model '#{url}' to SuperModel when we already had it." if @models[url]?
@models[url] = model
getCollection: (collection) ->
url = collection.url
url = url() if _.isFunction(url)
return @collections[url] or collection
addCollection: (collection) ->
url = collection.url
url = url() if _.isFunction(url)
if @collections[url]?
return console.warn "Tried to add Collection '#{url}' to SuperModel when we already had it."
@collections[url] = collection
# consolidate models
for model, i in collection.models
cachedModel = @getModelByURL(model.url())
if cachedModel
collection.models[i] = cachedModel
else
@addModel(model)
collection
progress: ->
total = 0
loaded = 0
for key, model of @models
total += 1
loaded += 1 if model.loaded
return 1.0 unless total
return loaded / total
finished: ->
return @progress() == 1.0
module.exports = SuperModel