From 65a32a262db6351aeddc94fd31597266bde2646d Mon Sep 17 00:00:00 2001
From: Ting-Kuan <gintau2000@gmail.com>
Date: Sat, 12 Apr 2014 00:03:56 -0400
Subject: [PATCH 1/6] Before change dependency without name.

---
 app/collections/DocumentFiles.coffee | 3 ++-
 app/models/SuperModel.coffee         | 2 ++
 2 files changed, 4 insertions(+), 1 deletion(-)

diff --git a/app/collections/DocumentFiles.coffee b/app/collections/DocumentFiles.coffee
index d78c41bd9..2b21a6211 100644
--- a/app/collections/DocumentFiles.coffee
+++ b/app/collections/DocumentFiles.coffee
@@ -5,4 +5,5 @@ module.exports = class ModelFiles extends CocoCollection
     super()
     url = model.constructor.prototype.urlRoot
     url += "/#{model.get('original') or model.id}/files"
-    @url = url 
\ No newline at end of file
+    @url = url 
+    @name = model.name
\ No newline at end of file
diff --git a/app/models/SuperModel.coffee b/app/models/SuperModel.coffee
index 14c439fdd..f4d7d3fb2 100644
--- a/app/models/SuperModel.coffee
+++ b/app/models/SuperModel.coffee
@@ -114,6 +114,7 @@ module.exports = class SuperModel extends Backbone.Model
       throw new Error('Resource name has been used.')
 
   storeResource: (name, resource, value)->
+    console.debug 'gintau', 'storeResource', name
     ResourceManager.resources[name] = resource
     @listenToOnce(resource, 'resource:loaded', @onResourceLoaded)
     @listenToOnce(resource, 'resource:failed', @onResourceFailed)
@@ -150,6 +151,7 @@ module.exports = class SuperModel extends Backbone.Model
       continue if @models[refURL]
 
       @models[refURL] = ref
+      console.debug 'gintau', 'addModelRefencesToLoad', ref
       res = @addModelResource(ref, refURL)
       res.load()
 

From 7ae3bd5a60af9fdba75afda6c9c42f3d3efff15a Mon Sep 17 00:00:00 2001
From: Ting-Kuan <gintau2000@gmail.com>
Date: Sat, 12 Apr 2014 16:29:49 -0400
Subject: [PATCH 2/6] Fix style and supermodel based on #815. Fix ladder_view
 and ladder_tab. Change error handling functions in CocoView.

---
 app/collections/DocumentFiles.coffee          |   3 +-
 app/locale/en.coffee                          |   6 +-
 app/models/SuperModel.coffee                  | 149 +++++++++---------
 app/views/editor/level/edit.coffee            |   2 +-
 app/views/editor/thang/edit.coffee            |  10 +-
 app/views/kinds/CocoView.coffee               |  38 ++---
 app/views/play/ladder/ladder_tab.coffee       |  54 +++++--
 app/views/play/ladder_view.coffee             |  15 +-
 .../play/level/level_loading_view.coffee      |   2 +-
 9 files changed, 151 insertions(+), 128 deletions(-)

diff --git a/app/collections/DocumentFiles.coffee b/app/collections/DocumentFiles.coffee
index 2b21a6211..d78c41bd9 100644
--- a/app/collections/DocumentFiles.coffee
+++ b/app/collections/DocumentFiles.coffee
@@ -5,5 +5,4 @@ module.exports = class ModelFiles extends CocoCollection
     super()
     url = model.constructor.prototype.urlRoot
     url += "/#{model.get('original') or model.id}/files"
-    @url = url 
-    @name = model.name
\ No newline at end of file
+    @url = url 
\ No newline at end of file
diff --git a/app/locale/en.coffee b/app/locale/en.coffee
index 9b4fb6ced..8c566cc5a 100644
--- a/app/locale/en.coffee
+++ b/app/locale/en.coffee
@@ -620,4 +620,8 @@ module.exports = nativeDescription: "English", englishDescription: "English", tr
     user_schema: "User Schema"
     user_profile: "User Profile"
     level_session: "LevelSession"
-    opponent_session: "OpponentSession"
\ No newline at end of file
+    level_sessions_collection: 'LevelSessionsCollection'
+    opponent_session: "OpponentSession"
+    simulator: 'Simulator'
+    level_document: 'Level Document'
+    thang_document: 'Thang Document'
\ No newline at end of file
diff --git a/app/models/SuperModel.coffee b/app/models/SuperModel.coffee
index f4d7d3fb2..93b5618f5 100644
--- a/app/models/SuperModel.coffee
+++ b/app/models/SuperModel.coffee
@@ -1,5 +1,12 @@
 module.exports = class SuperModel extends Backbone.Model
   constructor: ->
+    @num = 0
+    @denom = 0
+    @showing = false
+    @progress = 0
+    @resources = {}
+    @rid = 0
+
     @models = {}
     @collections = {}
     @schemas = {}
@@ -17,7 +24,7 @@ module.exports = class SuperModel extends Backbone.Model
     schema = model.schema()
     schemaRes = @addModelResource(schema, schema.urlRoot)
     @schemas[schema.urlRoot] = schema
-    modelRes.addDependency(schemaRes.name)
+    modelRes.addDependency(schemaRes)
 
     modelRes.load()
 
@@ -36,8 +43,9 @@ module.exports = class SuperModel extends Backbone.Model
     @removeEventsFromModel(model)
 
   removeEventsFromModel: (model) ->
-    model.off 'sync', @modelLoaded, @
-    model.off 'error', @modelErrored, @
+    # "Something" resource may have no model.
+    model?.off 'sync', @modelLoaded, @
+    model?.off 'error', @modelErrored, @
 
   getModel: (ModelClass_or_url, id) ->
     return @getModelByURL(ModelClass_or_url) if _.isString(ModelClass_or_url)
@@ -86,45 +94,45 @@ module.exports = class SuperModel extends Backbone.Model
     collection
 
   finished: ->
-    return ResourceManager.progress is 1.0 or Object.keys(ResourceManager.resources).length is 0
+    return @progress is 1.0 or Object.keys(@resources).length is 0
 
 
-  addModelResource: (modelOrCollection, name, fetchOptions, value=1)->
+  addModelResource: (modelOrCollection, name, fetchOptions, value=1) ->
     @checkName(name)
     res = new ModelResource(modelOrCollection, name, fetchOptions, value)
-    @storeResource(name, res, value)
+    @storeResource(res, value)
     return res
 
-  addRequestResource: (name, jqxhrOptions, value=1)->
+  addRequestResource: (name, jqxhrOptions, value=1) ->
     @checkName(name)
     res = new RequestResource(name, jqxhrOptions, value)
-    @storeResource(name, res, value)
+    @storeResource(res, value)
     return res
 
-  addSomethingResource: (name, value=1)->
+  addSomethingResource: (name, value=1) ->
     @checkName(name)
     res = new SomethingResource(name, value)
-    @storeResource(name, res, value)
+    @storeResource(res, value)
     return res
 
-  checkName: (name)->
+  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)->
-    console.debug 'gintau', 'storeResource', name
-    ResourceManager.resources[name] = resource
+  storeResource: (resource, value) ->
+    @rid++
+    resource.rid = @rid
+    @resources[@rid] = resource
     @listenToOnce(resource, 'resource:loaded', @onResourceLoaded)
     @listenToOnce(resource, 'resource:failed', @onResourceFailed)
-    ResourceManager.denom += value
+    @denom += value
 
-  loadResources: ()->
-    for name, res of ResourceManager.resources
+  loadResources: ->
+    for rid, res of @resources
       res.load()
 
-  onResourceLoaded: (r)=> 
+  onResourceLoaded: (r) ->
+    console.debug 'gintau', 'supermodel-onResourceLoaded', r
     @modelLoaded(r.model)
     # Check if the model has references
     if r.constructor.name is 'ModelResource'
@@ -134,10 +142,11 @@ module.exports = class SuperModel extends Backbone.Model
     else
       @updateProgress(r)
 
-  onResourceFailed: (r)=>
-    @modelErrored(r.model)
+  onResourceFailed: (source) ->
+    @trigger('resource:failed', source)
+    @modelErrored(source.resource.model)
 
