Skip to content

Commit

Permalink
Merge pull request #12025 from jasonmalinowski/persist-low-memory-mode
Browse files Browse the repository at this point in the history
Persist the low-memory-mode option to the registry
  • Loading branch information
jasonmalinowski authored Jun 15, 2016
2 parents c966b31 + 4b4ba64 commit 10a99fd
Show file tree
Hide file tree
Showing 10 changed files with 242 additions and 227 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
// Copyright (c) Microsoft. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.

using System;
using Microsoft.CodeAnalysis.Editor.Shared.Utilities;
using Microsoft.CodeAnalysis.Options;
using Microsoft.CodeAnalysis.Options.Providers;
using Microsoft.VisualStudio.Shell;
using Microsoft.VisualStudio.Shell.Interop;
using Microsoft.Win32;

namespace Microsoft.VisualStudio.LanguageServices.Implementation.Options
{
internal abstract class AbstractLocalUserRegistryOptionSerializer : ForegroundThreadAffinitizedObject, IOptionSerializer
{
/// <summary>
/// An object to gate access to <see cref="_registryKey"/>.
/// </summary>
private readonly object _gate = new object();
private readonly RegistryKey _registryKey;

protected abstract string GetCollectionPathForOption(OptionKey key);

public AbstractLocalUserRegistryOptionSerializer(IServiceProvider serviceProvider)
: base(assertIsForeground: true) // The VSRegistry.RegistryRoot call requires being on the UI thread or else it will marshal and risk deadlock
{
this._registryKey = VSRegistry.RegistryRoot(serviceProvider, __VsLocalRegistryType.RegType_UserSettings, writable: true);
}

bool IOptionSerializer.TryFetch(OptionKey optionKey, out object value)
{
var collectionPath = GetCollectionPathForOption(optionKey);
if (collectionPath == null)
{
value = null;
return false;
}

lock (_gate)
{
using (var subKey = this._registryKey.OpenSubKey(collectionPath))
{
if (subKey == null)
{
value = null;
return false;
}

// Options that are of type bool have to be serialized as integers
if (optionKey.Option.Type == typeof(bool))
{
value = subKey.GetValue(optionKey.Option.Name, defaultValue: (bool)optionKey.Option.DefaultValue ? 1 : 0).Equals(1);
return true;
}
else
{
// Otherwise we can just store normally
value = subKey.GetValue(optionKey.Option.Name, defaultValue: optionKey.Option.DefaultValue);
return true;
}
}
}
}

bool IOptionSerializer.TryPersist(OptionKey optionKey, object value)
{
if (this._registryKey == null)
{
throw new InvalidOperationException();
}

var collectionPath = GetCollectionPathForOption(optionKey);
if (collectionPath == null)
{
return false;
}

lock (_gate)
{
using (var subKey = this._registryKey.CreateSubKey(collectionPath))
{
// Options that are of type bool have to be serialized as integers
if (optionKey.Option.Type == typeof(bool))
{
subKey.SetValue(optionKey.Option.Name, (bool)value ? 1 : 0, RegistryValueKind.DWord);
return true;
}
else
{
subKey.SetValue(optionKey.Option.Name, value);
return true;
}
}
}
}
}
}

This file was deleted.

