Add Config::transact

Use this method to avoid emitting unecessary config events
when activating or deactivating multiple packages
This commit is contained in:
Max Brunsfeld
2014-12-17 12:21:42 -08:00
parent b0731afd4c
commit 28ac51d140
3 changed files with 48 additions and 9 deletions

View File

@@ -492,6 +492,26 @@ describe "Config", ->
atom.config.set('foo.bar.baz', "value 10")
expect(bazCatHandler).not.toHaveBeenCalled()
describe ".transact(callback)", ->
changeSpy = null
beforeEach ->
changeSpy = jasmine.createSpy('onDidChange callback')
atom.config.onDidChange("foo.bar.baz", changeSpy)
it "allows only one change event for the duration of the given callback", ->
atom.config.transact ->
atom.config.set("foo.bar.baz", 1)
atom.config.set("foo.bar.baz", 2)
atom.config.set("foo.bar.baz", 3)
expect(changeSpy.callCount).toBe(1)
expect(changeSpy.argsForCall[0][0]).toEqual(newValue: 3, oldValue: undefined)
it "does not emit an event if no changes occur while paused", ->
atom.config.transact ->
expect(changeSpy).not.toHaveBeenCalled()
describe ".initializeConfigDirectory()", ->
beforeEach ->
if fs.existsSync(dotAtomPath)

View File

@@ -318,6 +318,7 @@ class Config
@configFileHasErrors = false
@configFilePath = fs.resolve(@configDirPath, 'config', ['json', 'cson'])
@configFilePath ?= path.join(@configDirPath, 'config.cson')
@transactDepth = 0
###
Section: Config Subscription
@@ -614,6 +615,19 @@ class Config
getUserConfigPath: ->
@configFilePath
# Extended: Suppress calls to handler functions registered with {::onDidChange}
# and {::observe} for the duration of `callback`. After `callback` executes,
# handlers will be called once if the value for their key-path has changed.
#
# * `callback` {Function} to execute while suppressing calls to handlers.
transact: (callback) ->
@transactDepth++
try
callback()
finally
@transactDepth--
@emitChangeEvent()
###
Section: Deprecated
###
@@ -749,7 +763,7 @@ class Config
resetUserSettings: (newSettings) ->
unless isPlainObject(newSettings)
@settings = {}
@emitter.emit 'did-change'
@emitChangeEvent()
return
if newSettings.global?
@@ -801,7 +815,7 @@ class Config
value = undefined if _.isEqual(defaultValue, value)
_.setValueForKeyPath(@settings, keyPath, value)
@emitter.emit 'did-change'
@emitChangeEvent()
observeKeyPath: (keyPath, options, callback) ->
callback(@get(keyPath))
@@ -825,7 +839,7 @@ class Config
setRawDefault: (keyPath, value) ->
_.setValueForKeyPath(@defaultSettings, keyPath, value)
@emitter.emit 'did-change'
@emitChangeEvent()
setDefaults: (keyPath, defaults) ->
if defaults? and isPlainObject(defaults)
@@ -883,20 +897,23 @@ class Config
Section: Private Scoped Settings
###
emitChangeEvent: ->
@emitter.emit 'did-change' unless @transactDepth > 0
resetUserScopedSettings: (newScopedSettings) ->
@usersScopedSettings?.dispose()
@usersScopedSettings = new CompositeDisposable
@usersScopedSettings.add @scopedSettingsStore.addProperties('user-config', newScopedSettings, @usersScopedSettingPriority)
@emitter.emit 'did-change'
@emitChangeEvent()
addScopedSettings: (source, selector, value, options) ->
settingsBySelector = {}
settingsBySelector[selector] = value
disposable = @scopedSettingsStore.addProperties(source, settingsBySelector, options)
@emitter.emit 'did-change'
@emitChangeEvent()
new Disposable =>
disposable.dispose()
@emitter.emit 'did-change'
@emitChangeEvent()
setRawScopedValue: (selector, keyPath, value) ->
if keyPath?
@@ -907,7 +924,7 @@ class Config
settingsBySelector = {}
settingsBySelector[selector] = value
@usersScopedSettings.add @scopedSettingsStore.addProperties('user-config', settingsBySelector, @usersScopedSettingPriority)
@emitter.emit 'did-change'
@emitChangeEvent()
getRawScopedValue: (scopeDescriptor, keyPath) ->
scopeDescriptor = ScopeDescriptor.fromObject(scopeDescriptor)

View File

@@ -329,7 +329,8 @@ class PackageManager
@packageActivators.push([activator, types])
activatePackages: (packages) ->
@activatePackage(pack.name) for pack in packages
atom.config.transact =>
@activatePackage(pack.name) for pack in packages
@observeDisabledPackages()
# Activate a single package by name
@@ -344,7 +345,8 @@ class PackageManager
# Deactivate all packages
deactivatePackages: ->
@deactivatePackage(pack.name) for pack in @getLoadedPackages()
atom.config.transact =>
@deactivatePackage(pack.name) for pack in @getLoadedPackages()
@unobserveDisabledPackages()
# Deactivate the package with the given name