-  addModelRefencesToLoad: (model)->
+  addModelRefencesToLoad: (model) ->
     schema = model.schema?()
     return unless schema
 
@@ -151,61 +160,52 @@ module.exports = class SuperModel extends Backbone.Model
       continue if @models[refURL]
 
       @models[refURL] = ref
-      console.debug 'gintau', 'addModelRefencesToLoad', ref
       res = @addModelResource(ref, refURL)
       res.load()
 
-  updateProgress: (r)=>     
-    ResourceManager.num += r.value
-    ResourceManager.progress = ResourceManager.num / ResourceManager.denom
+  updateProgress: (r) =>     
+    @num += r.value
+    @progress = @num / @denom
 
-    @trigger('superModel:updateProgress', ResourceManager.progress)
-    @trigger 'loaded-all' if @finished()
+    console.debug 'gintau', 'superModel-updateProgress', @progress
+    @trigger('superModel:updateProgress', @progress)
+    @trigger('loaded-all') if @finished()
 
-  getResource: (name)->
-    return ResourceManager.resources[name]
+  getResource: (rid)->
+    return @resources[rid]
 
-  getProgress: ()-> return ResourceManager.progress
-
-# Both SuperModel and Resource access this class.
-# Set resources as static so no need to load resources multiple times when more than one view is used.
-class ResourceManager
-  @num = 0
-  @denom = 0
-  @showing = false
-  @progress = 0
-  @resources: {}
+  getProgress: -> return @progress
 
+ 
 class Resource extends Backbone.Model
-  constructor: (name, value=1)->
+  constructor: (name, value=1) ->
     @name = name
     @value = value
     @dependencies = []
+    @rid = -1 # Used for checking state and reloading
     @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 is @name)
-    @dependencies.push(name)
+  addDependency: (depRes) ->
+    return if depRes.isLoaded
+    @dependencies.push(depRes)
 
-  markLoaded: ()->
+  markLoaded: ->
     @trigger('resource:loaded', @) if not @isLoaded
     @isLoaded = true
     @isLoading = false
 
-  markFailed: ()->
-    @trigger('resource:failed', @) if not @isLoaded
+  markFailed: (error) ->
+    @trigger('resource:failed', {resource: @, error: error}) if not @isLoaded
     @isLoaded = false
     @isLoading = false
 
-  load: ()->
-  isReadyForLoad: ()-> return not (@isloaded and @isLoading)
-  getModel: ()-> @model
+  load: ->
+  isReadyForLoad: -> return not (@isloaded and @isLoading)
+  getModel: -> @model
 
 class ModelResource extends Resource
   constructor: (modelOrCollection, name, fetchOptions, value)->
@@ -213,7 +213,7 @@ class ModelResource extends Resource
     @model = modelOrCollection
     @fetchOptions = fetchOptions
 
-  load: ()->
+  load: ->
     return @loadDeferred.promise() if @isLoading or @isLoaded
 
     @isLoading = true
@@ -224,17 +224,16 @@ class ModelResource extends Resource
 
     return @loadDeferred.promise()
 
-  loadDependencies: ()->
+  loadDependencies: ->
     promises = []
 
-    for resName in @dependencies
-      dep = ResourceManager.resources[resName]
+    for dep in @dependencies
       continue if not dep.isReadyForLoad()
       promises.push(dep.load())
 
     return promises
 
-  onLoadDependenciesSuccess: ()=>
+  onLoadDependenciesSuccess: =>
     @model.fetch(@fetchOptions)
 
     @listenToOnce(@model, 'sync', ->
@@ -243,23 +242,23 @@ class ModelResource extends Resource
     )
 
     @listenToOnce(@model, 'error', ->
-      @markFailed()
+      @markFailed('Failed to load resource.')
       @loadDeferred.reject(@)
     )
 
-  onLoadDependenciesFailed: ()=>
-    @markFailed()
+  onLoadDependenciesFailed: =>
+    @markFailed('Failed to load dependencies.')
     @loadDeferred.reject(@)
 
 
 class RequestResource extends Resource
-  constructor: (name, jqxhrOptions, value)->
+  constructor: (name, jqxhrOptions, value) ->
     super(name, value)
     @model = $.ajax(jqxhrOptions)
     @jqxhrOptions = jqxhrOptions
     @loadDeferred = @model
 
-  load: ()->
+  load: ->
     return @loadDeferred.promise() if @isLoading or @isLoaded
 
     @isLoading = true
@@ -269,36 +268,36 @@ class RequestResource extends Resource
 
     return @loadDeferred.promise()
 
-  loadDependencies: ()->
+  loadDependencies: ->
     promises = []
-    for depName in @dependecies
-      dep = ResourceManager.resources[depName]
+
+    for dep in @dependecies
       continue if not dep.isReadyForLoad()
       promises.push(dep.load())
 
     return promises
 
-  onLoadDependenciesSuccess: ()->
+  onLoadDependenciesSuccess: ->
     @model = $.ajax(@jqxhrOptions)
-    @model.done(()=> @markLoaded()).failed(()=> @markFailed())
+    @model.done(=> @markLoaded()).failed((jqXHR, textStatus, errorThrown) => @markFailed(errorThrown))
 
-  onLoadDependenciesFailed: ()->
-    @markFailed()
+  onLoadDependenciesFailed: ->
+    @markFailed('Failed to load dependencies.')
 
 
 class SomethingResource extends Resource
-  constructor: (name, value)->
+  constructor: (name, value) ->
     super(value)
     @name = name
     @loadDeferred = $.Deferred()
 
-  load: ()->
+  load: ->
     return @loadDeferred.promise()
 
-  markLoaded: ()->
+  markLoaded: ->
     @loadDeferred.resolve()
     super()
 
-  markFailed: ()->
+  markFailed: (error) ->
     @loadDeferred.reject()
-    super()
\ No newline at end of file
+    super(error)
\ No newline at end of file
diff --git a/app/views/editor/level/edit.coffee b/app/views/editor/level/edit.coffee
index 2b6d70b79..df7e2502d 100644
--- a/app/views/editor/level/edit.coffee
+++ b/app/views/editor/level/edit.coffee
@@ -58,7 +58,7 @@ module.exports = class EditorLevelView extends View
 
   onLevelLoaded: ->
     @files = new DocumentFiles(@level)
-    @supermodel.addModelResource(@files, @files.url).load()
+    @supermodel.addModelResource(@files, 'level_document').load()
 
   onAllLoaded: ->
     @level.unset('nextLevel') if _.isString(@level.get('nextLevel'))
diff --git a/app/views/editor/thang/edit.coffee b/app/views/editor/thang/edit.coffee
index 7e468741f..cfd85aa43 100644
--- a/app/views/editor/thang/edit.coffee
+++ b/app/views/editor/thang/edit.coffee
@@ -56,11 +56,11 @@ module.exports = class ThangTypeEditView extends View
         @insertSubView(new ErrorView())
     )
 
-    thang_res = @supermodel.addModelResource(@thangType, 'thang_type')
-    thang_schema_res = @supermodel.addModelResource(@thangType.schema(), 'thang_type_schema')
-    thang_res.addDependency('thang_type_schema')
+    thangRes = @supermodel.addModelResource(@thangType, 'thang_type')
+    thangSchemaRes = @supermodel.addModelResource(@thangType.schema(), 'thang_type_schema')
+    thangRes.addDependency(thangSchemaRes)
 
-    thang_res.load()
+    thangRes.load()
     @listenToOnce(@thangType.schema(), 'sync', @onThangTypeSync)
     @listenToOnce(@thangType, 'sync', @onThangTypeSync)
 
@@ -70,7 +70,7 @@ module.exports = class ThangTypeEditView extends View
     return unless @thangType.loaded and ThangType.hasSchema()
     @startsLoading = false
     @files = new DocumentFiles(@thangType)
-    @supermodel.addModelResource(@files, @files.url).load()
+    @supermodel.addModelResource(@files, 'thang_document').load()
     @render()
 
   getRenderData: (context={}) ->
