From 6c67f42eab8d76ade80e44dfb2c3387696d89b37 Mon Sep 17 00:00:00 2001 From: Nathan Sobo Date: Fri, 2 Oct 2015 11:28:50 -0600 Subject: [PATCH] Move state loading for Atom environment to an instance method --- spec/atom-spec.coffee | 26 ++++--- spec/spec-helper.coffee | 3 +- src/atom.coffee | 94 +++++++++--------------- src/initialize-application-window.coffee | 5 +- src/initialize-test-window.coffee | 7 +- 5 files changed, 59 insertions(+), 76 deletions(-) diff --git a/spec/atom-spec.coffee b/spec/atom-spec.coffee index b73095805..c138e83eb 100644 --- a/spec/atom-spec.coffee +++ b/spec/atom-spec.coffee @@ -145,29 +145,31 @@ describe "the `atom` global", -> expect(errors).toEqual [] describe "saving and loading", -> - afterEach -> atom.mode = "spec" - it "selects the state based on the current project paths", -> - Atom = atom.constructor + jasmine.unspy(atom, 'saveStateSync') + # jasmine.unspy(atom, 'loadStateSync') + [dir1, dir2] = [temp.mkdirSync("dir1-"), temp.mkdirSync("dir2-")] - loadSettings = _.extend Atom.getLoadSettings(), + loadSettings = _.extend atom.constructor.getLoadSettings(), initialPaths: [dir1] windowState: null - spyOn(Atom, 'getLoadSettings').andCallFake -> loadSettings - spyOn(Atom.getStorageFolder(), 'getPath').andReturn(temp.mkdirSync("storage-dir-")) + spyOn(atom, 'getLoadSettings').andCallFake -> loadSettings + spyOn(atom.getStorageFolder(), 'getPath').andReturn(temp.mkdirSync("storage-dir-")) atom.state.stuff = "cool" atom.project.setPaths([dir1, dir2]) - atom.saveSync.originalValue.call(atom) + atom.saveStateSync() - atom1 = Atom.loadOrCreate() - expect(atom1.state.stuff).toBeUndefined() + atom.state = {} + atom.loadStateSync() + expect(atom.state.stuff).toBeUndefined() loadSettings.initialPaths = [dir2, dir1] - atom2 = Atom.loadOrCreate() - expect(atom2.state.stuff).toBe("cool") + atom.state = {} + atom.loadStateSync() + expect(atom.state.stuff).toBe("cool") describe "openInitialEmptyEditorIfNecessary", -> describe "when there are no paths set", -> @@ -224,7 +226,7 @@ describe "the `atom` global", -> expect(atom.state.workspace).toEqual workspaceState expect(atom.state.grammars).toEqual grammarsState expect(atom.state.project).toEqual projectState - expect(atom.saveSync).toHaveBeenCalled() + expect(atom.saveStateSync).toHaveBeenCalled() describe "::removeEditorWindow()", -> it "unsubscribes from all buffers", -> diff --git a/spec/spec-helper.coffee b/spec/spec-helper.coffee index 36b4e2a40..ec06b9087 100644 --- a/spec/spec-helper.coffee +++ b/spec/spec-helper.coffee @@ -104,7 +104,7 @@ beforeEach -> serializedWindowState = null - spyOn(atom, 'saveSync') + spyOn(atom, 'saveStateSync') atom.grammars.clearGrammarOverrides() spy = spyOn(atom.packages, 'resolvePackagePath').andCallFake (packageName) -> @@ -170,7 +170,6 @@ afterEach -> document.getElementById('jasmine-content').innerHTML = '' unless window.debugContent - jasmine.unspy(atom, 'saveSync') ensureNoPathSubscriptions() waits(0) # yield to ui thread to make screen update more frequently diff --git a/src/atom.coffee b/src/atom.coffee index 090ce4ee3..815063407 100644 --- a/src/atom.coffee +++ b/src/atom.coffee @@ -37,53 +37,6 @@ module.exports = class Atom extends Model @version: 1 # Increment this when the serialization format changes - # Load or create the Atom environment in the given mode. - # - # * `mode` A {String} mode that is either 'editor' or 'spec' depending on the - # kind of environment you want to build. - # - # Returns an Atom instance, fully initialized - @loadOrCreate: -> - startTime = Date.now() - atom = @deserialize(@loadState()) ? new this({@version}) - atom.deserializeTimings.atom = Date.now() - startTime - atom - - # Deserializes the Atom environment from a state object - @deserialize: (state) -> - new this(state) if state?.version is @version - - # Loads and returns the serialized state corresponding to this window - # if it exists; otherwise returns undefined. - @loadState: -> - if stateKey = @getStateKey(@getLoadSettings().initialPaths) - if state = @getStorageFolder().load(stateKey) - return state - - if windowState = @getLoadSettings().windowState - try - JSON.parse(@getLoadSettings().windowState) - catch error - console.warn "Error parsing window state: #{statePath} #{error.stack}", error - - # Returns the path where the state for the current window will be - # located if it exists. - @getStateKey: (paths) -> - if paths?.length > 0 - sha1 = crypto.createHash('sha1').update(paths.slice().sort().join("\n")).digest('hex') - "editor-#{sha1}" - else - null - - # Get the directory path to Atom's configuration area. - # - # Returns the absolute path to ~/.atom - @getConfigDirPath: -> - @configDirPath ?= process.env.ATOM_HOME - - @getStorageFolder: -> - @storageFolder ?= new StorageFolder(@getConfigDirPath()) - # Returns the load settings hash associated with the current window. @getLoadSettings: -> getWindowLoadSettings() @@ -154,8 +107,8 @@ class Atom extends Model ### # Call .loadOrCreate instead - constructor: (@state={}) -> - @state.version ?= @constructor.version + constructor: -> + @state = {version: @constructor.version} @loadTime = null {devMode, safeMode, resourcePath} = @getLoadSettings() @@ -318,12 +271,6 @@ class Atom extends Model isReleasedVersion: -> not /\w{7}/.test(@getVersion()) # Check if the release is a 7-character SHA prefix - # Public: Get the directory path to Atom's configuration area. - # - # Returns the absolute path to `~/.atom`. - getConfigDirPath: -> - @constructor.getConfigDirPath() - # Public: Get the time taken to completely load the current window. # # This time include things like loading and activating packages, creating @@ -586,7 +533,7 @@ class Atom extends Model @state.workspace = @workspace.serialize() @packages.deactivatePackages() @state.packageStates = @packages.packageStates - @saveSync() + @saveStateSync() @windowState = null removeEditorWindow: -> @@ -777,12 +724,41 @@ class Atom extends Model options.defaultPath ?= @project?.getPaths()[0] dialog.showSaveDialog currentWindow, options - saveSync: -> - if storageKey = @constructor.getStateKey(@project?.getPaths()) - @constructor.getStorageFolder().store(storageKey, @state) + saveStateSync: -> + if storageKey = @getStateKey(@project?.getPaths()) + @getStorageFolder().store(storageKey, @state) else @getCurrentWindow().loadSettings.windowState = JSON.stringify(@state) + loadStateSync: -> + startTime = Date.now() + + if stateKey = @getStateKey(@getLoadSettings().initialPaths) + if state = @getStorageFolder().load(stateKey) + @state = state + + if not @state? and windowState = @getLoadSettings().windowState + try + if state = JSON.parse(@getLoadSettings().windowState) + @state = state + catch error + console.warn "Error parsing window state: #{statePath} #{error.stack}", error + + @deserializeTimings.atom = Date.now() - startTime + + getStateKey: (paths) -> + if paths?.length > 0 + sha1 = crypto.createHash('sha1').update(paths.slice().sort().join("\n")).digest('hex') + "editor-#{sha1}" + else + null + + getConfigDirPath: -> + @configDirPath ?= process.env.ATOM_HOME + + getStorageFolder: -> + @storageFolder ?= new StorageFolder(@getConfigDirPath()) + crashMainProcess: -> remote.process.crash() diff --git a/src/initialize-application-window.coffee b/src/initialize-application-window.coffee index 246633179..1646c17a8 100644 --- a/src/initialize-application-window.coffee +++ b/src/initialize-application-window.coffee @@ -15,9 +15,10 @@ process.env.NODE_PATH = exportsPath process.env.NODE_ENV ?= 'production' unless devMode Atom = require './atom' -window.atom = Atom.loadOrCreate('editor') +window.atom = new Atom -atom.displayWindow() unless isSpec +atom.displayWindow() +atom.loadStateSync() atom.startEditorWindow() # Workaround for focus getting cleared upon window creation diff --git a/src/initialize-test-window.coffee b/src/initialize-test-window.coffee index 79a1d9c2c..90aa075e6 100644 --- a/src/initialize-test-window.coffee +++ b/src/initialize-test-window.coffee @@ -3,10 +3,15 @@ require('crash-reporter').start(productName: 'Atom', companyName: 'GitHub') path = require 'path' + +ipc = require 'ipc' +ipc.send('call-window-method', 'openDevTools') + + try require '../src/window' Atom = require '../src/atom' - window.atom = Atom.loadOrCreate('spec') + window.atom = new Atom # Show window synchronously so a focusout doesn't fire on input elements # that are focused in the very first spec run.