stash changes

This commit is contained in:
Tian Liao 2024-10-17 15:59:22 +08:00
commit 7258237c8a
9 changed files with 183 additions and 131 deletions

View file

@ -40,7 +40,6 @@ namespace
// struct SnapshotHelper
//{
// static constexpr int SnapshotVersion = 0;
// static Windows::Data::Json::JsonObject ^ SaveSnapshotToJson(const ApplicationSnapshot& value)
// {
@ -121,8 +120,9 @@ namespace
// static Windows::Data::Json::JsonObject ^ SaveSnapshotToJson(const CalculationManager::HISTORYITEM& value)
// {
// auto jsonObject = ref new Windows::Data::Json::JsonObject();
// jsonObject->SetNamedValue(L"Expression", Windows::Data::Json::JsonValue::CreateStringValue(ref new Platform::String(value.historyItemVector.expression.c_str())));
// jsonObject->SetNamedValue(L"Result", Windows::Data::Json::JsonValue::CreateStringValue(ref new Platform::String(value.historyItemVector.result.c_str())));
// jsonObject->SetNamedValue(L"Expression", Windows::Data::Json::JsonValue::CreateStringValue(ref new
// Platform::String(value.historyItemVector.expression.c_str()))); jsonObject->SetNamedValue(L"Result",
// Windows::Data::Json::JsonValue::CreateStringValue(ref new Platform::String(value.historyItemVector.result.c_str())));
// auto tokensJsonArray = ref new Windows::Data::Json::JsonArray();
// for (const auto& token : *value.historyItemVector.spTokens)
@ -512,6 +512,17 @@ void ApplicationViewModel::Categories::set(IObservableVector<NavCategoryGroup ^>
}
}
ApplicationSnapshot ^ ApplicationViewModel::Snapshot::get()
{
auto snapshot = ref new ApplicationSnapshot();
snapshot->Mode = static_cast<int>(Mode);
if (m_CalculatorViewModel != nullptr && m_mode == ViewMode::Standard)
{
snapshot->StandardCalculator = m_CalculatorViewModel->Snapshot;
}
return snapshot;
}
void ApplicationViewModel::Initialize(ViewMode mode)
{
if (!NavCategoryStates::IsValidViewMode(mode) || !NavCategoryStates::IsViewModeEnabled(mode))
@ -545,6 +556,12 @@ void ApplicationViewModel::Initialize(ViewMode mode)
}
}
void ApplicationViewModel::Initialize(ApplicationSnapshot ^ snapshot)
{
// TODO: restore
Initialize(static_cast<ViewMode>(snapshot->Mode));
}
bool ApplicationViewModel::TryRecoverFromNavigationModeFailure()
{
// Here we are simply trying to recover from being unable to navigate to a mode.

View file

@ -3,6 +3,7 @@
#pragma once
#include "Snapshots.h"
#include "StandardCalculatorViewModel.h"
#include "DateCalculatorViewModel.h"
#include "GraphingCalculator/GraphingCalculatorViewModel.h"
@ -12,19 +13,14 @@ namespace CalculatorApp
{
namespace ViewModel
{
struct ApplicationSnapshot
{
int SnapshotVersion;
int Mode;
//std::optional<StandardCalculatorSnapshot> StandardCalc;
};
[Windows::UI::Xaml::Data::Bindable] public ref class ApplicationViewModel sealed : public Windows::UI::Xaml::Data::INotifyPropertyChanged
{
public:
ApplicationViewModel();
[Windows::Foundation::Metadata::DefaultOverload]
void Initialize(CalculatorApp::ViewModel::Common::ViewMode mode); // Use for first init, use deserialize for rehydration
void Initialize(ApplicationSnapshot^ snapshot);
OBSERVABLE_OBJECT();
OBSERVABLE_PROPERTY_RW(StandardCalculatorViewModel ^, CalculatorViewModel);
@ -77,6 +73,11 @@ namespace CalculatorApp
}
}
property ApplicationSnapshot ^ Snapshot
{
ApplicationSnapshot ^ get();
}
static property Platform::String ^ LaunchedLocalSettings
{
Platform::String ^ get()
@ -103,7 +104,6 @@ namespace CalculatorApp
void ToggleAlwaysOnTop(float width, float height);
//Windows::Data::Json::JsonObject ^ SaveApplicationSnapshot();
//bool TryRestoreFromSnapshot(Windows::Data::Json::JsonObject ^ jsonObject);
private:

View file

@ -6,6 +6,7 @@
#include <stdexcept>
#include <vector>
#include "CalcManager/ExpressionCommand.h"
#include "Snapshots.h"
namespace
@ -152,4 +153,41 @@ namespace CalculatorApp::ViewModel
{
return {}; // TODO
}
std::vector<std::shared_ptr<IExpressionCommand>> ToUnderlying(Windows::Foundation::Collections::IVector<ICalcManagerIExprCommand ^> ^ commands)
{
std::vector<std::shared_ptr<IExpressionCommand>> result;
for (ICalcManagerIExprCommand ^ cmdEntry : commands)
{
if (auto unary = dynamic_cast<UnaryCommand ^>(cmdEntry); unary != nullptr)
{
if (unary->Commands.size() == 1)
{
result.push_back(std::make_shared<CUnaryCommand>(unary->Commands[0]));
}
else if (unary->Commands.size() == 2)
{
result.push_back(std::make_shared<CUnaryCommand>(unary->Commands[0], unary->Commands[1]));
}
else
{
throw std::logic_error{ "ill-formed command." };
}
}
else if (auto binary = dynamic_cast<BinaryCommand ^>(cmdEntry); binary != nullptr)
{
result.push_back(std::make_shared<CBinaryCommand>(binary->Command));
}
else if (auto paren = dynamic_cast<Parentheses ^>(cmdEntry); paren != nullptr)
{
result.push_back(std::make_shared<CParentheses>(paren->Command));
}
else if (auto operand = dynamic_cast<OperandCommand ^>(cmdEntry); operand != nullptr)
{
auto subcmds = std::make_shared<std::vector<int>>(operand->Commands);
result.push_back(std::make_shared<COpndCommand>(std::move(subcmds), operand->IsNegative, operand->IsDecimalPresent, operand->IsSciFmt));
}
}
return result;
}
} // namespace CalculatorApp::ViewModel

View file

@ -75,7 +75,15 @@ public
property Windows::Foundation::Collections::IVector<ICalcManagerIExprCommand ^> ^ DisplayCommands; // mandatory
};
public
ref struct ApplicationSnapshot sealed
{
property int Mode;
property StandardCalculatorSnapshot ^ StandardCalculator; // optional
};
ICalcManagerIExprCommand ^ CreateExprCommand(const IExpressionCommand* exprCmd);
std::vector<std::shared_ptr<IExpressionCommand>> ToUnderlying(Windows::Foundation::Collections::IVector<ICalcManagerIExprCommand ^> ^ commands);
std::vector<std::shared_ptr<CalculationManager::HISTORYITEM>> ToUnderlying(Windows::Foundation::Collections::IVector<CalcManagerHistoryItem ^> ^ items);
} // namespace CalculatorApp::ViewModel