diff --git a/app/views/kinds/CocoView.coffee b/app/views/kinds/CocoView.coffee
index c92fc7c39..afdc84499 100644
--- a/app/views/kinds/CocoView.coffee
+++ b/app/views/kinds/CocoView.coffee
@@ -43,8 +43,9 @@ module.exports = class CocoView extends Backbone.View
     @updateProgressBar = _.debounce @updateProgressBar, 100
     # Backbone.Mediator handles subscription setup/teardown automatically
 
-    @listenToOnce(@supermodel, 'loaded-all', ()=>@onLoaded)
+    @listenToOnce(@supermodel, 'loaded-all', @onLoaded)
     @listenToOnce(@supermodel, 'superModel:updateProgress', @updateProgress)
+    @listenToOnce(@supermodel, 'resource:failed', @onResourceLoadFailed)
 
     super options
 
@@ -117,38 +118,21 @@ module.exports = class CocoView extends Backbone.View
     @$el.find('.loading-screen .progress-bar').css('width', prog)
 
   onLoaded: ->
-    #@render()
+    console.debug 'gintau', 'CocoView-onLoaded()'
+    @render()
 
   # Error handling for loading
-  
-  onResourceLoadFailed: (resource, jqxhr) ->
-    for r, index in @loadProgress.resources
-      break if r.resource is resource
+  onResourceLoadFailed: (source) ->
     @$el.find('.loading-screen .errors').append(loadingErrorTemplate({
-      status:jqxhr.status,
-      name: r.name
-      resourceIndex: index,
-      responseText: jqxhr.responseText
+      status: 'error',
+      name: source.resource.name
+      resourceIndex: source.resource.rid,
+      responseText: source.error
     })).i18n()
   
   onRetryResource: (e) ->
-    r = @loadProgress.resources[$(e.target).data('resource-index')]
-    r.resource.fetch()
-    $(e.target).closest('.loading-error-alert').remove()
-    
-  onRequestLoadFailed: (jqxhr) =>
-    for r, index in @loadProgress.requests
-      break if r.request is jqxhr
-    @$el.find('.loading-screen .errors').append(loadingErrorTemplate({
-      status:jqxhr.status,
-      name: r.name
-      requestIndex: index,
-      responseText: jqxhr.responseText
-    }))
-    
-  onRetryRequest: (e) ->
-    r = @loadProgress.requests[$(e.target).data('request-index')]
-    @[r.retryFunc]?()
+    res = @supermodel.getResource($(e.target).data('resource-index'))
+    res.load()
     $(e.target).closest('.loading-error-alert').remove()
 
   # Modals
diff --git a/app/views/play/ladder/ladder_tab.coffee b/app/views/play/ladder/ladder_tab.coffee
index b9fddcf38..6936589f6 100644
--- a/app/views/play/ladder/ladder_tab.coffee
+++ b/app/views/play/ladder/ladder_tab.coffee
@@ -32,7 +32,8 @@ module.exports = class LadderTabView extends CocoView
 
   constructor: (options, @level, @sessions) ->
     super(options)
-    @addSomethingToLoad("social_network_apis")
+    @socialNetworkRes = @supermodel.addSomethingResource("social_network_apis")
+
     @teams = teamDataFromLevel @level
     @leaderboards = {}
     @refreshLadder()
@@ -42,17 +43,22 @@ module.exports = class LadderTabView extends CocoView
     return if @checked or (not window.FB) or (not window.gapi)
     @checked = true
     
-    @addSomethingToLoad("facebook_status")
+    # @addSomethingToLoad("facebook_status")
+
+    @fbStatusRes = @supermodel.addSomethingResource("facebook_status")
+    @fbStatusRes.load()
+
     FB.getLoginStatus (response) =>
       @facebookStatus = response.status
       @loadFacebookFriends() if @facebookStatus is 'connected'
-      @somethingLoaded("facebook_status")
+      @fbStatusRes.markLoaded()
 
     if application.gplusHandler.loggedIn is undefined
       @listenToOnce(application.gplusHandler, 'checked-state', @gplusSessionStateLoaded)
     else
       @gplusSessionStateLoaded()
-    @somethingLoaded("social_network_apis")
+
+    @socialNetworkRes.markLoaded()
 
   # FACEBOOK
 
@@ -63,23 +69,39 @@ module.exports = class LadderTabView extends CocoView
   onConnectedWithFacebook: -> location.reload() if @connecting
 
   loadFacebookFriends: ->
-    @addSomethingToLoad("facebook_friends")
+    # @addSomethingToLoad("facebook_friends")
+
+    @fbFriendRes = @supermodel.addSomethingResource("facebook_friends")
+    @fbFriendRes.load()
+
     FB.api '/me/friends', @onFacebookFriendsLoaded
     
   onFacebookFriendsLoaded: (response) =>
     @facebookData = response.data
     @loadFacebookFriendSessions()
-    @somethingLoaded("facebook_friends")
+    @fbFriendRes.markLoaded()
 
   loadFacebookFriendSessions: ->
     levelFrag = "#{@level.get('original')}.#{@level.get('version').major}"
     url = "/db/level/#{levelFrag}/leaderboard_facebook_friends"
+    
+    ###
     jqxhr = $.ajax url, {
       data: { friendIDs: (f.id for f in @facebookData) }
       method: 'POST'
       success: @onFacebookFriendSessionsLoaded
     }
+    
     @addRequestToLoad(jqxhr, 'facebook_friend_sessions', 'loadFacebookFriendSessions')
+    ###
+
+    @fbFriendSessionRes = @supermodel.addRequestResource('facebook_friend_sessions', {
+      url: url
+      data: { friendIDs: (f.id for f in @facebookData) }
+      method: 'POST'
+      success: @onFacebookFriendSessionsLoaded
+    })
+    @fbFriendSessionRes.load()
 
   onFacebookFriendSessionsLoaded: (result) =>
     friendsMap = {}
@@ -101,23 +123,34 @@ module.exports = class LadderTabView extends CocoView
     
   gplusSessionStateLoaded: ->
     if application.gplusHandler.loggedIn
-      @addSomethingToLoad("gplus_friends")
+      #@addSomethingToLoad("gplus_friends")
+      @gpFriendRes = @supermodel.addSomethingResource("gplus_friends")
+      @gpFriendRes.load()
       application.gplusHandler.loadFriends @gplusFriendsLoaded
 
   gplusFriendsLoaded: (friends) =>
     @gplusData = friends.items
     @loadGPlusFriendSessions()
-    @somethingLoaded("gplus_friends")
+    @gpFriendRes.markLoaded()
 
   loadGPlusFriendSessions: ->
     levelFrag = "#{@level.get('original')}.#{@level.get('version').major}"
     url = "/db/level/#{levelFrag}/leaderboard_gplus_friends"
+    ###
     jqxhr = $.ajax url, {
       data: { friendIDs: (f.id for f in @gplusData) }
       method: 'POST'
       success: @onGPlusFriendSessionsLoaded
     }
     @addRequestToLoad(jqxhr, 'gplus_friend_sessions', 'loadGPlusFriendSessions')
+    ###
+    @gpFriendSessionRes = @supermodel.addRequestResource('gplus_friend_sessions', {
+      url: url
+      data: { friendIDs: (f.id for f in @gplusData) }
+      method: 'POST'
+      success: @onGPlusFriendSessionsLoaded
+    })
+    @gpFriendSessionRes.load()
 
   onGPlusFriendSessionsLoaded: (result) =>
     friendsMap = {}
@@ -135,8 +168,9 @@ module.exports = class LadderTabView extends CocoView
       @leaderboards[team.id]?.destroy()
       teamSession = _.find @sessions.models, (session) -> session.get('team') is team.id
       @leaderboards[team.id] = new LeaderboardData(@level, team.id, teamSession)
-
-      @addResourceToLoad @leaderboards[team.id], 'leaderboard', 3
+      # @addResourceToLoad @leaderboards[team.id], 'leaderboard', 3
+      @leaderboardRes = @supermodel.addModelResource(@leaderboards[team.id], 'leaderboard', 3)
+      @leaderboardRes.load()
 
   render: ->
     super()