56 changes: 16 additions & 40 deletions src/VisualStudio/Core/Impl/Options/InternalOptionSerializer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -21,70 +21,46 @@ namespace Microsoft.VisualStudio.LanguageServices.Implementation.Options
CacheOptions.FeatureName,
InternalDiagnosticsOptions.OptionName,
InternalSolutionCrawlerOptions.OptionName), Shared]
internal class InternalOptionSerializer : AbstractSettingStoreOptionSerializer
internal class InternalOptionSerializer : AbstractLocalUserRegistryOptionSerializer
{
[ImportingConstructor]
public InternalOptionSerializer(SVsServiceProvider serviceProvider)
: base(serviceProvider)
{
}

protected override Tuple<string, string> GetCollectionPathAndPropertyNameForOption(IOption key, string languageName)
protected override string GetCollectionPathForOption(OptionKey key)
{
if (key.Feature == EditorComponentOnOffOptions.OptionName)
if (key.Option.Feature == EditorComponentOnOffOptions.OptionName)
{
return Tuple.Create(@"Roslyn\Internal\OnOff\Components", key.Name);
return @"Roslyn\Internal\OnOff\Components";
}
else if (key.Feature == InternalFeatureOnOffOptions.OptionName)
else if (key.Option.Feature == InternalFeatureOnOffOptions.OptionName)
{
return Tuple.Create(@"Roslyn\Internal\OnOff\Features", key.Name);
return @"Roslyn\Internal\OnOff\Features";
}
else if (key.Feature == PerformanceFunctionIdOptionsProvider.Name)
else if (key.Option.Feature == PerformanceFunctionIdOptionsProvider.Name)
{
return Tuple.Create(@"Roslyn\Internal\Performance\FunctionId", key.Name);
return @"Roslyn\Internal\Performance\FunctionId";
}
else if (key.Feature == LoggerOptions.FeatureName)
else if (key.Option.Feature == LoggerOptions.FeatureName)
{
return Tuple.Create(@"Roslyn\Internal\Performance\Logger", key.Name);
return @"Roslyn\Internal\Performance\Logger";
}
else if (key.Feature == InternalDiagnosticsOptions.OptionName)
else if (key.Option.Feature == InternalDiagnosticsOptions.OptionName)
{
return Tuple.Create(@"Roslyn\Internal\Diagnostics", key.Name);
return @"Roslyn\Internal\Diagnostics";
}
else if (key.Feature == InternalSolutionCrawlerOptions.OptionName)
else if (key.Option.Feature == InternalSolutionCrawlerOptions.OptionName)
{
return Tuple.Create(@"Roslyn\Internal\SolutionCrawler", key.Name);
return @"Roslyn\Internal\SolutionCrawler";
}
else if (key.Feature == CacheOptions.FeatureName)
else if (key.Option.Feature == CacheOptions.FeatureName)
{
return Tuple.Create(@"Roslyn\Internal\Performance\Cache", key.Name);
return @"Roslyn\Internal\Performance\Cache";
}

throw ExceptionUtilities.Unreachable;
}

public override bool TryFetch(OptionKey optionKey, out object value)
{
switch (optionKey.Option.Feature)
{
case CacheOptions.FeatureName:
case InternalSolutionCrawlerOptions.OptionName:
return TryFetch(optionKey, (r, k, o) => r.GetValue(k, defaultValue: o.DefaultValue), out value);
}

return base.TryFetch(optionKey, out value);
}

public override bool TryPersist(OptionKey optionKey, object value)
{
switch (optionKey.Option.Feature)
{
case CacheOptions.FeatureName:
case InternalSolutionCrawlerOptions.OptionName:
return TryPersist(optionKey, value, (r, k, o, v) => r.SetValue(k, v, o.Type == typeof(int) ? RegistryValueKind.DWord : RegistryValueKind.QWord));
}

return base.TryPersist(optionKey, value);
}
}
}
2 changes: 1 addition & 1 deletion src/VisualStudio/Core/Impl/ServicesVisualStudioImpl.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -244,7 +244,7 @@
<Compile Include="Options\AbstractOptionPageControl.cs" />
<Compile Include="Options\AbstractRadioButtonViewModel.cs" />
<Compile Include="Options\AbstractSettingsManagerOptionSerializer.cs" />
<Compile Include="Options\AbstractSettingStoreOptionSerializer.cs" />
<Compile Include="Options\AbstractLocalUserRegistryOptionSerializer.cs" />
<Compile Include="Options\CheckBoxViewModel.cs" />
<Compile Include="Options\HeaderItemViewModel.cs" />
<Compile Include="Options\OptionBinding.cs" />
Expand Down
Loading

0 comments on commit 10a99fd

Please sign in to comment.