View file

@ -194,11 +194,11 @@ StandardCalculatorViewModel::StandardCalculatorViewModel(StandardCalculatorSnaps
std::vector<int> commands;
if (snapshot->ExpressionDisplay != nullptr && snapshot->ExpressionDisplay->Tokens->GetAt(snapshot->ExpressionDisplay->Tokens->Size))
{
// commands = GetCommandsFromExpressionCommands(Snapshot->ExpressionDisplay->Commands);
commands = GetCommandsFromExpressionCommands(ToUnderlying(snapshot->ExpressionDisplay->Commands));
}
if (commands.empty() && snapshot->DisplayCommands->Size > 0)
{
// commands = GetCommandsFromExpressionCommands(snapshot->DisplayCommands);
commands = GetCommandsFromExpressionCommands(ToUnderlying(snapshot->DisplayCommands));
}
for (auto cmd : commands)
{
@ -206,9 +206,18 @@ StandardCalculatorViewModel::StandardCalculatorViewModel(StandardCalculatorSnaps
}
if (snapshot->ExpressionDisplay != nullptr)
{
// SetExpressionDisplay();
using RawTokenCollection = std::vector<std::pair<std::wstring, int>>;
RawTokenCollection rawTokens;
for (CalcManagerHistoryToken ^ token : snapshot->ExpressionDisplay->Tokens)
{
rawTokens.push_back(std::pair{ token->OpCodeName->Data(), token->CommandIndex });
}
// SetPrimaryDisplay();
snapshot->ExpressionDisplay->Tokens;
SetExpressionDisplay(
std::make_shared<RawTokenCollection>(rawTokens),
std::make_shared<std::vector<std::shared_ptr<IExpressionCommand>>>(ToUnderlying(snapshot->ExpressionDisplay->Commands)));
}
SetPrimaryDisplay(snapshot->PrimaryDisplay->DisplayValue, snapshot->PrimaryDisplay->IsError);
}
}