diff --git a/app/views/play/ladder_view.coffee b/app/views/play/ladder_view.coffee
index 58366fa58..b5b31f775 100644
--- a/app/views/play/ladder_view.coffee
+++ b/app/views/play/ladder_view.coffee
@@ -37,11 +37,13 @@ module.exports = class LadderView extends RootView
   constructor: (options, @levelID) ->
     super(options)
     @level = new Level(_id:@levelID)
-    @level.fetch()
+    levelRes = @supermodel.addModelResource(@level, 'level')
+    levelRes.load()
+
     @sessions = new LevelSessionsCollection(levelID)
-    @sessions.fetch({})
-    @addResourceToLoad(@sessions, 'your_sessions')
-    @addResourceToLoad(@level, 'level')
+    sessionRes = @supermodel.addModelResource(@sessions, 'level_sessions_collection')
+    sessionRes.load()
+
     @simulator = new Simulator()
     @listenTo(@simulator, 'statusUpdate', @updateSimulationStatus)
     @teams = []
@@ -62,7 +64,8 @@ module.exports = class LadderView extends RootView
 
   afterRender: ->
     super()
-    return if @loading()
+    console.debug 'gintau', 'ladder_view_finished', @supermodel.finished()
+    return unless @supermodel.finished()
     @insertSubView(@ladderTab = new LadderTabView({}, @level, @sessions))
     @insertSubView(@myMatchesTab = new MyMatchesTabView({}, @level, @sessions))
     @refreshInterval = setInterval(@fetchSessionsAndRefreshViews.bind(@), 10 * 1000)
@@ -71,7 +74,7 @@ module.exports = class LadderView extends RootView
       @showPlayModal(hash) if @sessions.loaded
 
   fetchSessionsAndRefreshViews: ->
-    return if @destroyed or application.userIsIdle or @$el.find('#simulate.active').length or (new Date() - 2000 < @lastRefreshTime) or @loading()
+    return if @destroyed or application.userIsIdle or @$el.find('#simulate.active').length or (new Date() - 2000 < @lastRefreshTime) or not @supermodel.finished()
     @sessions.fetch({"success": @refreshViews})
 
   refreshViews: =>
diff --git a/app/views/play/level/level_loading_view.coffee b/app/views/play/level/level_loading_view.coffee
index d0161f2ab..65fdb1bb5 100644
--- a/app/views/play/level/level_loading_view.coffee
+++ b/app/views/play/level/level_loading_view.coffee
@@ -23,7 +23,7 @@ module.exports = class LevelLoadingView extends View
     @updateProgressBar()
 
   updateProgressBar: ->
-    @$el.find('.progress-bar').css('width', (100 * @progress) + '%')
+    @$el?.find('.progress-bar').css('width', (100 * @progress) + '%')
 
   showReady: ->
     ready = $.i18n.t('play_level.loading_ready', defaultValue: 'Ready!')

From 8e19d8b71f1f9897d3fc53f5ee82a8fd1a75b9bb Mon Sep 17 00:00:00 2001
From: Ting-Kuan <gintau2000@gmail.com>
Date: Sun, 13 Apr 2014 13:29:43 -0400
Subject: [PATCH 3/6] Change some resource loading logic to fit new SuperModel.

---
 app/lib/NameLoader.coffee               | 12 ++++++++---
 app/models/Level.coffee                 |  4 +++-
 app/models/SuperModel.coffee            | 27 +++++++++++++------------
 app/views/editor/components/main.coffee | 19 +++++++----------
 app/views/editor/level/edit.coffee      |  9 +++------
 app/views/editor/patches_view.coffee    | 17 +++++++---------
 app/views/editor/thang/edit.coffee      | 21 +++----------------
 app/views/kinds/CocoView.coffee         |  5 +++--
 8 files changed, 49 insertions(+), 65 deletions(-)

diff --git a/app/lib/NameLoader.coffee b/app/lib/NameLoader.coffee
index 0dd798d80..477765fd4 100644
--- a/app/lib/NameLoader.coffee
+++ b/app/lib/NameLoader.coffee
@@ -6,9 +6,15 @@ class NameLoader extends CocoClass
   loadNames: (ids) ->
     toLoad = (id for id in ids when not namesCache[id])
     return false unless toLoad.length
-    jqxhr = $.ajax('/db/user/x/names', {type:'POST', data:{ids:toLoad}})
-    jqxhr.done @loadedNames
-      
+    jqxhrOptions = {
+    	url: '/db/user/x/names', 
+    	type:'POST', 
+    	data:{ids:toLoad}, 
+    	success: @loadedNames
+    }
+
+    return jqxhrOptions
+
   loadedNames: (newNames) =>
     _.extend namesCache, newNames
     
diff --git a/app/models/Level.coffee b/app/models/Level.coffee
index 7832c329a..d54b9d468 100644
--- a/app/models/Level.coffee
+++ b/app/models/Level.coffee
@@ -6,7 +6,7 @@ ThangType = require './ThangType'
 module.exports = class Level extends CocoModel
   @className: "Level"
   urlRoot: "/db/level"
-
+  
   serialize: (supermodel) ->
     o = _.cloneDeep @attributes  # slow in level editor when there are hundreds of Thangs
 
@@ -29,6 +29,8 @@ module.exports = class Level extends CocoModel
     visit = (system) ->
       return if system.original of originalsSeen
       systemModel = _.find systemModels, {original: system.original}
+      console.debug 'gintau', 'Level-systemModel', systemModel
+
       console.error "Couldn't find model for original", system.original, "from", systemModels unless systemModel
       for d in systemModel.dependencies or []
         system2 = _.find levelSystems, {original: d.original}
diff --git a/app/models/SuperModel.coffee b/app/models/SuperModel.coffee
index a319513fd..44661b2aa 100644
--- a/app/models/SuperModel.coffee
+++ b/app/models/SuperModel.coffee
@@ -21,15 +21,12 @@ module.exports = class SuperModel extends Backbone.Model
 
     resName = url unless resName
     modelRes = @addModelResource(model, url)
-<<<<<<< HEAD
+
     schema = model.schema()
-    schemaRes = @addModelResource(schema, schema.urlRoot)
     @schemas[schema.urlRoot] = schema
-    modelRes.addDependency(schemaRes)
-=======
->>>>>>> feature/loading-views
 
     modelRes.load()
+    return modelRes
 
   # replace or overwrite
   shouldLoadReference: (model) -> true
@@ -46,9 +43,10 @@ module.exports = class SuperModel extends Backbone.Model
     @removeEventsFromModel(model)
 
   removeEventsFromModel: (model) ->
+    # "Request" resource may have no off()
     # "Something" resource may have no model.
-    model?.off 'sync', @modelLoaded, @
-    model?.off 'error', @modelErrored, @
+    model?.off? 'sync', @modelLoaded, @
+    model?.off? 'error', @modelErrored, @
 
   getModel: (ModelClass_or_url, id) ->
     return @getModelByURL(ModelClass_or_url) if _.isString(ModelClass_or_url)
@@ -135,7 +133,6 @@ module.exports = class SuperModel extends Backbone.Model
       res.load()
 
   onResourceLoaded: (r) ->
-    console.debug 'gintau', 'supermodel-onResourceLoaded', r
     @modelLoaded(r.model)
     # Check if the model has references
     if r.constructor.name is 'ModelResource'
@@ -170,7 +167,6 @@ module.exports = class SuperModel extends Backbone.Model
     @num += r.value
     @progress = @num / @denom
 
-    console.debug 'gintau', 'superModel-updateProgress', @progress
     @trigger('superModel:updateProgress', @progress)
     @trigger('loaded-all') if @finished()
 
@@ -274,17 +270,22 @@ class RequestResource extends Resource
   loadDependencies: ->
     promises = []
 
-    for dep in @dependecies
+    for dep in @dependencies
       continue if not dep.isReadyForLoad()
       promises.push(dep.load())
 
     return promises
 
-  onLoadDependenciesSuccess: ->
+  onLoadDependenciesSuccess: =>
     @model = $.ajax(@jqxhrOptions)
