diff --git a/src/CalcManager/CCalcManager.cpp b/src/CalcManager/CCalcManager.cpp index d9ece638..9f8393e2 100644 --- a/src/CalcManager/CCalcManager.cpp +++ b/src/CalcManager/CCalcManager.cpp @@ -9,6 +9,8 @@ #include #include #include + +#if !defined(__EMSCRIPTEN__) #include #include @@ -39,6 +41,7 @@ VOID _DBGPRINT(LPCWSTR kwszFunction, INT iLineNumber, LPCWSTR kwszDebugFormatStr _freea(wszDebugString); va_end(args); } +#endif using namespace CalculationManager; @@ -59,11 +62,15 @@ public: std::wstring_convert> convert; auto str = convert.to_bytes(pszText); + printf("Native:SetPrimaryDisplay(%ls, %d)\n", pszText.data(), isError); + _params.SetPrimaryDisplay(_params.CalculatorState, str.data(), isError); } virtual void SetIsInError(bool isInError) override { + printf("Native:SetIsInError(%d)\n", isInError); + _params.SetIsInError(_params.CalculatorState, isInError); } @@ -71,35 +78,45 @@ public: std::shared_ptr>> const& /*tokens*/, std::shared_ptr>> const& /*commands*/) override { + printf("Native:SetExpressionDisplay()\n"); + } virtual void SetParenthesisNumber(unsigned int count) override { + printf("Native:SetParenthesisNumber(%d)\n", count); + _params.SetParenthesisNumber(_params.CalculatorState, count); } virtual void OnNoRightParenAdded() override { + printf("Native:OnNoRightParenAdded()\n"); _params.OnNoRightParenAdded(_params.CalculatorState); } virtual void MaxDigitsReached() override { + printf("Native:MaxDigitsReached()\n"); _params.MaxDigitsReached(_params.CalculatorState); } virtual void BinaryOperatorReceived() override { + printf("Native:BinaryOperatorReceived()\n"); _params.BinaryOperatorReceived(_params.CalculatorState); } virtual void OnHistoryItemAdded(unsigned int addedItemIndex) override { + printf("Native:OnHistoryItemAdded(%d)\n", addedItemIndex); _params.OnHistoryItemAdded(_params.CalculatorState, addedItemIndex); } virtual void SetMemorizedNumbers(const std::vector& memorizedNumbers) override { + printf("Native:SetMemorizedNumbers(%d)\n", (int)memorizedNumbers.size()); + auto numbers = new const wchar_t* [memorizedNumbers.size()] {}; for (size_t i = 0; i < memorizedNumbers.size(); i++) @@ -122,6 +139,8 @@ public: virtual void MemoryItemChanged(unsigned int indexOfMemory) override { + printf("Native:MemoryItemChanged(%d)\n", indexOfMemory); + _params.MemoryItemChanged(_params.CalculatorState, indexOfMemory); } }; @@ -139,7 +158,10 @@ public: virtual std::wstring GetCEngineString(const std::wstring& id) override { - return _params.GetCEngineString(_params.ResourceState, id.data()); + auto pResult = _params.GetCEngineString(_params.ResourceState, id.data()); + auto str = std::wstring(pResult); + printf("Native:GetCEngineString(id=%ls, str.data()=%ls)\n", id.data(), str.data()); + return str; } }; @@ -148,6 +170,11 @@ CalculatorManager* AsManager(void* manager) return static_cast(manager); } +IExpressionCommand* AsIExpressionCommand(void* pExpressionCommand) +{ + return static_cast(pExpressionCommand); +} + const wchar_t* ToWChar(std::wstring& str) { auto out = new wchar_t[str.size() + 1]{}; @@ -300,10 +327,13 @@ GetHistoryItemResult* MarshalHistoryItem(std::shared_ptrhistoryItemVector.spTokens->GetSize(&tokenCount); itemResult->TokenCount = tokenCount; + // + // Marshal Tokens + // auto tokenStrings = new const wchar_t* [tokenCount] {}; auto tokenValues = new int32_t[tokenCount]{}; - DBGPRINT(L"TokenCount: %d (int32_t: %d)\n", tokenCount, sizeof(int32_t)); + // DBGPRINT(L"TokenCount: %d (int32_t: %d)\n", tokenCount, sizeof(int32_t)); for (uint32_t j = 0; j < tokenCount; j++) { @@ -313,13 +343,33 @@ GetHistoryItemResult* MarshalHistoryItem(std::shared_ptrTokenStrings = tokenStrings; itemResult->TokenValues = tokenValues; + // + // Marshal Commands + // + unsigned int commandCount; + historyItem->historyItemVector.spCommands->GetSize(&commandCount); + itemResult->CommandCount = commandCount; + + auto commands = new void*[commandCount]{}; + + for (uint32_t commandId = 0; commandId < commandCount; commandId++) + { + std::shared_ptr command; + if (SUCCEEDED(historyItem->historyItemVector.spCommands->GetAt(commandId, &command))) + { + commands[commandId] = command.get(); + } + } + + itemResult->Commands = commands; + return itemResult; } @@ -362,3 +412,8 @@ void* CalculatorManager_GetHistoryItem(void* manager, int index) return MarshalHistoryItem(historyItem); } + +int IExpressionCommand_GetCommandType(void* pExpressionCommand) +{ + return (int)AsIExpressionCommand(pExpressionCommand)->GetCommandType(); +} diff --git a/src/CalcManager/CCalcManager.h b/src/CalcManager/CCalcManager.h index e8cf8cbd..76cf983d 100644 --- a/src/CalcManager/CCalcManager.h +++ b/src/CalcManager/CCalcManager.h @@ -102,10 +102,10 @@ extern "C" { DLL_EXPORT size_t CalculatorManager_MaxHistorySize(void* manager); DLL_EXPORT int CalculatorManager_GetCurrentDegreeMode(void* manager); DLL_EXPORT void CalculatorManager_SetInHistoryItemLoadMode(void* manager, bool isHistoryItemLoadMode); - void* MarshalHistoryItem(std::shared_ptr& historyItem, bool& retflag); - void* MarshalHistoryItems(std::vector>& historyItems); DLL_EXPORT void* CalculatorManager_GetHistoryItemsWithMode(void* manager, int mode); DLL_EXPORT void* CalculatorManager_GetHistoryItems(void* manager); DLL_EXPORT void* CalculatorManager_GetHistoryItem(void* manager, int index); + + DLL_EXPORT int IExpressionCommand_GetCommandType(void* pExpressionCommand); } diff --git a/src/CalcManager/CalcManager.wasm b/src/CalcManager/CalcManager.wasm index 924d9d07..873bff55 100644 Binary files a/src/CalcManager/CalcManager.wasm and b/src/CalcManager/CalcManager.wasm differ diff --git a/src/Calculator.Shared/CalcManager/CalculatorManager.Interop.cs b/src/Calculator.Shared/CalcManager/CalculatorManager.Interop.cs index a9b7a2ff..d66d1a09 100644 --- a/src/Calculator.Shared/CalcManager/CalculatorManager.Interop.cs +++ b/src/Calculator.Shared/CalcManager/CalculatorManager.Interop.cs @@ -93,7 +93,10 @@ namespace CalculationManager [DllImport("CalcManager")] public static extern IntPtr CalculatorManager_GetHistoryItem(IntPtr nativeManager, int uIdx); - public delegate IntPtr GetCEngineStringFunc(IntPtr state, string id); + [DllImport("CalcManager")] + public static extern CommandType IExpressionCommand_GetCommandType(IntPtr pExpressionCommand); + + public delegate IntPtr GetCEngineStringFunc(IntPtr state, IntPtr id); public delegate void BinaryOperatorReceivedFunc(IntPtr state); public delegate void SetPrimaryDisplayCallbackFunc(IntPtr state, string displayStringValue, bool isError); public delegate void SetIsInErrorCallbackFunc(IntPtr state, bool isError); @@ -207,16 +210,34 @@ namespace CalculationManager Debug.WriteLine($"CalculatorManager.SetIsInErrorCallback({isError})"); } - public static IntPtr GetCEngineStringCallback(IntPtr state, [MarshalAs(UnmanagedType.LPWStr)] string resourceId) + public static IntPtr GetCEngineStringCallback(IntPtr state, IntPtr pResourceId) { - var provider = GCHandle.FromIntPtr((IntPtr)state).Target as EngineResourceProvider; - var r = provider.GetCEngineString(resourceId) ?? ""; + var provider = GCHandle.FromIntPtr(state).Target as EngineResourceProvider; + var resourceId = Marshal.PtrToStringUni(pResourceId); + var resourceValue = provider.GetCEngineString(resourceId) ?? ""; - return Marshal.StringToHGlobalUni(r); +#if __WASM__ + // wchar_t is 32bits with emscripten + var pEngineString = StringToHGlobalUTF32(resourceValue); +#else + var pEngineString = Marshal.StringToHGlobalUni(resourceValue); +#endif + + Debug.WriteLine($"GetCEngineStringCallback({resourceId}, {resourceValue}"); + + return pEngineString; + } + + private static IntPtr StringToHGlobalUTF32(string resourceValue) + { + var ret = Encoding.UTF32.GetBytes(resourceValue); + var pRet2 = Marshal.AllocHGlobal(resourceValue.Length * 4 + 4); + Marshal.Copy(ret, 0, pRet2, resourceValue.Length * 4); + Marshal.WriteInt32(pRet2 + resourceValue.Length * 4, 0); + return pRet2; } } - [StructLayout(LayoutKind.Sequential)] public struct GetHistoryItemsResult { diff --git a/src/Calculator.Shared/CalcManager/CalculatorManager.cs b/src/Calculator.Shared/CalcManager/CalculatorManager.cs index 2b754e83..f76b1ad2 100644 --- a/src/Calculator.Shared/CalcManager/CalculatorManager.cs +++ b/src/Calculator.Shared/CalcManager/CalculatorManager.cs @@ -258,12 +258,41 @@ namespace CalculationManager for (var i = 0; i < historyResultItem.TokenCount; i++) { var tokenString = Marshal.PtrToStringUni(Marshal.ReadIntPtr(historyResultItem.TokenStrings, i * Marshal.SizeOf())); - var tokenValue = Marshal.ReadInt32(historyResultItem.TokenValues, i * Marshal.SizeOf()); historyItem.historyItemVector.spTokens.Append((tokenString, tokenValue)); } + historyItem.historyItemVector.spCommands = new CalculatorList(); + for (int j = 0; j < historyResultItem.CommandCount; j++) + { + var pExpressionCommand = Marshal.ReadIntPtr(historyResultItem.Commands, j * Marshal.SizeOf()); + var commandType = NativeDispatch.IExpressionCommand_GetCommandType(pExpressionCommand); + + IExpressionCommand getCommand() + { + switch (commandType) + { + case CommandType.BinaryCommand: + return new CUnaryCommand(pExpressionCommand); + + case CommandType.OperandCommand: + return new COpndCommand(pExpressionCommand); + + case CommandType.Parentheses: + return new CParentheses(pExpressionCommand); + + case CommandType.UnaryCommand: + return new CUnaryCommand(pExpressionCommand); + + default: + throw new NotSupportedException($"CommandType.{commandType} is not supported"); + } + } + + historyItem.historyItemVector.spCommands.Append(getCommand()); + } + return historyItem; } diff --git a/src/Calculator.Shared/CalcManager/ExpressionCommandInterface.cs b/src/Calculator.Shared/CalcManager/ExpressionCommandInterface.cs index e211b522..fd052726 100644 --- a/src/Calculator.Shared/CalcManager/ExpressionCommandInterface.cs +++ b/src/Calculator.Shared/CalcManager/ExpressionCommandInterface.cs @@ -61,14 +61,22 @@ namespace CalculationManager public class CParentheses : IParenthesisCommand { - public CParentheses(int command) => throw new NotImplementedException(); - public int GetCommand() => throw new NotImplementedException(); + private IntPtr pExpressionCommand; + + public CParentheses(int command) => throw new NotImplementedException(); + public CParentheses(IntPtr pExpressionCommand) => this.pExpressionCommand = pExpressionCommand; + + public int GetCommand() => throw new NotImplementedException(); public CalculationManager.CommandType GetCommandType() => throw new NotImplementedException(); public void Accept(ISerializeCommandVisitor commandVisitor) => throw new NotImplementedException(); } public class CUnaryCommand : IUnaryCommand { + private IntPtr pExpressionCommand; + + public CUnaryCommand(IntPtr pExpressionCommand) => this.pExpressionCommand = pExpressionCommand; + public CUnaryCommand(int command) => throw new NotImplementedException(); public CUnaryCommand(int command1, int command2) => throw new NotImplementedException(); public CalculatorList GetCommands() => throw new NotImplementedException(); @@ -78,21 +86,29 @@ namespace CalculationManager public void Accept(ISerializeCommandVisitor commandVisitor) => throw new NotImplementedException(); } - public class CBinaryCommand : IBinaryCommand - { - public CBinaryCommand(int command) => throw new NotImplementedException(); - public void SetCommand(int command) => throw new NotImplementedException(); - public int GetCommand() => throw new NotImplementedException(); - public CommandType GetCommandType() => throw new NotImplementedException(); - public void Accept(ISerializeCommandVisitor commandVisitor) => throw new NotImplementedException(); - } + public class CBinaryCommand : IBinaryCommand + { + private IntPtr pExpressionCommand; - public class COpndCommand : IOpndCommand - { - public COpndCommand(CalculatorList commands, bool fNegative, bool fDecimal, bool fSciFmt) => throw new NotImplementedException(); - // public void Initialize(CalcEngine.Rational rat) => throw new NotImplementedException(); + public CBinaryCommand(IntPtr pExpressionCommand) => this.pExpressionCommand = pExpressionCommand; - public CalculatorList GetCommands() => throw new NotImplementedException(); + public CBinaryCommand(int command) => throw new NotImplementedException(); + public void SetCommand(int command) => throw new NotImplementedException(); + public int GetCommand() => throw new NotImplementedException(); + public CommandType GetCommandType() => throw new NotImplementedException(); + public void Accept(ISerializeCommandVisitor commandVisitor) => throw new NotImplementedException(); + } + + public class COpndCommand : IOpndCommand + { + private IntPtr pExpressionCommand; + + public COpndCommand(CalculatorList commands, bool fNegative, bool fDecimal, bool fSciFmt) => throw new NotImplementedException(); + public COpndCommand(IntPtr pExpressionCommand) => this.pExpressionCommand = pExpressionCommand; + + // public void Initialize(CalcEngine.Rational rat) => throw new NotImplementedException(); + + public CalculatorList GetCommands() => throw new NotImplementedException(); public void SetCommands(CalculatorList commands) => throw new NotImplementedException(); public void AppendCommand(int command) => throw new NotImplementedException(); public void ToggleSign() => throw new NotImplementedException(); @@ -105,4 +121,4 @@ namespace CalculationManager public void Accept(ISerializeCommandVisitor commandVisitor) => throw new NotImplementedException(); public string GetString(uint radix, int precision) => throw new NotImplementedException(); } -} \ No newline at end of file +} diff --git a/src/Calculator.Wasm/Calculator.Wasm.csproj b/src/Calculator.Wasm/Calculator.Wasm.csproj index 3ec72b5f..cf7e9eef 100644 --- a/src/Calculator.Wasm/Calculator.Wasm.csproj +++ b/src/Calculator.Wasm/Calculator.Wasm.csproj @@ -12,7 +12,7 @@ release-dynamic - C:\Users\jerome.laban\Downloads\mono-wasm-4d023b6bf84.zip + C:\Users\jerome.laban\Downloads\mono-wasm-527abcd1152.zip @@ -40,7 +40,7 @@ - + diff --git a/src/Calculator.Wasm/WasmScripts/CalcManager.js b/src/Calculator.Wasm/WasmScripts/CalcManager.js index fffd2bfa..e3c5ac1e 100644 --- a/src/Calculator.Wasm/WasmScripts/CalcManager.js +++ b/src/Calculator.Wasm/WasmScripts/CalcManager.js @@ -13,7 +13,7 @@ var _setExpressionDisplayCallback = Module.mono_bind_static_method("[Calculator.Wasm] CalculationManager.NativeDispatch:SetExpressionDisplayCallback"); var _setMemorizedNumbersCallback = Module.mono_bind_static_method("[Calculator.Wasm] CalculationManager.NativeDispatch:SetMemorizedNumbersCallback"); - var fGetCEngineStringCallback = Module.addFunction((state, id) => _getCEngineStringCallback(state, Module.UTF8ToString(id)), 'iii'); + var fGetCEngineStringCallback = Module.addFunction((state, id) => _getCEngineStringCallback(state, id), 'iii'); var fBinaryOperatorReceivedCallback = Module.addFunction((state) => _binaryOperatorReceivedCallback(state), 'vi'); var fSetPrimaryDisplayCallback = Module.addFunction((state, displayStringValue, isError) => _setPrimaryDisplayCallback(state, Module.UTF8ToString(displayStringValue), isError), 'viii'); @@ -24,7 +24,7 @@ var fOnHistoryItemAddedCallback = Module.addFunction((state, addedItemIndex) => _onHistoryItemAddedCallback(state, addedItemIndex), 'vii'); var fOnNoRightParenAddedCallback = Module.addFunction((state) => _onNoRightParenAddedCallback (state), 'vi'); var fSetExpressionDisplayCallback = Module.addFunction((state) => _setExpressionDisplayCallback (state), 'vi'); - var fSetMemorizedNumbersCallback = Module.addFunction((state, numbers) => _setMemorizedNumbersCallback(state, numbers), 'vii'); + var fSetMemorizedNumbersCallback = Module.addFunction((state, size, numbers) => _setMemorizedNumbersCallback(state, size, numbers), 'viii'); var ret = `${fGetCEngineStringCallback};` + `${fBinaryOperatorReceivedCallback};`