diff --git a/app/lib/surface/MusicPlayer.coffee b/app/lib/surface/MusicPlayer.coffee index a3e1f0cb3..bf07dbf3c 100644 --- a/app/lib/surface/MusicPlayer.coffee +++ b/app/lib/surface/MusicPlayer.coffee @@ -25,6 +25,7 @@ module.exports = class MusicPlayer extends CocoClass @onPlayMusic(@standingBy) if @standingBy onPlayMusic: (e) -> + return if application.isIPadApp # Hard to measure, but just guessing this will save memory. src = e.file src = "/file#{e.file}#{AudioPlayer.ext}" if (not e.file) or src is @currentMusic?.src diff --git a/app/models/SuperModel.coffee b/app/models/SuperModel.coffee index 158f864f9..8da29ea70 100644 --- a/app/models/SuperModel.coffee +++ b/app/models/SuperModel.coffee @@ -181,6 +181,7 @@ module.exports = class SuperModel extends Backbone.Model @num += r.value _.defer @updateProgress r.clean() + @stopListening r, 'failed', @onResourceFailed @trigger 'resource-loaded', r onResourceFailed: (r) -> diff --git a/app/schemas/subscriptions/ipad.coffee b/app/schemas/subscriptions/ipad.coffee index c4013e52d..9c16a600c 100644 --- a/app/schemas/subscriptions/ipad.coffee +++ b/app/schemas/subscriptions/ipad.coffee @@ -2,10 +2,12 @@ c = require 'schemas/schemas' module.exports = 'ipad:products': c.object {required: ['products']}, - products: c.array {}, + products: c.array {}, c.object {}, price: { type: 'string' } id: { type: 'string' } - + 'ipad:iap-complete': c.object {}, productID: { type: 'string' } + + 'ipad:memory-warning': c.object {} diff --git a/app/views/play/WorldMapView.coffee b/app/views/play/WorldMapView.coffee index a5c263e2c..fc556515d 100644 --- a/app/views/play/WorldMapView.coffee +++ b/app/views/play/WorldMapView.coffee @@ -31,6 +31,8 @@ module.exports = class WorldMapView extends RootView 'click #volume-button': 'onToggleVolume' constructor: (options, @terrain) -> + if options and application.isIPAdApp # TODO: later only clear the SuperModel if it has received a memory warning (not in app store yet) + options.supermodel = null @terrain ?= 'dungeon' # or 'forest' super options @nextLevel = @getQueryVariable 'next' @@ -282,6 +284,7 @@ module.exports = class WorldMapView extends RootView storage.save("loaded-menu-music-#{@terrain}", true) unless @probablyCachedMusic preloadTopHeroes: -> + return # Don't do this because these two have feature images, so we don't need the raw vector data for them. Later they'll all have feature images... for heroID in ['captain', 'knight'] url = "/db/thang.type/#{ThangType.heroes[heroID]}/version" continue if @supermodel.getModel url diff --git a/app/views/play/level/ControlBarView.coffee b/app/views/play/level/ControlBarView.coffee index 354e46bd4..b718543a9 100644 --- a/app/views/play/level/ControlBarView.coffee +++ b/app/views/play/level/ControlBarView.coffee @@ -16,6 +16,7 @@ module.exports = class ControlBarView extends CocoView 'bus:player-states-changed': 'onPlayerStatesChanged' 'level:disable-controls': 'onDisableControls' 'level:enable-controls': 'onEnableControls' + 'ipad:memory-warning': 'onIPadMemoryWarning' events: 'click #next-game-button': -> Backbone.Mediator.publish 'level:next-game-pressed', {} @@ -56,7 +57,7 @@ module.exports = class ControlBarView extends CocoView if c.isMultiplayerLevel = @isMultiplayerLevel c.multiplayerStatus = @multiplayerStatusManager?.status c.spectateGame = @spectateGame - @homeViewArgs = [{supermodel: @supermodel}] + @homeViewArgs = [{supermodel: if @hasReceivedMemoryWarning then null else @supermodel}] if @level.get('type', true) in ['ladder', 'ladder-tutorial', 'hero-ladder'] levelID = @level.get('slug').replace /\-tutorial$/, '' @homeLink = c.homeLink = '/play/ladder/' + levelID @@ -105,6 +106,9 @@ module.exports = class ControlBarView extends CocoView for level in campaign.levels return campaign.id if level.id is slug + onIPadMemoryWarning: (e) -> + @hasReceivedMemoryWarning = true + destroy: -> @setupManager?.destroy() @multiplayerStatusManager?.destroy() diff --git a/app/views/play/level/PlayLevelView.coffee b/app/views/play/level/PlayLevelView.coffee index cd216a0fd..82ef103fa 100644 --- a/app/views/play/level/PlayLevelView.coffee +++ b/app/views/play/level/PlayLevelView.coffee @@ -77,6 +77,7 @@ module.exports = class PlayLevelView extends RootView 'real-time-multiplayer:joined-game': 'onRealTimeMultiplayerJoinedGame' 'real-time-multiplayer:left-game': 'onRealTimeMultiplayerLeftGame' 'real-time-multiplayer:manual-cast': 'onRealTimeMultiplayerCast' + 'ipad:memory-warning': 'onIPadMemoryWarning' events: 'click #level-done-button': 'onDonePressed' @@ -435,7 +436,7 @@ module.exports = class PlayLevelView extends RootView showVictory: -> @endHighlight() - options = {level: @level, supermodel: @supermodel, session: @session} + options = {level: @level, supermodel: @supermodel, session: @session, hasReceivedMemoryWarning: @hasReceivedMemoryWarning} ModalClass = if @level.get('type', true) in ['hero', 'hero-ladder', 'hero-coop'] then HeroVictoryModal else VictoryModal victoryModal = new ModalClass(options) @openModalView(victoryModal) @@ -459,7 +460,7 @@ module.exports = class PlayLevelView extends RootView Backbone.Mediator.publish 'router:navigate', { route: nextLevelURL, viewClass: PlayLevelView, - viewArgs: [{supermodel: @supermodel}, nextLevelID]} + viewArgs: [{supermodel: if @hasReceivedMemoryWarning then null else @supermodel}, nextLevelID]} getNextLevel: -> return null unless nextLevelOriginal = @level.get('nextLevel')?.original @@ -902,3 +903,6 @@ module.exports = class PlayLevelView extends RootView if sessionState? # TODO: Don't hardcode spellName Backbone.Mediator.publish 'level:select-sprite', thangID: sessionState.selected, spellName: 'plan' + + onIPadMemoryWarning: (e) -> + @hasReceivedMemoryWarning = true diff --git a/app/views/play/level/modal/HeroVictoryModal.coffee b/app/views/play/level/modal/HeroVictoryModal.coffee index 6e16c442e..dab851483 100644 --- a/app/views/play/level/modal/HeroVictoryModal.coffee +++ b/app/views/play/level/modal/HeroVictoryModal.coffee @@ -298,7 +298,7 @@ module.exports = class HeroVictoryModal extends ModalView skipPrompt ||= not (@skipAheadLevelLink or @morePractiveLevelLink) and me.getBranchingGroup() is 'choice-explicit' if skipPrompt # Preserve the supermodel as we navigate back to the world map. - Backbone.Mediator.publish 'router:navigate', route: nextLevelLink, viewClass: require('views/play/WorldMapView'), viewArgs: [{supermodel: @supermodel}, @getNextLevelCampaign()] + Backbone.Mediator.publish 'router:navigate', route: nextLevelLink, viewClass: require('views/play/WorldMapView'), viewArgs: [{supermodel: if @options.hasReceivedMemoryWarning then null else @supermodel}, @getNextLevelCampaign()] else # Hide everything except the buttons prompting them for which kind of next level to do @$el.find('.modal-footer, .modal-body > *').hide() @@ -309,10 +309,10 @@ module.exports = class HeroVictoryModal extends ModalView route = $(e.target).data('href') or "/play/#{@getNextLevelCampaign()}" application.tracker?.trackEvent 'Branch Selected', level: @level.get('slug'), label: @level.get('slug'), branch: $(e.target).data('branch-key'), branchingGroup: me.getBranchingGroup(), route: route # Preserve the supermodel as we navigate back to world map. - Backbone.Mediator.publish 'router:navigate', route: route, viewClass: require('views/play/WorldMapView'), viewArgs: [{supermodel: @supermodel}, @getNextLevelCampaign()] + Backbone.Mediator.publish 'router:navigate', route: route, viewClass: require('views/play/WorldMapView'), viewArgs: [{supermodel: if @options.hasReceivedMemoryWarning then null else @supermodel}, @getNextLevelCampaign()] onClickReturnToLadder: (e) -> e.preventDefault() route = $(e.target).data('href') # Preserve the supermodel as we navigate back to the ladder. - Backbone.Mediator.publish 'router:navigate', route: route, viewClass: require('views/play/ladder/LadderView'), viewArgs: [{supermodel: @supermodel}, @level.get('slug')] + Backbone.Mediator.publish 'router:navigate', route: route, viewClass: require('views/play/ladder/LadderView'), viewArgs: [{supermodel: if @options.hasReceivedMemoryWarning then null else @supermodel}, @level.get('slug')]