-    @model.done(=> @markLoaded()).failed((jqXHR, textStatus, errorThrown) => @markFailed(errorThrown))
+    @model.done(
+      => @markLoaded()
+    ).fail(
+      (jqXHR, textStatus, errorThrown) => 
+        @markFailed(errorThrown)
+    )
 
-  onLoadDependenciesFailed: ->
+  onLoadDependenciesFailed: =>
     @markFailed('Failed to load dependencies.')
 
 
diff --git a/app/views/editor/components/main.coffee b/app/views/editor/components/main.coffee
index 0104aa5d9..b415405a1 100644
--- a/app/views/editor/components/main.coffee
+++ b/app/views/editor/components/main.coffee
@@ -18,31 +18,26 @@ module.exports = class ThangComponentEditView extends CocoView
     @level = options.level
     @callback = options.callback
 
-  render: =>
-    return if @destroyed
-    if not @componentCollection
-      @componentCollection = @supermodel.getCollection new ComponentsCollection()
-    unless @componentCollection.loaded
-      @listenToOnce(@componentCollection, 'sync', @onComponentsSync)
-      @componentCollection.fetch()
-    super() # do afterRender at the end
+    @componentCollection = @supermodel.getCollection new ComponentsCollection()
+    @componentCollectionRes = @supermodel.addModelResource(@componentCollection, 'component_collection')
+    @listenToOnce(@componentCollectionRes, 'resource:loaded', @onComponentsSync)
+    @componentCollectionRes.load()
 
   afterRender: ->
     super()
-    return @showLoading() unless @componentCollection?.loaded
-    @hideLoading()
     @buildExtantComponentTreema()
     @buildAddComponentTreema()
 
-  onComponentsSync: ->
+  onComponentsSync: (res) ->
     return if @destroyed
     @supermodel.addCollection @componentCollection
     @render()
 
   buildExtantComponentTreema: ->
+    level = new Level()
     treemaOptions =
       supermodel: @supermodel
-      schema: Level.schema.properties.thangs.items.properties.components
+      schema: level.schema().properties.thangs.items.properties.components
       data: _.cloneDeep @components
       callbacks: {select: @onSelectExtantComponent, change:@onChangeExtantComponents}
       noSortable: true
diff --git a/app/views/editor/level/edit.coffee b/app/views/editor/level/edit.coffee
index a08cfde80..6dd860cd6 100644
--- a/app/views/editor/level/edit.coffee
+++ b/app/views/editor/level/edit.coffee
@@ -20,7 +20,6 @@ ErrorView = require '../../error_view'
 module.exports = class EditorLevelView extends View
   id: "editor-level-view"
   template: template
-  startsLoading: true
   cache: false
 
   events:
@@ -48,13 +47,13 @@ module.exports = class EditorLevelView extends View
 
     @level = new Level _id: @levelID
     @listenToOnce(@level, 'sync', @onLevelLoaded)
-
     @listenToOnce(@supermodel, 'error',
       () =>
         @hideLoading()
         @insertSubView(new ErrorView())
     )
-    @supermodel.populateModel(@level, 'level')
+
+    @levelRes = @supermodel.populateModel(@level, 'level')
 
   showLoading: ($el) ->
     $el ?= @$el.find('.tab-content')
@@ -67,8 +66,7 @@ module.exports = class EditorLevelView extends View
   onAllLoaded: ->
     @level.unset('nextLevel') if _.isString(@level.get('nextLevel'))
     @initWorld()
-    @startsLoading = false
-    @render()  # do it again but without the loading screen
+    # @render()  # do it again but without the loading screen
 
   initWorld: ->
     @world = new World @level.name
@@ -81,7 +79,6 @@ module.exports = class EditorLevelView extends View
     context
 
   afterRender: ->
-    return if @startsLoading
     super()
     new LevelSystem  # temp; trigger the LevelSystem schema to be loaded, if it isn't already
     @$el.find('a[data-toggle="tab"]').on 'shown.bs.tab', (e) =>
diff --git a/app/views/editor/patches_view.coffee b/app/views/editor/patches_view.coffee
index f8dd4fa15..721043ca4 100644
--- a/app/views/editor/patches_view.coffee
+++ b/app/views/editor/patches_view.coffee
@@ -20,19 +20,16 @@ module.exports = class PatchesView extends CocoView
   initPatches: ->
     @startedLoading = false
     @patches = new PatchesCollection([], {}, @model, @status)
-    @listenToOnce @patches, 'sync', @gotPatches
-    @addResourceToLoad @patches, 'patches'
-    
-  gotPatches: ->
+    @patchesRes = @supermodel.addModelResource(@patches, 'patches')
+
     ids = (p.get('creator') for p in @patches.models)
-    jqxhr = nameLoader.loadNames ids
-    if jqxhr then @addRequestToLoad(jqxhr, 'user_names', 'gotPatches') else @render()
+    jqxhrOptions = nameLoader.loadNames ids
+    @nameLoaderRes = @supermodel.addRequestResource('name_loader', jqxhrOptions)
+    @nameLoaderRes.addDependency(@patchesRes)
     
   load: ->
-    return if @startedLoading
-    @patches.fetch()
-    @startedLoading = true
-    
+    @nameLoaderRes.load()
+
   getRenderData: ->
     c = super()
     patch.userName = nameLoader.getName(patch.get('creator')) for patch in @patches.models
diff --git a/app/views/editor/thang/edit.coffee b/app/views/editor/thang/edit.coffee
index fe70fb72b..60568a524 100644
--- a/app/views/editor/thang/edit.coffee
+++ b/app/views/editor/thang/edit.coffee
@@ -61,27 +61,13 @@ module.exports = class ThangTypeEditView extends View
     )
 
     thangRes = @supermodel.addModelResource(@thangType, 'thang_type')
-<<<<<<< HEAD
-    thangSchemaRes = @supermodel.addModelResource(@thangType.schema(), 'thang_type_schema')
-    thangRes.addDependency(thangSchemaRes)
-
+    @files = new DocumentFiles(@thangType)
+    thangDocRes = @supermodel.addModelResource(@files, 'thang_document')
+    thangRes.addDependency(thangDocRes)
     thangRes.load()
-=======
-    thangRes.load()
-
->>>>>>> feature/loading-views
-    @listenToOnce(@thangType.schema(), 'sync', @onThangTypeSync)
-    @listenToOnce(@thangType, 'sync', @onThangTypeSync)
 
     @refreshAnimation = _.debounce @refreshAnimation, 500
 
-  onThangTypeSync: ->
-    return unless @thangType.loaded
-    @startsLoading = false
-    @files = new DocumentFiles(@thangType)
-    @supermodel.addModelResource(@files, 'thang_document').load()
-    @render()
-
   getRenderData: (context={}) ->
     context = super(context)
     context.thangType = @thangType
@@ -97,7 +83,6 @@ module.exports = class ThangTypeEditView extends View
 
   afterRender: ->
     super()
-    return unless @thangType.loaded
     @initStage()
     @buildTreema()
     @initSliders()
diff --git a/app/views/kinds/CocoView.coffee b/app/views/kinds/CocoView.coffee
index fcf1753e1..aa5858b24 100644
--- a/app/views/kinds/CocoView.coffee
+++ b/app/views/kinds/CocoView.coffee
@@ -119,8 +119,8 @@ module.exports = class CocoView extends Backbone.View
     @$el?.find('.loading-screen .progress-bar').css('width', prog)
 
   onLoaded: ->
-    console.debug 'gintau', 'CocoView-onLoaded()'
-    @render()
+    console.debug 'gintau', 'CocoView-onLoaded()', @
+    @render?()
 
   # Error handling for loading
   onResourceLoadFailed: (source) ->
@@ -133,6 +133,7 @@ module.exports = class CocoView extends Backbone.View
   
   onRetryResource: (e) ->
     res = @supermodel.getResource($(e.target).data('resource-index'))
+    console.debug 'gintau', 'retry-resource', res
     res.load()
     $(e.target).closest('.loading-error-alert').remove()
 

From e58a5ee4b5b242a7f5662d2230d197436c02c5db Mon Sep 17 00:00:00 2001
From: Ting-Kuan <gintau2000@gmail.com>
Date: Tue, 15 Apr 2014 13:31:52 -0400
Subject: [PATCH 4/6] add debug msg.

