Split ApplicationState into a Base and add an Elevated version
This commit is contained in:
parent
42c3eea136
commit
eb243f5e11
|
@ -103,28 +103,17 @@ using namespace ::Microsoft::Terminal::Settings::Model;
|
|||
|
||||
namespace winrt::Microsoft::Terminal::Settings::Model::implementation
|
||||
{
|
||||
ApplicationState::ApplicationState(std::filesystem::path path) noexcept :
|
||||
BaseApplicationState{ path } {}
|
||||
|
||||
// Returns the application-global ApplicationState object.
|
||||
Microsoft::Terminal::Settings::Model::ApplicationState ApplicationState::SharedInstance()
|
||||
{
|
||||
static auto state = winrt::make_self<ApplicationState>(GetBaseSettingsPath() / stateFileName);
|
||||
state->Reload();
|
||||
return *state;
|
||||
}
|
||||
|
||||
// ApplicationState::ApplicationState(std::filesystem::path path) noexcept :
|
||||
// _path{ std::move(path) },
|
||||
// _throttler{ std::chrono::seconds(1), [this]() { _write(); } }
|
||||
// {
|
||||
// _read();
|
||||
// }
|
||||
|
||||
// // The destructor ensures that the last write is flushed to disk before returning.
|
||||
// ApplicationState::~ApplicationState()
|
||||
// {
|
||||
// // This will ensure that we not just cancel the last outstanding timer,
|
||||
// // but instead force it to run as soon as possible and wait for it to complete.
|
||||
// _throttler.flush();
|
||||
// }
|
||||
|
||||
void ApplicationState::FromJson(const Json::Value& root) const noexcept
|
||||
{
|
||||
auto state = _state.lock();
|
||||
|
|
|
@ -14,10 +14,7 @@ Abstract:
|
|||
|
||||
#include "BaseApplicationState.h"
|
||||
#include "ApplicationState.g.h"
|
||||
|
||||
#include <inc/cppwinrt_utils.h>
|
||||
// #include <til/mutex.h>
|
||||
// #include <til/throttled_func.h>
|
||||
|
||||
// This macro generates all getters and setters for ApplicationState.
|
||||
// It provides X with the following arguments:
|
||||
|
@ -28,15 +25,14 @@ Abstract:
|
|||
|
||||
namespace winrt::Microsoft::Terminal::Settings::Model::implementation
|
||||
{
|
||||
struct ApplicationState : ApplicationStateT<ApplicationState>, public BaseApplicationState
|
||||
struct ApplicationState : public BaseApplicationState, ApplicationStateT<ApplicationState>
|
||||
{
|
||||
static Microsoft::Terminal::Settings::Model::ApplicationState SharedInstance();
|
||||
|
||||
ApplicationState(std::filesystem::path path) noexcept;
|
||||
~ApplicationState();
|
||||
|
||||
void FromJson(const Json::Value& root) const noexcept override;
|
||||
Json::Value ToJson() const noexcept override;
|
||||
virtual void FromJson(const Json::Value& root) const noexcept override;
|
||||
virtual Json::Value ToJson() const noexcept override;
|
||||
|
||||
// // Methods
|
||||
// void Reload() const noexcept;
|
||||
|
|
|
@ -18,7 +18,7 @@ BaseApplicationState::BaseApplicationState(std::filesystem::path path) noexcept
|
|||
_path{ std::move(path) },
|
||||
_throttler{ std::chrono::seconds(1), [this]() { _write(); } }
|
||||
{
|
||||
_read();
|
||||
// _read();
|
||||
}
|
||||
|
||||
// The destructor ensures that the last write is flushed to disk before returning.
|
||||
|
@ -62,7 +62,7 @@ try
|
|||
throw winrt::hresult_error(WEB_E_INVALID_JSON_STRING, winrt::to_hstring(errs));
|
||||
}
|
||||
|
||||
this->FromJson(root);
|
||||
FromJson(root);
|
||||
}
|
||||
CATCH_LOG()
|
||||
|
||||
|
|
163
src/cascadia/TerminalSettingsModel/ElevatedState.cpp
Normal file
163
src/cascadia/TerminalSettingsModel/ElevatedState.cpp
Normal file
|
@ -0,0 +1,163 @@
|
|||
// Copyright (c) Microsoft Corporation.
|
||||
// Licensed under the MIT license.
|
||||
|
||||
#include "pch.h"
|
||||
#include "ElevatedState.h"
|
||||
#include "CascadiaSettings.h"
|
||||
#include "ElevatedState.g.cpp"
|
||||
|
||||
#include "JsonUtils.h"
|
||||
#include "FileUtils.h"
|
||||
|
||||
constexpr std::wstring_view stateFileName{ L"elevated-state.json" };
|
||||
|
||||
namespace Microsoft::Terminal::Settings::Model::JsonUtils
|
||||
{
|
||||
// This trait exists in order to serialize the std::unordered_set for GeneratedProfiles.
|
||||
template<typename T>
|
||||
struct ConversionTrait<std::unordered_set<T>>
|
||||
{
|
||||
std::unordered_set<T> FromJson(const Json::Value& json) const
|
||||
{
|
||||
ConversionTrait<T> trait;
|
||||
std::unordered_set<T> val;
|
||||
val.reserve(json.size());
|
||||
|
||||
for (const auto& element : json)
|
||||
{
|
||||
val.emplace(trait.FromJson(element));
|
||||
}
|
||||
|
||||
return val;
|
||||
}
|
||||
|
||||
bool CanConvert(const Json::Value& json) const
|
||||
{
|
||||
ConversionTrait<T> trait;
|
||||
return json.isArray() && std::all_of(json.begin(), json.end(), [trait](const auto& json) -> bool { return trait.CanConvert(json); });
|
||||
}
|
||||
|
||||
Json::Value ToJson(const std::unordered_set<T>& val)
|
||||
{
|
||||
ConversionTrait<T> trait;
|
||||
Json::Value json{ Json::arrayValue };
|
||||
|
||||
for (const auto& key : val)
|
||||
{
|
||||
json.append(trait.ToJson(key));
|
||||
}
|
||||
|
||||
return json;
|
||||
}
|
||||
|
||||
std::string TypeDescription() const
|
||||
{
|
||||
return fmt::format("{}[]", ConversionTrait<GUID>{}.TypeDescription());
|
||||
}
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
struct ConversionTrait<winrt::Windows::Foundation::Collections::IVector<T>>
|
||||
{
|
||||
winrt::Windows::Foundation::Collections::IVector<T> FromJson(const Json::Value& json) const
|
||||
{
|
||||
ConversionTrait<T> trait;
|
||||
std::vector<T> val;
|
||||
val.reserve(json.size());
|
||||
|
||||
for (const auto& element : json)
|
||||
{
|
||||
val.push_back(trait.FromJson(element));
|
||||
}
|
||||
|
||||
return winrt::single_threaded_vector(move(val));
|
||||
}
|
||||
|
||||
bool CanConvert(const Json::Value& json) const
|
||||
{
|
||||
ConversionTrait<T> trait;
|
||||
return json.isArray() && std::all_of(json.begin(), json.end(), [trait](const auto& json) -> bool { return trait.CanConvert(json); });
|
||||
}
|
||||
|
||||
Json::Value ToJson(const winrt::Windows::Foundation::Collections::IVector<T>& val)
|
||||
{
|
||||
ConversionTrait<T> trait;
|
||||
Json::Value json{ Json::arrayValue };
|
||||
|
||||
for (const auto& key : val)
|
||||
{
|
||||
json.append(trait.ToJson(key));
|
||||
}
|
||||
|
||||
return json;
|
||||
}
|
||||
|
||||
std::string TypeDescription() const
|
||||
{
|
||||
return fmt::format("vector ({})", ConversionTrait<T>{}.TypeDescription());
|
||||
}
|
||||
};
|
||||
}
|
||||
using namespace ::Microsoft::Terminal::Settings::Model;
|
||||
|
||||
namespace winrt::Microsoft::Terminal::Settings::Model::implementation
|
||||
{
|
||||
ElevatedState::ElevatedState(std::filesystem::path path) noexcept :
|
||||
BaseApplicationState{ path } {}
|
||||
|
||||
// Returns the application-global ElevatedState object.
|
||||
Microsoft::Terminal::Settings::Model::ElevatedState ElevatedState::SharedInstance()
|
||||
{
|
||||
// TODO! place in a totally different file! and path!
|
||||
static auto state = winrt::make_self<ElevatedState>(GetBaseSettingsPath() / stateFileName);
|
||||
state->Reload();
|
||||
return *state;
|
||||
}
|
||||
|
||||
void ElevatedState::FromJson(const Json::Value& root) const noexcept
|
||||
{
|
||||
auto state = _state.lock();
|
||||
// GetValueForKey() comes in two variants:
|
||||
// * take a std::optional<T> reference
|
||||
// * return std::optional<T> by value
|
||||
// At the time of writing the former version skips missing fields in the json,
|
||||
// but we want to explicitly clear state fields that were removed from state.json.
|
||||
#define MTSM_ELEVATED_STATE_GEN(type, name, key, ...) state->name = JsonUtils::GetValueForKey<std::optional<type>>(root, key);
|
||||
MTSM_ELEVATED_STATE_FIELDS(MTSM_ELEVATED_STATE_GEN)
|
||||
#undef MTSM_ELEVATED_STATE_GEN
|
||||
}
|
||||
Json::Value ElevatedState::ToJson() const noexcept
|
||||
{
|
||||
Json::Value root{ Json::objectValue };
|
||||
|
||||
{
|
||||
auto state = _state.lock_shared();
|
||||
#define MTSM_ELEVATED_STATE_GEN(type, name, key, ...) JsonUtils::SetValueForKey(root, key, state->name);
|
||||
MTSM_ELEVATED_STATE_FIELDS(MTSM_ELEVATED_STATE_GEN)
|
||||
#undef MTSM_ELEVATED_STATE_GEN
|
||||
}
|
||||
return root;
|
||||
}
|
||||
|
||||
// Generate all getter/setters
|
||||
#define MTSM_ELEVATED_STATE_GEN(type, name, key, ...) \
|
||||
type ElevatedState::name() const noexcept \
|
||||
{ \
|
||||
const auto state = _state.lock_shared(); \
|
||||
const auto& value = state->name; \
|
||||
return value ? *value : type{ __VA_ARGS__ }; \
|
||||
} \
|
||||
\
|
||||
void ElevatedState::name(const type& value) noexcept \
|
||||
{ \
|
||||
{ \
|
||||
auto state = _state.lock(); \
|
||||
state->name.emplace(value); \
|
||||
} \
|
||||
\
|
||||
_throttler(); \
|
||||
}
|
||||
MTSM_ELEVATED_STATE_FIELDS(MTSM_ELEVATED_STATE_GEN)
|
||||
#undef MTSM_ELEVATED_STATE_GEN
|
||||
|
||||
}
|
57
src/cascadia/TerminalSettingsModel/ElevatedState.h
Normal file
57
src/cascadia/TerminalSettingsModel/ElevatedState.h
Normal file
|
@ -0,0 +1,57 @@
|
|||
/*++
|
||||
Copyright (c) Microsoft Corporation
|
||||
Licensed under the MIT license.
|
||||
|
||||
Module Name:
|
||||
- ElevatedState.h
|
||||
|
||||
Abstract:
|
||||
- If the CascadiaSettings class were AppData, then this class would be LocalAppData.
|
||||
Put anything in here that you wouldn't want to be stored next to user-editable settings.
|
||||
- Modify ElevatedState.idl and MTSM_ELEVATED_STATE_FIELDS to add new fields.
|
||||
--*/
|
||||
#pragma once
|
||||
|
||||
#include "BaseApplicationState.h"
|
||||
#include "ElevatedState.g.h"
|
||||
#include <inc/cppwinrt_utils.h>
|
||||
|
||||
// This macro generates all getters and setters for ElevatedState.
|
||||
// It provides X with the following arguments:
|
||||
// (type, function name, JSON key, ...variadic construction arguments)
|
||||
#define MTSM_ELEVATED_STATE_FIELDS(X) \
|
||||
X(Windows::Foundation::Collections::IVector<hstring>, AllowedCommandlines, "allowedCommandlines")
|
||||
|
||||
namespace winrt::Microsoft::Terminal::Settings::Model::implementation
|
||||
{
|
||||
struct ElevatedState : ElevatedStateT<ElevatedState>, public BaseApplicationState
|
||||
{
|
||||
static Microsoft::Terminal::Settings::Model::ElevatedState SharedInstance();
|
||||
|
||||
ElevatedState(std::filesystem::path path) noexcept;
|
||||
|
||||
void FromJson(const Json::Value& root) const noexcept override;
|
||||
Json::Value ToJson() const noexcept override;
|
||||
|
||||
// State getters/setters
|
||||
#define MTSM_ELEVATED_STATE_GEN(type, name, key, ...) \
|
||||
type name() const noexcept; \
|
||||
void name(const type& value) noexcept;
|
||||
MTSM_ELEVATED_STATE_FIELDS(MTSM_ELEVATED_STATE_GEN)
|
||||
#undef MTSM_ELEVATED_STATE_GEN
|
||||
|
||||
private:
|
||||
struct state_t
|
||||
{
|
||||
#define MTSM_ELEVATED_STATE_GEN(type, name, key, ...) std::optional<type> name{ __VA_ARGS__ };
|
||||
MTSM_ELEVATED_STATE_FIELDS(MTSM_ELEVATED_STATE_GEN)
|
||||
#undef MTSM_ELEVATED_STATE_GEN
|
||||
};
|
||||
til::shared_mutex<state_t> _state;
|
||||
};
|
||||
}
|
||||
|
||||
namespace winrt::Microsoft::Terminal::Settings::Model::factory_implementation
|
||||
{
|
||||
BASIC_FACTORY(ElevatedState);
|
||||
}
|
15
src/cascadia/TerminalSettingsModel/ElevatedState.idl
Normal file
15
src/cascadia/TerminalSettingsModel/ElevatedState.idl
Normal file
|
@ -0,0 +1,15 @@
|
|||
// Copyright (c) Microsoft Corporation.
|
||||
// Licensed under the MIT license.
|
||||
|
||||
namespace Microsoft.Terminal.Settings.Model
|
||||
{
|
||||
[default_interface] runtimeclass ElevatedState {
|
||||
static ElevatedState SharedInstance();
|
||||
|
||||
void Reload();
|
||||
|
||||
String FilePath { get; };
|
||||
|
||||
Windows.Foundation.Collections.IVector<String> AllowedCommandlines { get; set; };
|
||||
}
|
||||
}
|
|
@ -36,6 +36,9 @@
|
|||
<ClInclude Include="ApplicationState.h">
|
||||
<DependentUpon>ApplicationState.idl</DependentUpon>
|
||||
</ClInclude>
|
||||
<ClInclude Include="ElevatedState.h">
|
||||
<DependentUpon>ElevatedState.idl</DependentUpon>
|
||||
</ClInclude>
|
||||
<ClInclude Include="CascadiaSettings.h">
|
||||
<DependentUpon>CascadiaSettings.idl</DependentUpon>
|
||||
</ClInclude>
|
||||
|
@ -109,6 +112,9 @@
|
|||
<ClCompile Include="ApplicationState.cpp">
|
||||
<DependentUpon>ApplicationState.idl</DependentUpon>
|
||||
</ClCompile>
|
||||
<ClCompile Include="ElevatedState.cpp">
|
||||
<DependentUpon>ElevatedState.idl</DependentUpon>
|
||||
</ClCompile>
|
||||
<ClCompile Include="CascadiaSettings.cpp">
|
||||
<DependentUpon>CascadiaSettings.idl</DependentUpon>
|
||||
</ClCompile>
|
||||
|
@ -158,6 +164,7 @@
|
|||
<Midl Include="ActionArgs.idl" />
|
||||
<Midl Include="ActionMap.idl" />
|
||||
<Midl Include="ApplicationState.idl" />
|
||||
<Midl Include="ElevatedState.idl" />
|
||||
<Midl Include="CascadiaSettings.idl" />
|
||||
<Midl Include="ColorScheme.idl" />
|
||||
<Midl Include="Command.idl" />
|
||||
|
|
Loading…
Reference in a new issue