From ff9d026ea71326895fdc63bb31d626d282af0334 Mon Sep 17 00:00:00 2001 From: Tian Liao Date: Wed, 16 Oct 2024 14:20:29 +0800 Subject: [PATCH 01/21] stash changes --- src/CalcViewModel/ApplicationViewModel.cpp | 966 +++++++++--------- src/CalcViewModel/ApplicationViewModel.h | 6 +- src/CalcViewModel/CalcViewModel.vcxproj | 2 + .../CalcViewModel.vcxproj.filters | 2 + src/CalcViewModel/Snapshots.cpp | 59 ++ src/CalcViewModel/Snapshots.h | 69 ++ .../StandardCalculatorViewModel.cpp | 112 +- .../StandardCalculatorViewModel.h | 82 +- 8 files changed, 721 insertions(+), 577 deletions(-) create mode 100644 src/CalcViewModel/Snapshots.cpp create mode 100644 src/CalcViewModel/Snapshots.h diff --git a/src/CalcViewModel/ApplicationViewModel.cpp b/src/CalcViewModel/ApplicationViewModel.cpp index 7a54182d2..d3bdaa19a 100644 --- a/src/CalcViewModel/ApplicationViewModel.cpp +++ b/src/CalcViewModel/ApplicationViewModel.cpp @@ -38,445 +38,445 @@ namespace StringReference CategoriesPropertyName(L"Categories"); StringReference ClearMemoryVisibilityPropertyName(L"ClearMemoryVisibility"); - struct SnapshotHelper - { - static constexpr int SnapshotVersion = 0; - - static Windows::Data::Json::JsonObject ^ SaveSnapshotToJson(const ApplicationSnapshot& value) - { - auto jsonObject = ref new Windows::Data::Json::JsonObject(); - jsonObject->SetNamedValue(L"SnapshotVersion", Windows::Data::Json::JsonValue::CreateNumberValue(value.SnapshotVersion)); - jsonObject->SetNamedValue(L"Mode", Windows::Data::Json::JsonValue::CreateNumberValue(value.Mode)); - if (value.StandardCalc.has_value()) - { - jsonObject->SetNamedValue(L"StandardCalculatorSnapshot", SaveSnapshotToJson(*value.StandardCalc)); - } - return jsonObject; - } - - static Windows::Data::Json::JsonObject ^ SaveSnapshotToJson(const StandardCalculatorSnapshot& value) - { - auto jsonObject = ref new Windows::Data::Json::JsonObject(); - jsonObject->SetNamedValue(L"CalculatorManagerSnapshot", SaveSnapshotToJson(value.CalcManager)); - jsonObject->SetNamedValue(L"PrimaryDisplay", SaveSnapshotToJson(value.PrimaryDisplay)); - if (value.ExpressionDisplay.has_value()) - { - jsonObject->SetNamedValue(L"ExpressionDisplay", SaveSnapshotToJson(*value.ExpressionDisplay)); - } - auto commandsJsonArray = ref new Windows::Data::Json::JsonArray(); - for (const auto& command : value.DisplayCommands) - { - commandsJsonArray->Append(SaveSnapshotToJson(command)); - } - jsonObject->SetNamedValue(L"DisplayCommands", commandsJsonArray); - return jsonObject; - } - - static Windows::Data::Json::JsonObject ^ SaveSnapshotToJson(const PrimaryDisplaySnapshot& value) - { - auto jsonObject = ref new Windows::Data::Json::JsonObject(); - jsonObject->SetNamedValue(L"DisplayValue", Windows::Data::Json::JsonValue::CreateStringValue(value.DisplayValue)); - jsonObject->SetNamedValue(L"IsError", Windows::Data::Json::JsonValue::CreateBooleanValue(value.IsError)); - return jsonObject; - } - - static Windows::Data::Json::JsonObject ^ SaveSnapshotToJson(const ExpressionDisplaySnapshot& value) - { - auto jsonObject = ref new Windows::Data::Json::JsonObject(); - auto tokensJsonArray = ref new Windows::Data::Json::JsonArray(); - for (const auto& token : value.Tokens) - { - auto tokenJsonArray = ref new Windows::Data::Json::JsonArray(); - tokenJsonArray->Append(Windows::Data::Json::JsonValue::CreateStringValue(ref new Platform::String(token.first.c_str()))); - tokenJsonArray->Append(Windows::Data::Json::JsonValue::CreateNumberValue(token.second)); - tokensJsonArray->Append(tokenJsonArray); - } - jsonObject->SetNamedValue(L"Tokens", tokensJsonArray); - - auto commandsJsonArray = ref new Windows::Data::Json::JsonArray(); - for (const auto& command : value.Commands) - { - commandsJsonArray->Append(SaveSnapshotToJson(command)); - } - jsonObject->SetNamedValue(L"Commands", commandsJsonArray); - - return jsonObject; - } - - static Windows::Data::Json::JsonObject ^ SaveSnapshotToJson(const CalculatorManagerSnapshot& value) - { - auto jsonObject = ref new Windows::Data::Json::JsonObject(); - if (value.HistoryItems.has_value()) - { - auto historyJsonArray = ref new Windows::Data::Json::JsonArray(); - for (const auto& item : *value.HistoryItems) - { - historyJsonArray->Append(SaveSnapshotToJson(*item)); - } - jsonObject->SetNamedValue(L"HistoryItems", historyJsonArray); - } - return jsonObject; - } - - 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()))); - - auto tokensJsonArray = ref new Windows::Data::Json::JsonArray(); - for (const auto& token : *value.historyItemVector.spTokens) - { - auto tokenJsonArray = ref new Windows::Data::Json::JsonArray(); - tokenJsonArray->Append(Windows::Data::Json::JsonValue::CreateStringValue(ref new Platform::String(token.first.c_str()))); - tokenJsonArray->Append(Windows::Data::Json::JsonValue::CreateNumberValue(token.second)); - tokensJsonArray->Append(tokenJsonArray); - } - jsonObject->SetNamedValue(L"Tokens", tokensJsonArray); - - auto commandsJsonArray = ref new Windows::Data::Json::JsonArray(); - for (const auto& command : *value.historyItemVector.spCommands) - { - commandsJsonArray->Append(SaveSnapshotToJson(command)); - } - jsonObject->SetNamedValue(L"Commands", commandsJsonArray); - - return jsonObject; - } - - static Windows::Data::Json::JsonObject ^ SaveSnapshotToJson(const std::shared_ptr& value) - { - auto jsonObject = ref new Windows::Data::Json::JsonObject(); - auto opndCommand = dynamic_cast(value.get()); - if (opndCommand != nullptr) - { - jsonObject = SaveSnapshotToJson(*opndCommand); - } - auto unaryCommand = dynamic_cast(value.get()); - if (unaryCommand != nullptr) - { - jsonObject = SaveSnapshotToJson(*unaryCommand); - } - auto binaryCommand = dynamic_cast(value.get()); - if (binaryCommand != nullptr) - { - jsonObject = SaveSnapshotToJson(*binaryCommand); - } - auto parenthesesCommand = dynamic_cast(value.get()); - if (parenthesesCommand != nullptr) - { - jsonObject = SaveSnapshotToJson(*parenthesesCommand); - } - return jsonObject; - } - - static Windows::Data::Json::JsonObject ^ SaveSnapshotToJson(const COpndCommand& value) - { - auto jsonObject = ref new Windows::Data::Json::JsonObject(); - jsonObject->SetNamedValue(L"CommandType", Windows::Data::Json::JsonValue::CreateNumberValue(static_cast(value.GetCommandType()))); - jsonObject->SetNamedValue(L"IsNegative", Windows::Data::Json::JsonValue::CreateBooleanValue(value.IsNegative())); - jsonObject->SetNamedValue(L"IsDecimalPresent", Windows::Data::Json::JsonValue::CreateBooleanValue(value.IsDecimalPresent())); - jsonObject->SetNamedValue(L"IsSciFmt", Windows::Data::Json::JsonValue::CreateBooleanValue(value.IsSciFmt())); - auto commandsJsonArray = ref new Windows::Data::Json::JsonArray(); - for (const auto& command : *value.GetCommands()) - { - commandsJsonArray->Append(Windows::Data::Json::JsonValue::CreateNumberValue(command)); - } - jsonObject->SetNamedValue(L"Commands", commandsJsonArray); - return jsonObject; - } - - static Windows::Data::Json::JsonObject ^ SaveSnapshotToJson(const CUnaryCommand& value) - { - auto jsonObject = ref new Windows::Data::Json::JsonObject(); - jsonObject->SetNamedValue(L"CommandType", Windows::Data::Json::JsonValue::CreateNumberValue(static_cast(value.GetCommandType()))); - auto commandsJsonArray = ref new Windows::Data::Json::JsonArray(); - for (const auto& command : *value.GetCommands()) - { - commandsJsonArray->Append(Windows::Data::Json::JsonValue::CreateNumberValue(command)); - } - jsonObject->SetNamedValue(L"Commands", commandsJsonArray); - return jsonObject; - } - - static Windows::Data::Json::JsonObject ^ SaveSnapshotToJson(const CBinaryCommand& value) - { - auto jsonObject = ref new Windows::Data::Json::JsonObject(); - jsonObject->SetNamedValue(L"CommandType", Windows::Data::Json::JsonValue::CreateNumberValue(static_cast(value.GetCommandType()))); - jsonObject->SetNamedValue(L"Command", Windows::Data::Json::JsonValue::CreateNumberValue(value.GetCommand())); - return jsonObject; - } - - static Windows::Data::Json::JsonObject ^ SaveSnapshotToJson(const CParentheses& value) - { - auto jsonObject = ref new Windows::Data::Json::JsonObject(); - jsonObject->SetNamedValue(L"CommandType", Windows::Data::Json::JsonValue::CreateNumberValue(static_cast(value.GetCommandType()))); - jsonObject->SetNamedValue(L"Command", Windows::Data::Json::JsonValue::CreateNumberValue(value.GetCommand())); - return jsonObject; - } - - static void RestoreJsonToSnapshot(Windows::Data::Json::JsonObject ^ jsonObject, std::optional& value) - { - ApplicationSnapshot applicationSnapshot; - applicationSnapshot.SnapshotVersion = static_cast(jsonObject->GetNamedNumber(L"SnapshotVersion")); - if (applicationSnapshot.SnapshotVersion > SnapshotVersion) - { - return; - } - applicationSnapshot.Mode = static_cast(jsonObject->GetNamedNumber(L"Mode")); - if (jsonObject->HasKey(L"StandardCalculatorSnapshot")) - { - std::optional standardCalculatorSnapshot; - RestoreJsonToSnapshot(jsonObject->GetNamedObject(L"StandardCalculatorSnapshot"), standardCalculatorSnapshot); - if (standardCalculatorSnapshot.has_value()) - { - applicationSnapshot.StandardCalc = std::move(*standardCalculatorSnapshot); - } - else - { - return; - } - } - value = std::move(applicationSnapshot); - } - - static void RestoreJsonToSnapshot(Windows::Data::Json::JsonObject ^ jsonObject, std::optional& value) - { - StandardCalculatorSnapshot standardCalculatorSnapshot; - std::optional calcManagerSnapshot; - RestoreJsonToSnapshot(jsonObject->GetNamedObject(L"CalculatorManagerSnapshot"), calcManagerSnapshot); - if (calcManagerSnapshot.has_value()) - { - standardCalculatorSnapshot.CalcManager = std::move(*calcManagerSnapshot); - } - else - { - return; - } - std::optional primaryDisplaySnapshot; - RestoreJsonToSnapshot(jsonObject->GetNamedObject(L"PrimaryDisplay"), primaryDisplaySnapshot); - if (primaryDisplaySnapshot.has_value()) - { - standardCalculatorSnapshot.PrimaryDisplay = std::move(*primaryDisplaySnapshot); - } - else - { - return; - } - if (jsonObject->HasKey(L"ExpressionDisplay")) - { - std::optional expressionDisplaySnapshot; - RestoreJsonToSnapshot(jsonObject->GetNamedObject(L"ExpressionDisplay"), expressionDisplaySnapshot); - if (expressionDisplaySnapshot.has_value()) - { - standardCalculatorSnapshot.ExpressionDisplay = std::move(*expressionDisplaySnapshot); - } - else - { - return; - } - } - standardCalculatorSnapshot.DisplayCommands = RestoreExpressionCommandsFromJsonArray(jsonObject->GetNamedArray(L"DisplayCommands")); - value = std::move(standardCalculatorSnapshot); - } - - static void RestoreJsonToSnapshot(Windows::Data::Json::JsonObject ^ jsonObject, std::optional& value) - { - value = PrimaryDisplaySnapshot{ jsonObject->GetNamedString(L"DisplayValue"), jsonObject->GetNamedBoolean(L"IsError") }; - } - - static void RestoreJsonToSnapshot(Windows::Data::Json::JsonObject ^ jsonObject, std::optional& value) - { - ExpressionDisplaySnapshot expressionDisplaySnapshot; - expressionDisplaySnapshot.Tokens = RestoreExpressionTokensFromJsonArray(jsonObject->GetNamedArray(L"Tokens")); - if (expressionDisplaySnapshot.Tokens.empty()) - { - return; - } - expressionDisplaySnapshot.Commands = RestoreExpressionCommandsFromJsonArray(jsonObject->GetNamedArray(L"Commands")); - if (expressionDisplaySnapshot.Commands.empty()) - { - return; - } - value = std::move(expressionDisplaySnapshot); - } - - static void RestoreJsonToSnapshot(Windows::Data::Json::JsonObject ^ jsonObject, std::optional& value) - { - CalculatorManagerSnapshot calcManagerSnapshot; - if (jsonObject->HasKey(L"HistoryItems")) - { - std::vector> historyItems; - auto historyJsonArray = jsonObject->GetNamedArray(L"HistoryItems"); - for (uint32_t i = 0; i < historyJsonArray->Size; ++i) - { - std::optional historyItem; - RestoreJsonToSnapshot(historyJsonArray->GetObjectAt(i), historyItem); - if (historyItem.has_value()) - { - historyItems.push_back(std::make_shared(*historyItem)); - } - else - { - return; - } - } - calcManagerSnapshot.HistoryItems = std::move(historyItems); - } - value = std::move(calcManagerSnapshot); - } - - static void RestoreJsonToSnapshot(Windows::Data::Json::JsonObject ^ jsonObject, std::optional& value) - { - CalculationManager::HISTORYITEM historyItem; - historyItem.historyItemVector.expression = std::wstring(jsonObject->GetNamedString(L"Expression")->Data()); - historyItem.historyItemVector.result = std::wstring(jsonObject->GetNamedString(L"Result")->Data()); - historyItem.historyItemVector.spTokens = - std::make_shared>>(RestoreExpressionTokensFromJsonArray(jsonObject->GetNamedArray(L"Tokens"))); - if (historyItem.historyItemVector.spTokens->empty()) - { - return; - } - historyItem.historyItemVector.spCommands = std::make_shared>>( - RestoreExpressionCommandsFromJsonArray(jsonObject->GetNamedArray(L"Commands"))); - if (historyItem.historyItemVector.spCommands->empty()) - { - return; - } - value = std::move(historyItem); - } - - static void RestoreJsonToSnapshot(Windows::Data::Json::JsonObject ^ jsonObject, std::optional>& value) - { - auto commandType = static_cast(jsonObject->GetNamedNumber(L"CommandType")); - switch (commandType) - { - case CalculationManager::CommandType::OperandCommand: - { - std::optional opndCommand; - RestoreJsonToSnapshot(jsonObject, opndCommand); - if (opndCommand.has_value()) - { - value = std::make_shared(*opndCommand); - } - break; - } - case CalculationManager::CommandType::UnaryCommand: - { - std::optional unaryCommand; - RestoreJsonToSnapshot(jsonObject, unaryCommand); - if (unaryCommand.has_value()) - { - value = std::make_shared(*unaryCommand); - } - break; - } - case CalculationManager::CommandType::BinaryCommand: - { - std::optional binaryCommand; - RestoreJsonToSnapshot(jsonObject, binaryCommand); - if (binaryCommand.has_value()) - { - value = std::make_shared(*binaryCommand); - } - break; - } - case CalculationManager::CommandType::Parentheses: - { - std::optional parenthesesCommand; - RestoreJsonToSnapshot(jsonObject, parenthesesCommand); - if (parenthesesCommand.has_value()) - { - value = std::make_shared(*parenthesesCommand); - } - break; - } - default: - throw std::logic_error{ "c8cba597-dfec-447a-bd1c-e78a9ffaad95" }; - } - } - - static void RestoreJsonToSnapshot(Windows::Data::Json::JsonObject ^ jsonObject, std::optional& value) - { - auto isNegative = jsonObject->GetNamedBoolean(L"IsNegative"); - auto isDecimalPresent = jsonObject->GetNamedBoolean(L"IsDecimalPresent"); - auto isSciFmt = jsonObject->GetNamedBoolean(L"IsSciFmt"); - std::vector commands; - auto commandsJsonArray = jsonObject->GetNamedArray(L"Commands"); - for (uint32_t i = 0; i < commandsJsonArray->Size; ++i) - { - commands.push_back(static_cast(commandsJsonArray->GetNumberAt(i))); - } - value = COpndCommand(std::make_shared>(std::move(commands)), isNegative, isDecimalPresent, isSciFmt); - } - - static void RestoreJsonToSnapshot(Windows::Data::Json::JsonObject ^ jsonObject, std::optional& value) - { - std::vector commands; - auto commandsJsonArray = jsonObject->GetNamedArray(L"Commands"); - if (commandsJsonArray->Size == 1) - { - value = CUnaryCommand(static_cast(commandsJsonArray->GetNumberAt(0))); - } - else if (commandsJsonArray->Size == 2) - { - value = CUnaryCommand(static_cast(commandsJsonArray->GetNumberAt(0)), static_cast(commandsJsonArray->GetNumberAt(1))); - } - } - - static void RestoreJsonToSnapshot(Windows::Data::Json::JsonObject ^ jsonObject, std::optional& value) - { - value = CBinaryCommand(static_cast(jsonObject->GetNamedNumber(L"Command"))); - } - - static void RestoreJsonToSnapshot(Windows::Data::Json::JsonObject ^ jsonObject, std::optional& value) - { - value = CParentheses(static_cast(jsonObject->GetNamedNumber(L"Command"))); - } - - static std::vector> RestoreExpressionTokensFromJsonArray(Windows::Data::Json::JsonArray ^ jsonArray) - { - std::vector> tokens; - for (uint32_t i = 0; i < jsonArray->Size; ++i) - { - auto tokenJsonArray = jsonArray->GetArrayAt(i); - if (tokenJsonArray->Size == 2 && tokenJsonArray->GetAt(0)->ValueType == Windows::Data::Json::JsonValueType::String - && tokenJsonArray->GetAt(1)->ValueType == Windows::Data::Json::JsonValueType::Number) - { - tokens.emplace_back(std::wstring(tokenJsonArray->GetAt(0)->GetString()->Data()), static_cast(tokenJsonArray->GetAt(1)->GetNumber())); - } - else - { - return {}; - } - } - return tokens; - } - - static std::vector> RestoreExpressionCommandsFromJsonArray(Windows::Data::Json::JsonArray ^ jsonArray) - { - std::vector> commands; - for (uint32_t i = 0; i < jsonArray->Size; ++i) - { - std::optional> command; - RestoreJsonToSnapshot(jsonArray->GetObjectAt(i), command); - if (command.has_value()) - { - commands.push_back(*command); - } - else - { - return {}; - } - } - return commands; - } - - static bool IsJsonParsingException(Platform::COMException ^ e) - { - return e->HResult == WEB_E_JSON_VALUE_NOT_FOUND || e->HResult == E_ILLEGAL_METHOD_CALL; - } - }; + //struct SnapshotHelper + //{ + // static constexpr int SnapshotVersion = 0; + + // static Windows::Data::Json::JsonObject ^ SaveSnapshotToJson(const ApplicationSnapshot& value) + // { + // auto jsonObject = ref new Windows::Data::Json::JsonObject(); + // jsonObject->SetNamedValue(L"SnapshotVersion", Windows::Data::Json::JsonValue::CreateNumberValue(value.SnapshotVersion)); + // jsonObject->SetNamedValue(L"Mode", Windows::Data::Json::JsonValue::CreateNumberValue(value.Mode)); + // if (value.StandardCalc.has_value()) + // { + // jsonObject->SetNamedValue(L"StandardCalculatorSnapshot", SaveSnapshotToJson(*value.StandardCalc)); + // } + // return jsonObject; + // } + + // static Windows::Data::Json::JsonObject ^ SaveSnapshotToJson(const StandardCalculatorSnapshot& value) + // { + // auto jsonObject = ref new Windows::Data::Json::JsonObject(); + // jsonObject->SetNamedValue(L"CalculatorManagerSnapshot", SaveSnapshotToJson(value.CalcManager)); + // jsonObject->SetNamedValue(L"PrimaryDisplay", SaveSnapshotToJson(value.PrimaryDisplay)); + // if (value.ExpressionDisplay.has_value()) + // { + // jsonObject->SetNamedValue(L"ExpressionDisplay", SaveSnapshotToJson(*value.ExpressionDisplay)); + // } + // auto commandsJsonArray = ref new Windows::Data::Json::JsonArray(); + // for (const auto& command : value.DisplayCommands) + // { + // commandsJsonArray->Append(SaveSnapshotToJson(command)); + // } + // jsonObject->SetNamedValue(L"DisplayCommands", commandsJsonArray); + // return jsonObject; + // } + + // static Windows::Data::Json::JsonObject ^ SaveSnapshotToJson(const PrimaryDisplaySnapshot& value) + // { + // auto jsonObject = ref new Windows::Data::Json::JsonObject(); + // jsonObject->SetNamedValue(L"DisplayValue", Windows::Data::Json::JsonValue::CreateStringValue(value.DisplayValue)); + // jsonObject->SetNamedValue(L"IsError", Windows::Data::Json::JsonValue::CreateBooleanValue(value.IsError)); + // return jsonObject; + // } + + // static Windows::Data::Json::JsonObject ^ SaveSnapshotToJson(const ExpressionDisplaySnapshot& value) + // { + // auto jsonObject = ref new Windows::Data::Json::JsonObject(); + // auto tokensJsonArray = ref new Windows::Data::Json::JsonArray(); + // for (const auto& token : value.Tokens) + // { + // auto tokenJsonArray = ref new Windows::Data::Json::JsonArray(); + // tokenJsonArray->Append(Windows::Data::Json::JsonValue::CreateStringValue(ref new Platform::String(token.first.c_str()))); + // tokenJsonArray->Append(Windows::Data::Json::JsonValue::CreateNumberValue(token.second)); + // tokensJsonArray->Append(tokenJsonArray); + // } + // jsonObject->SetNamedValue(L"Tokens", tokensJsonArray); + + // auto commandsJsonArray = ref new Windows::Data::Json::JsonArray(); + // for (const auto& command : value.Commands) + // { + // commandsJsonArray->Append(SaveSnapshotToJson(command)); + // } + // jsonObject->SetNamedValue(L"Commands", commandsJsonArray); + + // return jsonObject; + // } + + // static Windows::Data::Json::JsonObject ^ SaveSnapshotToJson(const CalculatorManagerSnapshot& value) + // { + // auto jsonObject = ref new Windows::Data::Json::JsonObject(); + // if (value.HistoryItems.has_value()) + // { + // auto historyJsonArray = ref new Windows::Data::Json::JsonArray(); + // for (const auto& item : *value.HistoryItems) + // { + // historyJsonArray->Append(SaveSnapshotToJson(*item)); + // } + // jsonObject->SetNamedValue(L"HistoryItems", historyJsonArray); + // } + // return jsonObject; + // } + + // 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()))); + + // auto tokensJsonArray = ref new Windows::Data::Json::JsonArray(); + // for (const auto& token : *value.historyItemVector.spTokens) + // { + // auto tokenJsonArray = ref new Windows::Data::Json::JsonArray(); + // tokenJsonArray->Append(Windows::Data::Json::JsonValue::CreateStringValue(ref new Platform::String(token.first.c_str()))); + // tokenJsonArray->Append(Windows::Data::Json::JsonValue::CreateNumberValue(token.second)); + // tokensJsonArray->Append(tokenJsonArray); + // } + // jsonObject->SetNamedValue(L"Tokens", tokensJsonArray); + + // auto commandsJsonArray = ref new Windows::Data::Json::JsonArray(); + // for (const auto& command : *value.historyItemVector.spCommands) + // { + // commandsJsonArray->Append(SaveSnapshotToJson(command)); + // } + // jsonObject->SetNamedValue(L"Commands", commandsJsonArray); + + // return jsonObject; + // } + + // static Windows::Data::Json::JsonObject ^ SaveSnapshotToJson(const std::shared_ptr& value) + // { + // auto jsonObject = ref new Windows::Data::Json::JsonObject(); + // auto opndCommand = dynamic_cast(value.get()); + // if (opndCommand != nullptr) + // { + // jsonObject = SaveSnapshotToJson(*opndCommand); + // } + // auto unaryCommand = dynamic_cast(value.get()); + // if (unaryCommand != nullptr) + // { + // jsonObject = SaveSnapshotToJson(*unaryCommand); + // } + // auto binaryCommand = dynamic_cast(value.get()); + // if (binaryCommand != nullptr) + // { + // jsonObject = SaveSnapshotToJson(*binaryCommand); + // } + // auto parenthesesCommand = dynamic_cast(value.get()); + // if (parenthesesCommand != nullptr) + // { + // jsonObject = SaveSnapshotToJson(*parenthesesCommand); + // } + // return jsonObject; + // } + + // static Windows::Data::Json::JsonObject ^ SaveSnapshotToJson(const COpndCommand& value) + // { + // auto jsonObject = ref new Windows::Data::Json::JsonObject(); + // jsonObject->SetNamedValue(L"CommandType", Windows::Data::Json::JsonValue::CreateNumberValue(static_cast(value.GetCommandType()))); + // jsonObject->SetNamedValue(L"IsNegative", Windows::Data::Json::JsonValue::CreateBooleanValue(value.IsNegative())); + // jsonObject->SetNamedValue(L"IsDecimalPresent", Windows::Data::Json::JsonValue::CreateBooleanValue(value.IsDecimalPresent())); + // jsonObject->SetNamedValue(L"IsSciFmt", Windows::Data::Json::JsonValue::CreateBooleanValue(value.IsSciFmt())); + // auto commandsJsonArray = ref new Windows::Data::Json::JsonArray(); + // for (const auto& command : *value.GetCommands()) + // { + // commandsJsonArray->Append(Windows::Data::Json::JsonValue::CreateNumberValue(command)); + // } + // jsonObject->SetNamedValue(L"Commands", commandsJsonArray); + // return jsonObject; + // } + + // static Windows::Data::Json::JsonObject ^ SaveSnapshotToJson(const CUnaryCommand& value) + // { + // auto jsonObject = ref new Windows::Data::Json::JsonObject(); + // jsonObject->SetNamedValue(L"CommandType", Windows::Data::Json::JsonValue::CreateNumberValue(static_cast(value.GetCommandType()))); + // auto commandsJsonArray = ref new Windows::Data::Json::JsonArray(); + // for (const auto& command : *value.GetCommands()) + // { + // commandsJsonArray->Append(Windows::Data::Json::JsonValue::CreateNumberValue(command)); + // } + // jsonObject->SetNamedValue(L"Commands", commandsJsonArray); + // return jsonObject; + // } + + // static Windows::Data::Json::JsonObject ^ SaveSnapshotToJson(const CBinaryCommand& value) + // { + // auto jsonObject = ref new Windows::Data::Json::JsonObject(); + // jsonObject->SetNamedValue(L"CommandType", Windows::Data::Json::JsonValue::CreateNumberValue(static_cast(value.GetCommandType()))); + // jsonObject->SetNamedValue(L"Command", Windows::Data::Json::JsonValue::CreateNumberValue(value.GetCommand())); + // return jsonObject; + // } + + // static Windows::Data::Json::JsonObject ^ SaveSnapshotToJson(const CParentheses& value) + // { + // auto jsonObject = ref new Windows::Data::Json::JsonObject(); + // jsonObject->SetNamedValue(L"CommandType", Windows::Data::Json::JsonValue::CreateNumberValue(static_cast(value.GetCommandType()))); + // jsonObject->SetNamedValue(L"Command", Windows::Data::Json::JsonValue::CreateNumberValue(value.GetCommand())); + // return jsonObject; + // } + + // static void RestoreJsonToSnapshot(Windows::Data::Json::JsonObject ^ jsonObject, std::optional& value) + // { + // ApplicationSnapshot applicationSnapshot; + // applicationSnapshot.SnapshotVersion = static_cast(jsonObject->GetNamedNumber(L"SnapshotVersion")); + // if (applicationSnapshot.SnapshotVersion > SnapshotVersion) + // { + // return; + // } + // applicationSnapshot.Mode = static_cast(jsonObject->GetNamedNumber(L"Mode")); + // if (jsonObject->HasKey(L"StandardCalculatorSnapshot")) + // { + // std::optional standardCalculatorSnapshot; + // RestoreJsonToSnapshot(jsonObject->GetNamedObject(L"StandardCalculatorSnapshot"), standardCalculatorSnapshot); + // if (standardCalculatorSnapshot.has_value()) + // { + // applicationSnapshot.StandardCalc = std::move(*standardCalculatorSnapshot); + // } + // else + // { + // return; + // } + // } + // value = std::move(applicationSnapshot); + // } + + // static void RestoreJsonToSnapshot(Windows::Data::Json::JsonObject ^ jsonObject, std::optional& value) + // { + // StandardCalculatorSnapshot standardCalculatorSnapshot; + // std::optional calcManagerSnapshot; + // RestoreJsonToSnapshot(jsonObject->GetNamedObject(L"CalculatorManagerSnapshot"), calcManagerSnapshot); + // if (calcManagerSnapshot.has_value()) + // { + // standardCalculatorSnapshot.CalcManager = std::move(*calcManagerSnapshot); + // } + // else + // { + // return; + // } + // std::optional primaryDisplaySnapshot; + // RestoreJsonToSnapshot(jsonObject->GetNamedObject(L"PrimaryDisplay"), primaryDisplaySnapshot); + // if (primaryDisplaySnapshot.has_value()) + // { + // standardCalculatorSnapshot.PrimaryDisplay = std::move(*primaryDisplaySnapshot); + // } + // else + // { + // return; + // } + // if (jsonObject->HasKey(L"ExpressionDisplay")) + // { + // std::optional expressionDisplaySnapshot; + // RestoreJsonToSnapshot(jsonObject->GetNamedObject(L"ExpressionDisplay"), expressionDisplaySnapshot); + // if (expressionDisplaySnapshot.has_value()) + // { + // standardCalculatorSnapshot.ExpressionDisplay = std::move(*expressionDisplaySnapshot); + // } + // else + // { + // return; + // } + // } + // standardCalculatorSnapshot.DisplayCommands = RestoreExpressionCommandsFromJsonArray(jsonObject->GetNamedArray(L"DisplayCommands")); + // value = std::move(standardCalculatorSnapshot); + // } + + // static void RestoreJsonToSnapshot(Windows::Data::Json::JsonObject ^ jsonObject, std::optional& value) + // { + // value = PrimaryDisplaySnapshot{ jsonObject->GetNamedString(L"DisplayValue"), jsonObject->GetNamedBoolean(L"IsError") }; + // } + + // static void RestoreJsonToSnapshot(Windows::Data::Json::JsonObject ^ jsonObject, std::optional& value) + // { + // ExpressionDisplaySnapshot expressionDisplaySnapshot; + // expressionDisplaySnapshot.Tokens = RestoreExpressionTokensFromJsonArray(jsonObject->GetNamedArray(L"Tokens")); + // if (expressionDisplaySnapshot.Tokens.empty()) + // { + // return; + // } + // expressionDisplaySnapshot.Commands = RestoreExpressionCommandsFromJsonArray(jsonObject->GetNamedArray(L"Commands")); + // if (expressionDisplaySnapshot.Commands.empty()) + // { + // return; + // } + // value = std::move(expressionDisplaySnapshot); + // } + + // static void RestoreJsonToSnapshot(Windows::Data::Json::JsonObject ^ jsonObject, std::optional& value) + // { + // CalculatorManagerSnapshot calcManagerSnapshot; + // if (jsonObject->HasKey(L"HistoryItems")) + // { + // std::vector> historyItems; + // auto historyJsonArray = jsonObject->GetNamedArray(L"HistoryItems"); + // for (uint32_t i = 0; i < historyJsonArray->Size; ++i) + // { + // std::optional historyItem; + // RestoreJsonToSnapshot(historyJsonArray->GetObjectAt(i), historyItem); + // if (historyItem.has_value()) + // { + // historyItems.push_back(std::make_shared(*historyItem)); + // } + // else + // { + // return; + // } + // } + // calcManagerSnapshot.HistoryItems = std::move(historyItems); + // } + // value = std::move(calcManagerSnapshot); + // } + + // static void RestoreJsonToSnapshot(Windows::Data::Json::JsonObject ^ jsonObject, std::optional& value) + // { + // CalculationManager::HISTORYITEM historyItem; + // historyItem.historyItemVector.expression = std::wstring(jsonObject->GetNamedString(L"Expression")->Data()); + // historyItem.historyItemVector.result = std::wstring(jsonObject->GetNamedString(L"Result")->Data()); + // historyItem.historyItemVector.spTokens = + // std::make_shared>>(RestoreExpressionTokensFromJsonArray(jsonObject->GetNamedArray(L"Tokens"))); + // if (historyItem.historyItemVector.spTokens->empty()) + // { + // return; + // } + // historyItem.historyItemVector.spCommands = std::make_shared>>( + // RestoreExpressionCommandsFromJsonArray(jsonObject->GetNamedArray(L"Commands"))); + // if (historyItem.historyItemVector.spCommands->empty()) + // { + // return; + // } + // value = std::move(historyItem); + // } + + // static void RestoreJsonToSnapshot(Windows::Data::Json::JsonObject ^ jsonObject, std::optional>& value) + // { + // auto commandType = static_cast(jsonObject->GetNamedNumber(L"CommandType")); + // switch (commandType) + // { + // case CalculationManager::CommandType::OperandCommand: + // { + // std::optional opndCommand; + // RestoreJsonToSnapshot(jsonObject, opndCommand); + // if (opndCommand.has_value()) + // { + // value = std::make_shared(*opndCommand); + // } + // break; + // } + // case CalculationManager::CommandType::UnaryCommand: + // { + // std::optional unaryCommand; + // RestoreJsonToSnapshot(jsonObject, unaryCommand); + // if (unaryCommand.has_value()) + // { + // value = std::make_shared(*unaryCommand); + // } + // break; + // } + // case CalculationManager::CommandType::BinaryCommand: + // { + // std::optional binaryCommand; + // RestoreJsonToSnapshot(jsonObject, binaryCommand); + // if (binaryCommand.has_value()) + // { + // value = std::make_shared(*binaryCommand); + // } + // break; + // } + // case CalculationManager::CommandType::Parentheses: + // { + // std::optional parenthesesCommand; + // RestoreJsonToSnapshot(jsonObject, parenthesesCommand); + // if (parenthesesCommand.has_value()) + // { + // value = std::make_shared(*parenthesesCommand); + // } + // break; + // } + // default: + // throw std::logic_error{ "c8cba597-dfec-447a-bd1c-e78a9ffaad95" }; + // } + // } + + // static void RestoreJsonToSnapshot(Windows::Data::Json::JsonObject ^ jsonObject, std::optional& value) + // { + // auto isNegative = jsonObject->GetNamedBoolean(L"IsNegative"); + // auto isDecimalPresent = jsonObject->GetNamedBoolean(L"IsDecimalPresent"); + // auto isSciFmt = jsonObject->GetNamedBoolean(L"IsSciFmt"); + // std::vector commands; + // auto commandsJsonArray = jsonObject->GetNamedArray(L"Commands"); + // for (uint32_t i = 0; i < commandsJsonArray->Size; ++i) + // { + // commands.push_back(static_cast(commandsJsonArray->GetNumberAt(i))); + // } + // value = COpndCommand(std::make_shared>(std::move(commands)), isNegative, isDecimalPresent, isSciFmt); + // } + + // static void RestoreJsonToSnapshot(Windows::Data::Json::JsonObject ^ jsonObject, std::optional& value) + // { + // std::vector commands; + // auto commandsJsonArray = jsonObject->GetNamedArray(L"Commands"); + // if (commandsJsonArray->Size == 1) + // { + // value = CUnaryCommand(static_cast(commandsJsonArray->GetNumberAt(0))); + // } + // else if (commandsJsonArray->Size == 2) + // { + // value = CUnaryCommand(static_cast(commandsJsonArray->GetNumberAt(0)), static_cast(commandsJsonArray->GetNumberAt(1))); + // } + // } + + // static void RestoreJsonToSnapshot(Windows::Data::Json::JsonObject ^ jsonObject, std::optional& value) + // { + // value = CBinaryCommand(static_cast(jsonObject->GetNamedNumber(L"Command"))); + // } + + // static void RestoreJsonToSnapshot(Windows::Data::Json::JsonObject ^ jsonObject, std::optional& value) + // { + // value = CParentheses(static_cast(jsonObject->GetNamedNumber(L"Command"))); + // } + + // static std::vector> RestoreExpressionTokensFromJsonArray(Windows::Data::Json::JsonArray ^ jsonArray) + // { + // std::vector> tokens; + // for (uint32_t i = 0; i < jsonArray->Size; ++i) + // { + // auto tokenJsonArray = jsonArray->GetArrayAt(i); + // if (tokenJsonArray->Size == 2 && tokenJsonArray->GetAt(0)->ValueType == Windows::Data::Json::JsonValueType::String + // && tokenJsonArray->GetAt(1)->ValueType == Windows::Data::Json::JsonValueType::Number) + // { + // tokens.emplace_back(std::wstring(tokenJsonArray->GetAt(0)->GetString()->Data()), static_cast(tokenJsonArray->GetAt(1)->GetNumber())); + // } + // else + // { + // return {}; + // } + // } + // return tokens; + // } + + // static std::vector> RestoreExpressionCommandsFromJsonArray(Windows::Data::Json::JsonArray ^ jsonArray) + // { + // std::vector> commands; + // for (uint32_t i = 0; i < jsonArray->Size; ++i) + // { + // std::optional> command; + // RestoreJsonToSnapshot(jsonArray->GetObjectAt(i), command); + // if (command.has_value()) + // { + // commands.push_back(*command); + // } + // else + // { + // return {}; + // } + // } + // return commands; + // } + + // static bool IsJsonParsingException(Platform::COMException ^ e) + // { + // return e->HResult == WEB_E_JSON_VALUE_NOT_FOUND || e->HResult == E_ILLEGAL_METHOD_CALL; + // } + //}; } ApplicationViewModel::ApplicationViewModel() @@ -712,47 +712,47 @@ void ApplicationViewModel::SetDisplayNormalAlwaysOnTopOption() m_mode == ViewMode::Standard && ApplicationView::GetForCurrentView()->IsViewModeSupported(ApplicationViewMode::CompactOverlay) && !IsAlwaysOnTop; } -Windows::Data::Json::JsonObject ^ ApplicationViewModel::SaveApplicationSnapshot() -{ - ApplicationSnapshot applicationSnapshot; - applicationSnapshot.SnapshotVersion = SnapshotHelper::SnapshotVersion; - applicationSnapshot.Mode = static_cast(Mode); - if (m_CalculatorViewModel != nullptr && m_mode == ViewMode::Standard) - { - // Standard calculator is the only supported mode so far. - applicationSnapshot.StandardCalc = m_CalculatorViewModel->GetStandardCalculatorSnapshot(); - } - return SnapshotHelper::SaveSnapshotToJson(applicationSnapshot); -} - -bool ApplicationViewModel::TryRestoreFromSnapshot(Windows::Data::Json::JsonObject ^ jsonObject) -{ - std::optional applicationSnapshot; - try - { - SnapshotHelper::RestoreJsonToSnapshot(jsonObject, applicationSnapshot); - } - catch (Platform::COMException ^ e) - { - if (SnapshotHelper::IsJsonParsingException(e)) - { - return false; - } - throw; - } - - if (applicationSnapshot.has_value()) - { - Mode = static_cast(applicationSnapshot->Mode); - if (applicationSnapshot->StandardCalc.has_value()) - { - if (m_CalculatorViewModel == nullptr) - { - m_CalculatorViewModel = ref new StandardCalculatorViewModel(); - } - m_CalculatorViewModel->SetStandardCalculatorSnapshot(applicationSnapshot->StandardCalc.value()); - } - return true; - } - return false; -} +//Windows::Data::Json::JsonObject ^ ApplicationViewModel::SaveApplicationSnapshot() +//{ +// ApplicationSnapshot applicationSnapshot; +// applicationSnapshot.SnapshotVersion = SnapshotHelper::SnapshotVersion; +// applicationSnapshot.Mode = static_cast(Mode); +// if (m_CalculatorViewModel != nullptr && m_mode == ViewMode::Standard) +// { +// // Standard calculator is the only supported mode so far. +// applicationSnapshot.StandardCalc = m_CalculatorViewModel->GetStandardCalculatorSnapshot(); +// } +// return SnapshotHelper::SaveSnapshotToJson(applicationSnapshot); +//} +// +//bool ApplicationViewModel::TryRestoreFromSnapshot(Windows::Data::Json::JsonObject ^ jsonObject) +//{ +// std::optional applicationSnapshot; +// try +// { +// SnapshotHelper::RestoreJsonToSnapshot(jsonObject, applicationSnapshot); +// } +// catch (Platform::COMException ^ e) +// { +// if (SnapshotHelper::IsJsonParsingException(e)) +// { +// return false; +// } +// throw; +// } +// +// if (applicationSnapshot.has_value()) +// { +// Mode = static_cast(applicationSnapshot->Mode); +// if (applicationSnapshot->StandardCalc.has_value()) +// { +// if (m_CalculatorViewModel == nullptr) +// { +// m_CalculatorViewModel = ref new StandardCalculatorViewModel(); +// } +// m_CalculatorViewModel->SetStandardCalculatorSnapshot(applicationSnapshot->StandardCalc.value()); +// } +// return true; +// } +// return false; +//} diff --git a/src/CalcViewModel/ApplicationViewModel.h b/src/CalcViewModel/ApplicationViewModel.h index 542144fa5..992754d5e 100644 --- a/src/CalcViewModel/ApplicationViewModel.h +++ b/src/CalcViewModel/ApplicationViewModel.h @@ -16,7 +16,7 @@ namespace CalculatorApp { int SnapshotVersion; int Mode; - std::optional StandardCalc; + //std::optional StandardCalc; }; [Windows::UI::Xaml::Data::Bindable] public ref class ApplicationViewModel sealed : public Windows::UI::Xaml::Data::INotifyPropertyChanged @@ -103,8 +103,8 @@ namespace CalculatorApp void ToggleAlwaysOnTop(float width, float height); - Windows::Data::Json::JsonObject ^ SaveApplicationSnapshot(); - bool TryRestoreFromSnapshot(Windows::Data::Json::JsonObject ^ jsonObject); + //Windows::Data::Json::JsonObject ^ SaveApplicationSnapshot(); + //bool TryRestoreFromSnapshot(Windows::Data::Json::JsonObject ^ jsonObject); private: bool TryRecoverFromNavigationModeFailure(); diff --git a/src/CalcViewModel/CalcViewModel.vcxproj b/src/CalcViewModel/CalcViewModel.vcxproj index b8869d4bb..aedd8d8f0 100644 --- a/src/CalcViewModel/CalcViewModel.vcxproj +++ b/src/CalcViewModel/CalcViewModel.vcxproj @@ -338,6 +338,7 @@ + @@ -380,6 +381,7 @@ Create Create + diff --git a/src/CalcViewModel/CalcViewModel.vcxproj.filters b/src/CalcViewModel/CalcViewModel.vcxproj.filters index 46ee7fd0a..9de55c393 100644 --- a/src/CalcViewModel/CalcViewModel.vcxproj.filters +++ b/src/CalcViewModel/CalcViewModel.vcxproj.filters @@ -89,6 +89,7 @@ + @@ -203,6 +204,7 @@ + diff --git a/src/CalcViewModel/Snapshots.cpp b/src/CalcViewModel/Snapshots.cpp new file mode 100644 index 000000000..1af643c9b --- /dev/null +++ b/src/CalcViewModel/Snapshots.cpp @@ -0,0 +1,59 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT License. + +#include "pch.h" +#include + +#include "Snapshots.h" + +namespace CalculatorApp::ViewModel +{ + CalcEngineHistoryToken::CalcEngineHistoryToken(Platform::String ^ opCodeName, int cmdIndex) + { + assert(opCodeName != nullptr && "opCodeName is mandatory."); + OpCodeName = opCodeName; + CommandIndex = cmdIndex; + } + + CalcEnginHistoryItem::CalcEnginHistoryItem(const CalculationManager::HISTORYITEM& item) + { + Tokens = ref new Platform::Collections::Vector(); + if (item.historyItemVector.spTokens != nullptr) + { + for (auto& [opCode, cmdIdx] : *item.historyItemVector.spTokens) + { + Tokens->Append(ref new CalcEngineHistoryToken(ref new Platform::String(opCode.c_str()), cmdIdx)); + } + } + Expression = ref new Platform::String(item.historyItemVector.expression.c_str()); + Result = ref new Platform::String(item.historyItemVector.result.c_str()); + } + + CalcManagerSnapshot::CalcManagerSnapshot(const CalculationManager::CalculatorManager& calcMgr) + { + auto& items = calcMgr.GetHistoryItems(); + if (!items.empty()) + { + for (auto& item : items) + { + HistoryItems->Append(ref new CalcEnginHistoryItem(*item)); + } + } + } + + PrimaryDisplaySnapshot::PrimaryDisplaySnapshot(Platform::String ^ display, bool isError) + { + assert(display != nullptr && "display is mandatory"); + DisplayValue = display; + IsError = isError; + } + + ExpressionDisplaySnapshot::ExpressionDisplaySnapshot(const std::vector& tokens) + { + Tokens = ref new Platform::Collections::Vector(); + for (auto& [opCode, cmdIdx] : tokens) + { + Tokens->Append(ref new CalcEngineHistoryToken(ref new Platform::String(opCode.c_str()), cmdIdx)); + } + } +} diff --git a/src/CalcViewModel/Snapshots.h b/src/CalcViewModel/Snapshots.h new file mode 100644 index 000000000..91ee1a44e --- /dev/null +++ b/src/CalcViewModel/Snapshots.h @@ -0,0 +1,69 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT License. + +#pragma once +#include "CalcManager/CalculatorManager.h" + +namespace CalculatorApp::ViewModel +{ +public + ref struct CalcEngineHistoryToken sealed + { + property Platform::String ^ OpCodeName; // mandatory + property int CommandIndex; + + internal :; + explicit CalcEngineHistoryToken(Platform::String ^ opCodeName, int cmdIndex); + }; + +public + ref struct CalcEnginHistoryItem sealed + { + property Windows::Foundation::Collections::IVector ^ Tokens; // mandatory + // TODO: commands + property Platform::String ^ Expression; // mandatory + property Platform::String ^ Result; // mandatory + + internal :; + explicit CalcEnginHistoryItem(const CalculationManager::HISTORYITEM& item); + }; + +public + ref struct CalcManagerSnapshot sealed + { + property Windows::Foundation::Collections::IVector ^ HistoryItems; // optional + + internal :; + explicit CalcManagerSnapshot(const CalculationManager::CalculatorManager& calcMgr); + }; + +public + ref struct PrimaryDisplaySnapshot sealed + { + property Platform::String ^ DisplayValue; // mandatory + property bool IsError; + + internal :; + explicit PrimaryDisplaySnapshot(Platform::String ^ display, bool isError); + }; + +public + ref struct ExpressionDisplaySnapshot sealed + { + property Windows::Foundation::Collections::IVector ^ Tokens; + // TODO: commands + + internal :; + using CalcHistoryToken = std::pair; + explicit ExpressionDisplaySnapshot(const std::vector& tokens); + }; + +public + ref struct StandardCalculatorSnapshot sealed + { + property CalcManagerSnapshot ^ CalcManager; // mandatory + property PrimaryDisplaySnapshot ^ PrimaryDisplay; // mandatory + property ExpressionDisplaySnapshot ^ ExpressionDisplay; // optional + // TODO: commands + }; +} diff --git a/src/CalcViewModel/StandardCalculatorViewModel.cpp b/src/CalcViewModel/StandardCalculatorViewModel.cpp index 047356805..d39e58489 100644 --- a/src/CalcViewModel/StandardCalculatorViewModel.cpp +++ b/src/CalcViewModel/StandardCalculatorViewModel.cpp @@ -227,7 +227,7 @@ String ^ StandardCalculatorViewModel::CalculateNarratorDisplayValue(_In_ wstring String ^ StandardCalculatorViewModel::GetNarratorStringReadRawNumbers(_In_ String ^ localizedDisplayValue) { wstring ws; - LocalizationSettings^ locSettings = LocalizationSettings::GetInstance(); + LocalizationSettings ^ locSettings = LocalizationSettings::GetInstance(); // Insert a space after each digit in the string, to force Narrator to read them as separate numbers. for (const wchar_t& c : localizedDisplayValue) @@ -386,7 +386,7 @@ void StandardCalculatorViewModel::SetTokens(_Inout_ shared_ptr& newMemorizedNumbers) { - LocalizationSettings^ localizer = LocalizationSettings::GetInstance(); + LocalizationSettings ^ localizer = LocalizationSettings::GetInstance(); if (newMemorizedNumbers.size() == 0) // Memory has been cleared { MemorizedNumbers->Clear(); @@ -1060,8 +1060,8 @@ ButtonInfo StandardCalculatorViewModel::MapCharacterToButtonId(char16 ch) { if (LocalizationSettings::GetInstance()->IsLocalizedDigit(ch)) { - result.buttonId = - NumbersAndOperatorsEnum::Zero + static_cast(ch - LocalizationSettings::GetInstance()->GetDigitSymbolFromEnUsDigit('0')); + result.buttonId = NumbersAndOperatorsEnum::Zero + + static_cast(ch - LocalizationSettings::GetInstance()->GetDigitSymbolFromEnUsDigit('0')); result.canSendNegate = true; } } @@ -1588,7 +1588,7 @@ void StandardCalculatorViewModel::UpdateProgrammerPanelDisplay() binaryDisplayString = m_standardCalculatorManager.GetResultForRadix(2, precision, true); } } - LocalizationSettings^ localizer = LocalizationSettings::GetInstance(); + LocalizationSettings ^ localizer = LocalizationSettings::GetInstance(); binaryDisplayString = AddPadding(binaryDisplayString); localizer->LocalizeDisplayValue(&hexDisplayString); @@ -1787,49 +1787,57 @@ void StandardCalculatorViewModel::SetBitshiftRadioButtonCheckedAnnouncement(Plat Announcement = CalculatorAnnouncement::GetBitShiftRadioButtonCheckedAnnouncement(announcement); } -StandardCalculatorSnapshot StandardCalculatorViewModel::GetStandardCalculatorSnapshot() const -{ - StandardCalculatorSnapshot snapshot; - auto& historyItems = m_standardCalculatorManager.GetHistoryItems(); - if (!historyItems.empty()) - { - snapshot.CalcManager.HistoryItems = std::move(historyItems); - } - snapshot.PrimaryDisplay = PrimaryDisplaySnapshot{ m_DisplayValue, m_IsInError }; - if (!m_tokens->empty() && !m_commands->empty()) - { - snapshot.ExpressionDisplay = { *m_tokens, *m_commands }; - } - snapshot.DisplayCommands = m_standardCalculatorManager.GetDisplayCommandsSnapshot(); - return snapshot; -} - -void StandardCalculatorViewModel::SetStandardCalculatorSnapshot(const StandardCalculatorSnapshot& snapshot) -{ - if (snapshot.CalcManager.HistoryItems.has_value()) - { - m_standardCalculatorManager.SetHistoryItems(snapshot.CalcManager.HistoryItems.value()); - } - - std::vector commands; - if (snapshot.ExpressionDisplay.has_value() && snapshot.ExpressionDisplay->Tokens.back().first == L"=") - { - commands = GetCommandsFromExpressionCommands(snapshot.ExpressionDisplay->Commands); - } - if (commands.empty() && !snapshot.DisplayCommands.empty()) - { - commands = GetCommandsFromExpressionCommands(snapshot.DisplayCommands); - } - for (const auto& command : commands) - { - m_standardCalculatorManager.SendCommand(static_cast(command)); - } - - if (snapshot.ExpressionDisplay.has_value()) - { - SetExpressionDisplay( - std::make_shared>>(snapshot.ExpressionDisplay->Tokens), - std::make_shared>>(snapshot.ExpressionDisplay->Commands)); - } - SetPrimaryDisplay(snapshot.PrimaryDisplay.DisplayValue, snapshot.PrimaryDisplay.IsError); -} +StandardCalculatorSnapshot ^ StandardCalculatorViewModel::GetSnapshot() const +{ + auto result = ref new StandardCalculatorSnapshot(); + result->CalcManager = ref new CalcManagerSnapshot(m_standardCalculatorManager); + result->PrimaryDisplay = ref new PrimaryDisplaySnapshot(m_DisplayValue, m_IsInError); + result->ExpressionDisplay = ref new ExpressionDisplaySnapshot(*m_tokens); + return nullptr; +} +// StandardCalculatorSnapshot StandardCalculatorViewModel::GetStandardCalculatorSnapshot() const +//{ +// StandardCalculatorSnapshot snapshot; +// auto& historyItems = m_standardCalculatorManager.GetHistoryItems(); +// if (!historyItems.empty()) +// { +// snapshot.CalcManager.HistoryItems = std::move(historyItems); +// } +// snapshot.PrimaryDisplay = PrimaryDisplaySnapshot{ m_DisplayValue, m_IsInError }; +// if (!m_tokens->empty() && !m_commands->empty()) +// { +// snapshot.ExpressionDisplay = { *m_tokens, *m_commands }; +// } +// snapshot.DisplayCommands = m_standardCalculatorManager.GetDisplayCommandsSnapshot(); +// return snapshot; +// } +// +// void StandardCalculatorViewModel::SetStandardCalculatorSnapshot(const StandardCalculatorSnapshot& snapshot) +//{ +// if (snapshot.CalcManager.HistoryItems.has_value()) +// { +// m_standardCalculatorManager.SetHistoryItems(snapshot.CalcManager.HistoryItems.value()); +// } +// +// std::vector commands; +// if (snapshot.ExpressionDisplay.has_value() && snapshot.ExpressionDisplay->Tokens.back().first == L"=") +// { +// commands = GetCommandsFromExpressionCommands(snapshot.ExpressionDisplay->Commands); +// } +// if (commands.empty() && !snapshot.DisplayCommands.empty()) +// { +// commands = GetCommandsFromExpressionCommands(snapshot.DisplayCommands); +// } +// for (const auto& command : commands) +// { +// m_standardCalculatorManager.SendCommand(static_cast(command)); +// } +// +// if (snapshot.ExpressionDisplay.has_value()) +// { +// SetExpressionDisplay( +// std::make_shared>>(snapshot.ExpressionDisplay->Tokens), +// std::make_shared>>(snapshot.ExpressionDisplay->Commands)); +// } +// SetPrimaryDisplay(snapshot.PrimaryDisplay.DisplayValue, snapshot.PrimaryDisplay.IsError); +// } diff --git a/src/CalcViewModel/StandardCalculatorViewModel.h b/src/CalcViewModel/StandardCalculatorViewModel.h index 160a7fe8c..93fe41f74 100644 --- a/src/CalcViewModel/StandardCalculatorViewModel.h +++ b/src/CalcViewModel/StandardCalculatorViewModel.h @@ -7,11 +7,13 @@ #include "Common/CalculatorDisplay.h" #include "Common/EngineResourceProvider.h" #include "Common/CalculatorButtonUser.h" -#include "HistoryViewModel.h" -#include "MemoryItemViewModel.h" #include "Common/BitLength.h" #include "Common/NumberBase.h" +#include "HistoryViewModel.h" +#include "MemoryItemViewModel.h" +#include "Snapshots.h" + namespace CalculatorUnitTests { class MultiWindowUnitTests; @@ -25,38 +27,40 @@ namespace CalculatorApp namespace ViewModel { #define ASCII_0 48 - public delegate void HideMemoryClickedHandler(); + public + delegate void HideMemoryClickedHandler(); - public value struct ButtonInfo + public + value struct ButtonInfo { CalculatorApp::ViewModel::Common::NumbersAndOperatorsEnum buttonId; bool canSendNegate; }; - struct CalculatorManagerSnapshot - { - std::optional>> HistoryItems; - }; - - struct PrimaryDisplaySnapshot - { - Platform::String ^ DisplayValue; - bool IsError = false; - }; - - struct ExpressionDisplaySnapshot - { - std::vector> Tokens; - std::vector> Commands; - }; - - struct StandardCalculatorSnapshot - { - CalculatorManagerSnapshot CalcManager; - PrimaryDisplaySnapshot PrimaryDisplay; - std::optional ExpressionDisplay; - std::vector> DisplayCommands; - }; + // struct CalculatorManagerSnapshot + //{ + // std::optional>> HistoryItems; + // }; + + // struct PrimaryDisplaySnapshot + //{ + // Platform::String ^ DisplayValue; + // bool IsError = false; + // }; + + // struct ExpressionDisplaySnapshot + //{ + // std::vector> Tokens; + // std::vector> Commands; + // }; + + // struct StandardCalculatorSnapshot + //{ + // CalculatorManagerSnapshot CalcManager; + // PrimaryDisplaySnapshot PrimaryDisplay; + // std::optional ExpressionDisplay; + // std::vector> DisplayCommands; + // }; [Windows::UI::Xaml::Data::Bindable] public ref class StandardCalculatorViewModel sealed : public Windows::UI::Xaml::Data::INotifyPropertyChanged { @@ -136,7 +140,7 @@ namespace CalculatorApp static property Platform::String ^ IsBitFlipCheckedPropertyName { Platform::String ^ get() { return Platform::StringReference(L"IsBitFlipChecked"); } } - property CalculatorApp::ViewModel::Common::BitLength ValueBitLength + property CalculatorApp::ViewModel::Common::BitLength ValueBitLength { CalculatorApp::ViewModel::Common::BitLength get() { @@ -216,7 +220,7 @@ namespace CalculatorApp static property Platform::String ^ IsProgrammerPropertyName { Platform::String ^ get() { return Platform::StringReference(L"IsProgrammer"); } } - property bool IsEditingEnabled + property bool IsEditingEnabled { bool get() { @@ -265,6 +269,8 @@ namespace CalculatorApp } } + property StandardCalculatorSnapshot ^ Snapshot { StandardCalculatorSnapshot ^ get() { return GetSnapshot(); } } + // Used by unit tests void ResetCalcManager(bool clearMemory); void SendCommandToCalcManager(int command); @@ -284,8 +290,7 @@ namespace CalculatorApp void SwitchAngleType(CalculatorApp::ViewModel::Common::NumbersAndOperatorsEnum num); void FtoEButtonToggled(); - internal: - void OnPaste(Platform::String ^ pastedString); + internal : void OnPaste(Platform::String ^ pastedString); void OnCopyCommand(Platform::Object ^ parameter); void OnPasteCommand(Platform::Object ^ parameter); @@ -307,9 +312,9 @@ namespace CalculatorApp Platform::String ^ GetRawDisplayValue(); void Recalculate(bool fromHistory = false); bool IsOperator(CalculationManager::Command cmdenum); - void SetMemorizedNumbersString(); + void SetMemorizedNumbersString(); void ResetRadixAndUpdateMemory(bool resetRadix); - + void SetPrecision(int32_t precision); void UpdateMaxIntDigits() { @@ -320,10 +325,10 @@ namespace CalculatorApp return m_CurrentAngleType; } - StandardCalculatorSnapshot GetStandardCalculatorSnapshot() const; - void SetStandardCalculatorSnapshot(const StandardCalculatorSnapshot& state); - + // void SetStandardCalculatorSnapshot(const StandardCalculatorSnapshot& state); + private: + StandardCalculatorSnapshot ^ GetSnapshot() const; void SetMemorizedNumbers(const std::vector& memorizedNumbers); void UpdateProgrammerPanelDisplay(); void HandleUpdatedOperandData(CalculationManager::Command cmdenum); @@ -372,8 +377,7 @@ namespace CalculatorApp Common::DisplayExpressionToken ^ m_selectedExpressionToken; Platform::String ^ LocalizeDisplayValue(_In_ std::wstring const& displayValue); - Platform::String - ^ CalculateNarratorDisplayValue(_In_ std::wstring const& displayValue, _In_ Platform::String ^ localizedDisplayValue); + Platform::String ^ CalculateNarratorDisplayValue(_In_ std::wstring const& displayValue, _In_ Platform::String ^ localizedDisplayValue); CalculatorApp::ViewModel::Common::Automation::NarratorAnnouncement ^ GetDisplayUpdatedNarratorAnnouncement(); Platform::String ^ GetCalculatorExpressionAutomationName(); Platform::String ^ GetNarratorStringReadRawNumbers(_In_ Platform::String ^ localizedDisplayValue); From 5bb3c54840a68473c44983cba212fc82e69a9e4f Mon Sep 17 00:00:00 2001 From: Tian Liao Date: Wed, 16 Oct 2024 15:36:42 +0800 Subject: [PATCH 02/21] stash changes --- src/CalcViewModel/Snapshots.cpp | 90 +++++++++++++++++-- src/CalcViewModel/Snapshots.h | 35 ++++---- .../StandardCalculatorViewModel.cpp | 1 + 3 files changed, 104 insertions(+), 22 deletions(-) diff --git a/src/CalcViewModel/Snapshots.cpp b/src/CalcViewModel/Snapshots.cpp index 1af643c9b..b238afce3 100644 --- a/src/CalcViewModel/Snapshots.cpp +++ b/src/CalcViewModel/Snapshots.cpp @@ -3,26 +3,102 @@ #include "pch.h" #include +#include #include "Snapshots.h" +namespace +{ + ref struct UnaryCommand sealed : public CalculatorApp::ViewModel::ICalcManagerIExprCommand + { + property Windows::Foundation::Collections::IVector ^ Commands; + }; + + ref struct BinaryCommand sealed : public CalculatorApp::ViewModel::ICalcManagerIExprCommand + { + property int Command; + }; + + ref struct OperandCommand sealed : public CalculatorApp::ViewModel::ICalcManagerIExprCommand + { + property bool IsNegative; + property bool IsDecimalPresent; + property bool IsSciFmt; + property Windows::Foundation::Collections::IVector ^ Commands; + }; + + ref struct Parentheses sealed : public CalculatorApp::ViewModel::ICalcManagerIExprCommand + { + property int Command; + }; + + CalculatorApp::ViewModel::ICalcManagerIExprCommand ^ CreateExprCommand(const IExpressionCommand* exprCmd) { + switch (exprCmd->GetCommandType()) + { + case CalculationManager::CommandType::UnaryCommand: + { + auto cmd = static_cast(exprCmd); + auto result = ref new UnaryCommand(); + result->Commands = ref new Platform::Collections::Vector(); + for (auto& subcmd : *cmd->GetCommands()) + { + result->Commands->Append(subcmd); + } + return result; + } + case CalculationManager::CommandType::BinaryCommand: + { + auto cmd = static_cast(exprCmd); + auto result = ref new BinaryCommand(); + result->Command = cmd->GetCommand(); + return result; + } + case CalculationManager::CommandType::OperandCommand: + { + auto cmd = static_cast(exprCmd); + auto result = ref new OperandCommand(); + result->IsNegative = cmd->IsNegative(); + result->IsDecimalPresent = cmd->IsDecimalPresent(); + result->IsSciFmt = cmd->IsSciFmt(); + result->Commands = ref new Platform::Collections::Vector(); + for (auto& subcmd : *cmd->GetCommands()) + { + result->Commands->Append(subcmd); + } + return result; + } + case CalculationManager::CommandType::Parentheses: + { + auto cmd = static_cast(exprCmd); + auto result = ref new Parentheses(); + result->Command = cmd->GetCommand(); + return result; + } + default: + throw std::logic_error{ "unhandled command type." }; + } + } +} // namespace + namespace CalculatorApp::ViewModel { - CalcEngineHistoryToken::CalcEngineHistoryToken(Platform::String ^ opCodeName, int cmdIndex) + CalcManagerHistoryToken::CalcManagerHistoryToken(Platform::String ^ opCodeName, int cmdIndex) { assert(opCodeName != nullptr && "opCodeName is mandatory."); OpCodeName = opCodeName; CommandIndex = cmdIndex; } - CalcEnginHistoryItem::CalcEnginHistoryItem(const CalculationManager::HISTORYITEM& item) + CalcManagerHistoryItem::CalcManagerHistoryItem(const CalculationManager::HISTORYITEM& item) { - Tokens = ref new Platform::Collections::Vector(); + Tokens = ref new Platform::Collections::Vector(); + Commands = ref new Platform::Collections::Vector(); if (item.historyItemVector.spTokens != nullptr) { for (auto& [opCode, cmdIdx] : *item.historyItemVector.spTokens) { - Tokens->Append(ref new CalcEngineHistoryToken(ref new Platform::String(opCode.c_str()), cmdIdx)); + Tokens->Append(ref new CalcManagerHistoryToken(ref new Platform::String(opCode.c_str()), cmdIdx)); + // Commands->Append(); } } Expression = ref new Platform::String(item.historyItemVector.expression.c_str()); @@ -36,7 +112,7 @@ namespace CalculatorApp::ViewModel { for (auto& item : items) { - HistoryItems->Append(ref new CalcEnginHistoryItem(*item)); + HistoryItems->Append(ref new CalcManagerHistoryItem(*item)); } } } @@ -50,10 +126,10 @@ namespace CalculatorApp::ViewModel ExpressionDisplaySnapshot::ExpressionDisplaySnapshot(const std::vector& tokens) { - Tokens = ref new Platform::Collections::Vector(); + Tokens = ref new Platform::Collections::Vector(); for (auto& [opCode, cmdIdx] : tokens) { - Tokens->Append(ref new CalcEngineHistoryToken(ref new Platform::String(opCode.c_str()), cmdIdx)); + Tokens->Append(ref new CalcManagerHistoryToken(ref new Platform::String(opCode.c_str()), cmdIdx)); } } } diff --git a/src/CalcViewModel/Snapshots.h b/src/CalcViewModel/Snapshots.h index 91ee1a44e..ab62dda04 100644 --- a/src/CalcViewModel/Snapshots.h +++ b/src/CalcViewModel/Snapshots.h @@ -7,31 +7,36 @@ namespace CalculatorApp::ViewModel { public - ref struct CalcEngineHistoryToken sealed + interface struct ICalcManagerIExprCommand + { + }; + +public + ref struct CalcManagerHistoryToken sealed { property Platform::String ^ OpCodeName; // mandatory property int CommandIndex; internal :; - explicit CalcEngineHistoryToken(Platform::String ^ opCodeName, int cmdIndex); + explicit CalcManagerHistoryToken(Platform::String ^ opCodeName, int cmdIndex); }; public - ref struct CalcEnginHistoryItem sealed + ref struct CalcManagerHistoryItem sealed { - property Windows::Foundation::Collections::IVector ^ Tokens; // mandatory - // TODO: commands - property Platform::String ^ Expression; // mandatory - property Platform::String ^ Result; // mandatory + property Windows::Foundation::Collections::IVector ^ Tokens; // mandatory + property Windows::Foundation::Collections::IVector ^ Commands; // mandatory + property Platform::String ^ Expression; // mandatory + property Platform::String ^ Result; // mandatory internal :; - explicit CalcEnginHistoryItem(const CalculationManager::HISTORYITEM& item); + explicit CalcManagerHistoryItem(const CalculationManager::HISTORYITEM& item); }; public ref struct CalcManagerSnapshot sealed { - property Windows::Foundation::Collections::IVector ^ HistoryItems; // optional + property Windows::Foundation::Collections::IVector ^ HistoryItems; // optional internal :; explicit CalcManagerSnapshot(const CalculationManager::CalculatorManager& calcMgr); @@ -50,7 +55,7 @@ public public ref struct ExpressionDisplaySnapshot sealed { - property Windows::Foundation::Collections::IVector ^ Tokens; + property Windows::Foundation::Collections::IVector ^ Tokens; // TODO: commands internal :; @@ -61,9 +66,9 @@ public public ref struct StandardCalculatorSnapshot sealed { - property CalcManagerSnapshot ^ CalcManager; // mandatory - property PrimaryDisplaySnapshot ^ PrimaryDisplay; // mandatory - property ExpressionDisplaySnapshot ^ ExpressionDisplay; // optional - // TODO: commands + property CalcManagerSnapshot ^ CalcManager; // mandatory + property PrimaryDisplaySnapshot ^ PrimaryDisplay; // mandatory + property ExpressionDisplaySnapshot ^ ExpressionDisplay; // optional + property Windows::Foundation::Collections::IVector ^ Commands; // mandatory }; -} +} // namespace CalculatorApp::ViewModel diff --git a/src/CalcViewModel/StandardCalculatorViewModel.cpp b/src/CalcViewModel/StandardCalculatorViewModel.cpp index d39e58489..6a0727ab0 100644 --- a/src/CalcViewModel/StandardCalculatorViewModel.cpp +++ b/src/CalcViewModel/StandardCalculatorViewModel.cpp @@ -1789,6 +1789,7 @@ void StandardCalculatorViewModel::SetBitshiftRadioButtonCheckedAnnouncement(Plat StandardCalculatorSnapshot ^ StandardCalculatorViewModel::GetSnapshot() const { + CUnaryCommand; auto result = ref new StandardCalculatorSnapshot(); result->CalcManager = ref new CalcManagerSnapshot(m_standardCalculatorManager); result->PrimaryDisplay = ref new PrimaryDisplaySnapshot(m_DisplayValue, m_IsInError); From 54d891a1eee7b6e34715795b23f33c26b1598686 Mon Sep 17 00:00:00 2001 From: Tian Liao Date: Wed, 16 Oct 2024 17:17:33 +0800 Subject: [PATCH 03/21] pass build --- src/CalcViewModel/Snapshots.cpp | 25 +++++++++++-------- .../StandardCalculatorViewModel.cpp | 1 - .../CalcViewModelCopyForUT.vcxproj | 2 ++ .../CalcViewModelCopyForUT.vcxproj.filters | 2 ++ 4 files changed, 18 insertions(+), 12 deletions(-) diff --git a/src/CalcViewModel/Snapshots.cpp b/src/CalcViewModel/Snapshots.cpp index b238afce3..87fc31dba 100644 --- a/src/CalcViewModel/Snapshots.cpp +++ b/src/CalcViewModel/Snapshots.cpp @@ -4,6 +4,7 @@ #include "pch.h" #include #include +#include #include "Snapshots.h" @@ -11,25 +12,29 @@ namespace { ref struct UnaryCommand sealed : public CalculatorApp::ViewModel::ICalcManagerIExprCommand { - property Windows::Foundation::Collections::IVector ^ Commands; + internal :; + std::vector Commands; }; ref struct BinaryCommand sealed : public CalculatorApp::ViewModel::ICalcManagerIExprCommand { - property int Command; + internal :; + int Command; }; ref struct OperandCommand sealed : public CalculatorApp::ViewModel::ICalcManagerIExprCommand { - property bool IsNegative; - property bool IsDecimalPresent; - property bool IsSciFmt; - property Windows::Foundation::Collections::IVector ^ Commands; + internal :; + bool IsNegative; + bool IsDecimalPresent; + bool IsSciFmt; + std::vector Commands; }; ref struct Parentheses sealed : public CalculatorApp::ViewModel::ICalcManagerIExprCommand { - property int Command; + internal :; + int Command; }; CalculatorApp::ViewModel::ICalcManagerIExprCommand ^ CreateExprCommand(const IExpressionCommand* exprCmd) { @@ -39,10 +44,9 @@ namespace { auto cmd = static_cast(exprCmd); auto result = ref new UnaryCommand(); - result->Commands = ref new Platform::Collections::Vector(); for (auto& subcmd : *cmd->GetCommands()) { - result->Commands->Append(subcmd); + result->Commands.push_back(subcmd); } return result; } @@ -60,10 +64,9 @@ namespace result->IsNegative = cmd->IsNegative(); result->IsDecimalPresent = cmd->IsDecimalPresent(); result->IsSciFmt = cmd->IsSciFmt(); - result->Commands = ref new Platform::Collections::Vector(); for (auto& subcmd : *cmd->GetCommands()) { - result->Commands->Append(subcmd); + result->Commands.push_back(subcmd); } return result; } diff --git a/src/CalcViewModel/StandardCalculatorViewModel.cpp b/src/CalcViewModel/StandardCalculatorViewModel.cpp index 6a0727ab0..d39e58489 100644 --- a/src/CalcViewModel/StandardCalculatorViewModel.cpp +++ b/src/CalcViewModel/StandardCalculatorViewModel.cpp @@ -1789,7 +1789,6 @@ void StandardCalculatorViewModel::SetBitshiftRadioButtonCheckedAnnouncement(Plat StandardCalculatorSnapshot ^ StandardCalculatorViewModel::GetSnapshot() const { - CUnaryCommand; auto result = ref new StandardCalculatorSnapshot(); result->CalcManager = ref new CalcManagerSnapshot(m_standardCalculatorManager); result->PrimaryDisplay = ref new PrimaryDisplaySnapshot(m_DisplayValue, m_IsInError); diff --git a/src/CalcViewModelCopyForUT/CalcViewModelCopyForUT.vcxproj b/src/CalcViewModelCopyForUT/CalcViewModelCopyForUT.vcxproj index 7aef42f57..2171c9cda 100644 --- a/src/CalcViewModelCopyForUT/CalcViewModelCopyForUT.vcxproj +++ b/src/CalcViewModelCopyForUT/CalcViewModelCopyForUT.vcxproj @@ -333,6 +333,7 @@ + @@ -375,6 +376,7 @@ Create Create + diff --git a/src/CalcViewModelCopyForUT/CalcViewModelCopyForUT.vcxproj.filters b/src/CalcViewModelCopyForUT/CalcViewModelCopyForUT.vcxproj.filters index 19ca2cee8..2691d5344 100644 --- a/src/CalcViewModelCopyForUT/CalcViewModelCopyForUT.vcxproj.filters +++ b/src/CalcViewModelCopyForUT/CalcViewModelCopyForUT.vcxproj.filters @@ -87,6 +87,7 @@ GraphingCalculator + @@ -204,6 +205,7 @@ Common + From 2535c75501bc39f8bbcb5e376a5f7c864bf42f73 Mon Sep 17 00:00:00 2001 From: Tian Liao Date: Wed, 16 Oct 2024 18:18:44 +0800 Subject: [PATCH 04/21] set snapshot --- src/CalcViewModel/Snapshots.cpp | 41 +++++++++++++------ src/CalcViewModel/Snapshots.h | 19 ++++++--- .../StandardCalculatorViewModel.cpp | 37 ++++++++++++++++- .../StandardCalculatorViewModel.h | 12 +++--- 4 files changed, 84 insertions(+), 25 deletions(-) diff --git a/src/CalcViewModel/Snapshots.cpp b/src/CalcViewModel/Snapshots.cpp index 87fc31dba..ca6dc339b 100644 --- a/src/CalcViewModel/Snapshots.cpp +++ b/src/CalcViewModel/Snapshots.cpp @@ -37,7 +37,11 @@ namespace int Command; }; - CalculatorApp::ViewModel::ICalcManagerIExprCommand ^ CreateExprCommand(const IExpressionCommand* exprCmd) { +} // namespace + +namespace CalculatorApp::ViewModel +{ + ICalcManagerIExprCommand ^ CreateExprCommand(const IExpressionCommand* exprCmd) { switch (exprCmd->GetCommandType()) { case CalculationManager::CommandType::UnaryCommand: @@ -81,10 +85,7 @@ namespace throw std::logic_error{ "unhandled command type." }; } } -} // namespace -namespace CalculatorApp::ViewModel -{ CalcManagerHistoryToken::CalcManagerHistoryToken(Platform::String ^ opCodeName, int cmdIndex) { assert(opCodeName != nullptr && "opCodeName is mandatory."); @@ -95,14 +96,16 @@ namespace CalculatorApp::ViewModel CalcManagerHistoryItem::CalcManagerHistoryItem(const CalculationManager::HISTORYITEM& item) { Tokens = ref new Platform::Collections::Vector(); + assert(item.historyItemVector.spTokens != nullptr && "spTokens shall not be null."); + for (auto& [opCode, cmdIdx] : *item.historyItemVector.spTokens) + { + Tokens->Append(ref new CalcManagerHistoryToken(ref new Platform::String(opCode.c_str()), cmdIdx)); + } Commands = ref new Platform::Collections::Vector(); - if (item.historyItemVector.spTokens != nullptr) + assert(item.historyItemVector.spCommands != nullptr && "spCommands shall not be null."); + for (auto& cmd : *item.historyItemVector.spCommands) { - for (auto& [opCode, cmdIdx] : *item.historyItemVector.spTokens) - { - Tokens->Append(ref new CalcManagerHistoryToken(ref new Platform::String(opCode.c_str()), cmdIdx)); - // Commands->Append(); - } + Commands->Append(CreateExprCommand(cmd.get())); } Expression = ref new Platform::String(item.historyItemVector.expression.c_str()); Result = ref new Platform::String(item.historyItemVector.result.c_str()); @@ -113,6 +116,7 @@ namespace CalculatorApp::ViewModel auto& items = calcMgr.GetHistoryItems(); if (!items.empty()) { + HistoryItems = ref new Platform::Collections::Vector(); for (auto& item : items) { HistoryItems->Append(ref new CalcManagerHistoryItem(*item)); @@ -127,12 +131,25 @@ namespace CalculatorApp::ViewModel IsError = isError; } - ExpressionDisplaySnapshot::ExpressionDisplaySnapshot(const std::vector& tokens) + ExpressionDisplaySnapshot::ExpressionDisplaySnapshot( + const std::vector& tokens, + const std::vector>& commands) { Tokens = ref new Platform::Collections::Vector(); for (auto& [opCode, cmdIdx] : tokens) { Tokens->Append(ref new CalcManagerHistoryToken(ref new Platform::String(opCode.c_str()), cmdIdx)); } + + Commands = ref new Platform::Collections::Vector(); + for (auto& cmd : commands) + { + Commands->Append(CreateExprCommand(cmd.get())); + } + } + + std::vector> ToUnderlying(Windows::Foundation::Collections::IVector ^ items) + { + return {}; // TODO } -} +} // namespace CalculatorApp::ViewModel diff --git a/src/CalcViewModel/Snapshots.h b/src/CalcViewModel/Snapshots.h index ab62dda04..507fc0323 100644 --- a/src/CalcViewModel/Snapshots.h +++ b/src/CalcViewModel/Snapshots.h @@ -2,6 +2,9 @@ // Licensed under the MIT License. #pragma once +#include +#include + #include "CalcManager/CalculatorManager.h" namespace CalculatorApp::ViewModel @@ -56,19 +59,23 @@ public ref struct ExpressionDisplaySnapshot sealed { property Windows::Foundation::Collections::IVector ^ Tokens; - // TODO: commands + property Windows::Foundation::Collections::IVector ^ Commands; internal :; using CalcHistoryToken = std::pair; - explicit ExpressionDisplaySnapshot(const std::vector& tokens); + explicit ExpressionDisplaySnapshot(const std::vector& tokens, const std::vector>& commands); }; public ref struct StandardCalculatorSnapshot sealed { - property CalcManagerSnapshot ^ CalcManager; // mandatory - property PrimaryDisplaySnapshot ^ PrimaryDisplay; // mandatory - property ExpressionDisplaySnapshot ^ ExpressionDisplay; // optional - property Windows::Foundation::Collections::IVector ^ Commands; // mandatory + property CalcManagerSnapshot ^ CalcManager; // mandatory + property PrimaryDisplaySnapshot ^ PrimaryDisplay; // mandatory + property ExpressionDisplaySnapshot ^ ExpressionDisplay; // optional + property Windows::Foundation::Collections::IVector ^ DisplayCommands; // mandatory }; + + ICalcManagerIExprCommand ^ CreateExprCommand(const IExpressionCommand* exprCmd); + std::vector> ToUnderlying(Windows::Foundation::Collections::IVector ^ items); + } // namespace CalculatorApp::ViewModel diff --git a/src/CalcViewModel/StandardCalculatorViewModel.cpp b/src/CalcViewModel/StandardCalculatorViewModel.cpp index d39e58489..38889fe18 100644 --- a/src/CalcViewModel/StandardCalculatorViewModel.cpp +++ b/src/CalcViewModel/StandardCalculatorViewModel.cpp @@ -115,7 +115,7 @@ namespace CalculatorResourceKeys StringReference DisplayCopied(L"Display_Copied"); } -StandardCalculatorViewModel::StandardCalculatorViewModel() +StandardCalculatorViewModel::StandardCalculatorViewModel(StandardCalculatorSnapshot ^ snapshot) : m_DisplayValue(L"0") , m_DecimalDisplayValue(L"0") , m_HexDisplayValue(L"0") @@ -183,6 +183,33 @@ StandardCalculatorViewModel::StandardCalculatorViewModel() IsNegateEnabled = true; IsDecimalEnabled = true; AreProgrammerRadixOperatorsVisible = false; + + if (snapshot != nullptr) + { + if (snapshot->CalcManager->HistoryItems != nullptr) + { + m_standardCalculatorManager.SetHistoryItems(ToUnderlying(snapshot->CalcManager->HistoryItems)); + } + + std::vector commands; + if (snapshot->ExpressionDisplay != nullptr && snapshot->ExpressionDisplay->Tokens->GetAt(snapshot->ExpressionDisplay->Tokens->Size)) + { + // commands = GetCommandsFromExpressionCommands(Snapshot->ExpressionDisplay->Commands); + } + if (commands.empty() && snapshot->DisplayCommands->Size > 0) + { + // commands = GetCommandsFromExpressionCommands(snapshot->DisplayCommands); + } + for (auto cmd : commands) + { + m_standardCalculatorManager.SendCommand(static_cast(cmd)); + } + if (snapshot->ExpressionDisplay != nullptr) + { + // SetExpressionDisplay(); + } + // SetPrimaryDisplay(); + } } String ^ StandardCalculatorViewModel::LocalizeDisplayValue(_In_ wstring const& displayValue) @@ -1792,9 +1819,15 @@ StandardCalculatorSnapshot ^ StandardCalculatorViewModel::GetSnapshot() const auto result = ref new StandardCalculatorSnapshot(); result->CalcManager = ref new CalcManagerSnapshot(m_standardCalculatorManager); result->PrimaryDisplay = ref new PrimaryDisplaySnapshot(m_DisplayValue, m_IsInError); - result->ExpressionDisplay = ref new ExpressionDisplaySnapshot(*m_tokens); + result->ExpressionDisplay = ref new ExpressionDisplaySnapshot(*m_tokens, *m_commands); + result->DisplayCommands = ref new Platform::Collections::Vector(); + for (auto cmd : m_standardCalculatorManager.GetDisplayCommandsSnapshot()) + { + result->DisplayCommands->Append(CreateExprCommand(cmd.get())); + } return nullptr; } + // StandardCalculatorSnapshot StandardCalculatorViewModel::GetStandardCalculatorSnapshot() const //{ // StandardCalculatorSnapshot snapshot; diff --git a/src/CalcViewModel/StandardCalculatorViewModel.h b/src/CalcViewModel/StandardCalculatorViewModel.h index 93fe41f74..5e17eee44 100644 --- a/src/CalcViewModel/StandardCalculatorViewModel.h +++ b/src/CalcViewModel/StandardCalculatorViewModel.h @@ -65,7 +65,6 @@ namespace CalculatorApp [Windows::UI::Xaml::Data::Bindable] public ref class StandardCalculatorViewModel sealed : public Windows::UI::Xaml::Data::INotifyPropertyChanged { public: - StandardCalculatorViewModel(); void UpdateOperand(int pos, Platform::String ^ text); OBSERVABLE_OBJECT_CALLBACK(OnPropertyChanged); @@ -269,10 +268,12 @@ namespace CalculatorApp } } - property StandardCalculatorSnapshot ^ Snapshot { StandardCalculatorSnapshot ^ get() { return GetSnapshot(); } } + property StandardCalculatorSnapshot + ^ Snapshot { StandardCalculatorSnapshot ^ get() { return GetSnapshot(); } } - // Used by unit tests - void ResetCalcManager(bool clearMemory); + // Used by unit tests + void + ResetCalcManager(bool clearMemory); void SendCommandToCalcManager(int command); public: @@ -325,7 +326,8 @@ namespace CalculatorApp return m_CurrentAngleType; } - // void SetStandardCalculatorSnapshot(const StandardCalculatorSnapshot& state); + internal :; + explicit StandardCalculatorViewModel(StandardCalculatorSnapshot ^ snapshot = nullptr); private: StandardCalculatorSnapshot ^ GetSnapshot() const; From 7258237c8a279c3ed3271fa0bb5efc75acfd2f4d Mon Sep 17 00:00:00 2001 From: Tian Liao Date: Thu, 17 Oct 2024 15:59:22 +0800 Subject: [PATCH 05/21] stash changes --- src/CalcViewModel/ApplicationViewModel.cpp | 105 ++++++++++-------- src/CalcViewModel/ApplicationViewModel.h | 16 +-- src/CalcViewModel/Snapshots.cpp | 38 +++++++ src/CalcViewModel/Snapshots.h | 8 ++ .../StandardCalculatorViewModel.cpp | 17 ++- .../CalcViewModelCopyForUT.vcxproj | 8 ++ src/Calculator/App.xaml.cs | 3 +- src/Calculator/Common/LaunchArguments.cs | 32 +----- src/Calculator/Views/MainPage.xaml.cs | 97 ++++++++-------- 9 files changed, 188 insertions(+), 136 deletions(-) diff --git a/src/CalcViewModel/ApplicationViewModel.cpp b/src/CalcViewModel/ApplicationViewModel.cpp index d3bdaa19a..1d4e6e126 100644 --- a/src/CalcViewModel/ApplicationViewModel.cpp +++ b/src/CalcViewModel/ApplicationViewModel.cpp @@ -38,9 +38,8 @@ namespace StringReference CategoriesPropertyName(L"Categories"); StringReference ClearMemoryVisibilityPropertyName(L"ClearMemoryVisibility"); - //struct SnapshotHelper + // 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 } } +ApplicationSnapshot ^ ApplicationViewModel::Snapshot::get() +{ + auto snapshot = ref new ApplicationSnapshot(); + snapshot->Mode = static_cast(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(snapshot->Mode)); +} + bool ApplicationViewModel::TryRecoverFromNavigationModeFailure() { // Here we are simply trying to recover from being unable to navigate to a mode. @@ -712,47 +729,47 @@ void ApplicationViewModel::SetDisplayNormalAlwaysOnTopOption() m_mode == ViewMode::Standard && ApplicationView::GetForCurrentView()->IsViewModeSupported(ApplicationViewMode::CompactOverlay) && !IsAlwaysOnTop; } -//Windows::Data::Json::JsonObject ^ ApplicationViewModel::SaveApplicationSnapshot() +// Windows::Data::Json::JsonObject ^ ApplicationViewModel::SaveApplicationSnapshot() //{ -// ApplicationSnapshot applicationSnapshot; -// applicationSnapshot.SnapshotVersion = SnapshotHelper::SnapshotVersion; -// applicationSnapshot.Mode = static_cast(Mode); -// if (m_CalculatorViewModel != nullptr && m_mode == ViewMode::Standard) -// { -// // Standard calculator is the only supported mode so far. -// applicationSnapshot.StandardCalc = m_CalculatorViewModel->GetStandardCalculatorSnapshot(); -// } -// return SnapshotHelper::SaveSnapshotToJson(applicationSnapshot); -//} +// ApplicationSnapshot applicationSnapshot; +// applicationSnapshot.SnapshotVersion = SnapshotHelper::SnapshotVersion; +// applicationSnapshot.Mode = static_cast(Mode); +// if (m_CalculatorViewModel != nullptr && m_mode == ViewMode::Standard) +// { +// // Standard calculator is the only supported mode so far. +// applicationSnapshot.StandardCalc = m_CalculatorViewModel->GetStandardCalculatorSnapshot(); +// } +// return SnapshotHelper::SaveSnapshotToJson(applicationSnapshot); +// } // -//bool ApplicationViewModel::TryRestoreFromSnapshot(Windows::Data::Json::JsonObject ^ jsonObject) +// bool ApplicationViewModel::TryRestoreFromSnapshot(Windows::Data::Json::JsonObject ^ jsonObject) //{ -// std::optional applicationSnapshot; -// try -// { -// SnapshotHelper::RestoreJsonToSnapshot(jsonObject, applicationSnapshot); -// } -// catch (Platform::COMException ^ e) -// { -// if (SnapshotHelper::IsJsonParsingException(e)) -// { -// return false; -// } -// throw; -// } +// std::optional applicationSnapshot; +// try +// { +// SnapshotHelper::RestoreJsonToSnapshot(jsonObject, applicationSnapshot); +// } +// catch (Platform::COMException ^ e) +// { +// if (SnapshotHelper::IsJsonParsingException(e)) +// { +// return false; +// } +// throw; +// } // -// if (applicationSnapshot.has_value()) -// { -// Mode = static_cast(applicationSnapshot->Mode); -// if (applicationSnapshot->StandardCalc.has_value()) -// { -// if (m_CalculatorViewModel == nullptr) -// { -// m_CalculatorViewModel = ref new StandardCalculatorViewModel(); -// } -// m_CalculatorViewModel->SetStandardCalculatorSnapshot(applicationSnapshot->StandardCalc.value()); -// } -// return true; -// } -// return false; -//} +// if (applicationSnapshot.has_value()) +// { +// Mode = static_cast(applicationSnapshot->Mode); +// if (applicationSnapshot->StandardCalc.has_value()) +// { +// if (m_CalculatorViewModel == nullptr) +// { +// m_CalculatorViewModel = ref new StandardCalculatorViewModel(); +// } +// m_CalculatorViewModel->SetStandardCalculatorSnapshot(applicationSnapshot->StandardCalc.value()); +// } +// return true; +// } +// return false; +// } diff --git a/src/CalcViewModel/ApplicationViewModel.h b/src/CalcViewModel/ApplicationViewModel.h index 992754d5e..05cd1fbd1 100644 --- a/src/CalcViewModel/ApplicationViewModel.h +++ b/src/CalcViewModel/ApplicationViewModel.h @@ -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 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: diff --git a/src/CalcViewModel/Snapshots.cpp b/src/CalcViewModel/Snapshots.cpp index ca6dc339b..a7ffccea4 100644 --- a/src/CalcViewModel/Snapshots.cpp +++ b/src/CalcViewModel/Snapshots.cpp @@ -6,6 +6,7 @@ #include #include +#include "CalcManager/ExpressionCommand.h" #include "Snapshots.h" namespace @@ -152,4 +153,41 @@ namespace CalculatorApp::ViewModel { return {}; // TODO } + + std::vector> ToUnderlying(Windows::Foundation::Collections::IVector ^ commands) + { + std::vector> result; + for (ICalcManagerIExprCommand ^ cmdEntry : commands) + { + if (auto unary = dynamic_cast(cmdEntry); unary != nullptr) + { + if (unary->Commands.size() == 1) + { + result.push_back(std::make_shared(unary->Commands[0])); + } + else if (unary->Commands.size() == 2) + { + result.push_back(std::make_shared(unary->Commands[0], unary->Commands[1])); + } + else + { + throw std::logic_error{ "ill-formed command." }; + } + } + else if (auto binary = dynamic_cast(cmdEntry); binary != nullptr) + { + result.push_back(std::make_shared(binary->Command)); + } + else if (auto paren = dynamic_cast(cmdEntry); paren != nullptr) + { + result.push_back(std::make_shared(paren->Command)); + } + else if (auto operand = dynamic_cast(cmdEntry); operand != nullptr) + { + auto subcmds = std::make_shared>(operand->Commands); + result.push_back(std::make_shared(std::move(subcmds), operand->IsNegative, operand->IsDecimalPresent, operand->IsSciFmt)); + } + } + return result; + } } // namespace CalculatorApp::ViewModel diff --git a/src/CalcViewModel/Snapshots.h b/src/CalcViewModel/Snapshots.h index 507fc0323..558e302fe 100644 --- a/src/CalcViewModel/Snapshots.h +++ b/src/CalcViewModel/Snapshots.h @@ -75,7 +75,15 @@ public property Windows::Foundation::Collections::IVector ^ DisplayCommands; // mandatory }; +public + ref struct ApplicationSnapshot sealed + { + property int Mode; + property StandardCalculatorSnapshot ^ StandardCalculator; // optional + }; + ICalcManagerIExprCommand ^ CreateExprCommand(const IExpressionCommand* exprCmd); + std::vector> ToUnderlying(Windows::Foundation::Collections::IVector ^ commands); std::vector> ToUnderlying(Windows::Foundation::Collections::IVector ^ items); } // namespace CalculatorApp::ViewModel diff --git a/src/CalcViewModel/StandardCalculatorViewModel.cpp b/src/CalcViewModel/StandardCalculatorViewModel.cpp index 38889fe18..844a063cf 100644 --- a/src/CalcViewModel/StandardCalculatorViewModel.cpp +++ b/src/CalcViewModel/StandardCalculatorViewModel.cpp @@ -194,11 +194,11 @@ StandardCalculatorViewModel::StandardCalculatorViewModel(StandardCalculatorSnaps std::vector 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>; + RawTokenCollection rawTokens; + for (CalcManagerHistoryToken ^ token : snapshot->ExpressionDisplay->Tokens) + { + rawTokens.push_back(std::pair{ token->OpCodeName->Data(), token->CommandIndex }); + } + snapshot->ExpressionDisplay->Tokens; + SetExpressionDisplay( + std::make_shared(rawTokens), + std::make_shared>>(ToUnderlying(snapshot->ExpressionDisplay->Commands))); } - // SetPrimaryDisplay(); + SetPrimaryDisplay(snapshot->PrimaryDisplay->DisplayValue, snapshot->PrimaryDisplay->IsError); } } diff --git a/src/CalcViewModelCopyForUT/CalcViewModelCopyForUT.vcxproj b/src/CalcViewModelCopyForUT/CalcViewModelCopyForUT.vcxproj index 2171c9cda..ed1a9fb16 100644 --- a/src/CalcViewModelCopyForUT/CalcViewModelCopyForUT.vcxproj +++ b/src/CalcViewModelCopyForUT/CalcViewModelCopyForUT.vcxproj @@ -394,6 +394,14 @@ /DUSE_MOCK_DATA %(AdditionalOptions) + stdcpp17 + stdcpp17 + stdcpp17 + stdcpp17 + stdcpp17 + stdcpp17 + stdcpp17 + stdcpp17 diff --git a/src/Calculator/App.xaml.cs b/src/Calculator/App.xaml.cs index 342e68516..782543224 100644 --- a/src/Calculator/App.xaml.cs +++ b/src/Calculator/App.xaml.cs @@ -81,8 +81,7 @@ protected override void OnActivated(IActivatedEventArgs args) OnAppLaunch(args, new SnapshotLaunchArguments { - ActivityId = protoArgs.Uri.GetActivityId(), - LaunchUri = protoArgs.Uri + Snapshot = null // TODO: }, false); } diff --git a/src/Calculator/Common/LaunchArguments.cs b/src/Calculator/Common/LaunchArguments.cs index 8a1be58d7..0686e1aaa 100644 --- a/src/Calculator/Common/LaunchArguments.cs +++ b/src/Calculator/Common/LaunchArguments.cs @@ -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 @@ args is IProtocolActivatedEventArgs protoArgs && protoArgs.Uri != null && protoArgs.Uri.Segments != null && protoArgs.Uri.Segments.Length == 2 && - protoArgs.Uri.Segments[0] == "snapshots/"; - - /// - /// GetActivityId() requires the parameter `launchUri` to be a well-formed - /// snapshot URI. - /// - /// the Uri to launch with a snapshot context. - /// Activity ID - 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/"; } } diff --git a/src/Calculator/Views/MainPage.xaml.cs b/src/Calculator/Views/MainPage.xaml.cs index ff6fbe6c0..0a3035fd5 100644 --- a/src/Calculator/Views/MainPage.xaml.cs +++ b/src/Calculator/Views/MainPage.xaml.cs @@ -69,8 +69,7 @@ public MainPage() } 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 @@ protected override void OnNavigatedTo(NavigationEventArgs e) } 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); - - if (TryRestoreFromActivity(snapshotArgs, activity, out var errorMessage)) - { - TraceLogger.GetInstance().LogRecallRestore(Model.Mode); - SelectNavigationItemByModel(); - } - else - { - TraceLogger.GetInstance().LogRecallError(Model.Mode, errorMessage); - } - }); - Model.Initialize(initialMode); + //_ = 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(snapshotArgs.Snapshot); } else { @@ -188,37 +187,37 @@ protected override void OnNavigatedTo(NavigationEventArgs e) } } - 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; - } - - if (!activityJson.ContainsKey("contentInfo")) - { - errorMessage = "ContentInfoNotExist"; - return false; - } - - if (!Model.TryRestoreFromSnapshot(activityJson.GetNamedObject("contentInfo"))) - { - errorMessage = "RestoreFromSnapshotFailed"; - return false; - } - - errorMessage = string.Empty; - return true; - } + //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; + // } + + // if (!activityJson.ContainsKey("contentInfo")) + // { + // errorMessage = "ContentInfoNotExist"; + // return false; + // } + + // if (!Model.TryRestoreFromSnapshot(activityJson.GetNamedObject("contentInfo"))) + // { + // errorMessage = "RestoreFromSnapshotFailed"; + // return false; + // } + + // errorMessage = string.Empty; + // return true; + //} private void InitializeNavViewCategoriesSource() { From 3e45a394ce2400a54c846ba91bb94b77bb439e9f Mon Sep 17 00:00:00 2001 From: Tian Liao Date: Thu, 17 Oct 2024 16:45:19 +0800 Subject: [PATCH 06/21] update launch utils --- src/Calculator/App.xaml.cs | 18 +++++++---------- src/Calculator/Common/LaunchArguments.cs | 25 +++++++++++++++++------- 2 files changed, 25 insertions(+), 18 deletions(-) diff --git a/src/Calculator/App.xaml.cs b/src/Calculator/App.xaml.cs index 782543224..13fe4a6f2 100644 --- a/src/Calculator/App.xaml.cs +++ b/src/Calculator/App.xaml.cs @@ -73,23 +73,19 @@ protected override void OnLaunched(LaunchActivatedEventArgs args) protected override void OnActivated(IActivatedEventArgs args) { - if (args.Kind != ActivationKind.Protocol) return; - - if (args.IsSnapshotProtocol()) + if (args.Kind != ActivationKind.Protocol) { - var protoArgs = (IProtocolActivatedEventArgs)args; - OnAppLaunch(args, - new SnapshotLaunchArguments - { - Snapshot = null // TODO: - }, - false); + return; + } + else if (args.TryGetSnapshotProtocol(out var protoArgs)) + { + OnAppLaunch(args, protoArgs.GetSnapshotLaunchArgs(), false); } else { // handle any unknown protocol launch as a normal app launch. OnAppLaunch(args, null, false); - } + } } private void OnAppLaunch(IActivatedEventArgs args, object arguments, bool isPreLaunch) diff --git a/src/Calculator/Common/LaunchArguments.cs b/src/Calculator/Common/LaunchArguments.cs index 0686e1aaa..ee643fab4 100644 --- a/src/Calculator/Common/LaunchArguments.cs +++ b/src/Calculator/Common/LaunchArguments.cs @@ -7,16 +7,27 @@ namespace CalculatorApp { internal class SnapshotLaunchArguments { - public ApplicationSnapshot Snapshot; + public bool HasError { get; set; } + public ApplicationSnapshot Snapshot { get; set; } } internal static class LaunchExtensions { - public static bool IsSnapshotProtocol(this IActivatedEventArgs args) => - args is IProtocolActivatedEventArgs protoArgs && - protoArgs.Uri != null && - protoArgs.Uri.Segments != null && - protoArgs.Uri.Segments.Length == 2 && - protoArgs.Uri.Segments[0] == "snapshot/"; + public static bool TryGetSnapshotProtocol(this IActivatedEventArgs args, out IProtocolActivatedEventArgs result) + { + result = null; + var protoArgs = args as IProtocolActivatedEventArgs; + if (protoArgs == null || protoArgs.Uri == null) + { + return false; + } + result = protoArgs; + return true; + } + + public static SnapshotLaunchArguments GetSnapshotLaunchArgs(this IProtocolActivatedEventArgs args) + { + return null; + } } } From 1645cfddcd46807aea0fb9ac6c25d323a602202f Mon Sep 17 00:00:00 2001 From: Tian Liao Date: Thu, 24 Oct 2024 11:32:26 +0800 Subject: [PATCH 07/21] stash changes --- src/CalcViewModel/ApplicationViewModel.cpp | 6 +- src/CalcViewModel/ApplicationViewModel.h | 6 +- src/CalcViewModel/Snapshots.cpp | 78 ++++++++----------- src/CalcViewModel/Snapshots.h | 60 +++++++++++++- .../StandardCalculatorViewModel.cpp | 20 ++--- .../StandardCalculatorViewModel.h | 8 +- src/Calculator/Calculator.csproj | 4 + src/Calculator/Common/LaunchArguments.cs | 4 +- src/Calculator/Utils/SerdeUtils.cs | 49 ++++++++++++ src/Calculator/Views/MainPage.xaml.cs | 3 + 10 files changed, 167 insertions(+), 71 deletions(-) create mode 100644 src/Calculator/Utils/SerdeUtils.cs diff --git a/src/CalcViewModel/ApplicationViewModel.cpp b/src/CalcViewModel/ApplicationViewModel.cpp index 1d4e6e126..190e72715 100644 --- a/src/CalcViewModel/ApplicationViewModel.cpp +++ b/src/CalcViewModel/ApplicationViewModel.cpp @@ -512,9 +512,9 @@ void ApplicationViewModel::Categories::set(IObservableVector } } -ApplicationSnapshot ^ ApplicationViewModel::Snapshot::get() +CalculatorApp::ViewModel::Snapshot::ApplicationSnapshot ^ ApplicationViewModel::Snapshot::get() { - auto snapshot = ref new ApplicationSnapshot(); + auto snapshot = ref new CalculatorApp::ViewModel::Snapshot::ApplicationSnapshot(); snapshot->Mode = static_cast(Mode); if (m_CalculatorViewModel != nullptr && m_mode == ViewMode::Standard) { @@ -556,7 +556,7 @@ void ApplicationViewModel::Initialize(ViewMode mode) } } -void ApplicationViewModel::Initialize(ApplicationSnapshot ^ snapshot) +void ApplicationViewModel::Initialize(CalculatorApp::ViewModel::Snapshot::ApplicationSnapshot ^ snapshot) { // TODO: restore Initialize(static_cast(snapshot->Mode)); diff --git a/src/CalcViewModel/ApplicationViewModel.h b/src/CalcViewModel/ApplicationViewModel.h index 05cd1fbd1..1cb2f2dfd 100644 --- a/src/CalcViewModel/ApplicationViewModel.h +++ b/src/CalcViewModel/ApplicationViewModel.h @@ -20,7 +20,7 @@ namespace CalculatorApp [Windows::Foundation::Metadata::DefaultOverload] void Initialize(CalculatorApp::ViewModel::Common::ViewMode mode); // Use for first init, use deserialize for rehydration - void Initialize(ApplicationSnapshot^ snapshot); + void Initialize(CalculatorApp::ViewModel::Snapshot::ApplicationSnapshot^ snapshot); OBSERVABLE_OBJECT(); OBSERVABLE_PROPERTY_RW(StandardCalculatorViewModel ^, CalculatorViewModel); @@ -73,9 +73,9 @@ namespace CalculatorApp } } - property ApplicationSnapshot ^ Snapshot + property CalculatorApp::ViewModel::Snapshot::ApplicationSnapshot ^ Snapshot { - ApplicationSnapshot ^ get(); + CalculatorApp::ViewModel::Snapshot::ApplicationSnapshot ^ get(); } static property Platform::String ^ LaunchedLocalSettings diff --git a/src/CalcViewModel/Snapshots.cpp b/src/CalcViewModel/Snapshots.cpp index a7ffccea4..ff651dd4a 100644 --- a/src/CalcViewModel/Snapshots.cpp +++ b/src/CalcViewModel/Snapshots.cpp @@ -9,78 +9,64 @@ #include "CalcManager/ExpressionCommand.h" #include "Snapshots.h" -namespace +namespace CalculatorApp::ViewModel::Snapshot { - ref struct UnaryCommand sealed : public CalculatorApp::ViewModel::ICalcManagerIExprCommand + UnaryCommand::UnaryCommand(Windows::Foundation::Collections::IVectorView ^ cmds) { - internal :; - std::vector Commands; - }; - - ref struct BinaryCommand sealed : public CalculatorApp::ViewModel::ICalcManagerIExprCommand - { - internal :; - int Command; - }; + for (auto cmd : cmds) + { + m_cmds.push_back(cmd); + } + } - ref struct OperandCommand sealed : public CalculatorApp::ViewModel::ICalcManagerIExprCommand + Windows::Foundation::Collections::IVectorView ^ UnaryCommand::Commands::get() { - internal :; - bool IsNegative; - bool IsDecimalPresent; - bool IsSciFmt; - std::vector Commands; - }; + return ref new Platform::Collections::VectorView(m_cmds); + } - ref struct Parentheses sealed : public CalculatorApp::ViewModel::ICalcManagerIExprCommand + OperandCommand::OperandCommand(bool isNegative, bool isDecimal, bool isSciFmt, Windows::Foundation::Collections::IVectorView ^ cmds) { - internal :; - int Command; - }; - -} // namespace + IsNegative = isNegative; + IsDecimalPresent = isDecimal; + IsSciFmt = isSciFmt; + for (auto cmd : cmds) + { + m_cmds.push_back(cmd); + } + } -namespace CalculatorApp::ViewModel -{ ICalcManagerIExprCommand ^ CreateExprCommand(const IExpressionCommand* exprCmd) { switch (exprCmd->GetCommandType()) { case CalculationManager::CommandType::UnaryCommand: { auto cmd = static_cast(exprCmd); - auto result = ref new UnaryCommand(); + std::vector cmdlist; for (auto& subcmd : *cmd->GetCommands()) { - result->Commands.push_back(subcmd); + cmdlist.push_back(subcmd); } - return result; + return ref new UnaryCommand(std::move(cmdlist)); } case CalculationManager::CommandType::BinaryCommand: { auto cmd = static_cast(exprCmd); - auto result = ref new BinaryCommand(); - result->Command = cmd->GetCommand(); - return result; + return ref new BinaryCommand(cmd->GetCommand()); } case CalculationManager::CommandType::OperandCommand: { auto cmd = static_cast(exprCmd); - auto result = ref new OperandCommand(); - result->IsNegative = cmd->IsNegative(); - result->IsDecimalPresent = cmd->IsDecimalPresent(); - result->IsSciFmt = cmd->IsSciFmt(); + std::vector cmdlist; for (auto& subcmd : *cmd->GetCommands()) { - result->Commands.push_back(subcmd); + cmdlist.push_back(subcmd); } - return result; + return ref new OperandCommand(cmd->IsNegative(), cmd->IsDecimalPresent(), cmd->IsSciFmt(), std::move(cmdlist)); } case CalculationManager::CommandType::Parentheses: { auto cmd = static_cast(exprCmd); - auto result = ref new Parentheses(); - result->Command = cmd->GetCommand(); - return result; + return ref new Parentheses(cmd->GetCommand()); } default: throw std::logic_error{ "unhandled command type." }; @@ -161,13 +147,13 @@ namespace CalculatorApp::ViewModel { if (auto unary = dynamic_cast(cmdEntry); unary != nullptr) { - if (unary->Commands.size() == 1) + if (unary->m_cmds.size() == 1) { - result.push_back(std::make_shared(unary->Commands[0])); + result.push_back(std::make_shared(unary->m_cmds[0])); } - else if (unary->Commands.size() == 2) + else if (unary->m_cmds.size() == 2) { - result.push_back(std::make_shared(unary->Commands[0], unary->Commands[1])); + result.push_back(std::make_shared(unary->m_cmds[0], unary->m_cmds[1])); } else { @@ -184,7 +170,7 @@ namespace CalculatorApp::ViewModel } else if (auto operand = dynamic_cast(cmdEntry); operand != nullptr) { - auto subcmds = std::make_shared>(operand->Commands); + auto subcmds = std::make_shared>(operand->m_cmds); result.push_back(std::make_shared(std::move(subcmds), operand->IsNegative, operand->IsDecimalPresent, operand->IsSciFmt)); } } diff --git a/src/CalcViewModel/Snapshots.h b/src/CalcViewModel/Snapshots.h index 558e302fe..b75d424c1 100644 --- a/src/CalcViewModel/Snapshots.h +++ b/src/CalcViewModel/Snapshots.h @@ -7,20 +7,70 @@ #include "CalcManager/CalculatorManager.h" -namespace CalculatorApp::ViewModel +namespace CalculatorApp::ViewModel::Snapshot { public interface struct ICalcManagerIExprCommand { }; + ref struct UnaryCommand sealed : public ICalcManagerIExprCommand + { + property Windows::Foundation::Collections::IVectorView ^ Commands { Windows::Foundation::Collections::IVectorView ^ get(); }; + + explicit UnaryCommand(Windows::Foundation::Collections::IVectorView ^ cmds); + + internal :; + explicit UnaryCommand(std::vector cmds) + : m_cmds(std::move(cmds)) + { + } + std::vector m_cmds; + }; + + ref struct BinaryCommand sealed : public ICalcManagerIExprCommand + { + property int Command; + explicit BinaryCommand(int cmd) + { + Command = cmd; + } + }; + + ref struct OperandCommand sealed : public ICalcManagerIExprCommand + { + property bool IsNegative; + property bool IsDecimalPresent; + property bool IsSciFmt; + property Windows::Foundation::Collections::IVectorView ^ Commands { Windows::Foundation::Collections::IVectorView ^ get(); }; + + explicit OperandCommand(bool isNegative, bool isDecimal, bool isSciFmt, Windows::Foundation::Collections::IVectorView ^ cmds); + internal :; + explicit OperandCommand(bool isNegative, bool isDecimal, bool isSciFmt, std::vector cmds) + { + IsNegative = isNegative; + IsDecimalPresent = isDecimal; + IsSciFmt = isSciFmt; + m_cmds = std::move(cmds); + } + std::vector m_cmds; + }; + + ref struct Parentheses sealed : public ICalcManagerIExprCommand + { + property int Command; + explicit Parentheses(int cmd) + { + Command = cmd; + } + }; + public ref struct CalcManagerHistoryToken sealed { property Platform::String ^ OpCodeName; // mandatory property int CommandIndex; - internal :; explicit CalcManagerHistoryToken(Platform::String ^ opCodeName, int cmdIndex); }; @@ -32,6 +82,12 @@ public property Platform::String ^ Expression; // mandatory property Platform::String ^ Result; // mandatory + // explicit CalcManagerHistoryItem( + // Windows::Foundation::Collections::IVector ^ tokens, + // Windows::Foundation::Collections::IVector ^ commands, + // Platform::String ^ expression, + // Platform::String ^ result); + internal :; explicit CalcManagerHistoryItem(const CalculationManager::HISTORYITEM& item); }; diff --git a/src/CalcViewModel/StandardCalculatorViewModel.cpp b/src/CalcViewModel/StandardCalculatorViewModel.cpp index 844a063cf..9d7739749 100644 --- a/src/CalcViewModel/StandardCalculatorViewModel.cpp +++ b/src/CalcViewModel/StandardCalculatorViewModel.cpp @@ -115,7 +115,7 @@ namespace CalculatorResourceKeys StringReference DisplayCopied(L"Display_Copied"); } -StandardCalculatorViewModel::StandardCalculatorViewModel(StandardCalculatorSnapshot ^ snapshot) +StandardCalculatorViewModel::StandardCalculatorViewModel(CalculatorApp::ViewModel::Snapshot::StandardCalculatorSnapshot ^ snapshot) : m_DisplayValue(L"0") , m_DecimalDisplayValue(L"0") , m_HexDisplayValue(L"0") @@ -208,7 +208,7 @@ StandardCalculatorViewModel::StandardCalculatorViewModel(StandardCalculatorSnaps { using RawTokenCollection = std::vector>; RawTokenCollection rawTokens; - for (CalcManagerHistoryToken ^ token : snapshot->ExpressionDisplay->Tokens) + for (CalculatorApp::ViewModel::Snapshot::CalcManagerHistoryToken ^ token : snapshot->ExpressionDisplay->Tokens) { rawTokens.push_back(std::pair{ token->OpCodeName->Data(), token->CommandIndex }); } @@ -1823,18 +1823,18 @@ void StandardCalculatorViewModel::SetBitshiftRadioButtonCheckedAnnouncement(Plat Announcement = CalculatorAnnouncement::GetBitShiftRadioButtonCheckedAnnouncement(announcement); } -StandardCalculatorSnapshot ^ StandardCalculatorViewModel::GetSnapshot() const +CalculatorApp::ViewModel::Snapshot::StandardCalculatorSnapshot ^ StandardCalculatorViewModel::GetSnapshot() const { - auto result = ref new StandardCalculatorSnapshot(); - result->CalcManager = ref new CalcManagerSnapshot(m_standardCalculatorManager); - result->PrimaryDisplay = ref new PrimaryDisplaySnapshot(m_DisplayValue, m_IsInError); - result->ExpressionDisplay = ref new ExpressionDisplaySnapshot(*m_tokens, *m_commands); - result->DisplayCommands = ref new Platform::Collections::Vector(); + auto result = ref new CalculatorApp::ViewModel::Snapshot::StandardCalculatorSnapshot(); + result->CalcManager = ref new CalculatorApp::ViewModel::Snapshot::CalcManagerSnapshot(m_standardCalculatorManager); + result->PrimaryDisplay = ref new CalculatorApp::ViewModel::Snapshot::PrimaryDisplaySnapshot(m_DisplayValue, m_IsInError); + result->ExpressionDisplay = ref new CalculatorApp::ViewModel::Snapshot::ExpressionDisplaySnapshot(*m_tokens, *m_commands); + result->DisplayCommands = ref new Platform::Collections::Vector(); for (auto cmd : m_standardCalculatorManager.GetDisplayCommandsSnapshot()) { - result->DisplayCommands->Append(CreateExprCommand(cmd.get())); + result->DisplayCommands->Append(CalculatorApp::ViewModel::Snapshot::CreateExprCommand(cmd.get())); } - return nullptr; + return result; } // StandardCalculatorSnapshot StandardCalculatorViewModel::GetStandardCalculatorSnapshot() const diff --git a/src/CalcViewModel/StandardCalculatorViewModel.h b/src/CalcViewModel/StandardCalculatorViewModel.h index 5e17eee44..8026e709f 100644 --- a/src/CalcViewModel/StandardCalculatorViewModel.h +++ b/src/CalcViewModel/StandardCalculatorViewModel.h @@ -268,8 +268,8 @@ namespace CalculatorApp } } - property StandardCalculatorSnapshot - ^ Snapshot { StandardCalculatorSnapshot ^ get() { return GetSnapshot(); } } + property CalculatorApp::ViewModel::Snapshot::StandardCalculatorSnapshot + ^ Snapshot { CalculatorApp::ViewModel::Snapshot::StandardCalculatorSnapshot ^ get() { return GetSnapshot(); } } // Used by unit tests void @@ -327,10 +327,10 @@ namespace CalculatorApp } internal :; - explicit StandardCalculatorViewModel(StandardCalculatorSnapshot ^ snapshot = nullptr); + explicit StandardCalculatorViewModel(CalculatorApp::ViewModel::Snapshot::StandardCalculatorSnapshot ^ snapshot = nullptr); private: - StandardCalculatorSnapshot ^ GetSnapshot() const; + CalculatorApp::ViewModel::Snapshot::StandardCalculatorSnapshot ^ GetSnapshot() const; void SetMemorizedNumbers(const std::vector& memorizedNumbers); void UpdateProgrammerPanelDisplay(); void HandleUpdatedOperandData(CalculationManager::Command cmdenum); diff --git a/src/Calculator/Calculator.csproj b/src/Calculator/Calculator.csproj index 6c73ba688..589e2fe88 100644 --- a/src/Calculator/Calculator.csproj +++ b/src/Calculator/Calculator.csproj @@ -167,6 +167,7 @@ + EquationStylePanelControl.xaml @@ -799,6 +800,9 @@ 6.2.14 + + 8.0.5 + diff --git a/src/Calculator/Common/LaunchArguments.cs b/src/Calculator/Common/LaunchArguments.cs index ee643fab4..1906c14fc 100644 --- a/src/Calculator/Common/LaunchArguments.cs +++ b/src/Calculator/Common/LaunchArguments.cs @@ -1,7 +1,5 @@ -using System; using Windows.ApplicationModel.Activation; -using Windows.ApplicationModel.UserActivities; -using CalculatorApp.ViewModel; +using CalculatorApp.ViewModel.Snapshot; namespace CalculatorApp { diff --git a/src/Calculator/Utils/SerdeUtils.cs b/src/Calculator/Utils/SerdeUtils.cs new file mode 100644 index 000000000..053f2a54b --- /dev/null +++ b/src/Calculator/Utils/SerdeUtils.cs @@ -0,0 +1,49 @@ +using System.Collections.Generic; +using System.Linq; +using System.Text.Json.Serialization; +using CalculatorApp.ViewModel.Snapshot; + +namespace CalculatorApp +{ + internal class CalcManagerHistoryTokenAlias + { + [JsonIgnore] + public CalcManagerHistoryToken Value; + + [JsonPropertyName("t")] + public string OpCodeName + { + get => Value.OpCodeName; + set => Value.OpCodeName = value; + } + [JsonPropertyName("c")] + public int CommandIndex { get => Value.CommandIndex; } + } + + internal class CalcManagerIExprCommandAlias + { + [JsonPropertyName("t")] + public string Type; + + [JsonPropertyName("c")] + public string CmdString; + } + + internal class CalcManagerHistoryItemAlias + { + [JsonIgnore] + public CalcManagerHistoryItem Value; + + [JsonPropertyName("t")] + public IList Tokens + { + get => Value.Tokens.Select(x => new CalcManagerHistoryTokenAlias { Value = x }).ToList(); + set => Value.Tokens = value.Select(x => new CalcManagerHistoryToken(x.OpCodeName, x.CommandIndex)).ToList(); + } + + //public IList Commands + //{ + // get => Value.Commands; + //} + } +} diff --git a/src/Calculator/Views/MainPage.xaml.cs b/src/Calculator/Views/MainPage.xaml.cs index 0a3035fd5..5f656db21 100644 --- a/src/Calculator/Views/MainPage.xaml.cs +++ b/src/Calculator/Views/MainPage.xaml.cs @@ -23,6 +23,7 @@ using CalculatorApp.ViewModel.Common.Automation; using wuxc = Windows.UI.Xaml.Controls; +using System.Text.Json; namespace CalculatorApp { @@ -69,6 +70,8 @@ public MainPage() } var channel = UserActivityChannel.GetDefault(); var activity = await channel.GetOrCreateUserActivityAsync($"{Guid.NewGuid()}"); + var s = Model.Snapshot; + var j = JsonSerializer.Serialize(s); activity.ActivationUri = new Uri($"ms-calculator:snapshot/TODO"); activity.IsRoamable = false; var resProvider = AppResourceProvider.GetInstance(); From 950f92da00183cb31bf6b66fd3c7ae27d603fee0 Mon Sep 17 00:00:00 2001 From: Tian Liao Date: Fri, 25 Oct 2024 09:38:42 +0800 Subject: [PATCH 08/21] stash changes --- src/CalcViewModel/Snapshots.cpp | 5 + src/CalcViewModel/Snapshots.h | 4 + src/Calculator/Utils/SerdeUtils.cs | 152 ++++++++++++++++++++++++-- src/Calculator/Views/MainPage.xaml.cs | 87 ++++++++++++--- 4 files changed, 221 insertions(+), 27 deletions(-) diff --git a/src/CalcViewModel/Snapshots.cpp b/src/CalcViewModel/Snapshots.cpp index ff651dd4a..e12c44cfb 100644 --- a/src/CalcViewModel/Snapshots.cpp +++ b/src/CalcViewModel/Snapshots.cpp @@ -35,6 +35,11 @@ namespace CalculatorApp::ViewModel::Snapshot } } + Windows::Foundation::Collections::IVectorView ^ OperandCommand::Commands::get() + { + return ref new Platform::Collections::VectorView(m_cmds); + } + ICalcManagerIExprCommand ^ CreateExprCommand(const IExpressionCommand* exprCmd) { switch (exprCmd->GetCommandType()) { diff --git a/src/CalcViewModel/Snapshots.h b/src/CalcViewModel/Snapshots.h index b75d424c1..f22d1c369 100644 --- a/src/CalcViewModel/Snapshots.h +++ b/src/CalcViewModel/Snapshots.h @@ -14,6 +14,7 @@ public { }; +public ref struct UnaryCommand sealed : public ICalcManagerIExprCommand { property Windows::Foundation::Collections::IVectorView ^ Commands { Windows::Foundation::Collections::IVectorView ^ get(); }; @@ -28,6 +29,7 @@ public std::vector m_cmds; }; +public ref struct BinaryCommand sealed : public ICalcManagerIExprCommand { property int Command; @@ -37,6 +39,7 @@ public } }; +public ref struct OperandCommand sealed : public ICalcManagerIExprCommand { property bool IsNegative; @@ -56,6 +59,7 @@ public std::vector m_cmds; }; +public ref struct Parentheses sealed : public ICalcManagerIExprCommand { property int Command; diff --git a/src/Calculator/Utils/SerdeUtils.cs b/src/Calculator/Utils/SerdeUtils.cs index 053f2a54b..bf4ec6632 100644 --- a/src/Calculator/Utils/SerdeUtils.cs +++ b/src/Calculator/Utils/SerdeUtils.cs @@ -1,9 +1,11 @@ +using System; using System.Collections.Generic; using System.Linq; +using System.Security.Cryptography.X509Certificates; using System.Text.Json.Serialization; using CalculatorApp.ViewModel.Snapshot; -namespace CalculatorApp +namespace CalculatorApp.SerdeUtils { internal class CalcManagerHistoryTokenAlias { @@ -20,13 +22,55 @@ public string OpCodeName public int CommandIndex { get => Value.CommandIndex; } } - internal class CalcManagerIExprCommandAlias + [JsonPolymorphic(TypeDiscriminatorPropertyName = "$t")] + [JsonDerivedType(typeof(UnaryCommandAlias), typeDiscriminator: 0)] + [JsonDerivedType(typeof(BinaryCommandAlias), typeDiscriminator: 1)] + [JsonDerivedType(typeof(OperandCommandAlias), typeDiscriminator: 2)] + [JsonDerivedType(typeof(ParenthesesAlias), typeDiscriminator: 3)] + internal interface ICalcManagerIExprCommandAlias { - [JsonPropertyName("t")] - public string Type; + } + + internal class UnaryCommandAlias : ICalcManagerIExprCommandAlias + { + [JsonIgnore] + public UnaryCommand Value; + + [JsonPropertyName("c")] + public IList Commands { get => Value.Commands.ToList(); } + } + + internal class BinaryCommandAlias : ICalcManagerIExprCommandAlias + { + [JsonIgnore] + public BinaryCommand Value; [JsonPropertyName("c")] - public string CmdString; + public int Command { get => Value.Command; } + } + + internal class OperandCommandAlias : ICalcManagerIExprCommandAlias + { + [JsonIgnore] + public OperandCommand Value; + + [JsonPropertyName("n")] + public bool IsNegative { get => Value.IsNegative; } + [JsonPropertyName("d")] + public bool IsDecimalPresent { get => Value.IsDecimalPresent; } + [JsonPropertyName("s")] + public bool IsSciFmt { get => Value.IsSciFmt; } + [JsonPropertyName("c")] + public IList Commands { get => Value.Commands.ToList(); } + } + + internal class ParenthesesAlias : ICalcManagerIExprCommandAlias + { + [JsonIgnore] + public Parentheses Value; + + [JsonPropertyName("c")] + public int Command { get => Value.Command; } } internal class CalcManagerHistoryItemAlias @@ -38,12 +82,100 @@ internal class CalcManagerHistoryItemAlias public IList Tokens { get => Value.Tokens.Select(x => new CalcManagerHistoryTokenAlias { Value = x }).ToList(); - set => Value.Tokens = value.Select(x => new CalcManagerHistoryToken(x.OpCodeName, x.CommandIndex)).ToList(); } - //public IList Commands - //{ - // get => Value.Commands; - //} + [JsonPropertyName("c")] + public IList Commands + { + get => Value.Commands.Select(Helpers.MapCommandAlias).ToList(); + } + + [JsonPropertyName("e")] + public string Expression { get => Value.Expression; } + + [JsonPropertyName("r")] + public string Result { get => Value.Result; } + + } + + internal class CalcManagerSnapshotAlias + { + [JsonIgnore] + public CalcManagerSnapshot Value; + + [JsonPropertyName("h")] + public IList HistoryItems { get => Value.HistoryItems.Select(x => new CalcManagerHistoryItemAlias { Value = x }).ToList(); } + } + + internal class PrimaryDisplaySnapshotAlias + { + [JsonIgnore] + public PrimaryDisplaySnapshot Value; + + [JsonPropertyName("d")] + public string DisplayValue { get => Value.DisplayValue; } + [JsonPropertyName("e")] + public bool IsError { get => Value.IsError; } + } + + internal class ExpressionDisplaySnapshotAlias + { + [JsonIgnore] + public ExpressionDisplaySnapshot Value; + + [JsonPropertyName("t")] + public IList Tokens { get => Value.Tokens.Select(x => new CalcManagerHistoryTokenAlias { Value = x }).ToList(); } + [JsonPropertyName("c")] + public IList Commands { get => Value.Commands.Select(Helpers.MapCommandAlias).ToList(); } + } + + internal class StandardCalculatorSnapshotAlias + { + [JsonIgnore] + public StandardCalculatorSnapshot Value; + + [JsonPropertyName("m")] + public CalcManagerSnapshotAlias CalcManager { get => new CalcManagerSnapshotAlias { Value = Value.CalcManager }; } + [JsonPropertyName("p")] + public PrimaryDisplaySnapshotAlias PrimaryDisplay { get => new PrimaryDisplaySnapshotAlias { Value = Value.PrimaryDisplay }; } + [JsonPropertyName("e")] + public ExpressionDisplaySnapshotAlias ExpressionDisplay { get => new ExpressionDisplaySnapshotAlias { Value = Value.ExpressionDisplay }; } + [JsonPropertyName("c")] + public IList Commands { get => Value.DisplayCommands.Select(Helpers.MapCommandAlias).ToList(); } + } + + internal class ApplicationSnapshotAlias + { + [JsonIgnore] + public ApplicationSnapshot Value; + + [JsonPropertyName("m")] + public int Mode { get => Value.Mode; } + [JsonPropertyName("s")] + public StandardCalculatorSnapshotAlias StandardCalculatorSnapshot { get => new StandardCalculatorSnapshotAlias { Value = Value.StandardCalculator }; } + } + + internal static class Helpers + { + public static ICalcManagerIExprCommandAlias MapCommandAlias(ICalcManagerIExprCommand exprCmd) + { + if (exprCmd is UnaryCommand unary) + { + return new UnaryCommandAlias { Value = unary }; + } + else if (exprCmd is BinaryCommand binary) + { + return new BinaryCommandAlias { Value = binary }; + } + else if (exprCmd is OperandCommand operand) + { + return new OperandCommandAlias { Value = operand }; + } + else if (exprCmd is Parentheses paren) + { + return new ParenthesesAlias { Value = paren }; + } + throw new NotImplementedException("unhandled command type."); + } } } diff --git a/src/Calculator/Views/MainPage.xaml.cs b/src/Calculator/Views/MainPage.xaml.cs index 5f656db21..cb6a50360 100644 --- a/src/Calculator/Views/MainPage.xaml.cs +++ b/src/Calculator/Views/MainPage.xaml.cs @@ -24,6 +24,9 @@ using wuxc = Windows.UI.Xaml.Controls; using System.Text.Json; +using System.IO.Compression; +using System.IO; +using System.Text; namespace CalculatorApp { @@ -62,25 +65,40 @@ public MainPage() UserActivityRequestManager.GetForCurrentView().UserActivityRequested += async (_, args) => { - var deferral = args.GetDeferral(); - if (deferral == null) + using (var deferral = args.GetDeferral()) { - // Windows Bug in ni_moment won't return the deferral propoerly, see https://microsoft.visualstudio.com/DefaultCollection/OS/_workitems/edit/47775705/ - return; + if (deferral == null) + { + // Windows Bug in ni_moment won't return the deferral propoerly, see https://microsoft.visualstudio.com/DefaultCollection/OS/_workitems/edit/47775705/ + return; + } + var channel = UserActivityChannel.GetDefault(); + var activity = await channel.GetOrCreateUserActivityAsync($"{Guid.NewGuid()}"); + string embeddedData; + try + { + var json = JsonSerializer.Serialize(new SerdeUtils.ApplicationSnapshotAlias { Value = Model.Snapshot }); + var json2 = JsonSerializer.Serialize(Model.Snapshot); + embeddedData = Convert.ToBase64String(Compress(json)); + var e2 = Convert.ToBase64String(Compress(json2)); + var diff = embeddedData.Length - e2.Length; + } + catch (Exception) + { + // TODO: trace errors + deferral.Complete(); + return; + } + activity.ActivationUri = new Uri($"ms-calculator:snapshot/{embeddedData}"); + activity.IsRoamable = false; + var resProvider = AppResourceProvider.GetInstance(); + activity.VisualElements.DisplayText = + $"{resProvider.GetResourceString("AppName")} - {resProvider.GetResourceString(NavCategoryStates.GetNameResourceKey(Model.Mode))}"; + await activity.SaveAsync(); + args.Request.SetUserActivity(activity); + deferral.Complete(); + TraceLogger.GetInstance().LogRecallSnapshot(Model.Mode); } - var channel = UserActivityChannel.GetDefault(); - var activity = await channel.GetOrCreateUserActivityAsync($"{Guid.NewGuid()}"); - var s = Model.Snapshot; - var j = JsonSerializer.Serialize(s); - activity.ActivationUri = new Uri($"ms-calculator:snapshot/TODO"); - activity.IsRoamable = false; - var resProvider = AppResourceProvider.GetInstance(); - activity.VisualElements.DisplayText = - $"{resProvider.GetResourceString("AppName")} - {resProvider.GetResourceString(NavCategoryStates.GetNameResourceKey(Model.Mode))}"; - await activity.SaveAsync(); - args.Request.SetUserActivity(activity); - deferral.Complete(); - TraceLogger.GetInstance().LogRecallSnapshot(Model.Mode); }; } @@ -705,6 +723,41 @@ private async Task ShowSnapshotLaunchErrorAsync() await dialog.ShowAsync(); } + private static byte[] Compress(string text) + { + var data = Encoding.UTF8.GetBytes(text); + using (var compressed = new MemoryStream()) + { + using (var deflater = new DeflateStream(compressed, CompressionLevel.Optimal)) + { + deflater.Write(data, 0, data.Length); + } + return compressed.ToArray(); + } + + //encodedSnapshot = null; + //try + //{ + // var rawJson = Encoding.UTF8.GetBytes(JsonSerializer.Serialize(new SerdeUtils.ApplicationSnapshotAlias { Value = Model.Snapshot })); + // using (var compressed = new MemoryStream()) + // { + // using (var deflater = new DeflateStream(compressed, CompressionLevel.Optimal, true)) + // { + // deflater.Write(rawJson, 0, rawJson.Length); + // } + // byte[] data; + // compressed.Read(data, 0, ); + // Convert.ToBase64String(compressed.GetBuffer()); + // } + //} + //catch (Exception) + //{ + // // TODO: trace errors + // return false; + //} + //return true; + } + private Calculator m_calculator; private GraphingCalculator m_graphingCalculator; private UnitConverter m_converter; From f23786ce5e30d0f629a6a09583a472bc5dbdcd8c Mon Sep 17 00:00:00 2001 From: Tian Liao Date: Fri, 25 Oct 2024 09:54:02 +0800 Subject: [PATCH 09/21] renaming --- src/Calculator/Calculator.csproj | 2 +- .../Utils/{SerdeUtils.cs => JsonUtils.cs} | 3 +- src/Calculator/Views/MainPage.xaml.cs | 29 ++----------------- 3 files changed, 4 insertions(+), 30 deletions(-) rename src/Calculator/Utils/{SerdeUtils.cs => JsonUtils.cs} (98%) diff --git a/src/Calculator/Calculator.csproj b/src/Calculator/Calculator.csproj index 589e2fe88..6dee5aa81 100644 --- a/src/Calculator/Calculator.csproj +++ b/src/Calculator/Calculator.csproj @@ -167,7 +167,7 @@ - + EquationStylePanelControl.xaml diff --git a/src/Calculator/Utils/SerdeUtils.cs b/src/Calculator/Utils/JsonUtils.cs similarity index 98% rename from src/Calculator/Utils/SerdeUtils.cs rename to src/Calculator/Utils/JsonUtils.cs index bf4ec6632..060c2b147 100644 --- a/src/Calculator/Utils/SerdeUtils.cs +++ b/src/Calculator/Utils/JsonUtils.cs @@ -1,11 +1,10 @@ using System; using System.Collections.Generic; using System.Linq; -using System.Security.Cryptography.X509Certificates; using System.Text.Json.Serialization; using CalculatorApp.ViewModel.Snapshot; -namespace CalculatorApp.SerdeUtils +namespace CalculatorApp.JsonUtils { internal class CalcManagerHistoryTokenAlias { diff --git a/src/Calculator/Views/MainPage.xaml.cs b/src/Calculator/Views/MainPage.xaml.cs index cb6a50360..a3f142bca 100644 --- a/src/Calculator/Views/MainPage.xaml.cs +++ b/src/Calculator/Views/MainPage.xaml.cs @@ -4,7 +4,6 @@ using System.Threading.Tasks; using Windows.ApplicationModel.UserActivities; -using Windows.Data.Json; using Windows.Foundation; using Windows.Graphics.Display; using Windows.Storage; @@ -18,6 +17,7 @@ using CalculatorApp.Common; using CalculatorApp.Converters; +using CalculatorApp.JsonUtils; using CalculatorApp.ViewModel; using CalculatorApp.ViewModel.Common; using CalculatorApp.ViewModel.Common.Automation; @@ -77,11 +77,8 @@ public MainPage() string embeddedData; try { - var json = JsonSerializer.Serialize(new SerdeUtils.ApplicationSnapshotAlias { Value = Model.Snapshot }); - var json2 = JsonSerializer.Serialize(Model.Snapshot); + var json = JsonSerializer.Serialize(new ApplicationSnapshotAlias { Value = Model.Snapshot }); embeddedData = Convert.ToBase64String(Compress(json)); - var e2 = Convert.ToBase64String(Compress(json2)); - var diff = embeddedData.Length - e2.Length; } catch (Exception) { @@ -734,28 +731,6 @@ private static byte[] Compress(string text) } return compressed.ToArray(); } - - //encodedSnapshot = null; - //try - //{ - // var rawJson = Encoding.UTF8.GetBytes(JsonSerializer.Serialize(new SerdeUtils.ApplicationSnapshotAlias { Value = Model.Snapshot })); - // using (var compressed = new MemoryStream()) - // { - // using (var deflater = new DeflateStream(compressed, CompressionLevel.Optimal, true)) - // { - // deflater.Write(rawJson, 0, rawJson.Length); - // } - // byte[] data; - // compressed.Read(data, 0, ); - // Convert.ToBase64String(compressed.GetBuffer()); - // } - //} - //catch (Exception) - //{ - // // TODO: trace errors - // return false; - //} - //return true; } private Calculator m_calculator; From e36faaa0b5fad5c2a6d8c4b3825d1b458383da42 Mon Sep 17 00:00:00 2001 From: Tian Liao Date: Fri, 25 Oct 2024 10:46:44 +0800 Subject: [PATCH 10/21] DeflateUtils --- src/Calculator/Calculator.csproj | 1 + src/Calculator/Common/LaunchArguments.cs | 6 +++- src/Calculator/Utils/DeflateUtils.cs | 44 ++++++++++++++++++++++++ src/Calculator/Views/MainPage.xaml.cs | 20 ++--------- 4 files changed, 52 insertions(+), 19 deletions(-) create mode 100644 src/Calculator/Utils/DeflateUtils.cs diff --git a/src/Calculator/Calculator.csproj b/src/Calculator/Calculator.csproj index 6dee5aa81..00bdc954b 100644 --- a/src/Calculator/Calculator.csproj +++ b/src/Calculator/Calculator.csproj @@ -165,6 +165,7 @@ + diff --git a/src/Calculator/Common/LaunchArguments.cs b/src/Calculator/Common/LaunchArguments.cs index 1906c14fc..3d60896d1 100644 --- a/src/Calculator/Common/LaunchArguments.cs +++ b/src/Calculator/Common/LaunchArguments.cs @@ -15,7 +15,11 @@ public static bool TryGetSnapshotProtocol(this IActivatedEventArgs args, out IPr { result = null; var protoArgs = args as IProtocolActivatedEventArgs; - if (protoArgs == null || protoArgs.Uri == null) + if (protoArgs == null || + protoArgs.Uri == null || + protoArgs.Uri.Segments == null || + protoArgs.Uri.Segments.Length < 2 || + protoArgs.Uri.Segments[0] != "snapshot/") { return false; } diff --git a/src/Calculator/Utils/DeflateUtils.cs b/src/Calculator/Utils/DeflateUtils.cs new file mode 100644 index 000000000..1cdb4c6c1 --- /dev/null +++ b/src/Calculator/Utils/DeflateUtils.cs @@ -0,0 +1,44 @@ +using System; +using System.IO; +using System.IO.Compression; +using System.Text; + +namespace CalculatorApp +{ + internal static class DeflateUtils + { + public static byte[] Compress(string text) + { + var data = Encoding.UTF8.GetBytes(text); + using (var compressed = new MemoryStream()) + { + using (var deflater = new DeflateStream(compressed, CompressionLevel.Optimal)) + { + deflater.Write(data, 0, data.Length); + } + return compressed.ToArray(); + } + } + + public static bool TryDecompress(byte[] data, out string text) + { + text = null; + try + { + using (var srcStream = new MemoryStream(data)) + using (var deflateStream = new DeflateStream(srcStream, CompressionMode.Decompress)) + using (var resultStream = new MemoryStream()) + { + deflateStream.CopyTo(resultStream); + byte[] decompressed = resultStream.ToArray(); + text = Encoding.UTF8.GetString(decompressed); + return true; + } + } + catch (Exception) + { + return false; + } + } + } +} diff --git a/src/Calculator/Views/MainPage.xaml.cs b/src/Calculator/Views/MainPage.xaml.cs index a3f142bca..e7efa4c6a 100644 --- a/src/Calculator/Views/MainPage.xaml.cs +++ b/src/Calculator/Views/MainPage.xaml.cs @@ -1,6 +1,7 @@ using System; using System.Collections.Generic; using System.ComponentModel; +using System.Text.Json; using System.Threading.Tasks; using Windows.ApplicationModel.UserActivities; @@ -23,10 +24,6 @@ using CalculatorApp.ViewModel.Common.Automation; using wuxc = Windows.UI.Xaml.Controls; -using System.Text.Json; -using System.IO.Compression; -using System.IO; -using System.Text; namespace CalculatorApp { @@ -78,7 +75,7 @@ public MainPage() try { var json = JsonSerializer.Serialize(new ApplicationSnapshotAlias { Value = Model.Snapshot }); - embeddedData = Convert.ToBase64String(Compress(json)); + embeddedData = Convert.ToBase64String(DeflateUtils.Compress(json)); } catch (Exception) { @@ -720,19 +717,6 @@ private async Task ShowSnapshotLaunchErrorAsync() await dialog.ShowAsync(); } - private static byte[] Compress(string text) - { - var data = Encoding.UTF8.GetBytes(text); - using (var compressed = new MemoryStream()) - { - using (var deflater = new DeflateStream(compressed, CompressionLevel.Optimal)) - { - deflater.Write(data, 0, data.Length); - } - return compressed.ToArray(); - } - } - private Calculator m_calculator; private GraphingCalculator m_graphingCalculator; private UnitConverter m_converter; From bfb6682360cccbaa751432af7aa1adf99e473e4d Mon Sep 17 00:00:00 2001 From: Tian Liao Date: Fri, 25 Oct 2024 13:38:40 +0800 Subject: [PATCH 11/21] stash changes --- src/CalcViewModel/Snapshots.cpp | 98 +++++++++++-- src/CalcViewModel/Snapshots.h | 63 +++++---- src/Calculator/Common/LaunchArguments.cs | 18 ++- src/Calculator/Utils/DeflateUtils.cs | 23 +--- src/Calculator/Utils/JsonUtils.cs | 166 +++++++++++++++++++---- 5 files changed, 289 insertions(+), 79 deletions(-) diff --git a/src/CalcViewModel/Snapshots.cpp b/src/CalcViewModel/Snapshots.cpp index e12c44cfb..404cce36f 100644 --- a/src/CalcViewModel/Snapshots.cpp +++ b/src/CalcViewModel/Snapshots.cpp @@ -11,33 +11,76 @@ namespace CalculatorApp::ViewModel::Snapshot { - UnaryCommand::UnaryCommand(Windows::Foundation::Collections::IVectorView ^ cmds) + UnaryCommand::UnaryCommand() { - for (auto cmd : cmds) + } + + UnaryCommand::UnaryCommand(std::vector cmds) + : m_cmds(std::move(cmds)) + { + } + + Windows::Foundation::Collections::IVectorView ^ UnaryCommand::Commands::get() + { + return ref new Platform::Collections::VectorView(m_cmds); + } + + void UnaryCommand::Commands::set(Windows::Foundation::Collections::IVectorView ^ commands) + { + m_cmds.clear(); + for (auto cmd : commands) { m_cmds.push_back(cmd); } } - Windows::Foundation::Collections::IVectorView ^ UnaryCommand::Commands::get() + BinaryCommand::BinaryCommand() { - return ref new Platform::Collections::VectorView(m_cmds); + Command = 0; } - OperandCommand::OperandCommand(bool isNegative, bool isDecimal, bool isSciFmt, Windows::Foundation::Collections::IVectorView ^ cmds) + BinaryCommand::BinaryCommand(int cmd) + { + Command = cmd; + } + + OperandCommand::OperandCommand() + { + IsNegative = false; + IsDecimalPresent = false; + IsSciFmt = false; + } + + OperandCommand::OperandCommand(bool isNegative, bool isDecimal, bool isSciFmt, std::vector cmds) { IsNegative = isNegative; IsDecimalPresent = isDecimal; IsSciFmt = isSciFmt; - for (auto cmd : cmds) + m_cmds = std::move(cmds); + } + + Windows::Foundation::Collections::IVectorView ^ OperandCommand::Commands::get() + { + return ref new Platform::Collections::VectorView(m_cmds); + } + + void OperandCommand::Commands::set(Windows::Foundation::Collections::IVectorView ^ commands) + { + m_cmds.clear(); + for (auto cmd : commands) { m_cmds.push_back(cmd); } } - Windows::Foundation::Collections::IVectorView ^ OperandCommand::Commands::get() + Parentheses::Parentheses() { - return ref new Platform::Collections::VectorView(m_cmds); + Command = 0; + } + + Parentheses::Parentheses(int cmd) + { + Command = cmd; } ICalcManagerIExprCommand ^ CreateExprCommand(const IExpressionCommand* exprCmd) { @@ -78,6 +121,12 @@ namespace CalculatorApp::ViewModel::Snapshot } } + CalcManagerHistoryToken::CalcManagerHistoryToken() + { + OpCodeName = nullptr; + CommandIndex = 0; + } + CalcManagerHistoryToken::CalcManagerHistoryToken(Platform::String ^ opCodeName, int cmdIndex) { assert(opCodeName != nullptr && "opCodeName is mandatory."); @@ -85,6 +134,14 @@ namespace CalculatorApp::ViewModel::Snapshot CommandIndex = cmdIndex; } + CalcManagerHistoryItem::CalcManagerHistoryItem() + { + Tokens = ref new Platform::Collections::Vector(); + Commands = ref new Platform::Collections::Vector(); + Expression = ref new Platform::String(); + Result = ref new Platform::String(); + } + CalcManagerHistoryItem::CalcManagerHistoryItem(const CalculationManager::HISTORYITEM& item) { Tokens = ref new Platform::Collections::Vector(); @@ -103,6 +160,11 @@ namespace CalculatorApp::ViewModel::Snapshot Result = ref new Platform::String(item.historyItemVector.result.c_str()); } + CalcManagerSnapshot::CalcManagerSnapshot() + { + HistoryItems = nullptr; + } + CalcManagerSnapshot::CalcManagerSnapshot(const CalculationManager::CalculatorManager& calcMgr) { auto& items = calcMgr.GetHistoryItems(); @@ -116,6 +178,12 @@ namespace CalculatorApp::ViewModel::Snapshot } } + PrimaryDisplaySnapshot::PrimaryDisplaySnapshot() + { + DisplayValue = ref new Platform::String(); + IsError = false; + } + PrimaryDisplaySnapshot::PrimaryDisplaySnapshot(Platform::String ^ display, bool isError) { assert(display != nullptr && "display is mandatory"); @@ -123,6 +191,12 @@ namespace CalculatorApp::ViewModel::Snapshot IsError = isError; } + ExpressionDisplaySnapshot::ExpressionDisplaySnapshot() + { + Tokens = ref new Platform::Collections::Vector(); + Commands = ref new Platform::Collections::Vector(); + } + ExpressionDisplaySnapshot::ExpressionDisplaySnapshot( const std::vector& tokens, const std::vector>& commands) @@ -140,6 +214,14 @@ namespace CalculatorApp::ViewModel::Snapshot } } + StandardCalculatorSnapshot::StandardCalculatorSnapshot() + { + CalcManager = ref new CalcManagerSnapshot(); + PrimaryDisplay = ref new PrimaryDisplaySnapshot(); + ExpressionDisplay = nullptr; + DisplayCommands = ref new Platform::Collections::Vector(); + } + std::vector> ToUnderlying(Windows::Foundation::Collections::IVector ^ items) { return {}; // TODO diff --git a/src/CalcViewModel/Snapshots.h b/src/CalcViewModel/Snapshots.h index f22d1c369..cee12933b 100644 --- a/src/CalcViewModel/Snapshots.h +++ b/src/CalcViewModel/Snapshots.h @@ -17,15 +17,15 @@ public public ref struct UnaryCommand sealed : public ICalcManagerIExprCommand { - property Windows::Foundation::Collections::IVectorView ^ Commands { Windows::Foundation::Collections::IVectorView ^ get(); }; + property Windows::Foundation::Collections::IVectorView ^ Commands { + Windows::Foundation::Collections::IVectorView ^ get(); + void set(Windows::Foundation::Collections::IVectorView ^ commands); + }; - explicit UnaryCommand(Windows::Foundation::Collections::IVectorView ^ cmds); + UnaryCommand(); internal :; - explicit UnaryCommand(std::vector cmds) - : m_cmds(std::move(cmds)) - { - } + explicit UnaryCommand(std::vector cmds); std::vector m_cmds; }; @@ -33,10 +33,11 @@ public ref struct BinaryCommand sealed : public ICalcManagerIExprCommand { property int Command; - explicit BinaryCommand(int cmd) - { - Command = cmd; - } + + BinaryCommand(); + + internal :; + explicit BinaryCommand(int cmd); }; public @@ -45,17 +46,15 @@ public property bool IsNegative; property bool IsDecimalPresent; property bool IsSciFmt; - property Windows::Foundation::Collections::IVectorView ^ Commands { Windows::Foundation::Collections::IVectorView ^ get(); }; + property Windows::Foundation::Collections::IVectorView ^ Commands { + Windows::Foundation::Collections::IVectorView ^ get(); + void set(Windows::Foundation::Collections::IVectorView ^ commands); + }; + + OperandCommand(); - explicit OperandCommand(bool isNegative, bool isDecimal, bool isSciFmt, Windows::Foundation::Collections::IVectorView ^ cmds); internal :; - explicit OperandCommand(bool isNegative, bool isDecimal, bool isSciFmt, std::vector cmds) - { - IsNegative = isNegative; - IsDecimalPresent = isDecimal; - IsSciFmt = isSciFmt; - m_cmds = std::move(cmds); - } + explicit OperandCommand(bool isNegative, bool isDecimal, bool isSciFmt, std::vector cmds); std::vector m_cmds; }; @@ -63,10 +62,11 @@ public ref struct Parentheses sealed : public ICalcManagerIExprCommand { property int Command; - explicit Parentheses(int cmd) - { - Command = cmd; - } + + Parentheses(); + + internal :; + explicit Parentheses(int cmd); }; public @@ -75,6 +75,9 @@ public property Platform::String ^ OpCodeName; // mandatory property int CommandIndex; + CalcManagerHistoryToken(); + + internal :; explicit CalcManagerHistoryToken(Platform::String ^ opCodeName, int cmdIndex); }; @@ -86,11 +89,7 @@ public property Platform::String ^ Expression; // mandatory property Platform::String ^ Result; // mandatory - // explicit CalcManagerHistoryItem( - // Windows::Foundation::Collections::IVector ^ tokens, - // Windows::Foundation::Collections::IVector ^ commands, - // Platform::String ^ expression, - // Platform::String ^ result); + CalcManagerHistoryItem(); internal :; explicit CalcManagerHistoryItem(const CalculationManager::HISTORYITEM& item); @@ -101,6 +100,8 @@ public { property Windows::Foundation::Collections::IVector ^ HistoryItems; // optional + CalcManagerSnapshot(); + internal :; explicit CalcManagerSnapshot(const CalculationManager::CalculatorManager& calcMgr); }; @@ -111,6 +112,8 @@ public property Platform::String ^ DisplayValue; // mandatory property bool IsError; + PrimaryDisplaySnapshot(); + internal :; explicit PrimaryDisplaySnapshot(Platform::String ^ display, bool isError); }; @@ -121,6 +124,8 @@ public property Windows::Foundation::Collections::IVector ^ Tokens; property Windows::Foundation::Collections::IVector ^ Commands; + ExpressionDisplaySnapshot(); + internal :; using CalcHistoryToken = std::pair; explicit ExpressionDisplaySnapshot(const std::vector& tokens, const std::vector>& commands); @@ -133,6 +138,8 @@ public property PrimaryDisplaySnapshot ^ PrimaryDisplay; // mandatory property ExpressionDisplaySnapshot ^ ExpressionDisplay; // optional property Windows::Foundation::Collections::IVector ^ DisplayCommands; // mandatory + + StandardCalculatorSnapshot(); }; public diff --git a/src/Calculator/Common/LaunchArguments.cs b/src/Calculator/Common/LaunchArguments.cs index 3d60896d1..fc887356f 100644 --- a/src/Calculator/Common/LaunchArguments.cs +++ b/src/Calculator/Common/LaunchArguments.cs @@ -1,5 +1,10 @@ +using System; +using System.Linq; +using System.Text.Json; using Windows.ApplicationModel.Activation; + using CalculatorApp.ViewModel.Snapshot; +using CalculatorApp.JsonUtils; namespace CalculatorApp { @@ -29,7 +34,18 @@ public static bool TryGetSnapshotProtocol(this IActivatedEventArgs args, out IPr public static SnapshotLaunchArguments GetSnapshotLaunchArgs(this IProtocolActivatedEventArgs args) { - return null; + try + { + var rawbase64 = args.Uri.Segments.Skip(1).Aggregate((folded, x) => folded += x); + var compressed = Convert.FromBase64String(rawbase64); + var jsonStr = DeflateUtils.Decompress(compressed); + var snapshot = JsonSerializer.Deserialize(jsonStr); + return new SnapshotLaunchArguments { HasError = false, Snapshot = snapshot.Value }; + } + catch (Exception) + { + return new SnapshotLaunchArguments { HasError = true }; + } } } } diff --git a/src/Calculator/Utils/DeflateUtils.cs b/src/Calculator/Utils/DeflateUtils.cs index 1cdb4c6c1..3d4b2fbd3 100644 --- a/src/Calculator/Utils/DeflateUtils.cs +++ b/src/Calculator/Utils/DeflateUtils.cs @@ -20,24 +20,15 @@ public static byte[] Compress(string text) } } - public static bool TryDecompress(byte[] data, out string text) + public static string Decompress(byte[] data) { - text = null; - try + using (var srcStream = new MemoryStream(data)) + using (var deflateStream = new DeflateStream(srcStream, CompressionMode.Decompress)) + using (var resultStream = new MemoryStream()) { - using (var srcStream = new MemoryStream(data)) - using (var deflateStream = new DeflateStream(srcStream, CompressionMode.Decompress)) - using (var resultStream = new MemoryStream()) - { - deflateStream.CopyTo(resultStream); - byte[] decompressed = resultStream.ToArray(); - text = Encoding.UTF8.GetString(decompressed); - return true; - } - } - catch (Exception) - { - return false; + deflateStream.CopyTo(resultStream); + byte[] decompressed = resultStream.ToArray(); + return Encoding.UTF8.GetString(decompressed); } } } diff --git a/src/Calculator/Utils/JsonUtils.cs b/src/Calculator/Utils/JsonUtils.cs index 060c2b147..33a947e96 100644 --- a/src/Calculator/Utils/JsonUtils.cs +++ b/src/Calculator/Utils/JsonUtils.cs @@ -3,6 +3,7 @@ using System.Linq; using System.Text.Json.Serialization; using CalculatorApp.ViewModel.Snapshot; +using Windows.ApplicationModel; namespace CalculatorApp.JsonUtils { @@ -18,7 +19,11 @@ public string OpCodeName set => Value.OpCodeName = value; } [JsonPropertyName("c")] - public int CommandIndex { get => Value.CommandIndex; } + public int CommandIndex + { + get => Value.CommandIndex; + set => Value.CommandIndex = value; + } } [JsonPolymorphic(TypeDiscriminatorPropertyName = "$t")] @@ -36,7 +41,11 @@ internal class UnaryCommandAlias : ICalcManagerIExprCommandAlias public UnaryCommand Value; [JsonPropertyName("c")] - public IList Commands { get => Value.Commands.ToList(); } + public IReadOnlyList Commands + { + get => Value.Commands; + set => Value.Commands = value; + } } internal class BinaryCommandAlias : ICalcManagerIExprCommandAlias @@ -45,7 +54,11 @@ internal class BinaryCommandAlias : ICalcManagerIExprCommandAlias public BinaryCommand Value; [JsonPropertyName("c")] - public int Command { get => Value.Command; } + public int Command + { + get => Value.Command; + set => Value.Command = value; + } } internal class OperandCommandAlias : ICalcManagerIExprCommandAlias @@ -54,13 +67,29 @@ internal class OperandCommandAlias : ICalcManagerIExprCommandAlias public OperandCommand Value; [JsonPropertyName("n")] - public bool IsNegative { get => Value.IsNegative; } + public bool IsNegative + { + get => Value.IsNegative; + set => Value.IsNegative = value; + } [JsonPropertyName("d")] - public bool IsDecimalPresent { get => Value.IsDecimalPresent; } + public bool IsDecimalPresent + { + get => Value.IsDecimalPresent; + set => Value.IsDecimalPresent = value; + } [JsonPropertyName("s")] - public bool IsSciFmt { get => Value.IsSciFmt; } + public bool IsSciFmt + { + get => Value.IsSciFmt; + set => Value.IsSciFmt = value; + } [JsonPropertyName("c")] - public IList Commands { get => Value.Commands.ToList(); } + public IReadOnlyList Commands + { + get => Value.Commands; + set => Value.Commands = value; + } } internal class ParenthesesAlias : ICalcManagerIExprCommandAlias @@ -69,7 +98,11 @@ internal class ParenthesesAlias : ICalcManagerIExprCommandAlias public Parentheses Value; [JsonPropertyName("c")] - public int Command { get => Value.Command; } + public int Command + { + get => Value.Command; + set => Value.Command = value; + } } internal class CalcManagerHistoryItemAlias @@ -78,23 +111,32 @@ internal class CalcManagerHistoryItemAlias public CalcManagerHistoryItem Value; [JsonPropertyName("t")] - public IList Tokens + public IEnumerable Tokens { - get => Value.Tokens.Select(x => new CalcManagerHistoryTokenAlias { Value = x }).ToList(); + get => Value.Tokens.Select(x => new CalcManagerHistoryTokenAlias { Value = x }); + set => Value.Tokens = value.Select(Helpers.MapHistoryToken).ToList(); } [JsonPropertyName("c")] - public IList Commands + public IEnumerable Commands { - get => Value.Commands.Select(Helpers.MapCommandAlias).ToList(); + get => Value.Commands.Select(Helpers.MapCommandAlias); + set => Value.Commands = value.Select(Helpers.MapCommandAlias).ToList(); } [JsonPropertyName("e")] - public string Expression { get => Value.Expression; } + public string Expression + { + get => Value.Expression; + set => Value.Expression = value; + } [JsonPropertyName("r")] - public string Result { get => Value.Result; } - + public string Result + { + get => Value.Result; + set => Value.Result = value; + } } internal class CalcManagerSnapshotAlias @@ -103,7 +145,11 @@ internal class CalcManagerSnapshotAlias public CalcManagerSnapshot Value; [JsonPropertyName("h")] - public IList HistoryItems { get => Value.HistoryItems.Select(x => new CalcManagerHistoryItemAlias { Value = x }).ToList(); } + public IEnumerable HistoryItems + { + get => Value.HistoryItems.Select(x => new CalcManagerHistoryItemAlias { Value = x }); + set => Value.HistoryItems = value.Select(x => new CalcManagerHistoryItem { Tokens = x.Tokens.Select(Helpers.MapHistoryToken).ToList() }).ToList(); + } } internal class PrimaryDisplaySnapshotAlias @@ -112,9 +158,17 @@ internal class PrimaryDisplaySnapshotAlias public PrimaryDisplaySnapshot Value; [JsonPropertyName("d")] - public string DisplayValue { get => Value.DisplayValue; } + public string DisplayValue + { + get => Value.DisplayValue; + set => Value.DisplayValue = value; + } [JsonPropertyName("e")] - public bool IsError { get => Value.IsError; } + public bool IsError + { + get => Value.IsError; + set => IsError = value; + } } internal class ExpressionDisplaySnapshotAlias @@ -123,9 +177,17 @@ internal class ExpressionDisplaySnapshotAlias public ExpressionDisplaySnapshot Value; [JsonPropertyName("t")] - public IList Tokens { get => Value.Tokens.Select(x => new CalcManagerHistoryTokenAlias { Value = x }).ToList(); } + public IEnumerable Tokens + { + get => Value.Tokens.Select(x => new CalcManagerHistoryTokenAlias { Value = x }); + set => Value.Tokens = value.Select(Helpers.MapHistoryToken).ToList(); + } [JsonPropertyName("c")] - public IList Commands { get => Value.Commands.Select(Helpers.MapCommandAlias).ToList(); } + public IEnumerable Commands + { + get => Value.Commands.Select(Helpers.MapCommandAlias); + set => Value.Commands = value.Select(Helpers.MapCommandAlias).ToList(); + } } internal class StandardCalculatorSnapshotAlias @@ -134,13 +196,29 @@ internal class StandardCalculatorSnapshotAlias public StandardCalculatorSnapshot Value; [JsonPropertyName("m")] - public CalcManagerSnapshotAlias CalcManager { get => new CalcManagerSnapshotAlias { Value = Value.CalcManager }; } + public CalcManagerSnapshotAlias CalcManager + { + get => new CalcManagerSnapshotAlias { Value = Value.CalcManager }; + set => Value.CalcManager = value.Value; + } [JsonPropertyName("p")] - public PrimaryDisplaySnapshotAlias PrimaryDisplay { get => new PrimaryDisplaySnapshotAlias { Value = Value.PrimaryDisplay }; } + public PrimaryDisplaySnapshotAlias PrimaryDisplay + { + get => new PrimaryDisplaySnapshotAlias { Value = Value.PrimaryDisplay }; + set => Value.PrimaryDisplay = value.Value; + } [JsonPropertyName("e")] - public ExpressionDisplaySnapshotAlias ExpressionDisplay { get => new ExpressionDisplaySnapshotAlias { Value = Value.ExpressionDisplay }; } + public ExpressionDisplaySnapshotAlias ExpressionDisplay + { + get => new ExpressionDisplaySnapshotAlias { Value = Value.ExpressionDisplay }; + set => Value.ExpressionDisplay = value.Value; + } [JsonPropertyName("c")] - public IList Commands { get => Value.DisplayCommands.Select(Helpers.MapCommandAlias).ToList(); } + public IEnumerable Commands + { + get => Value.DisplayCommands.Select(Helpers.MapCommandAlias); + set => Value.DisplayCommands = value.Select(Helpers.MapCommandAlias).ToList(); + } } internal class ApplicationSnapshotAlias @@ -149,13 +227,22 @@ internal class ApplicationSnapshotAlias public ApplicationSnapshot Value; [JsonPropertyName("m")] - public int Mode { get => Value.Mode; } + public int Mode { get => Value.Mode; set => Value.Mode = value; } [JsonPropertyName("s")] - public StandardCalculatorSnapshotAlias StandardCalculatorSnapshot { get => new StandardCalculatorSnapshotAlias { Value = Value.StandardCalculator }; } + public StandardCalculatorSnapshotAlias StandardCalculatorSnapshot + { + get => new StandardCalculatorSnapshotAlias { Value = Value.StandardCalculator }; + set => Value.StandardCalculator = value.Value; + } } internal static class Helpers { + public static CalcManagerHistoryToken MapHistoryToken(CalcManagerHistoryTokenAlias token) + { + return new CalcManagerHistoryToken { OpCodeName = token.OpCodeName, CommandIndex = token.CommandIndex }; + } + public static ICalcManagerIExprCommandAlias MapCommandAlias(ICalcManagerIExprCommand exprCmd) { if (exprCmd is UnaryCommand unary) @@ -176,5 +263,32 @@ public static ICalcManagerIExprCommandAlias MapCommandAlias(ICalcManagerIExprCom } throw new NotImplementedException("unhandled command type."); } + + public static ICalcManagerIExprCommand MapCommandAlias(ICalcManagerIExprCommandAlias exprCmd) + { + if (exprCmd is UnaryCommandAlias unary) + { + return new UnaryCommand { Commands = unary.Commands }; + } + else if (exprCmd is BinaryCommandAlias binary) + { + return new BinaryCommand { Command = binary.Command }; + } + else if (exprCmd is OperandCommandAlias operand) + { + return new OperandCommand + { + IsNegative = operand.IsNegative, + IsDecimalPresent = operand.IsDecimalPresent, + IsSciFmt = operand.IsSciFmt, + Commands = operand.Commands + }; + } + else if (exprCmd is ParenthesesAlias paren) + { + return new Parentheses { Command = paren.Command }; + } + throw new NotImplementedException("unhandled command type."); + } } } From a683e2346bd06252f440f3e6f803618bee689202 Mon Sep 17 00:00:00 2001 From: Tian Liao Date: Fri, 25 Oct 2024 16:47:05 +0800 Subject: [PATCH 12/21] deserialization --- src/Calculator/Utils/JsonUtils.cs | 52 ++++++++++++++++++++++++------- 1 file changed, 41 insertions(+), 11 deletions(-) diff --git a/src/Calculator/Utils/JsonUtils.cs b/src/Calculator/Utils/JsonUtils.cs index 33a947e96..e138b2eb8 100644 --- a/src/Calculator/Utils/JsonUtils.cs +++ b/src/Calculator/Utils/JsonUtils.cs @@ -24,6 +24,9 @@ public int CommandIndex get => Value.CommandIndex; set => Value.CommandIndex = value; } + + public CalcManagerHistoryTokenAlias() => Value = new CalcManagerHistoryToken(); + public CalcManagerHistoryTokenAlias(CalcManagerHistoryToken value) => Value = value; } [JsonPolymorphic(TypeDiscriminatorPropertyName = "$t")] @@ -46,6 +49,9 @@ public IReadOnlyList Commands get => Value.Commands; set => Value.Commands = value; } + + public UnaryCommandAlias() => Value = new UnaryCommand(); + public UnaryCommandAlias(UnaryCommand value) => Value = value; } internal class BinaryCommandAlias : ICalcManagerIExprCommandAlias @@ -59,6 +65,8 @@ public int Command get => Value.Command; set => Value.Command = value; } + public BinaryCommandAlias() => Value = new BinaryCommand(); + public BinaryCommandAlias(BinaryCommand value) => Value = value; } internal class OperandCommandAlias : ICalcManagerIExprCommandAlias @@ -90,6 +98,9 @@ public IReadOnlyList Commands get => Value.Commands; set => Value.Commands = value; } + + public OperandCommandAlias() => Value = new OperandCommand(); + public OperandCommandAlias(OperandCommand value) => Value = value; } internal class ParenthesesAlias : ICalcManagerIExprCommandAlias @@ -103,6 +114,8 @@ public int Command get => Value.Command; set => Value.Command = value; } + public ParenthesesAlias() => Value = new Parentheses(); + public ParenthesesAlias(Parentheses value) => Value = value; } internal class CalcManagerHistoryItemAlias @@ -113,7 +126,7 @@ internal class CalcManagerHistoryItemAlias [JsonPropertyName("t")] public IEnumerable Tokens { - get => Value.Tokens.Select(x => new CalcManagerHistoryTokenAlias { Value = x }); + get => Value.Tokens.Select(x => new CalcManagerHistoryTokenAlias(x)); set => Value.Tokens = value.Select(Helpers.MapHistoryToken).ToList(); } @@ -137,6 +150,8 @@ public string Result get => Value.Result; set => Value.Result = value; } + public CalcManagerHistoryItemAlias() => Value = new CalcManagerHistoryItem(); + public CalcManagerHistoryItemAlias(CalcManagerHistoryItem value) => Value = value; } internal class CalcManagerSnapshotAlias @@ -150,6 +165,9 @@ public IEnumerable HistoryItems get => Value.HistoryItems.Select(x => new CalcManagerHistoryItemAlias { Value = x }); set => Value.HistoryItems = value.Select(x => new CalcManagerHistoryItem { Tokens = x.Tokens.Select(Helpers.MapHistoryToken).ToList() }).ToList(); } + + public CalcManagerSnapshotAlias() => Value = new CalcManagerSnapshot(); + public CalcManagerSnapshotAlias(CalcManagerSnapshot value) => Value = value; } internal class PrimaryDisplaySnapshotAlias @@ -167,8 +185,11 @@ public string DisplayValue public bool IsError { get => Value.IsError; - set => IsError = value; + set => Value.IsError = value; } + + public PrimaryDisplaySnapshotAlias() => Value = new PrimaryDisplaySnapshot(); + public PrimaryDisplaySnapshotAlias(PrimaryDisplaySnapshot value) => Value = value; } internal class ExpressionDisplaySnapshotAlias @@ -179,7 +200,7 @@ internal class ExpressionDisplaySnapshotAlias [JsonPropertyName("t")] public IEnumerable Tokens { - get => Value.Tokens.Select(x => new CalcManagerHistoryTokenAlias { Value = x }); + get => Value.Tokens.Select(x => new CalcManagerHistoryTokenAlias(x)); set => Value.Tokens = value.Select(Helpers.MapHistoryToken).ToList(); } [JsonPropertyName("c")] @@ -188,6 +209,9 @@ public IEnumerable Commands get => Value.Commands.Select(Helpers.MapCommandAlias); set => Value.Commands = value.Select(Helpers.MapCommandAlias).ToList(); } + + public ExpressionDisplaySnapshotAlias() => Value = new ExpressionDisplaySnapshot(); + public ExpressionDisplaySnapshotAlias(ExpressionDisplaySnapshot value) => Value = value; } internal class StandardCalculatorSnapshotAlias @@ -198,19 +222,19 @@ internal class StandardCalculatorSnapshotAlias [JsonPropertyName("m")] public CalcManagerSnapshotAlias CalcManager { - get => new CalcManagerSnapshotAlias { Value = Value.CalcManager }; + get => new CalcManagerSnapshotAlias(Value.CalcManager); set => Value.CalcManager = value.Value; } [JsonPropertyName("p")] public PrimaryDisplaySnapshotAlias PrimaryDisplay { - get => new PrimaryDisplaySnapshotAlias { Value = Value.PrimaryDisplay }; + get => new PrimaryDisplaySnapshotAlias(Value.PrimaryDisplay); set => Value.PrimaryDisplay = value.Value; } [JsonPropertyName("e")] public ExpressionDisplaySnapshotAlias ExpressionDisplay { - get => new ExpressionDisplaySnapshotAlias { Value = Value.ExpressionDisplay }; + get => new ExpressionDisplaySnapshotAlias(Value.ExpressionDisplay); set => Value.ExpressionDisplay = value.Value; } [JsonPropertyName("c")] @@ -219,6 +243,9 @@ public IEnumerable Commands get => Value.DisplayCommands.Select(Helpers.MapCommandAlias); set => Value.DisplayCommands = value.Select(Helpers.MapCommandAlias).ToList(); } + + public StandardCalculatorSnapshotAlias() => Value = new StandardCalculatorSnapshot(); + public StandardCalculatorSnapshotAlias(StandardCalculatorSnapshot value) => Value = value; } internal class ApplicationSnapshotAlias @@ -231,9 +258,12 @@ internal class ApplicationSnapshotAlias [JsonPropertyName("s")] public StandardCalculatorSnapshotAlias StandardCalculatorSnapshot { - get => new StandardCalculatorSnapshotAlias { Value = Value.StandardCalculator }; + get => new StandardCalculatorSnapshotAlias(Value.StandardCalculator); set => Value.StandardCalculator = value.Value; } + + public ApplicationSnapshotAlias() => Value = new ApplicationSnapshot(); + public ApplicationSnapshotAlias(ApplicationSnapshot value) => Value = value; } internal static class Helpers @@ -247,19 +277,19 @@ public static ICalcManagerIExprCommandAlias MapCommandAlias(ICalcManagerIExprCom { if (exprCmd is UnaryCommand unary) { - return new UnaryCommandAlias { Value = unary }; + return new UnaryCommandAlias(unary); } else if (exprCmd is BinaryCommand binary) { - return new BinaryCommandAlias { Value = binary }; + return new BinaryCommandAlias(binary); } else if (exprCmd is OperandCommand operand) { - return new OperandCommandAlias { Value = operand }; + return new OperandCommandAlias(operand); } else if (exprCmd is Parentheses paren) { - return new ParenthesesAlias { Value = paren }; + return new ParenthesesAlias(paren); } throw new NotImplementedException("unhandled command type."); } From bcedac85a12d01950c6d5f68d3836a8e93608e74 Mon Sep 17 00:00:00 2001 From: Tian Liao Date: Fri, 25 Oct 2024 17:45:49 +0800 Subject: [PATCH 13/21] restore session --- src/CalcViewModel/ApplicationViewModel.cpp | 2 +- src/Calculator/Views/MainPage.xaml.cs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/CalcViewModel/ApplicationViewModel.cpp b/src/CalcViewModel/ApplicationViewModel.cpp index 190e72715..c8b2153eb 100644 --- a/src/CalcViewModel/ApplicationViewModel.cpp +++ b/src/CalcViewModel/ApplicationViewModel.cpp @@ -558,7 +558,7 @@ void ApplicationViewModel::Initialize(ViewMode mode) void ApplicationViewModel::Initialize(CalculatorApp::ViewModel::Snapshot::ApplicationSnapshot ^ snapshot) { - // TODO: restore + m_CalculatorViewModel = ref new StandardCalculatorViewModel(snapshot->StandardCalculator); Initialize(static_cast(snapshot->Mode)); } diff --git a/src/Calculator/Views/MainPage.xaml.cs b/src/Calculator/Views/MainPage.xaml.cs index e7efa4c6a..3d9cc9ea7 100644 --- a/src/Calculator/Views/MainPage.xaml.cs +++ b/src/Calculator/Views/MainPage.xaml.cs @@ -74,7 +74,7 @@ public MainPage() string embeddedData; try { - var json = JsonSerializer.Serialize(new ApplicationSnapshotAlias { Value = Model.Snapshot }); + var json = JsonSerializer.Serialize(new ApplicationSnapshotAlias(Model.Snapshot)); embeddedData = Convert.ToBase64String(DeflateUtils.Compress(json)); } catch (Exception) From bce6ec10e476da96a69a4722bad61ea5b073b8d2 Mon Sep 17 00:00:00 2001 From: Tian Liao Date: Mon, 28 Oct 2024 16:55:52 +0800 Subject: [PATCH 14/21] connect ui --- src/CalcViewModel/ApplicationViewModel.cpp | 494 +----------------- src/CalcViewModel/ApplicationViewModel.h | 5 +- src/CalcViewModel/Snapshots.cpp | 19 +- .../StandardCalculatorViewModel.cpp | 122 ++--- .../StandardCalculatorViewModel.h | 39 +- src/Calculator/Utils/JsonUtils.cs | 8 +- src/Calculator/Views/MainPage.xaml.cs | 50 +- 7 files changed, 78 insertions(+), 659 deletions(-) diff --git a/src/CalcViewModel/ApplicationViewModel.cpp b/src/CalcViewModel/ApplicationViewModel.cpp index c8b2153eb..f2835fb4a 100644 --- a/src/CalcViewModel/ApplicationViewModel.cpp +++ b/src/CalcViewModel/ApplicationViewModel.cpp @@ -37,446 +37,6 @@ namespace { StringReference CategoriesPropertyName(L"Categories"); StringReference ClearMemoryVisibilityPropertyName(L"ClearMemoryVisibility"); - - // struct SnapshotHelper - //{ - - // static Windows::Data::Json::JsonObject ^ SaveSnapshotToJson(const ApplicationSnapshot& value) - // { - // auto jsonObject = ref new Windows::Data::Json::JsonObject(); - // jsonObject->SetNamedValue(L"SnapshotVersion", Windows::Data::Json::JsonValue::CreateNumberValue(value.SnapshotVersion)); - // jsonObject->SetNamedValue(L"Mode", Windows::Data::Json::JsonValue::CreateNumberValue(value.Mode)); - // if (value.StandardCalc.has_value()) - // { - // jsonObject->SetNamedValue(L"StandardCalculatorSnapshot", SaveSnapshotToJson(*value.StandardCalc)); - // } - // return jsonObject; - // } - - // static Windows::Data::Json::JsonObject ^ SaveSnapshotToJson(const StandardCalculatorSnapshot& value) - // { - // auto jsonObject = ref new Windows::Data::Json::JsonObject(); - // jsonObject->SetNamedValue(L"CalculatorManagerSnapshot", SaveSnapshotToJson(value.CalcManager)); - // jsonObject->SetNamedValue(L"PrimaryDisplay", SaveSnapshotToJson(value.PrimaryDisplay)); - // if (value.ExpressionDisplay.has_value()) - // { - // jsonObject->SetNamedValue(L"ExpressionDisplay", SaveSnapshotToJson(*value.ExpressionDisplay)); - // } - // auto commandsJsonArray = ref new Windows::Data::Json::JsonArray(); - // for (const auto& command : value.DisplayCommands) - // { - // commandsJsonArray->Append(SaveSnapshotToJson(command)); - // } - // jsonObject->SetNamedValue(L"DisplayCommands", commandsJsonArray); - // return jsonObject; - // } - - // static Windows::Data::Json::JsonObject ^ SaveSnapshotToJson(const PrimaryDisplaySnapshot& value) - // { - // auto jsonObject = ref new Windows::Data::Json::JsonObject(); - // jsonObject->SetNamedValue(L"DisplayValue", Windows::Data::Json::JsonValue::CreateStringValue(value.DisplayValue)); - // jsonObject->SetNamedValue(L"IsError", Windows::Data::Json::JsonValue::CreateBooleanValue(value.IsError)); - // return jsonObject; - // } - - // static Windows::Data::Json::JsonObject ^ SaveSnapshotToJson(const ExpressionDisplaySnapshot& value) - // { - // auto jsonObject = ref new Windows::Data::Json::JsonObject(); - // auto tokensJsonArray = ref new Windows::Data::Json::JsonArray(); - // for (const auto& token : value.Tokens) - // { - // auto tokenJsonArray = ref new Windows::Data::Json::JsonArray(); - // tokenJsonArray->Append(Windows::Data::Json::JsonValue::CreateStringValue(ref new Platform::String(token.first.c_str()))); - // tokenJsonArray->Append(Windows::Data::Json::JsonValue::CreateNumberValue(token.second)); - // tokensJsonArray->Append(tokenJsonArray); - // } - // jsonObject->SetNamedValue(L"Tokens", tokensJsonArray); - - // auto commandsJsonArray = ref new Windows::Data::Json::JsonArray(); - // for (const auto& command : value.Commands) - // { - // commandsJsonArray->Append(SaveSnapshotToJson(command)); - // } - // jsonObject->SetNamedValue(L"Commands", commandsJsonArray); - - // return jsonObject; - // } - - // static Windows::Data::Json::JsonObject ^ SaveSnapshotToJson(const CalculatorManagerSnapshot& value) - // { - // auto jsonObject = ref new Windows::Data::Json::JsonObject(); - // if (value.HistoryItems.has_value()) - // { - // auto historyJsonArray = ref new Windows::Data::Json::JsonArray(); - // for (const auto& item : *value.HistoryItems) - // { - // historyJsonArray->Append(SaveSnapshotToJson(*item)); - // } - // jsonObject->SetNamedValue(L"HistoryItems", historyJsonArray); - // } - // return jsonObject; - // } - - // 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()))); - - // auto tokensJsonArray = ref new Windows::Data::Json::JsonArray(); - // for (const auto& token : *value.historyItemVector.spTokens) - // { - // auto tokenJsonArray = ref new Windows::Data::Json::JsonArray(); - // tokenJsonArray->Append(Windows::Data::Json::JsonValue::CreateStringValue(ref new Platform::String(token.first.c_str()))); - // tokenJsonArray->Append(Windows::Data::Json::JsonValue::CreateNumberValue(token.second)); - // tokensJsonArray->Append(tokenJsonArray); - // } - // jsonObject->SetNamedValue(L"Tokens", tokensJsonArray); - - // auto commandsJsonArray = ref new Windows::Data::Json::JsonArray(); - // for (const auto& command : *value.historyItemVector.spCommands) - // { - // commandsJsonArray->Append(SaveSnapshotToJson(command)); - // } - // jsonObject->SetNamedValue(L"Commands", commandsJsonArray); - - // return jsonObject; - // } - - // static Windows::Data::Json::JsonObject ^ SaveSnapshotToJson(const std::shared_ptr& value) - // { - // auto jsonObject = ref new Windows::Data::Json::JsonObject(); - // auto opndCommand = dynamic_cast(value.get()); - // if (opndCommand != nullptr) - // { - // jsonObject = SaveSnapshotToJson(*opndCommand); - // } - // auto unaryCommand = dynamic_cast(value.get()); - // if (unaryCommand != nullptr) - // { - // jsonObject = SaveSnapshotToJson(*unaryCommand); - // } - // auto binaryCommand = dynamic_cast(value.get()); - // if (binaryCommand != nullptr) - // { - // jsonObject = SaveSnapshotToJson(*binaryCommand); - // } - // auto parenthesesCommand = dynamic_cast(value.get()); - // if (parenthesesCommand != nullptr) - // { - // jsonObject = SaveSnapshotToJson(*parenthesesCommand); - // } - // return jsonObject; - // } - - // static Windows::Data::Json::JsonObject ^ SaveSnapshotToJson(const COpndCommand& value) - // { - // auto jsonObject = ref new Windows::Data::Json::JsonObject(); - // jsonObject->SetNamedValue(L"CommandType", Windows::Data::Json::JsonValue::CreateNumberValue(static_cast(value.GetCommandType()))); - // jsonObject->SetNamedValue(L"IsNegative", Windows::Data::Json::JsonValue::CreateBooleanValue(value.IsNegative())); - // jsonObject->SetNamedValue(L"IsDecimalPresent", Windows::Data::Json::JsonValue::CreateBooleanValue(value.IsDecimalPresent())); - // jsonObject->SetNamedValue(L"IsSciFmt", Windows::Data::Json::JsonValue::CreateBooleanValue(value.IsSciFmt())); - // auto commandsJsonArray = ref new Windows::Data::Json::JsonArray(); - // for (const auto& command : *value.GetCommands()) - // { - // commandsJsonArray->Append(Windows::Data::Json::JsonValue::CreateNumberValue(command)); - // } - // jsonObject->SetNamedValue(L"Commands", commandsJsonArray); - // return jsonObject; - // } - - // static Windows::Data::Json::JsonObject ^ SaveSnapshotToJson(const CUnaryCommand& value) - // { - // auto jsonObject = ref new Windows::Data::Json::JsonObject(); - // jsonObject->SetNamedValue(L"CommandType", Windows::Data::Json::JsonValue::CreateNumberValue(static_cast(value.GetCommandType()))); - // auto commandsJsonArray = ref new Windows::Data::Json::JsonArray(); - // for (const auto& command : *value.GetCommands()) - // { - // commandsJsonArray->Append(Windows::Data::Json::JsonValue::CreateNumberValue(command)); - // } - // jsonObject->SetNamedValue(L"Commands", commandsJsonArray); - // return jsonObject; - // } - - // static Windows::Data::Json::JsonObject ^ SaveSnapshotToJson(const CBinaryCommand& value) - // { - // auto jsonObject = ref new Windows::Data::Json::JsonObject(); - // jsonObject->SetNamedValue(L"CommandType", Windows::Data::Json::JsonValue::CreateNumberValue(static_cast(value.GetCommandType()))); - // jsonObject->SetNamedValue(L"Command", Windows::Data::Json::JsonValue::CreateNumberValue(value.GetCommand())); - // return jsonObject; - // } - - // static Windows::Data::Json::JsonObject ^ SaveSnapshotToJson(const CParentheses& value) - // { - // auto jsonObject = ref new Windows::Data::Json::JsonObject(); - // jsonObject->SetNamedValue(L"CommandType", Windows::Data::Json::JsonValue::CreateNumberValue(static_cast(value.GetCommandType()))); - // jsonObject->SetNamedValue(L"Command", Windows::Data::Json::JsonValue::CreateNumberValue(value.GetCommand())); - // return jsonObject; - // } - - // static void RestoreJsonToSnapshot(Windows::Data::Json::JsonObject ^ jsonObject, std::optional& value) - // { - // ApplicationSnapshot applicationSnapshot; - // applicationSnapshot.SnapshotVersion = static_cast(jsonObject->GetNamedNumber(L"SnapshotVersion")); - // if (applicationSnapshot.SnapshotVersion > SnapshotVersion) - // { - // return; - // } - // applicationSnapshot.Mode = static_cast(jsonObject->GetNamedNumber(L"Mode")); - // if (jsonObject->HasKey(L"StandardCalculatorSnapshot")) - // { - // std::optional standardCalculatorSnapshot; - // RestoreJsonToSnapshot(jsonObject->GetNamedObject(L"StandardCalculatorSnapshot"), standardCalculatorSnapshot); - // if (standardCalculatorSnapshot.has_value()) - // { - // applicationSnapshot.StandardCalc = std::move(*standardCalculatorSnapshot); - // } - // else - // { - // return; - // } - // } - // value = std::move(applicationSnapshot); - // } - - // static void RestoreJsonToSnapshot(Windows::Data::Json::JsonObject ^ jsonObject, std::optional& value) - // { - // StandardCalculatorSnapshot standardCalculatorSnapshot; - // std::optional calcManagerSnapshot; - // RestoreJsonToSnapshot(jsonObject->GetNamedObject(L"CalculatorManagerSnapshot"), calcManagerSnapshot); - // if (calcManagerSnapshot.has_value()) - // { - // standardCalculatorSnapshot.CalcManager = std::move(*calcManagerSnapshot); - // } - // else - // { - // return; - // } - // std::optional primaryDisplaySnapshot; - // RestoreJsonToSnapshot(jsonObject->GetNamedObject(L"PrimaryDisplay"), primaryDisplaySnapshot); - // if (primaryDisplaySnapshot.has_value()) - // { - // standardCalculatorSnapshot.PrimaryDisplay = std::move(*primaryDisplaySnapshot); - // } - // else - // { - // return; - // } - // if (jsonObject->HasKey(L"ExpressionDisplay")) - // { - // std::optional expressionDisplaySnapshot; - // RestoreJsonToSnapshot(jsonObject->GetNamedObject(L"ExpressionDisplay"), expressionDisplaySnapshot); - // if (expressionDisplaySnapshot.has_value()) - // { - // standardCalculatorSnapshot.ExpressionDisplay = std::move(*expressionDisplaySnapshot); - // } - // else - // { - // return; - // } - // } - // standardCalculatorSnapshot.DisplayCommands = RestoreExpressionCommandsFromJsonArray(jsonObject->GetNamedArray(L"DisplayCommands")); - // value = std::move(standardCalculatorSnapshot); - // } - - // static void RestoreJsonToSnapshot(Windows::Data::Json::JsonObject ^ jsonObject, std::optional& value) - // { - // value = PrimaryDisplaySnapshot{ jsonObject->GetNamedString(L"DisplayValue"), jsonObject->GetNamedBoolean(L"IsError") }; - // } - - // static void RestoreJsonToSnapshot(Windows::Data::Json::JsonObject ^ jsonObject, std::optional& value) - // { - // ExpressionDisplaySnapshot expressionDisplaySnapshot; - // expressionDisplaySnapshot.Tokens = RestoreExpressionTokensFromJsonArray(jsonObject->GetNamedArray(L"Tokens")); - // if (expressionDisplaySnapshot.Tokens.empty()) - // { - // return; - // } - // expressionDisplaySnapshot.Commands = RestoreExpressionCommandsFromJsonArray(jsonObject->GetNamedArray(L"Commands")); - // if (expressionDisplaySnapshot.Commands.empty()) - // { - // return; - // } - // value = std::move(expressionDisplaySnapshot); - // } - - // static void RestoreJsonToSnapshot(Windows::Data::Json::JsonObject ^ jsonObject, std::optional& value) - // { - // CalculatorManagerSnapshot calcManagerSnapshot; - // if (jsonObject->HasKey(L"HistoryItems")) - // { - // std::vector> historyItems; - // auto historyJsonArray = jsonObject->GetNamedArray(L"HistoryItems"); - // for (uint32_t i = 0; i < historyJsonArray->Size; ++i) - // { - // std::optional historyItem; - // RestoreJsonToSnapshot(historyJsonArray->GetObjectAt(i), historyItem); - // if (historyItem.has_value()) - // { - // historyItems.push_back(std::make_shared(*historyItem)); - // } - // else - // { - // return; - // } - // } - // calcManagerSnapshot.HistoryItems = std::move(historyItems); - // } - // value = std::move(calcManagerSnapshot); - // } - - // static void RestoreJsonToSnapshot(Windows::Data::Json::JsonObject ^ jsonObject, std::optional& value) - // { - // CalculationManager::HISTORYITEM historyItem; - // historyItem.historyItemVector.expression = std::wstring(jsonObject->GetNamedString(L"Expression")->Data()); - // historyItem.historyItemVector.result = std::wstring(jsonObject->GetNamedString(L"Result")->Data()); - // historyItem.historyItemVector.spTokens = - // std::make_shared>>(RestoreExpressionTokensFromJsonArray(jsonObject->GetNamedArray(L"Tokens"))); - // if (historyItem.historyItemVector.spTokens->empty()) - // { - // return; - // } - // historyItem.historyItemVector.spCommands = std::make_shared>>( - // RestoreExpressionCommandsFromJsonArray(jsonObject->GetNamedArray(L"Commands"))); - // if (historyItem.historyItemVector.spCommands->empty()) - // { - // return; - // } - // value = std::move(historyItem); - // } - - // static void RestoreJsonToSnapshot(Windows::Data::Json::JsonObject ^ jsonObject, std::optional>& value) - // { - // auto commandType = static_cast(jsonObject->GetNamedNumber(L"CommandType")); - // switch (commandType) - // { - // case CalculationManager::CommandType::OperandCommand: - // { - // std::optional opndCommand; - // RestoreJsonToSnapshot(jsonObject, opndCommand); - // if (opndCommand.has_value()) - // { - // value = std::make_shared(*opndCommand); - // } - // break; - // } - // case CalculationManager::CommandType::UnaryCommand: - // { - // std::optional unaryCommand; - // RestoreJsonToSnapshot(jsonObject, unaryCommand); - // if (unaryCommand.has_value()) - // { - // value = std::make_shared(*unaryCommand); - // } - // break; - // } - // case CalculationManager::CommandType::BinaryCommand: - // { - // std::optional binaryCommand; - // RestoreJsonToSnapshot(jsonObject, binaryCommand); - // if (binaryCommand.has_value()) - // { - // value = std::make_shared(*binaryCommand); - // } - // break; - // } - // case CalculationManager::CommandType::Parentheses: - // { - // std::optional parenthesesCommand; - // RestoreJsonToSnapshot(jsonObject, parenthesesCommand); - // if (parenthesesCommand.has_value()) - // { - // value = std::make_shared(*parenthesesCommand); - // } - // break; - // } - // default: - // throw std::logic_error{ "c8cba597-dfec-447a-bd1c-e78a9ffaad95" }; - // } - // } - - // static void RestoreJsonToSnapshot(Windows::Data::Json::JsonObject ^ jsonObject, std::optional& value) - // { - // auto isNegative = jsonObject->GetNamedBoolean(L"IsNegative"); - // auto isDecimalPresent = jsonObject->GetNamedBoolean(L"IsDecimalPresent"); - // auto isSciFmt = jsonObject->GetNamedBoolean(L"IsSciFmt"); - // std::vector commands; - // auto commandsJsonArray = jsonObject->GetNamedArray(L"Commands"); - // for (uint32_t i = 0; i < commandsJsonArray->Size; ++i) - // { - // commands.push_back(static_cast(commandsJsonArray->GetNumberAt(i))); - // } - // value = COpndCommand(std::make_shared>(std::move(commands)), isNegative, isDecimalPresent, isSciFmt); - // } - - // static void RestoreJsonToSnapshot(Windows::Data::Json::JsonObject ^ jsonObject, std::optional& value) - // { - // std::vector commands; - // auto commandsJsonArray = jsonObject->GetNamedArray(L"Commands"); - // if (commandsJsonArray->Size == 1) - // { - // value = CUnaryCommand(static_cast(commandsJsonArray->GetNumberAt(0))); - // } - // else if (commandsJsonArray->Size == 2) - // { - // value = CUnaryCommand(static_cast(commandsJsonArray->GetNumberAt(0)), static_cast(commandsJsonArray->GetNumberAt(1))); - // } - // } - - // static void RestoreJsonToSnapshot(Windows::Data::Json::JsonObject ^ jsonObject, std::optional& value) - // { - // value = CBinaryCommand(static_cast(jsonObject->GetNamedNumber(L"Command"))); - // } - - // static void RestoreJsonToSnapshot(Windows::Data::Json::JsonObject ^ jsonObject, std::optional& value) - // { - // value = CParentheses(static_cast(jsonObject->GetNamedNumber(L"Command"))); - // } - - // static std::vector> RestoreExpressionTokensFromJsonArray(Windows::Data::Json::JsonArray ^ jsonArray) - // { - // std::vector> tokens; - // for (uint32_t i = 0; i < jsonArray->Size; ++i) - // { - // auto tokenJsonArray = jsonArray->GetArrayAt(i); - // if (tokenJsonArray->Size == 2 && tokenJsonArray->GetAt(0)->ValueType == Windows::Data::Json::JsonValueType::String - // && tokenJsonArray->GetAt(1)->ValueType == Windows::Data::Json::JsonValueType::Number) - // { - // tokens.emplace_back(std::wstring(tokenJsonArray->GetAt(0)->GetString()->Data()), static_cast(tokenJsonArray->GetAt(1)->GetNumber())); - // } - // else - // { - // return {}; - // } - // } - // return tokens; - // } - - // static std::vector> RestoreExpressionCommandsFromJsonArray(Windows::Data::Json::JsonArray ^ jsonArray) - // { - // std::vector> commands; - // for (uint32_t i = 0; i < jsonArray->Size; ++i) - // { - // std::optional> command; - // RestoreJsonToSnapshot(jsonArray->GetObjectAt(i), command); - // if (command.has_value()) - // { - // commands.push_back(*command); - // } - // else - // { - // return {}; - // } - // } - // return commands; - // } - - // static bool IsJsonParsingException(Platform::COMException ^ e) - // { - // return e->HResult == WEB_E_JSON_VALUE_NOT_FOUND || e->HResult == E_ILLEGAL_METHOD_CALL; - // } - //}; } ApplicationViewModel::ApplicationViewModel() @@ -556,10 +116,13 @@ void ApplicationViewModel::Initialize(ViewMode mode) } } -void ApplicationViewModel::Initialize(CalculatorApp::ViewModel::Snapshot::ApplicationSnapshot ^ snapshot) +void ApplicationViewModel::RestoreFromSnapshot(CalculatorApp::ViewModel::Snapshot::ApplicationSnapshot ^ snapshot) { - m_CalculatorViewModel = ref new StandardCalculatorViewModel(snapshot->StandardCalculator); - Initialize(static_cast(snapshot->Mode)); + Mode = static_cast(snapshot->Mode); + if (snapshot->StandardCalculator != nullptr) + { + m_CalculatorViewModel->Snapshot = snapshot->StandardCalculator; + } } bool ApplicationViewModel::TryRecoverFromNavigationModeFailure() @@ -728,48 +291,3 @@ void ApplicationViewModel::SetDisplayNormalAlwaysOnTopOption() DisplayNormalAlwaysOnTopOption = m_mode == ViewMode::Standard && ApplicationView::GetForCurrentView()->IsViewModeSupported(ApplicationViewMode::CompactOverlay) && !IsAlwaysOnTop; } - -// Windows::Data::Json::JsonObject ^ ApplicationViewModel::SaveApplicationSnapshot() -//{ -// ApplicationSnapshot applicationSnapshot; -// applicationSnapshot.SnapshotVersion = SnapshotHelper::SnapshotVersion; -// applicationSnapshot.Mode = static_cast(Mode); -// if (m_CalculatorViewModel != nullptr && m_mode == ViewMode::Standard) -// { -// // Standard calculator is the only supported mode so far. -// applicationSnapshot.StandardCalc = m_CalculatorViewModel->GetStandardCalculatorSnapshot(); -// } -// return SnapshotHelper::SaveSnapshotToJson(applicationSnapshot); -// } -// -// bool ApplicationViewModel::TryRestoreFromSnapshot(Windows::Data::Json::JsonObject ^ jsonObject) -//{ -// std::optional applicationSnapshot; -// try -// { -// SnapshotHelper::RestoreJsonToSnapshot(jsonObject, applicationSnapshot); -// } -// catch (Platform::COMException ^ e) -// { -// if (SnapshotHelper::IsJsonParsingException(e)) -// { -// return false; -// } -// throw; -// } -// -// if (applicationSnapshot.has_value()) -// { -// Mode = static_cast(applicationSnapshot->Mode); -// if (applicationSnapshot->StandardCalc.has_value()) -// { -// if (m_CalculatorViewModel == nullptr) -// { -// m_CalculatorViewModel = ref new StandardCalculatorViewModel(); -// } -// m_CalculatorViewModel->SetStandardCalculatorSnapshot(applicationSnapshot->StandardCalc.value()); -// } -// return true; -// } -// return false; -// } diff --git a/src/CalcViewModel/ApplicationViewModel.h b/src/CalcViewModel/ApplicationViewModel.h index 1cb2f2dfd..afb67eb69 100644 --- a/src/CalcViewModel/ApplicationViewModel.h +++ b/src/CalcViewModel/ApplicationViewModel.h @@ -18,9 +18,8 @@ namespace CalculatorApp public: ApplicationViewModel(); - [Windows::Foundation::Metadata::DefaultOverload] void Initialize(CalculatorApp::ViewModel::Common::ViewMode mode); // Use for first init, use deserialize for rehydration - void Initialize(CalculatorApp::ViewModel::Snapshot::ApplicationSnapshot^ snapshot); + void RestoreFromSnapshot(CalculatorApp::ViewModel::Snapshot::ApplicationSnapshot^ snapshot); OBSERVABLE_OBJECT(); OBSERVABLE_PROPERTY_RW(StandardCalculatorViewModel ^, CalculatorViewModel); @@ -104,8 +103,6 @@ namespace CalculatorApp void ToggleAlwaysOnTop(float width, float height); - //bool TryRestoreFromSnapshot(Windows::Data::Json::JsonObject ^ jsonObject); - private: bool TryRecoverFromNavigationModeFailure(); diff --git a/src/CalcViewModel/Snapshots.cpp b/src/CalcViewModel/Snapshots.cpp index 404cce36f..69c082ad1 100644 --- a/src/CalcViewModel/Snapshots.cpp +++ b/src/CalcViewModel/Snapshots.cpp @@ -123,7 +123,7 @@ namespace CalculatorApp::ViewModel::Snapshot CalcManagerHistoryToken::CalcManagerHistoryToken() { - OpCodeName = nullptr; + OpCodeName = ref new Platform::String(); CommandIndex = 0; } @@ -224,7 +224,22 @@ namespace CalculatorApp::ViewModel::Snapshot std::vector> ToUnderlying(Windows::Foundation::Collections::IVector ^ items) { - return {}; // TODO + std::vector> result; + for (CalcManagerHistoryItem ^ item : items) + { + CalculationManager::HISTORYITEMVECTOR nativeItem; + nativeItem.spTokens = std::make_shared>>(); + for (CalcManagerHistoryToken ^ token : item->Tokens) + { + nativeItem.spTokens->push_back(std::make_pair(token->OpCodeName->Data(), token->CommandIndex)); + } + nativeItem.spCommands = std::make_shared>>(ToUnderlying(item->Commands)); + nativeItem.expression = item->Expression->Data(); + nativeItem.result = item->Result->Data(); + auto spItem = std::make_shared(CalculationManager::HISTORYITEM{ std::move(nativeItem) }); + result.push_back(std::move(std::move(spItem))); + } + return result; } std::vector> ToUnderlying(Windows::Foundation::Collections::IVector ^ commands) diff --git a/src/CalcViewModel/StandardCalculatorViewModel.cpp b/src/CalcViewModel/StandardCalculatorViewModel.cpp index 9d7739749..a1cee93b1 100644 --- a/src/CalcViewModel/StandardCalculatorViewModel.cpp +++ b/src/CalcViewModel/StandardCalculatorViewModel.cpp @@ -115,7 +115,7 @@ namespace CalculatorResourceKeys StringReference DisplayCopied(L"Display_Copied"); } -StandardCalculatorViewModel::StandardCalculatorViewModel(CalculatorApp::ViewModel::Snapshot::StandardCalculatorSnapshot ^ snapshot) +StandardCalculatorViewModel::StandardCalculatorViewModel() : m_DisplayValue(L"0") , m_DecimalDisplayValue(L"0") , m_HexDisplayValue(L"0") @@ -183,42 +183,6 @@ StandardCalculatorViewModel::StandardCalculatorViewModel(CalculatorApp::ViewMode IsNegateEnabled = true; IsDecimalEnabled = true; AreProgrammerRadixOperatorsVisible = false; - - if (snapshot != nullptr) - { - if (snapshot->CalcManager->HistoryItems != nullptr) - { - m_standardCalculatorManager.SetHistoryItems(ToUnderlying(snapshot->CalcManager->HistoryItems)); - } - - std::vector commands; - if (snapshot->ExpressionDisplay != nullptr && snapshot->ExpressionDisplay->Tokens->GetAt(snapshot->ExpressionDisplay->Tokens->Size)) - { - commands = GetCommandsFromExpressionCommands(ToUnderlying(snapshot->ExpressionDisplay->Commands)); - } - if (commands.empty() && snapshot->DisplayCommands->Size > 0) - { - commands = GetCommandsFromExpressionCommands(ToUnderlying(snapshot->DisplayCommands)); - } - for (auto cmd : commands) - { - m_standardCalculatorManager.SendCommand(static_cast(cmd)); - } - if (snapshot->ExpressionDisplay != nullptr) - { - using RawTokenCollection = std::vector>; - RawTokenCollection rawTokens; - for (CalculatorApp::ViewModel::Snapshot::CalcManagerHistoryToken ^ token : snapshot->ExpressionDisplay->Tokens) - { - rawTokens.push_back(std::pair{ token->OpCodeName->Data(), token->CommandIndex }); - } - snapshot->ExpressionDisplay->Tokens; - SetExpressionDisplay( - std::make_shared(rawTokens), - std::make_shared>>(ToUnderlying(snapshot->ExpressionDisplay->Commands))); - } - SetPrimaryDisplay(snapshot->PrimaryDisplay->DisplayValue, snapshot->PrimaryDisplay->IsError); - } } String ^ StandardCalculatorViewModel::LocalizeDisplayValue(_In_ wstring const& displayValue) @@ -1823,7 +1787,7 @@ void StandardCalculatorViewModel::SetBitshiftRadioButtonCheckedAnnouncement(Plat Announcement = CalculatorAnnouncement::GetBitShiftRadioButtonCheckedAnnouncement(announcement); } -CalculatorApp::ViewModel::Snapshot::StandardCalculatorSnapshot ^ StandardCalculatorViewModel::GetSnapshot() const +CalculatorApp::ViewModel::Snapshot::StandardCalculatorSnapshot ^ StandardCalculatorViewModel::Snapshot::get() { auto result = ref new CalculatorApp::ViewModel::Snapshot::StandardCalculatorSnapshot(); result->CalcManager = ref new CalculatorApp::ViewModel::Snapshot::CalcManagerSnapshot(m_standardCalculatorManager); @@ -1837,49 +1801,39 @@ CalculatorApp::ViewModel::Snapshot::StandardCalculatorSnapshot ^ StandardCalcula return result; } -// StandardCalculatorSnapshot StandardCalculatorViewModel::GetStandardCalculatorSnapshot() const -//{ -// StandardCalculatorSnapshot snapshot; -// auto& historyItems = m_standardCalculatorManager.GetHistoryItems(); -// if (!historyItems.empty()) -// { -// snapshot.CalcManager.HistoryItems = std::move(historyItems); -// } -// snapshot.PrimaryDisplay = PrimaryDisplaySnapshot{ m_DisplayValue, m_IsInError }; -// if (!m_tokens->empty() && !m_commands->empty()) -// { -// snapshot.ExpressionDisplay = { *m_tokens, *m_commands }; -// } -// snapshot.DisplayCommands = m_standardCalculatorManager.GetDisplayCommandsSnapshot(); -// return snapshot; -// } -// -// void StandardCalculatorViewModel::SetStandardCalculatorSnapshot(const StandardCalculatorSnapshot& snapshot) -//{ -// if (snapshot.CalcManager.HistoryItems.has_value()) -// { -// m_standardCalculatorManager.SetHistoryItems(snapshot.CalcManager.HistoryItems.value()); -// } -// -// std::vector commands; -// if (snapshot.ExpressionDisplay.has_value() && snapshot.ExpressionDisplay->Tokens.back().first == L"=") -// { -// commands = GetCommandsFromExpressionCommands(snapshot.ExpressionDisplay->Commands); -// } -// if (commands.empty() && !snapshot.DisplayCommands.empty()) -// { -// commands = GetCommandsFromExpressionCommands(snapshot.DisplayCommands); -// } -// for (const auto& command : commands) -// { -// m_standardCalculatorManager.SendCommand(static_cast(command)); -// } -// -// if (snapshot.ExpressionDisplay.has_value()) -// { -// SetExpressionDisplay( -// std::make_shared>>(snapshot.ExpressionDisplay->Tokens), -// std::make_shared>>(snapshot.ExpressionDisplay->Commands)); -// } -// SetPrimaryDisplay(snapshot.PrimaryDisplay.DisplayValue, snapshot.PrimaryDisplay.IsError); -// } +void CalculatorApp::ViewModel::StandardCalculatorViewModel::Snapshot::set(CalculatorApp::ViewModel::Snapshot::StandardCalculatorSnapshot ^ snapshot) +{ + assert(snapshot != nullptr); + m_standardCalculatorManager.Reset(); + if (snapshot->CalcManager->HistoryItems != nullptr) + { + m_standardCalculatorManager.SetHistoryItems(ToUnderlying(snapshot->CalcManager->HistoryItems)); + } + + std::vector commands; + if (snapshot->ExpressionDisplay != nullptr && snapshot->ExpressionDisplay->Tokens->GetAt(snapshot->ExpressionDisplay->Tokens->Size - 1)->OpCodeName == L"=") + { + commands = GetCommandsFromExpressionCommands(ToUnderlying(snapshot->ExpressionDisplay->Commands)); + } + if (commands.empty() && snapshot->DisplayCommands->Size > 0) + { + commands = GetCommandsFromExpressionCommands(ToUnderlying(snapshot->DisplayCommands)); + } + for (auto cmd : commands) + { + m_standardCalculatorManager.SendCommand(static_cast(cmd)); + } + if (snapshot->ExpressionDisplay != nullptr) + { + using RawTokenCollection = std::vector>; + RawTokenCollection rawTokens; + for (CalculatorApp::ViewModel::Snapshot::CalcManagerHistoryToken ^ token : snapshot->ExpressionDisplay->Tokens) + { + rawTokens.push_back(std::pair{ token->OpCodeName->Data(), token->CommandIndex }); + } + SetExpressionDisplay( + std::make_shared(rawTokens), + std::make_shared>>(ToUnderlying(snapshot->ExpressionDisplay->Commands))); + } + SetPrimaryDisplay(snapshot->PrimaryDisplay->DisplayValue, snapshot->PrimaryDisplay->IsError); +} diff --git a/src/CalcViewModel/StandardCalculatorViewModel.h b/src/CalcViewModel/StandardCalculatorViewModel.h index 8026e709f..65cf7eb66 100644 --- a/src/CalcViewModel/StandardCalculatorViewModel.h +++ b/src/CalcViewModel/StandardCalculatorViewModel.h @@ -37,31 +37,6 @@ namespace CalculatorApp bool canSendNegate; }; - // struct CalculatorManagerSnapshot - //{ - // std::optional>> HistoryItems; - // }; - - // struct PrimaryDisplaySnapshot - //{ - // Platform::String ^ DisplayValue; - // bool IsError = false; - // }; - - // struct ExpressionDisplaySnapshot - //{ - // std::vector> Tokens; - // std::vector> Commands; - // }; - - // struct StandardCalculatorSnapshot - //{ - // CalculatorManagerSnapshot CalcManager; - // PrimaryDisplaySnapshot PrimaryDisplay; - // std::optional ExpressionDisplay; - // std::vector> DisplayCommands; - // }; - [Windows::UI::Xaml::Data::Bindable] public ref class StandardCalculatorViewModel sealed : public Windows::UI::Xaml::Data::INotifyPropertyChanged { public: @@ -268,12 +243,13 @@ namespace CalculatorApp } } - property CalculatorApp::ViewModel::Snapshot::StandardCalculatorSnapshot - ^ Snapshot { CalculatorApp::ViewModel::Snapshot::StandardCalculatorSnapshot ^ get() { return GetSnapshot(); } } + property CalculatorApp::ViewModel::Snapshot::StandardCalculatorSnapshot ^ Snapshot { + CalculatorApp::ViewModel::Snapshot::StandardCalculatorSnapshot ^ get(); + void set(CalculatorApp::ViewModel::Snapshot::StandardCalculatorSnapshot ^ snapshot); + }; - // Used by unit tests - void - ResetCalcManager(bool clearMemory); + // Used by unit tests + void ResetCalcManager(bool clearMemory); void SendCommandToCalcManager(int command); public: @@ -327,10 +303,9 @@ namespace CalculatorApp } internal :; - explicit StandardCalculatorViewModel(CalculatorApp::ViewModel::Snapshot::StandardCalculatorSnapshot ^ snapshot = nullptr); + explicit StandardCalculatorViewModel(); private: - CalculatorApp::ViewModel::Snapshot::StandardCalculatorSnapshot ^ GetSnapshot() const; void SetMemorizedNumbers(const std::vector& memorizedNumbers); void UpdateProgrammerPanelDisplay(); void HandleUpdatedOperandData(CalculationManager::Command cmdenum); diff --git a/src/Calculator/Utils/JsonUtils.cs b/src/Calculator/Utils/JsonUtils.cs index e138b2eb8..0a49b430d 100644 --- a/src/Calculator/Utils/JsonUtils.cs +++ b/src/Calculator/Utils/JsonUtils.cs @@ -163,7 +163,13 @@ internal class CalcManagerSnapshotAlias public IEnumerable HistoryItems { get => Value.HistoryItems.Select(x => new CalcManagerHistoryItemAlias { Value = x }); - set => Value.HistoryItems = value.Select(x => new CalcManagerHistoryItem { Tokens = x.Tokens.Select(Helpers.MapHistoryToken).ToList() }).ToList(); + set => Value.HistoryItems = value.Select(x => new CalcManagerHistoryItem + { + Tokens = x.Tokens.Select(Helpers.MapHistoryToken).ToList(), + Commands = x.Commands.Select(Helpers.MapCommandAlias).ToList(), + Expression = x.Expression, + Result = x.Result + }).ToList(); } public CalcManagerSnapshotAlias() => Value = new CalcManagerSnapshot(); diff --git a/src/Calculator/Views/MainPage.xaml.cs b/src/Calculator/Views/MainPage.xaml.cs index 3d9cc9ea7..7f3b10cfc 100644 --- a/src/Calculator/Views/MainPage.xaml.cs +++ b/src/Calculator/Views/MainPage.xaml.cs @@ -179,22 +179,8 @@ protected override void OnNavigatedTo(NavigationEventArgs e) } 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); - - // if (TryRestoreFromActivity(snapshotArgs, activity, out var errorMessage)) - // { - // TraceLogger.GetInstance().LogRecallRestore(Model.Mode); - // SelectNavigationItemByModel(); - // } - // else - // { - // TraceLogger.GetInstance().LogRecallError(Model.Mode, errorMessage); - // } - //}); - Model.Initialize(snapshotArgs.Snapshot); + Model.RestoreFromSnapshot(snapshotArgs.Snapshot); + Model.Initialize(initialMode); } else { @@ -202,38 +188,6 @@ protected override void OnNavigatedTo(NavigationEventArgs e) } } - //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; - // } - - // if (!activityJson.ContainsKey("contentInfo")) - // { - // errorMessage = "ContentInfoNotExist"; - // return false; - // } - - // if (!Model.TryRestoreFromSnapshot(activityJson.GetNamedObject("contentInfo"))) - // { - // errorMessage = "RestoreFromSnapshotFailed"; - // return false; - // } - - // errorMessage = string.Empty; - // return true; - //} - private void InitializeNavViewCategoriesSource() { NavViewCategoriesSource = ExpandNavViewCategoryGroups(Model.Categories); From 2c93865e7b53032db2123352c74f0c89e050a0e3 Mon Sep 17 00:00:00 2001 From: Tian Liao Date: Wed, 30 Oct 2024 13:48:06 +0800 Subject: [PATCH 15/21] handle errors --- src/CalcViewModel/Common/TraceLogger.cpp | 3 +-- src/CalcViewModel/Common/TraceLogger.h | 2 +- src/Calculator/Common/LaunchArguments.cs | 4 +++- src/Calculator/Utils/DeflateUtils.cs | 4 ++-- src/Calculator/Utils/JsonUtils.cs | 6 +++--- src/Calculator/Views/MainPage.xaml.cs | 16 +++++++++++++--- 6 files changed, 23 insertions(+), 12 deletions(-) diff --git a/src/CalcViewModel/Common/TraceLogger.cpp b/src/CalcViewModel/Common/TraceLogger.cpp index 9d4bac780..b1017e6f2 100644 --- a/src/CalcViewModel/Common/TraceLogger.cpp +++ b/src/CalcViewModel/Common/TraceLogger.cpp @@ -345,10 +345,9 @@ namespace CalculatorApp TraceLoggingCommon::GetInstance()->LogLevel2Event(StringReference(EVENT_NAME_RECALL_RESTORE), fields); } - void TraceLogger::LogRecallError(CalculatorApp::ViewModel::Common::ViewMode mode, Platform::String^ message) + void TraceLogger::LogRecallError(Platform::String^ message) { auto fields = ref new LoggingFields(); - fields->AddString(StringReference(CALC_MODE), NavCategoryStates::GetFriendlyName(mode)); fields->AddString(StringReference(L"FunctionName"), L"Recall"); fields->AddString(StringReference(L"Message"), message); TraceLoggingCommon::GetInstance()->LogLevel2Event(StringReference(EVENT_NAME_EXCEPTION), fields); diff --git a/src/CalcViewModel/Common/TraceLogger.h b/src/CalcViewModel/Common/TraceLogger.h index 25e57eea8..0c70b0a98 100644 --- a/src/CalcViewModel/Common/TraceLogger.h +++ b/src/CalcViewModel/Common/TraceLogger.h @@ -87,7 +87,7 @@ namespace CalculatorApp::ViewModel::Common void LogPlatformExceptionInfo(CalculatorApp::ViewModel::Common::ViewMode mode, Platform::String ^ functionName, Platform::String ^ message, int hresult); void LogRecallSnapshot(CalculatorApp::ViewModel::Common::ViewMode mode); void LogRecallRestore(CalculatorApp::ViewModel::Common::ViewMode mode); - void LogRecallError(CalculatorApp::ViewModel::Common::ViewMode mode, Platform::String ^ message); + void LogRecallError(Platform::String ^ message); internal: void LogPlatformException(CalculatorApp::ViewModel::Common::ViewMode mode, Platform::String ^ functionName, Platform::Exception ^ e); diff --git a/src/Calculator/Common/LaunchArguments.cs b/src/Calculator/Common/LaunchArguments.cs index fc887356f..27c8853d8 100644 --- a/src/Calculator/Common/LaunchArguments.cs +++ b/src/Calculator/Common/LaunchArguments.cs @@ -5,6 +5,7 @@ using CalculatorApp.ViewModel.Snapshot; using CalculatorApp.JsonUtils; +using CalculatorApp.ViewModel.Common; namespace CalculatorApp { @@ -42,8 +43,9 @@ public static SnapshotLaunchArguments GetSnapshotLaunchArgs(this IProtocolActiva var snapshot = JsonSerializer.Deserialize(jsonStr); return new SnapshotLaunchArguments { HasError = false, Snapshot = snapshot.Value }; } - catch (Exception) + catch (Exception ex) { + TraceLogger.GetInstance().LogRecallError($"Error occurs during the deserialization of Snapshot. Exception: {ex}"); return new SnapshotLaunchArguments { HasError = true }; } } diff --git a/src/Calculator/Utils/DeflateUtils.cs b/src/Calculator/Utils/DeflateUtils.cs index 3d4b2fbd3..b5a511d1f 100644 --- a/src/Calculator/Utils/DeflateUtils.cs +++ b/src/Calculator/Utils/DeflateUtils.cs @@ -23,10 +23,10 @@ public static byte[] Compress(string text) public static string Decompress(byte[] data) { using (var srcStream = new MemoryStream(data)) - using (var deflateStream = new DeflateStream(srcStream, CompressionMode.Decompress)) + using (var inflater = new DeflateStream(srcStream, CompressionMode.Decompress)) using (var resultStream = new MemoryStream()) { - deflateStream.CopyTo(resultStream); + inflater.CopyTo(resultStream); byte[] decompressed = resultStream.ToArray(); return Encoding.UTF8.GetString(decompressed); } diff --git a/src/Calculator/Utils/JsonUtils.cs b/src/Calculator/Utils/JsonUtils.cs index 0a49b430d..86fbc953f 100644 --- a/src/Calculator/Utils/JsonUtils.cs +++ b/src/Calculator/Utils/JsonUtils.cs @@ -65,6 +65,7 @@ public int Command get => Value.Command; set => Value.Command = value; } + public BinaryCommandAlias() => Value = new BinaryCommand(); public BinaryCommandAlias(BinaryCommand value) => Value = value; } @@ -114,6 +115,7 @@ public int Command get => Value.Command; set => Value.Command = value; } + public ParenthesesAlias() => Value = new Parentheses(); public ParenthesesAlias(Parentheses value) => Value = value; } @@ -129,27 +131,25 @@ public IEnumerable Tokens get => Value.Tokens.Select(x => new CalcManagerHistoryTokenAlias(x)); set => Value.Tokens = value.Select(Helpers.MapHistoryToken).ToList(); } - [JsonPropertyName("c")] public IEnumerable Commands { get => Value.Commands.Select(Helpers.MapCommandAlias); set => Value.Commands = value.Select(Helpers.MapCommandAlias).ToList(); } - [JsonPropertyName("e")] public string Expression { get => Value.Expression; set => Value.Expression = value; } - [JsonPropertyName("r")] public string Result { get => Value.Result; set => Value.Result = value; } + public CalcManagerHistoryItemAlias() => Value = new CalcManagerHistoryItem(); public CalcManagerHistoryItemAlias(CalcManagerHistoryItem value) => Value = value; } diff --git a/src/Calculator/Views/MainPage.xaml.cs b/src/Calculator/Views/MainPage.xaml.cs index 7f3b10cfc..de0a51940 100644 --- a/src/Calculator/Views/MainPage.xaml.cs +++ b/src/Calculator/Views/MainPage.xaml.cs @@ -77,9 +77,9 @@ public MainPage() var json = JsonSerializer.Serialize(new ApplicationSnapshotAlias(Model.Snapshot)); embeddedData = Convert.ToBase64String(DeflateUtils.Compress(json)); } - catch (Exception) + catch (Exception ex) { - // TODO: trace errors + TraceLogger.GetInstance().LogRecallError($"Error occurs during the serialization of Snapshot. Exception: {ex}"); deferral.Complete(); return; } @@ -179,8 +179,18 @@ protected override void OnNavigatedTo(NavigationEventArgs e) } else if (e.Parameter is SnapshotLaunchArguments snapshotArgs) { - Model.RestoreFromSnapshot(snapshotArgs.Snapshot); Model.Initialize(initialMode); + if (!snapshotArgs.HasError) + { + Model.RestoreFromSnapshot(snapshotArgs.Snapshot); + TraceLogger.GetInstance().LogRecallRestore((ViewMode)snapshotArgs.Snapshot.Mode); + } + else + { + _ = Window.Current.Dispatcher.RunAsync(CoreDispatcherPriority.Normal, + async () => await ShowSnapshotLaunchErrorAsync()); + TraceLogger.GetInstance().LogRecallError("OnNavigatedTo:Found errors."); + } } else { From a50753f166b1b182a3a72c3304c80231ebebb497 Mon Sep 17 00:00:00 2001 From: Tian Liao Date: Tue, 5 Nov 2024 14:49:53 +0800 Subject: [PATCH 16/21] rename CalcManagerHistoryToken --- src/CalcViewModel/Snapshots.cpp | 18 ++++++++--------- src/CalcViewModel/Snapshots.h | 10 +++++----- .../StandardCalculatorViewModel.cpp | 2 +- src/Calculator/Utils/JsonUtils.cs | 20 +++++++++---------- 4 files changed, 25 insertions(+), 25 deletions(-) diff --git a/src/CalcViewModel/Snapshots.cpp b/src/CalcViewModel/Snapshots.cpp index 69c082ad1..0389afc5f 100644 --- a/src/CalcViewModel/Snapshots.cpp +++ b/src/CalcViewModel/Snapshots.cpp @@ -121,13 +121,13 @@ namespace CalculatorApp::ViewModel::Snapshot } } - CalcManagerHistoryToken::CalcManagerHistoryToken() + CalcManagerToken::CalcManagerToken() { OpCodeName = ref new Platform::String(); CommandIndex = 0; } - CalcManagerHistoryToken::CalcManagerHistoryToken(Platform::String ^ opCodeName, int cmdIndex) + CalcManagerToken::CalcManagerToken(Platform::String ^ opCodeName, int cmdIndex) { assert(opCodeName != nullptr && "opCodeName is mandatory."); OpCodeName = opCodeName; @@ -136,7 +136,7 @@ namespace CalculatorApp::ViewModel::Snapshot CalcManagerHistoryItem::CalcManagerHistoryItem() { - Tokens = ref new Platform::Collections::Vector(); + Tokens = ref new Platform::Collections::Vector(); Commands = ref new Platform::Collections::Vector(); Expression = ref new Platform::String(); Result = ref new Platform::String(); @@ -144,11 +144,11 @@ namespace CalculatorApp::ViewModel::Snapshot CalcManagerHistoryItem::CalcManagerHistoryItem(const CalculationManager::HISTORYITEM& item) { - Tokens = ref new Platform::Collections::Vector(); + Tokens = ref new Platform::Collections::Vector(); assert(item.historyItemVector.spTokens != nullptr && "spTokens shall not be null."); for (auto& [opCode, cmdIdx] : *item.historyItemVector.spTokens) { - Tokens->Append(ref new CalcManagerHistoryToken(ref new Platform::String(opCode.c_str()), cmdIdx)); + Tokens->Append(ref new CalcManagerToken(ref new Platform::String(opCode.c_str()), cmdIdx)); } Commands = ref new Platform::Collections::Vector(); assert(item.historyItemVector.spCommands != nullptr && "spCommands shall not be null."); @@ -193,7 +193,7 @@ namespace CalculatorApp::ViewModel::Snapshot ExpressionDisplaySnapshot::ExpressionDisplaySnapshot() { - Tokens = ref new Platform::Collections::Vector(); + Tokens = ref new Platform::Collections::Vector(); Commands = ref new Platform::Collections::Vector(); } @@ -201,10 +201,10 @@ namespace CalculatorApp::ViewModel::Snapshot const std::vector& tokens, const std::vector>& commands) { - Tokens = ref new Platform::Collections::Vector(); + Tokens = ref new Platform::Collections::Vector(); for (auto& [opCode, cmdIdx] : tokens) { - Tokens->Append(ref new CalcManagerHistoryToken(ref new Platform::String(opCode.c_str()), cmdIdx)); + Tokens->Append(ref new CalcManagerToken(ref new Platform::String(opCode.c_str()), cmdIdx)); } Commands = ref new Platform::Collections::Vector(); @@ -229,7 +229,7 @@ namespace CalculatorApp::ViewModel::Snapshot { CalculationManager::HISTORYITEMVECTOR nativeItem; nativeItem.spTokens = std::make_shared>>(); - for (CalcManagerHistoryToken ^ token : item->Tokens) + for (CalcManagerToken ^ token : item->Tokens) { nativeItem.spTokens->push_back(std::make_pair(token->OpCodeName->Data(), token->CommandIndex)); } diff --git a/src/CalcViewModel/Snapshots.h b/src/CalcViewModel/Snapshots.h index cee12933b..65afd4e4a 100644 --- a/src/CalcViewModel/Snapshots.h +++ b/src/CalcViewModel/Snapshots.h @@ -70,21 +70,21 @@ public }; public - ref struct CalcManagerHistoryToken sealed + ref struct CalcManagerToken sealed { property Platform::String ^ OpCodeName; // mandatory property int CommandIndex; - CalcManagerHistoryToken(); + CalcManagerToken(); internal :; - explicit CalcManagerHistoryToken(Platform::String ^ opCodeName, int cmdIndex); + explicit CalcManagerToken(Platform::String ^ opCodeName, int cmdIndex); }; public ref struct CalcManagerHistoryItem sealed { - property Windows::Foundation::Collections::IVector ^ Tokens; // mandatory + property Windows::Foundation::Collections::IVector ^ Tokens; // mandatory property Windows::Foundation::Collections::IVector ^ Commands; // mandatory property Platform::String ^ Expression; // mandatory property Platform::String ^ Result; // mandatory @@ -121,7 +121,7 @@ public public ref struct ExpressionDisplaySnapshot sealed { - property Windows::Foundation::Collections::IVector ^ Tokens; + property Windows::Foundation::Collections::IVector ^ Tokens; property Windows::Foundation::Collections::IVector ^ Commands; ExpressionDisplaySnapshot(); diff --git a/src/CalcViewModel/StandardCalculatorViewModel.cpp b/src/CalcViewModel/StandardCalculatorViewModel.cpp index a1cee93b1..0839a9f2d 100644 --- a/src/CalcViewModel/StandardCalculatorViewModel.cpp +++ b/src/CalcViewModel/StandardCalculatorViewModel.cpp @@ -1827,7 +1827,7 @@ void CalculatorApp::ViewModel::StandardCalculatorViewModel::Snapshot::set(Calcul { using RawTokenCollection = std::vector>; RawTokenCollection rawTokens; - for (CalculatorApp::ViewModel::Snapshot::CalcManagerHistoryToken ^ token : snapshot->ExpressionDisplay->Tokens) + for (CalculatorApp::ViewModel::Snapshot::CalcManagerToken ^ token : snapshot->ExpressionDisplay->Tokens) { rawTokens.push_back(std::pair{ token->OpCodeName->Data(), token->CommandIndex }); } diff --git a/src/Calculator/Utils/JsonUtils.cs b/src/Calculator/Utils/JsonUtils.cs index 86fbc953f..7d4ffd09a 100644 --- a/src/Calculator/Utils/JsonUtils.cs +++ b/src/Calculator/Utils/JsonUtils.cs @@ -7,10 +7,10 @@ namespace CalculatorApp.JsonUtils { - internal class CalcManagerHistoryTokenAlias + internal class CalcManagerTokenAlias { [JsonIgnore] - public CalcManagerHistoryToken Value; + public CalcManagerToken Value; [JsonPropertyName("t")] public string OpCodeName @@ -25,8 +25,8 @@ public int CommandIndex set => Value.CommandIndex = value; } - public CalcManagerHistoryTokenAlias() => Value = new CalcManagerHistoryToken(); - public CalcManagerHistoryTokenAlias(CalcManagerHistoryToken value) => Value = value; + public CalcManagerTokenAlias() => Value = new CalcManagerToken(); + public CalcManagerTokenAlias(CalcManagerToken value) => Value = value; } [JsonPolymorphic(TypeDiscriminatorPropertyName = "$t")] @@ -126,9 +126,9 @@ internal class CalcManagerHistoryItemAlias public CalcManagerHistoryItem Value; [JsonPropertyName("t")] - public IEnumerable Tokens + public IEnumerable Tokens { - get => Value.Tokens.Select(x => new CalcManagerHistoryTokenAlias(x)); + get => Value.Tokens.Select(x => new CalcManagerTokenAlias(x)); set => Value.Tokens = value.Select(Helpers.MapHistoryToken).ToList(); } [JsonPropertyName("c")] @@ -204,9 +204,9 @@ internal class ExpressionDisplaySnapshotAlias public ExpressionDisplaySnapshot Value; [JsonPropertyName("t")] - public IEnumerable Tokens + public IEnumerable Tokens { - get => Value.Tokens.Select(x => new CalcManagerHistoryTokenAlias(x)); + get => Value.Tokens.Select(x => new CalcManagerTokenAlias(x)); set => Value.Tokens = value.Select(Helpers.MapHistoryToken).ToList(); } [JsonPropertyName("c")] @@ -274,9 +274,9 @@ public StandardCalculatorSnapshotAlias StandardCalculatorSnapshot internal static class Helpers { - public static CalcManagerHistoryToken MapHistoryToken(CalcManagerHistoryTokenAlias token) + public static CalcManagerToken MapHistoryToken(CalcManagerTokenAlias token) { - return new CalcManagerHistoryToken { OpCodeName = token.OpCodeName, CommandIndex = token.CommandIndex }; + return new CalcManagerToken { OpCodeName = token.OpCodeName, CommandIndex = token.CommandIndex }; } public static ICalcManagerIExprCommandAlias MapCommandAlias(ICalcManagerIExprCommand exprCmd) From c8cfe10ed0b25a685a32346b7938323c964f78ea Mon Sep 17 00:00:00 2001 From: Tian Liao Date: Wed, 6 Nov 2024 12:25:48 +0800 Subject: [PATCH 17/21] handle optional props --- src/Calculator/Utils/JsonUtils.cs | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/src/Calculator/Utils/JsonUtils.cs b/src/Calculator/Utils/JsonUtils.cs index 7d4ffd09a..39ffcf184 100644 --- a/src/Calculator/Utils/JsonUtils.cs +++ b/src/Calculator/Utils/JsonUtils.cs @@ -160,10 +160,10 @@ internal class CalcManagerSnapshotAlias public CalcManagerSnapshot Value; [JsonPropertyName("h")] - public IEnumerable HistoryItems + public IEnumerable HistoryItems // optional { - get => Value.HistoryItems.Select(x => new CalcManagerHistoryItemAlias { Value = x }); - set => Value.HistoryItems = value.Select(x => new CalcManagerHistoryItem + get => Value?.HistoryItems.Select(x => new CalcManagerHistoryItemAlias { Value = x }); + set => Value.HistoryItems = value?.Select(x => new CalcManagerHistoryItem { Tokens = x.Tokens.Select(Helpers.MapHistoryToken).ToList(), Commands = x.Commands.Select(Helpers.MapCommandAlias).ToList(), @@ -238,10 +238,10 @@ public PrimaryDisplaySnapshotAlias PrimaryDisplay set => Value.PrimaryDisplay = value.Value; } [JsonPropertyName("e")] - public ExpressionDisplaySnapshotAlias ExpressionDisplay + public ExpressionDisplaySnapshotAlias ExpressionDisplay // optional { - get => new ExpressionDisplaySnapshotAlias(Value.ExpressionDisplay); - set => Value.ExpressionDisplay = value.Value; + get => Value != null ? new ExpressionDisplaySnapshotAlias(Value.ExpressionDisplay) : null; + set => Value.ExpressionDisplay = value?.Value; } [JsonPropertyName("c")] public IEnumerable Commands @@ -262,10 +262,10 @@ internal class ApplicationSnapshotAlias [JsonPropertyName("m")] public int Mode { get => Value.Mode; set => Value.Mode = value; } [JsonPropertyName("s")] - public StandardCalculatorSnapshotAlias StandardCalculatorSnapshot + public StandardCalculatorSnapshotAlias StandardCalculatorSnapshot // optional { - get => new StandardCalculatorSnapshotAlias(Value.StandardCalculator); - set => Value.StandardCalculator = value.Value; + get => Value != null ? new StandardCalculatorSnapshotAlias(Value.StandardCalculator) : null; + set => Value.StandardCalculator = value?.Value; } public ApplicationSnapshotAlias() => Value = new ApplicationSnapshot(); From 3bc92544d2f51282bf06dcfb410c32c387a2606a Mon Sep 17 00:00:00 2001 From: Tian Liao Date: Wed, 6 Nov 2024 22:37:10 +0800 Subject: [PATCH 18/21] fix optional props --- src/CalcViewModel/StandardCalculatorViewModel.cpp | 5 ++++- src/Calculator/Utils/JsonUtils.cs | 6 +++--- 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/src/CalcViewModel/StandardCalculatorViewModel.cpp b/src/CalcViewModel/StandardCalculatorViewModel.cpp index 0839a9f2d..ef4409922 100644 --- a/src/CalcViewModel/StandardCalculatorViewModel.cpp +++ b/src/CalcViewModel/StandardCalculatorViewModel.cpp @@ -1792,7 +1792,10 @@ CalculatorApp::ViewModel::Snapshot::StandardCalculatorSnapshot ^ StandardCalcula auto result = ref new CalculatorApp::ViewModel::Snapshot::StandardCalculatorSnapshot(); result->CalcManager = ref new CalculatorApp::ViewModel::Snapshot::CalcManagerSnapshot(m_standardCalculatorManager); result->PrimaryDisplay = ref new CalculatorApp::ViewModel::Snapshot::PrimaryDisplaySnapshot(m_DisplayValue, m_IsInError); - result->ExpressionDisplay = ref new CalculatorApp::ViewModel::Snapshot::ExpressionDisplaySnapshot(*m_tokens, *m_commands); + if (!m_tokens->empty() && !m_commands->empty()) + { + result->ExpressionDisplay = ref new CalculatorApp::ViewModel::Snapshot::ExpressionDisplaySnapshot(*m_tokens, *m_commands); + } result->DisplayCommands = ref new Platform::Collections::Vector(); for (auto cmd : m_standardCalculatorManager.GetDisplayCommandsSnapshot()) { diff --git a/src/Calculator/Utils/JsonUtils.cs b/src/Calculator/Utils/JsonUtils.cs index 39ffcf184..7cfa03be2 100644 --- a/src/Calculator/Utils/JsonUtils.cs +++ b/src/Calculator/Utils/JsonUtils.cs @@ -162,7 +162,7 @@ internal class CalcManagerSnapshotAlias [JsonPropertyName("h")] public IEnumerable HistoryItems // optional { - get => Value?.HistoryItems.Select(x => new CalcManagerHistoryItemAlias { Value = x }); + get => Value.HistoryItems?.Select(x => new CalcManagerHistoryItemAlias { Value = x }); set => Value.HistoryItems = value?.Select(x => new CalcManagerHistoryItem { Tokens = x.Tokens.Select(Helpers.MapHistoryToken).ToList(), @@ -240,7 +240,7 @@ public PrimaryDisplaySnapshotAlias PrimaryDisplay [JsonPropertyName("e")] public ExpressionDisplaySnapshotAlias ExpressionDisplay // optional { - get => Value != null ? new ExpressionDisplaySnapshotAlias(Value.ExpressionDisplay) : null; + get => Value.ExpressionDisplay != null ? new ExpressionDisplaySnapshotAlias(Value.ExpressionDisplay) : null; set => Value.ExpressionDisplay = value?.Value; } [JsonPropertyName("c")] @@ -264,7 +264,7 @@ internal class ApplicationSnapshotAlias [JsonPropertyName("s")] public StandardCalculatorSnapshotAlias StandardCalculatorSnapshot // optional { - get => Value != null ? new StandardCalculatorSnapshotAlias(Value.StandardCalculator) : null; + get => Value.StandardCalculator != null ? new StandardCalculatorSnapshotAlias(Value.StandardCalculator) : null; set => Value.StandardCalculator = value?.Value; } From 624f140d7cb8fd191684ac07b17f4bf1be831784 Mon Sep 17 00:00:00 2001 From: Tian Liao Date: Wed, 6 Nov 2024 23:11:58 +0800 Subject: [PATCH 19/21] ensure error state --- src/Calculator/Views/Calculator.xaml.cs | 1 + 1 file changed, 1 insertion(+) diff --git a/src/Calculator/Views/Calculator.xaml.cs b/src/Calculator/Views/Calculator.xaml.cs index ccd42637d..7249e8a7f 100644 --- a/src/Calculator/Views/Calculator.xaml.cs +++ b/src/Calculator/Views/Calculator.xaml.cs @@ -245,6 +245,7 @@ private void OnLoaded(object sender, RoutedEventArgs e) HistoryFlyout.FlyoutPresenterStyle.Setters.Add(new Setter(AutomationProperties.NameProperty, historyPaneName)); string memoryPaneName = AppResourceProvider.GetInstance().GetResourceString("MemoryPane"); MemoryFlyout.FlyoutPresenterStyle.Setters.Add(new Setter(AutomationProperties.NameProperty, memoryPaneName)); + OnIsInErrorPropertyChanged(); // Delay load things later when we get a chance. WeakReference weakThis = new WeakReference(this); From ee96edbdbedf25dfd01338f1e3ea10f4e88eef4d Mon Sep 17 00:00:00 2001 From: Tian Liao Date: Wed, 6 Nov 2024 23:15:59 +0800 Subject: [PATCH 20/21] resolve a comment --- src/Calculator/Utils/JsonUtils.cs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/Calculator/Utils/JsonUtils.cs b/src/Calculator/Utils/JsonUtils.cs index 7cfa03be2..1e86f94a6 100644 --- a/src/Calculator/Utils/JsonUtils.cs +++ b/src/Calculator/Utils/JsonUtils.cs @@ -129,7 +129,7 @@ internal class CalcManagerHistoryItemAlias public IEnumerable Tokens { get => Value.Tokens.Select(x => new CalcManagerTokenAlias(x)); - set => Value.Tokens = value.Select(Helpers.MapHistoryToken).ToList(); + set => Value.Tokens = value.Select(Helpers.MapToken).ToList(); } [JsonPropertyName("c")] public IEnumerable Commands @@ -165,7 +165,7 @@ public IEnumerable HistoryItems // optional get => Value.HistoryItems?.Select(x => new CalcManagerHistoryItemAlias { Value = x }); set => Value.HistoryItems = value?.Select(x => new CalcManagerHistoryItem { - Tokens = x.Tokens.Select(Helpers.MapHistoryToken).ToList(), + Tokens = x.Tokens.Select(Helpers.MapToken).ToList(), Commands = x.Commands.Select(Helpers.MapCommandAlias).ToList(), Expression = x.Expression, Result = x.Result @@ -207,7 +207,7 @@ internal class ExpressionDisplaySnapshotAlias public IEnumerable Tokens { get => Value.Tokens.Select(x => new CalcManagerTokenAlias(x)); - set => Value.Tokens = value.Select(Helpers.MapHistoryToken).ToList(); + set => Value.Tokens = value.Select(Helpers.MapToken).ToList(); } [JsonPropertyName("c")] public IEnumerable Commands @@ -274,7 +274,7 @@ public StandardCalculatorSnapshotAlias StandardCalculatorSnapshot // optional internal static class Helpers { - public static CalcManagerToken MapHistoryToken(CalcManagerTokenAlias token) + public static CalcManagerToken MapToken(CalcManagerTokenAlias token) { return new CalcManagerToken { OpCodeName = token.OpCodeName, CommandIndex = token.CommandIndex }; } From 5b602d8b5e6f05ff0df8f29c1f87fef49b3bd0c8 Mon Sep 17 00:00:00 2001 From: Tian Liao Date: Thu, 7 Nov 2024 15:32:09 +0800 Subject: [PATCH 21/21] resolve a comment --- src/Calculator/Views/MainPage.xaml.cs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/Calculator/Views/MainPage.xaml.cs b/src/Calculator/Views/MainPage.xaml.cs index de0a51940..32bfdb26a 100644 --- a/src/Calculator/Views/MainPage.xaml.cs +++ b/src/Calculator/Views/MainPage.xaml.cs @@ -66,7 +66,8 @@ public MainPage() { if (deferral == null) { - // Windows Bug in ni_moment won't return the deferral propoerly, see https://microsoft.visualstudio.com/DefaultCollection/OS/_workitems/edit/47775705/ + // FIXME: https://microsoft.visualstudio.com/DefaultCollection/OS/_workitems/edit/47775705/ + TraceLogger.GetInstance().LogRecallError("55e29ba5-6097-40ec-8960-458750be3039"); return; } var channel = UserActivityChannel.GetDefault();