---
 app/models/Level.coffee | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/app/models/Level.coffee b/app/models/Level.coffee
index d54b9d468..1c1dc34a8 100644
--- a/app/models/Level.coffee
+++ b/app/models/Level.coffee
@@ -29,7 +29,7 @@ module.exports = class Level extends CocoModel
     visit = (system) ->
       return if system.original of originalsSeen
       systemModel = _.find systemModels, {original: system.original}
-      console.debug 'gintau', 'Level-systemModel', systemModel
+      console.debug 'gintau', 'Level-systemModel', system, systemModel, systemModels
 
       console.error "Couldn't find model for original", system.original, "from", systemModels unless systemModel
       for d in systemModel.dependencies or []

From 52a73ceae349a62fe59101ead5b64a1d5ce80d34 Mon Sep 17 00:00:00 2001
From: Ting-Kuan <gintau2000@gmail.com>
Date: Wed, 16 Apr 2014 02:28:59 -0400
Subject: [PATCH 5/6] Migrate view to fit new supermodel.

---
 app/models/SuperModel.coffee                  | 21 ++++++-----
 app/views/editor/components/main.coffee       |  3 +-
 app/views/editor/level/add_thangs_view.coffee | 10 ++----
 .../editor/level/components_tab_view.coffee   |  1 +
 app/views/editor/level/edit.coffee            | 35 +++++++++----------
 .../editor/level/scripts_tab_view.coffee      |  3 +-
 .../editor/level/settings_tab_view.coffee     |  1 +
 .../editor/level/systems_tab_view.coffee      | 16 ++++-----
 app/views/editor/level/thang/edit.coffee      |  1 +
 app/views/editor/level/thangs_tab_view.coffee | 29 ++++++++-------
 app/views/kinds/CocoView.coffee               |  2 +-
 11 files changed, 65 insertions(+), 57 deletions(-)

diff --git a/app/models/SuperModel.coffee b/app/models/SuperModel.coffee
index 44661b2aa..56d505b1f 100644
--- a/app/models/SuperModel.coffee
+++ b/app/models/SuperModel.coffee
@@ -15,12 +15,11 @@ module.exports = class SuperModel extends Backbone.Model
     @mustPopulate = model
     model.saveBackups = @shouldSaveBackups(model)
 
-    url = model.url()
-    @models[url] = model unless @models[url]?
+    @addModel(model)
     @modelLoaded(model) if model.loaded
 
-    resName = url unless resName
-    modelRes = @addModelResource(model, url)
+    resName = model.url unless resName
+    modelRes = @addModelResource(model, model.url)
 
     schema = model.schema()
     @schemas[schema.urlRoot] = schema
@@ -68,9 +67,7 @@ module.exports = class SuperModel extends Backbone.Model
     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]?
+    url = model.url
     @models[url] = model
 
   getCollection: (collection) ->
@@ -97,9 +94,9 @@ module.exports = class SuperModel extends Backbone.Model
   finished: ->
     return @progress is 1.0 or Object.keys(@resources).length is 0
 
-
   addModelResource: (modelOrCollection, name, fetchOptions, value=1) ->
     @checkName(name)
+    @addModel(modelOrCollection)
     res = new ModelResource(modelOrCollection, name, fetchOptions, value)
     @storeResource(res, value)
     return res
@@ -167,6 +164,7 @@ module.exports = class SuperModel extends Backbone.Model
     @num += r.value
     @progress = @num / @denom
 
+    console.debug 'gintau', 'super-progress' , @progress, @num, @denom
     @trigger('superModel:updateProgress', @progress)
     @trigger('loaded-all') if @finished()
 
@@ -219,7 +217,7 @@ class ModelResource extends Resource
     @loadDeferred = $.Deferred()
     $.when.apply($, @loadDependencies())
       .then(@onLoadDependenciesSuccess, @onLoadDependenciesFailed)
-      .always(()=> @isLoading = false)
+      .always(=> @isLoading = false)
 
     return @loadDeferred.promise()
 
@@ -235,6 +233,11 @@ class ModelResource extends Resource
   onLoadDependenciesSuccess: =>
     @model.fetch(@fetchOptions)
 