View file

@ -394,6 +394,14 @@
<ItemDefinitionGroup Condition="!Exists('..\CalcViewModel\DataLoaders\DataLoaderConstants.h')">
<ClCompile>
<AdditionalOptions>/DUSE_MOCK_DATA %(AdditionalOptions)</AdditionalOptions>
<LanguageStandard Condition="'$(Configuration)|$(Platform)'=='Debug|ARM'">stdcpp17</LanguageStandard>
<LanguageStandard Condition="'$(Configuration)|$(Platform)'=='Release|ARM'">stdcpp17</LanguageStandard>
<LanguageStandard Condition="'$(Configuration)|$(Platform)'=='Debug|ARM64'">stdcpp17</LanguageStandard>
<LanguageStandard Condition="'$(Configuration)|$(Platform)'=='Release|ARM64'">stdcpp17</LanguageStandard>
<LanguageStandard Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">stdcpp17</LanguageStandard>
<LanguageStandard Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">stdcpp17</LanguageStandard>
<LanguageStandard Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">stdcpp17</LanguageStandard>
<LanguageStandard Condition="'$(Configuration)|$(Platform)'=='Release|x64'">stdcpp17</LanguageStandard>
</ClCompile>
</ItemDefinitionGroup>
<Choose>

View file

@ -81,8 +81,7 @@ namespace CalculatorApp
OnAppLaunch(args,
new SnapshotLaunchArguments
{
ActivityId = protoArgs.Uri.GetActivityId(),
LaunchUri = protoArgs.Uri
Snapshot = null // TODO:
},
false);
}

View file

@ -1,14 +1,13 @@
using System;
using Windows.ApplicationModel.Activation;
using Windows.ApplicationModel.UserActivities;
using CalculatorApp.ViewModel;
namespace CalculatorApp
{
internal class SnapshotLaunchArguments
{
public string ActivityId { get; set; }
public Uri LaunchUri { get; set; }
public ApplicationSnapshot Snapshot;
}
internal static class LaunchExtensions
@ -18,31 +17,6 @@ namespace CalculatorApp
protoArgs.Uri != null &&
protoArgs.Uri.Segments != null &&
protoArgs.Uri.Segments.Length == 2 &&
protoArgs.Uri.Segments[0] == "snapshots/";
/// <summary>
/// GetActivityId() requires the parameter `launchUri` to be a well-formed
/// snapshot URI.
/// </summary>
/// <param name="launchUri">the Uri to launch with a snapshot context.</param>
/// <returns>Activity ID</returns>
public static string GetActivityId(this Uri launchUri)
{
return launchUri.Segments[1].Trim();
}
public static bool VerifyIncomingActivity(this SnapshotLaunchArguments launchArgs, UserActivity activity)
{
if (activity.State != UserActivityState.Published ||
string.IsNullOrEmpty(activity.ActivityId) ||
activity.ActivationUri == null ||
activity.ActivationUri.Segments == null ||
activity.ActivationUri.Segments.Length != 2 ||
activity.ActivationUri.Segments[0] != "snapshots/")
{
return false;
}
return activity.ActivityId == GetActivityId(launchArgs.LaunchUri);
}
protoArgs.Uri.Segments[0] == "snapshot/";
}
}

View file

