Did some refactoring to simplify using SuperModel and registering models and collections.

This commit is contained in:
Scott Erickson 2014-04-26 12:54:03 -07:00
parent d5bcec5ad0
commit 14cffc5875
5 changed files with 81 additions and 40 deletions

View file

@ -5,4 +5,7 @@ module.exports = class CocoCollection extends Backbone.Collection
super()
@once 'sync', =>
@loaded = true
model.loaded = true for model in @models
model.loaded = true for model in @models
getURL: ->
return if _.isString @url then @url else @url()

View file

@ -228,4 +228,12 @@ class CocoModel extends Backbone.Model
model.url = makeUrlFunc(link)
return model
setURL: (url) ->
makeURLFunc = (u) -> -> u
@url = makeURLFunc(url)
@
getURL: ->
return if _.isString @url then @url else @url()
module.exports = CocoModel

View file

@ -8,6 +8,51 @@ module.exports = class SuperModel extends Backbone.Model
@models = {}
@collections = {}
# Since the supermodel has undergone some changes into being a loader and a cache interface,
# it's a bit wonky to use. The next couple functions are meant to cover the majority of
# use cases across the site. If they are used, the view will automatically handle errors,
# retries, progress, and filling the cache. Note that the resource it passes back will not
# necessarily have the same model or collection that was passed in, if it was fetched from
# the cache.
loadModel: (model, name, fetchOptions, value=1) ->
cachedModel = @getModelByURL(model.getURL())
if cachedModel
console.debug 'Model cache hit', cachedModel.getURL(), 'already loaded', cachedModel.loaded
if cachedModel.loaded
res = @addModelResource(cachedModel, name, fetchOptions, 0)
res.markLoaded()
return res
else
res = @addModelResource(cachedModel, name, fetchOptions, value)
res.markLoading()
return res
else
@registerModel(model)
console.debug 'Registering model', model.getURL()
return @addModelResource(model, name, fetchOptions, value).load()
loadCollection: (collection, name, fetchOptions, value=1) ->
url = collection.getURL()
if cachedCollection = @collections[url]
console.debug 'Collection cache hit', url, 'already loaded', cachedModel.loaded
if cachedModel.loaded
res = @addModelResource(cachedCollection, name, fetchOptions, 0)
res.markLoaded()
return res
else
res = @addModelResource(cachedCollection, name, fetchOptions, value)
res.markLoading()
return res
else
@addCollection collection
@listenToOnce collection, 'sync', (c) ->
console.debug 'Registering collection', url
@registerCollection c
return @addModelResource(collection, name, fetchOptions, value).load()
# replace or overwrite
shouldSaveBackups: (model) -> false
@ -17,7 +62,7 @@ module.exports = class SuperModel extends Backbone.Model
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())
return @getModelByURL(m.getURL())
getModelByURL: (modelURL) ->
modelURL = modelURL() if _.isFunction(modelURL)
@ -35,35 +80,33 @@ module.exports = class SuperModel extends Backbone.Model
return _.values @models
registerModel: (model) ->
url = model.url
url = model.url() if _.isFunction(model.url)
@models[url] = model
@models[model.getURL()] = model
getCollection: (collection) ->
url = collection.url
url = url() if _.isFunction(url)
return @collections[url] or collection
return @collections[collection.getURL()] or collection
addCollection: (collection) ->
url = collection.url
url = url() if _.isFunction(url)
if @collections[url]?
# TODO: remove, instead just use registerCollection?
url = collection.getURL()
if @collections[url]? and @collections[url] isnt collection
return console.warn "Tried to add Collection '#{url}' to SuperModel when we already had it."
@collections[url] = collection
@registerCollection(collection)
registerCollection: (collection) ->
@collections[collection.getURL()] = collection
# consolidate models
for model, i in collection.models
cachedModel = @getModelByURL(model.url())
cachedModel = @getModelByURL(model.getURL())
if cachedModel
collection.models[i] = cachedModel
else
@registerModel(model)
collection
# New, loading tracking stuff
# Tracking resources being loaded for this supermodel
finished: ->
return @progress is 1.0 or Object.keys(@resources).length is 0
return @progress is 1.0 or not @denom
addModelResource: (modelOrCollection, name, fetchOptions, value=1) ->
modelOrCollection.saveBackups = @shouldSaveBackups(modelOrCollection)
@ -108,8 +151,9 @@ module.exports = class SuperModel extends Backbone.Model
# Because this is _.defer'd, this might end up getting called after
# a bunch of things load all at once.
# So make sure we only emit events if @progress has changed.
return if @progress is @num / @denom
@progress = @num / @denom
newProg = if @denom then @num / @denom else 1
return if @progress is newProg
@progress = newProg
@trigger('update-progress', @progress)
@trigger('loaded-all') if @finished()

View file

@ -41,7 +41,7 @@ module.exports = class EditorLevelView extends View
@levelLoader = new LevelLoader supermodel: @supermodel, levelID: @levelID, headless: true
@level = @levelLoader.level
@files = new DocumentFiles(@levelLoader.level)
@supermodel.addModelResource(@files, 'file_names').load()
@supermodel.loadCollection(@files, 'file_names')
showLoading: ($el) ->
$el ?= @$el.find('.outer-content')

View file

@ -11,7 +11,6 @@ module.exports = class SystemsTabView extends View
id: "editor-level-systems-tab-view"
template: template
className: 'tab-pane'
startsLoading: true
subscriptions:
'level-system-added': 'onLevelSystemAdded'
@ -27,36 +26,23 @@ module.exports = class SystemsTabView extends View
constructor: (options) ->
super options
@toLoad = 0
for system in @buildDefaultSystems()
url = "/db/level.system/#{system.original}/version/#{system.majorVersion}"
ls = new LevelSystem()
ls.saveBackups = true
do (url) -> ls.url = -> url
continue if @supermodel.getModelByURL ls.url
lsRes = @supermodel.addModelResource(ls, 'level_system_' + system.original)
lsRes.load()
@listenToOnce(lsRes, 'loaded', @onSystemLoaded)
++@toLoad
@onDefaultSystemsLoaded() unless @toLoad
onSystemLoaded: (lsRes) ->
ls = lsRes.model
@supermodel.registerModel(ls)
--@toLoad
@onDefaultSystemsLoaded() unless @toLoad
onDefaultSystemsLoaded: ->
@startsLoading = false
@render() # do it again but without the loading screen
@onLevelLoaded level: @level if @level
ls = new LevelSystem().setURL(url)
@supermodel.loadModel(ls, 'system')
afterRender: ->
@buildSystemsTreema()
onLoaded: ->
super()
onLevelLoaded: (e) ->
@level = e.level
@buildSystemsTreema()
buildSystemsTreema: ->
return unless @level and @supermodel.finished()
systems = $.extend(true, [], @level.get('systems') ? [])
unless systems.length
systems = @buildDefaultSystems()