+    # Hack: some components seem cannot be downloaded, 
+    # so we need to complete fetching manually after a while if no error occurs.
+    if @model.constructor.className is 'ComponentsCollection'
+      setTimeout((=> @markLoaded() if @isLoading), 5000)
+
     @listenToOnce(@model, 'sync', ->
       @markLoaded()
       @loadDeferred.resolve(@)
diff --git a/app/views/editor/components/main.coffee b/app/views/editor/components/main.coffee
index b415405a1..96ccd4913 100644
--- a/app/views/editor/components/main.coffee
+++ b/app/views/editor/components/main.coffee
@@ -23,6 +23,7 @@ module.exports = class ThangComponentEditView extends CocoView
     @listenToOnce(@componentCollectionRes, 'resource:loaded', @onComponentsSync)
     @componentCollectionRes.load()
 
+  onLoaded: ->
   afterRender: ->
     super()
     @buildExtantComponentTreema()
@@ -31,7 +32,7 @@ module.exports = class ThangComponentEditView extends CocoView
   onComponentsSync: (res) ->
     return if @destroyed
     @supermodel.addCollection @componentCollection
-    @render()
+    @hideLoading()
 
   buildExtantComponentTreema: ->
     level = new Level()
diff --git a/app/views/editor/level/add_thangs_view.coffee b/app/views/editor/level/add_thangs_view.coffee
index 35e8917c9..9c64a9ab5 100644
--- a/app/views/editor/level/add_thangs_view.coffee
+++ b/app/views/editor/level/add_thangs_view.coffee
@@ -22,13 +22,10 @@ module.exports = class AddThangsView extends View
   constructor: (options) ->
     super options
     @world = options.world
+    
     @thangTypes = @supermodel.getCollection new ThangTypeSearchCollection()  # should load depended-on Components, too
-    @listenToOnce(@thangTypes, 'sync', @onThangTypesLoaded)
-    @thangTypes.fetch()
-
-  onThangTypesLoaded: ->
-    return if @destroyed
-    @render()  # do it again but without the loading screen
+    @thangTypesRes = @supermodel.addModelResource(@thangTypes, 'add_thang_type_search_collection')
+    @thangTypesRes.load()
 
   getRenderData: (context={}) ->
     context = super(context)
@@ -59,7 +56,6 @@ module.exports = class AddThangsView extends View
     context
 
   afterRender: ->
-    return if @startsLoading
     super()
 
   runSearch: (e) =>
diff --git a/app/views/editor/level/components_tab_view.coffee b/app/views/editor/level/components_tab_view.coffee
index 823bebed1..0b632476e 100644
--- a/app/views/editor/level/components_tab_view.coffee
+++ b/app/views/editor/level/components_tab_view.coffee
@@ -22,6 +22,7 @@ module.exports = class ComponentsTabView extends View
   events:
     'click #create-new-component-button': 'createNewLevelComponent'
 
+  onLoaded: ->
   onLevelThangsChanged: (e) ->
     thangsData = e.thangsData
     presentComponents = {}
diff --git a/app/views/editor/level/edit.coffee b/app/views/editor/level/edit.coffee
index 6dd860cd6..ee6260cbc 100644
--- a/app/views/editor/level/edit.coffee
+++ b/app/views/editor/level/edit.coffee
@@ -27,7 +27,7 @@ module.exports = class EditorLevelView extends View
     'click #commit-level-start-button': 'startCommittingLevel'
     'click #fork-level-start-button': 'startForkingLevel'
     'click #history-button': 'showVersionHistory'
-    'click #patches-tab': -> @patchesView.load()
+    'click #patches-tab': -> @patchesView?.load()
     'click #commit-level-patch-button': 'startPatchingLevel'
 
   constructor: (options, @levelID) ->
@@ -45,32 +45,30 @@ module.exports = class EditorLevelView extends View
     @supermodel.shouldSaveBackups = (model) ->
       model.constructor.className in ['Level', 'LevelComponent', 'LevelSystem']
 
+    @worldRes = @supermodel.addSomethingResource('world')
+
     @level = new Level _id: @levelID
-    @listenToOnce(@level, 'sync', @onLevelLoaded)
-    @listenToOnce(@supermodel, 'error',
-      () =>
+    #@listenToOnce(@level, 'sync', @onLevelLoaded)
+    @listenToOnce(@supermodel, 'error', =>
         @hideLoading()
         @insertSubView(new ErrorView())
     )
 
-    @levelRes = @supermodel.populateModel(@level, 'level')
+    @levelRes = @supermodel.addModelResource(@level, 'level')
+    @listenToOnce(@levelRes, 'resource:loaded', ->
+      console.debug 'gintau', 'init-world'
+      @world = new World @level.name
+      @worldRes.markLoaded()
+    )
+    @levelRes.load()
+
+    @files = new DocumentFiles(@level)
+    @supermodel.addModelResource(@files, 'level_document').load()   
 
   showLoading: ($el) ->
     $el ?= @$el.find('.tab-content')
     super($el)
 
-  onLevelLoaded: ->
-    @files = new DocumentFiles(@level)
-    @supermodel.addModelResource(@files, 'level_document').load()
-
-  onAllLoaded: ->
-    @level.unset('nextLevel') if _.isString(@level.get('nextLevel'))
-    @initWorld()
-    # @render()  # do it again but without the loading screen
-
-  initWorld: ->
-    @world = new World @level.name
-
   getRenderData: (context={}) ->
     context = super(context)
     context.level = @level
@@ -80,7 +78,8 @@ module.exports = class EditorLevelView extends View
 
   afterRender: ->
     super()
-    new LevelSystem  # temp; trigger the LevelSystem schema to be loaded, if it isn't already
+    return unless @world and @level
+    console.debug 'gintau', 'edit-afterRender'
     @$el.find('a[data-toggle="tab"]').on 'shown.bs.tab', (e) =>
       Backbone.Mediator.publish 'level:view-switched', e
     @thangsTab = @insertSubView new ThangsTabView world: @world, supermodel: @supermodel
diff --git a/app/views/editor/level/scripts_tab_view.coffee b/app/views/editor/level/scripts_tab_view.coffee
index 03855662d..4c8f18912 100644
--- a/app/views/editor/level/scripts_tab_view.coffee
+++ b/app/views/editor/level/scripts_tab_view.coffee
@@ -16,7 +16,8 @@ module.exports = class ScriptsTabView extends View
     super options
     @world = options.world
     @files = options.files
-
+  
+  onLoaded: ->
   onLevelLoaded: (e) ->
     @level = e.level
     @dimensions = @level.dimensions()
diff --git a/app/views/editor/level/settings_tab_view.coffee b/app/views/editor/level/settings_tab_view.coffee
index 6f6822885..3b47024c3 100644
--- a/app/views/editor/level/settings_tab_view.coffee
+++ b/app/views/editor/level/settings_tab_view.coffee
@@ -22,6 +22,7 @@ module.exports = class SettingsTabView extends View
     super options
     @world = options.world
 
+  onLoaded: ->
   onLevelLoaded: (e) ->
     @level = e.level
     data = _.pick @level.attributes, (value, key) => key in @editableSettings
diff --git a/app/views/editor/level/systems_tab_view.coffee b/app/views/editor/level/systems_tab_view.coffee
index eb4747b0e..b7fa9482d 100644
--- a/app/views/editor/level/systems_tab_view.coffee
+++ b/app/views/editor/level/systems_tab_view.coffee
@@ -31,15 +31,17 @@ module.exports = class SystemsTabView extends View
       url = "/db/level.system/#{system.original}/version/#{system.majorVersion}"
       ls = new LevelSystem()
       ls.saveBackups = true
+      lsRes = @supermodel.addModelResource(ls, 'level_system_' + system.original);
       do (url) -> ls.url = -> url
       continue if @supermodel.getModelByURL ls.url
-      ls.fetch()
-      @listenToOnce ls, 'sync', @onSystemLoaded
+      lsRes.load()
+      @listenToOnce(lsRes, 'resource:loaded', @onSystemLoaded)
       ++@toLoad
     @onDefaultSystemsLoaded() unless @toLoad
 
-  onSystemLoaded: (ls) ->
-    @supermodel.addModel ls
+  onSystemLoaded: (lsRes) ->
+    ls = lsRes.model
+    @supermodel.addModel(ls)
     --@toLoad
     @onDefaultSystemsLoaded() unless @toLoad
 
@@ -48,9 +50,9 @@ module.exports = class SystemsTabView extends View
     @render()  # do it again but without the loading screen
     @onLevelLoaded level: @level if @level
 
+  onLoaded: ->
   onLevelLoaded: (e) ->
     @level = e.level
-    return if @startsLoading
     @buildSystemsTreema()
 
   buildSystemsTreema: ->
@@ -145,9 +147,7 @@ class LevelSystemNode extends TreemaObjectNode
   grabDBComponent: ->
     unless _.isString @data.original
       return alert('Press the "Add System" button at the bottom instead of the "+". Sorry.')
-    @system = @settings.supermodel.getModelByOriginalAndMajorVersion LevelSystem, @data.original, @data.majorVersion
-    #@system = _.find @settings.supermodel.getModels(LevelSystem), (m) =>
-    #  m.get('original') is @data.original and m.get('version').major is @data.majorVersion
+    @system = @settings.supermodel.getModelByOriginalAndMajorVersion(LevelSystem, @data.original, @data.majorVersion)
     console.error "Couldn't find system for", @data.original, @data.majorVersion, "from models", @settings.supermodel.models unless @system
 
   getChildSchema: (key) ->
diff --git a/app/views/editor/level/thang/edit.coffee b/app/views/editor/level/thang/edit.coffee
index 2a92fd0b1..a361a7ea0 100644
--- a/app/views/editor/level/thang/edit.coffee
+++ b/app/views/editor/level/thang/edit.coffee
@@ -50,6 +50,7 @@ module.exports = class LevelThangEditView extends View
     input.val(thangTypeName)
     @$el.find('#thang-type-link span').text(thangTypeName)
     window.input = input
+    @hideLoading()
 
   saveThang: (e) ->
     # Make sure it validates first?
diff --git a/app/views/editor/level/thangs_tab_view.coffee b/app/views/editor/level/thangs_tab_view.coffee
index 2a8536f9f..47329678f 100644
--- a/app/views/editor/level/thangs_tab_view.coffee
+++ b/app/views/editor/level/thangs_tab_view.coffee
@@ -60,31 +60,34 @@ module.exports = class ThangsTabView extends View
   constructor: (options) ->
     super options
     @world = options.world
+
     @thangTypes = @supermodel.getCollection new ThangTypeSearchCollection()  # should load depended-on Components, too
-    @listenToOnce(@thangTypes, 'sync', @onThangTypesLoaded)
-    @thangTypes.fetch()
+    @thangTypesRes = @supermodel.addModelResource(@thangTypes, 'thang_type_search_collection')
+    @listenToOnce(@thangTypesRes, 'resource:loaded', @onThangTypesLoaded)
+    @thangTypesRes.load()
+    
     $(document).bind 'contextmenu', @preventDefaultContextMenu
 
     # just loading all Components for now: https://github.com/codecombat/codecombat/issues/405
+
     @componentCollection = @supermodel.getCollection new ComponentsCollection()
-    @listenToOnce(@componentCollection, 'sync', @onComponentsLoaded)
-    @componentCollection.fetch()
+    @componentCollectionRes = @supermodel.addModelResource(@componentCollection, 'components_collection')
+    @listenToOnce(@componentCollectionRes, 'resource:loaded', @onComponentsLoaded)
+    @componentCollectionRes.load()
 
   onThangTypesLoaded: ->
     return if @destroyed
     @supermodel.addCollection @thangTypes
     for model in @thangTypes.models
       @supermodel.populateModel(model, model.name)
-    @startsLoading = not @componentCollection.loaded
-    @render()  # do it again but without the loading screen
-    @onLevelLoaded level: @level if @level and not @startsLoading
+    # @render()  # do it again but without the loading screen
+    # @onLevelLoaded level: @level if @level and not @startsLoading
 
   onComponentsLoaded: ->
     return if @destroyed
     @supermodel.addCollection @componentCollection
-    @startsLoading = not @thangTypes.loaded
-    @render()  # do it again but without the loading screen
-    @onLevelLoaded level: @level if @level and not @startsLoading
+    # @render()  # do it again but without the loading screen
+    # @onLevelLoaded level: @level if @level and not @startsLoading
 
   getRenderData: (context={}) ->
     context = super(context)
@@ -115,8 +118,8 @@ module.exports = class ThangsTabView extends View
     oldHeight = $('#thangs-list').height()
     $('#thangs-list').height(oldHeight - thangsHeaderHeight - 80)
 
+  onLoaded: ->
   afterRender: ->
-    return if @startsLoading
     super()
     $('.tab-content').click @selectAddThang
     $('#thangs-list').bind 'mousewheel', @preventBodyScrollingInThangList
@@ -137,8 +140,9 @@ module.exports = class ThangsTabView extends View
     e.preventDefault()
 
   onLevelLoaded: (e) ->
+    console.debug 'gintau', 'thangs-tab-view', 'onLevelLoaded'
     @level = e.level
-    return if @startsLoading
+
     data = $.extend(true, {}, @level.attributes)
     treemaOptions =
       schema: Level.schema.properties.thangs
@@ -153,6 +157,7 @@ module.exports = class ThangsTabView extends View
         thang: ThangNode
         array: ThangsNode
       world: @world
+
     @thangsTreema = @$el.find('#thangs-treema').treema treemaOptions
     @thangsTreema.build()
     @thangsTreema.open()
diff --git a/app/views/kinds/CocoView.coffee b/app/views/kinds/CocoView.coffee
index aa5858b24..3186e31a6 100644
--- a/app/views/kinds/CocoView.coffee
+++ b/app/views/kinds/CocoView.coffee
@@ -84,6 +84,7 @@ module.exports = class CocoView extends Backbone.View
   render: ->
     return @ unless me
     super()
+    console.debug 'gintau', 'CocoView-Render', @
     return @template if _.isString(@template)
     @$el.html @template(@getRenderData())
 
@@ -133,7 +134,6 @@ module.exports = class CocoView extends Backbone.View
   
   onRetryResource: (e) ->
     res = @supermodel.getResource($(e.target).data('resource-index'))
-    console.debug 'gintau', 'retry-resource', res
     res.load()
     $(e.target).closest('.loading-error-alert').remove()
 

From c53eb562a3b9e6e247255dcd4f72835160b95a31 Mon Sep 17 00:00:00 2001
From: Ting-Kuan <gintau2000@gmail.com>
Date: Wed, 16 Apr 2014 02:31:18 -0400
Subject: [PATCH 6/6] Remove debug msg.

---
 app/models/Level.coffee                       | 1 -
 app/models/SuperModel.coffee                  | 6 ------
 app/views/editor/components/main.coffee       | 1 -
 app/views/editor/level/edit.coffee            | 1 -
 app/views/editor/level/thangs_tab_view.coffee | 1 -
 app/views/kinds/CocoView.coffee               | 2 --
 app/views/play/ladder_view.coffee             | 1 -
 7 files changed, 13 deletions(-)

diff --git a/app/models/Level.coffee b/app/models/Level.coffee
index 1c1dc34a8..ed5c86091 100644
--- a/app/models/Level.coffee
+++ b/app/models/Level.coffee
@@ -29,7 +29,6 @@ module.exports = class Level extends CocoModel
     visit = (system) ->
       return if system.original of originalsSeen
       systemModel = _.find systemModels, {original: system.original}
-      console.debug 'gintau', 'Level-systemModel', system, systemModel, systemModels
 
       console.error "Couldn't find model for original", system.original, "from", systemModels unless systemModel
       for d in systemModel.dependencies or []
diff --git a/app/models/SuperModel.coffee b/app/models/SuperModel.coffee
index 56d505b1f..3898a7394 100644
--- a/app/models/SuperModel.coffee
+++ b/app/models/SuperModel.coffee
@@ -164,7 +164,6 @@ module.exports = class SuperModel extends Backbone.Model
     @num += r.value
     @progress = @num / @denom
 
-    console.debug 'gintau', 'super-progress' , @progress, @num, @denom
     @trigger('superModel:updateProgress', @progress)
     @trigger('loaded-all') if @finished()
 
@@ -233,11 +232,6 @@ class ModelResource extends Resource
   onLoadDependenciesSuccess: =>
     @model.fetch(@fetchOptions)
 
-    # Hack: some components seem cannot be downloaded, 
-    # so we need to complete fetching manually after a while if no error occurs.
-    if @model.constructor.className is 'ComponentsCollection'
-      setTimeout((=> @markLoaded() if @isLoading), 5000)
-
     @listenToOnce(@model, 'sync', ->
       @markLoaded()
       @loadDeferred.resolve(@)
diff --git a/app/views/editor/components/main.coffee b/app/views/editor/components/main.coffee
index 96ccd4913..0f7ad7414 100644
--- a/app/views/editor/components/main.coffee
+++ b/app/views/editor/components/main.coffee
@@ -32,7 +32,6 @@ module.exports = class ThangComponentEditView extends CocoView
   onComponentsSync: (res) ->
     return if @destroyed
     @supermodel.addCollection @componentCollection
-    @hideLoading()
 
   buildExtantComponentTreema: ->
     level = new Level()
diff --git a/app/views/editor/level/edit.coffee b/app/views/editor/level/edit.coffee
index ee6260cbc..ee7f8ba77 100644
--- a/app/views/editor/level/edit.coffee
+++ b/app/views/editor/level/edit.coffee
@@ -56,7 +56,6 @@ module.exports = class EditorLevelView extends View
 
     @levelRes = @supermodel.addModelResource(@level, 'level')
     @listenToOnce(@levelRes, 'resource:loaded', ->
-      console.debug 'gintau', 'init-world'
       @world = new World @level.name
       @worldRes.markLoaded()
     )
diff --git a/app/views/editor/level/thangs_tab_view.coffee b/app/views/editor/level/thangs_tab_view.coffee
index 47329678f..653dd3953 100644
--- a/app/views/editor/level/thangs_tab_view.coffee
+++ b/app/views/editor/level/thangs_tab_view.coffee
@@ -140,7 +140,6 @@ module.exports = class ThangsTabView extends View
     e.preventDefault()
 
   onLevelLoaded: (e) ->
-    console.debug 'gintau', 'thangs-tab-view', 'onLevelLoaded'
     @level = e.level
 
     data = $.extend(true, {}, @level.attributes)
diff --git a/app/views/kinds/CocoView.coffee b/app/views/kinds/CocoView.coffee
index 3186e31a6..8c3cd025a 100644
--- a/app/views/kinds/CocoView.coffee
+++ b/app/views/kinds/CocoView.coffee
@@ -84,7 +84,6 @@ module.exports = class CocoView extends Backbone.View
   render: ->
     return @ unless me
     super()
-    console.debug 'gintau', 'CocoView-Render', @
     return @template if _.isString(@template)
     @$el.html @template(@getRenderData())
 
@@ -120,7 +119,6 @@ module.exports = class CocoView extends Backbone.View
     @$el?.find('.loading-screen .progress-bar').css('width', prog)
 
   onLoaded: ->
-    console.debug 'gintau', 'CocoView-onLoaded()', @
     @render?()
 
   # Error handling for loading
diff --git a/app/views/play/ladder_view.coffee b/app/views/play/ladder_view.coffee
index b5b31f775..73cc351de 100644
--- a/app/views/play/ladder_view.coffee
+++ b/app/views/play/ladder_view.coffee
@@ -64,7 +64,6 @@ module.exports = class LadderView extends RootView
 
   afterRender: ->
     super()
-    console.debug 'gintau', 'ladder_view_finished', @supermodel.finished()
     return unless @supermodel.finished()
     @insertSubView(@ladderTab = new LadderTabView({}, @level, @sessions))
     @insertSubView(@myMatchesTab = new MyMatchesTabView({}, @level, @sessions))