@ -69,8 +69,7 @@ namespace CalculatorApp
}
var channel = UserActivityChannel.GetDefault();
var activity = await channel.GetOrCreateUserActivityAsync($"{Guid.NewGuid()}");
activity.ActivationUri = new Uri($"ms-calculator:snapshots/{activity.ActivityId}");
activity.ContentInfo = UserActivityContentInfo.FromJson(Model.SaveApplicationSnapshot().Stringify());
activity.ActivationUri = new Uri($"ms-calculator:snapshot/TODO");
activity.IsRoamable = false;
var resProvider = AppResourceProvider.GetInstance();
activity.VisualElements.DisplayText =
@ -165,22 +164,22 @@ namespace CalculatorApp
}
else if (e.Parameter is SnapshotLaunchArguments snapshotArgs)
{
_ = Window.Current.Dispatcher.RunAsync(CoreDispatcherPriority.Normal, async () =>
{
var channel = UserActivityChannel.GetDefault();
var activity = await channel.GetOrCreateUserActivityAsync(snapshotArgs.ActivityId);
//_ = Window.Current.Dispatcher.RunAsync(CoreDispatcherPriority.Normal, async () =>
//{
// var channel = UserActivityChannel.GetDefault();
// var activity = await channel.GetOrCreateUserActivityAsync(snapshotArgs.ActivityId);
if (TryRestoreFromActivity(snapshotArgs, activity, out var errorMessage))
{
TraceLogger.GetInstance().LogRecallRestore(Model.Mode);
SelectNavigationItemByModel();
}
else
{
TraceLogger.GetInstance().LogRecallError(Model.Mode, errorMessage);
}
});
Model.Initialize(initialMode);
// if (TryRestoreFromActivity(snapshotArgs, activity, out var errorMessage))
// {
// TraceLogger.GetInstance().LogRecallRestore(Model.Mode);
// SelectNavigationItemByModel();
// }
// else
// {
// TraceLogger.GetInstance().LogRecallError(Model.Mode, errorMessage);
// }
//});
Model.Initialize(snapshotArgs.Snapshot);
}
else
{
@ -188,37 +187,37 @@ namespace CalculatorApp
}
}
private bool TryRestoreFromActivity(SnapshotLaunchArguments snapshotArgs, UserActivity activity, out string errorMessage)
{
if (!snapshotArgs.VerifyIncomingActivity(activity))
{
errorMessage = "IncomingActivityFailed";
return false;
}
//private bool TryRestoreFromActivity(SnapshotLaunchArguments snapshotArgs, UserActivity activity, out string errorMessage)
//{
// if (!snapshotArgs.VerifyIncomingActivity(activity))
// {
// errorMessage = "IncomingActivityFailed";
// return false;
// }
// Work around for bug https://microsoft.visualstudio.com/DefaultCollection/OS/_workitems/edit/48931227
// where ContentInfo can't be directly accessed.
if (!JsonObject.TryParse(activity.ToJson(), out var activityJson))
{
errorMessage = "ParseJsonError";
return false;
}
// // Work around for bug https://microsoft.visualstudio.com/DefaultCollection/OS/_workitems/edit/48931227
// // where ContentInfo can't be directly accessed.
// if (!JsonObject.TryParse(activity.ToJson(), out var activityJson))
// {
// errorMessage = "ParseJsonError";
// return false;
// }
if (!activityJson.ContainsKey("contentInfo"))
{
errorMessage = "ContentInfoNotExist";
return false;
}
// if (!activityJson.ContainsKey("contentInfo"))
// {
// errorMessage = "ContentInfoNotExist";
// return false;
// }
if (!Model.TryRestoreFromSnapshot(activityJson.GetNamedObject("contentInfo")))
{
errorMessage = "RestoreFromSnapshotFailed";
return false;
}
// if (!Model.TryRestoreFromSnapshot(activityJson.GetNamedObject("contentInfo")))
// {
// errorMessage = "RestoreFromSnapshotFailed";
// return false;
// }
errorMessage = string.Empty;
return true;
}
// errorMessage = string.Empty;
// return true;
//}
private void InitializeNavViewCategoriesSource()
{