Add support for Wasm, fonts, loading.

This commit is contained in:
Jérôme Laban 2019-05-15 11:26:44 -04:00
commit 8ae0af3e25
12 changed files with 307 additions and 181 deletions

Binary file not shown.

View file

@ -10,26 +10,26 @@ using System.Text;
namespace CalculationManager
{
public partial class CalculatorManager : ICalcDisplay
public static class NativeDispatch
{
[DllImport("CalcManager")]
public static extern IntPtr CalculatorManager_Create(ref CalculatorManager_CreateParams parms);
public static extern int CalculatorManager_Create(ref CalculatorManager_CreateParams parms);
[DllImport("CalcManager")]
public static extern void CalculatorManager_SendCommand(IntPtr instance, Command command);
public static extern void CalculatorManager_SendCommand(int instance, Command command);
private delegate IntPtr GetCEngineStringFunc(IntPtr state, string id);
private delegate void BinaryOperatorReceivedFunc(IntPtr state);
private delegate void SetPrimaryDisplayCallbackFunc(IntPtr state, string displayStringValue, bool isError);
private delegate void SetIsInErrorCallbackFunc(IntPtr state, bool isError);
private delegate void SetParenthesisNumberCallbackFunc(IntPtr state, int parenthesisCount);
private delegate int GetCEngineStringFunc(int state, string id);
private delegate void BinaryOperatorReceivedFunc(int state);
private delegate void SetPrimaryDisplayCallbackFunc(int state, string displayStringValue, bool isError);
private delegate void SetIsInErrorCallbackFunc(int state, bool isError);
private delegate void SetParenthesisNumberCallbackFunc(int state, int parenthesisCount);
private delegate void MaxDigitsReachedCallbackFunc(IntPtr state);
private delegate void MemoryItemChangedCallbackFunc(IntPtr state, int indexOfMemory);
private delegate void OnHistoryItemAddedCallbackFunc(IntPtr state, int addedItemIndex);
private delegate void OnNoRightParenAddedCallbackFunc(IntPtr state);
private delegate void SetExpressionDisplayCallbackFunc(IntPtr state);
private delegate void SetMemorizedNumbersCallbackFunc(IntPtr state, string[] newMemorizedNumbers);
private delegate void MaxDigitsReachedCallbackFunc(int state);
private delegate void MemoryItemChangedCallbackFunc(int state, int indexOfMemory);
private delegate void OnHistoryItemAddedCallbackFunc(int state, int addedItemIndex);
private delegate void OnNoRightParenAddedCallbackFunc(int state);
private delegate void SetExpressionDisplayCallbackFunc(int state);
private delegate void SetMemorizedNumbersCallbackFunc(int state, string[] newMemorizedNumbers);
private static GetCEngineStringFunc _getCEngineStringCallback = GetCEngineStringCallback;
private static BinaryOperatorReceivedFunc _binaryOperatorReceivedCallback = BinaryOperatorReceivedCallback;
@ -44,103 +44,108 @@ namespace CalculationManager
private static SetExpressionDisplayCallbackFunc _setExpressionDisplayCallback = SetExpressionDisplayCallback;
private static SetMemorizedNumbersCallbackFunc _setMemorizedNumbersCallback = SetMemorizedNumbersCallback;
private GCHandle _displayCallbackHandle;
private GCHandle _resourceProviderHandle;
private readonly IntPtr _nativeManager;
private static void MaxDigitsReachedCallback(IntPtr state)
public static void MaxDigitsReachedCallback(int state)
{
var manager = GCHandle.FromIntPtr(state).Target as CalculatorDisplay;
var manager = GCHandle.FromIntPtr((IntPtr)state).Target as CalculatorDisplay;
manager.MaxDigitsReached();
Debug.WriteLine($"CalculatorManager.MaxDigitsReachedCallback");
}
private static void MemoryItemChangedCallback(IntPtr state, int indexOfMemory)
public static void MemoryItemChangedCallback(int state, int indexOfMemory)
{
var manager = GCHandle.FromIntPtr(state).Target as CalculatorDisplay;
var manager = GCHandle.FromIntPtr((IntPtr)state).Target as CalculatorDisplay;
manager.MemoryItemChanged(indexOfMemory);
Debug.WriteLine($"CalculatorManager.MemoryItemChangedCallback({indexOfMemory})");
}
private static void OnHistoryItemAddedCallback(IntPtr state, int addedItemIndex)
public static void OnHistoryItemAddedCallback(int state, int addedItemIndex)
{
var manager = GCHandle.FromIntPtr(state).Target as CalculatorDisplay;
var manager = GCHandle.FromIntPtr((IntPtr)state).Target as CalculatorDisplay;
manager.OnHistoryItemAdded(addedItemIndex);
Debug.WriteLine($"CalculatorManager.OnHistoryItemAddedCallback({addedItemIndex})");
}
private static void OnNoRightParenAddedCallback(IntPtr state)
public static void OnNoRightParenAddedCallback(int state)
{
var manager = GCHandle.FromIntPtr(state).Target as CalculatorDisplay;
var manager = GCHandle.FromIntPtr((IntPtr)state).Target as CalculatorDisplay;
manager.OnNoRightParenAdded();
Debug.WriteLine($"CalculatorManager.OnNoRightParenAddedCallback");
}
private static void SetExpressionDisplayCallback(IntPtr state)
public static void SetExpressionDisplayCallback(int state)
{
var manager = GCHandle.FromIntPtr(state).Target as CalculatorDisplay;
var manager = GCHandle.FromIntPtr((IntPtr)state).Target as CalculatorDisplay;
// manager.SetExpressionDisplay();
Debug.WriteLine($"CalculatorManager.SetExpressionDisplayCallback");
}
private static void SetMemorizedNumbersCallback(IntPtr state, string[] newMemorizedNumbers)
public static void SetMemorizedNumbersCallback(int state, string[] newMemorizedNumbers)
{
var manager = GCHandle.FromIntPtr(state).Target as CalculatorDisplay;
var manager = GCHandle.FromIntPtr((IntPtr)state).Target as CalculatorDisplay;
manager.SetMemorizedNumbers(newMemorizedNumbers.ToList());
Debug.WriteLine($"CalculatorManager.SetMemorizedNumbersCallback({string.Join(";", newMemorizedNumbers)})");
}
private static void SetParenthesisNumberCallback(IntPtr state, int parenthesisCount)
public static void SetParenthesisNumberCallback(int state, int parenthesisCount)
{
var manager = GCHandle.FromIntPtr(state).Target as CalculatorDisplay;
var manager = GCHandle.FromIntPtr((IntPtr)state).Target as CalculatorDisplay;
manager.SetParenthesisNumber(parenthesisCount);
Debug.WriteLine($"CalculatorManager.SetParenthesisNumberCallback({parenthesisCount})");
}
private static void BinaryOperatorReceivedCallback(IntPtr state)
public static void BinaryOperatorReceivedCallback(int state)
{
var manager = GCHandle.FromIntPtr(state).Target as CalculatorDisplay;
var manager = GCHandle.FromIntPtr((IntPtr)state).Target as CalculatorDisplay;
manager.BinaryOperatorReceived();
Debug.WriteLine($"CalculatorManager.BinaryOperatorReceivedCallback");
}
private static void SetPrimaryDisplayCallback(IntPtr state, string displayStringValue, bool isError)
public static void SetPrimaryDisplayCallback(int state, string displayStringValue, bool isError)
{
var manager = GCHandle.FromIntPtr(state).Target as CalculatorDisplay;
var manager = GCHandle.FromIntPtr((IntPtr)state).Target as CalculatorDisplay;
manager.SetPrimaryDisplay(displayStringValue, isError);
Debug.WriteLine($"CalculatorManager.SetPrimaryDisplayCallback({displayStringValue}, {isError})");
}
private static void SetIsInErrorCallback(IntPtr state, bool isError)
public static void SetIsInErrorCallback(int state, bool isError)
{
var manager = GCHandle.FromIntPtr(state).Target as CalculatorDisplay;
var manager = GCHandle.FromIntPtr((IntPtr)state).Target as CalculatorDisplay;
manager.SetIsInError(isError);
Debug.WriteLine($"CalculatorManager.SetIsInErrorCallback({isError})");
}
private static IntPtr GetCEngineStringCallback(IntPtr state, string resourceId)
public static int GetCEngineStringCallback(int state, string resourceId)
{
var provider = GCHandle.FromIntPtr(state).Target as EngineResourceProvider;
var provider = GCHandle.FromIntPtr((IntPtr)state).Target as EngineResourceProvider;
var ret = provider.GetCEngineString(resourceId) ?? "";
var retBytes = Encoding.UTF8.GetBytes(ret);
var retPtr = Marshal.AllocHGlobal(retBytes.Length+1);
var retPtr = Marshal.AllocHGlobal(retBytes.Length + 1);
Marshal.WriteByte(retPtr + retBytes.Length, 0);
Marshal.Copy(retBytes, 0, retPtr, retBytes.Length);
Debug.WriteLine($"CalculatorManager.GetCEngineStringCallback({resourceId},{ret})");
return retPtr;
return (int)retPtr;
}
}
public partial class CalculatorManager : ICalcDisplay
{
private GCHandle _displayCallbackHandle;
private GCHandle _resourceProviderHandle;
private readonly int _nativeManager;
}
}

View file

@ -6,6 +6,8 @@ using System.Collections.Generic;
using System.Diagnostics;
using System.Runtime.InteropServices;
using System.Text;
using Uno;
using Uno.Foundation;
namespace CalculationManager
{
@ -107,6 +109,29 @@ namespace CalculationManager
_displayCallbackHandle = GCHandle.Alloc(displayCallback);
_resourceProviderHandle = GCHandle.Alloc(resourceProvider);
#if __WASM__
var rawPtrs = WebAssemblyRuntime.InvokeJS("CalcManager.registerCallbacks()");
var ptrs = rawPtrs.Split(new[] { ';' }, StringSplitOptions.RemoveEmptyEntries);
var p = new CalculatorManager_CreateParams
{
CalculatorState = GCHandle.ToIntPtr(_displayCallbackHandle),
ResourceState = GCHandle.ToIntPtr(_resourceProviderHandle),
GetCEngineString = (IntPtr)int.Parse(ptrs[0]),
BinaryOperatorReceived = (IntPtr)int.Parse(ptrs[1]),
SetPrimaryDisplay = (IntPtr)int.Parse(ptrs[2]),
SetIsInError = (IntPtr)int.Parse(ptrs[3]),
SetParenthesisNumber = (IntPtr)int.Parse(ptrs[4]),
MaxDigitsReached = (IntPtr)int.Parse(ptrs[5]),
MemoryItemChanged = (IntPtr)int.Parse(ptrs[6]),
OnHistoryItemAdded = (IntPtr)int.Parse(ptrs[7]),
OnNoRightParenAdded = (IntPtr)int.Parse(ptrs[8]),
SetExpressionDisplay = (IntPtr)int.Parse(ptrs[9]),
SetMemorizedNumbers = (IntPtr)int.Parse(ptrs[10]),
};
#else
var p = new CalculatorManager_CreateParams
{
CalculatorState = GCHandle.ToIntPtr(_displayCallbackHandle),
@ -125,7 +150,10 @@ namespace CalculationManager
SetMemorizedNumbers = Marshal.GetFunctionPointerForDelegate(_setMemorizedNumbersCallback),
};
_nativeManager = CalculatorManager_Create(ref p);
#endif
Debug.WriteLine($"-> CalculatorManager_Create");
_nativeManager = NativeDispatch.CalculatorManager_Create(ref p);
Debug.WriteLine($"<- CalculatorManager_Create");
}
public void Reset(bool clearMemory = true) => throw new NotImplementedException();
@ -136,7 +164,7 @@ namespace CalculationManager
{
Debug.WriteLine($"CalculatorManager.SendCommand({command})");
CalculatorManager_SendCommand(_nativeManager, command);
NativeDispatch.CalculatorManager_SendCommand(_nativeManager, command);
}
public List<char> SerializeCommands() => throw new NotImplementedException();

View file

@ -225,6 +225,7 @@
</ItemGroup>
<ItemGroup>
<Content Include="$(MSBuildThisFileDirectory)Assets\CalcMDL2.ttf" />
<Content Include="$(MSBuildThisFileDirectory)Assets\CalcMDL2.woff" />
<Content Include="$(MSBuildThisFileDirectory)Assets\CalculatorAppList.targetsize-96.png" />
<Content Include="$(MSBuildThisFileDirectory)Assets\CalculatorLargeTile.contrast-white_scale-400.png" />
<Content Include="$(MSBuildThisFileDirectory)Assets\CalculatorMedTile.contrast-white_scale-400.png" />

View file

@ -1,10 +1,13 @@
<ResourceDictionary
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:xamarin="http://uno.ui/xamarin"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:Controls="using:CalculatorApp.Controls"
xmlns:common="using:CalculatorApp.Common"
xmlns:converters="using:CalculatorApp.Converters"
xmlns:local="using:CalculatorApp">
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="using:CalculatorApp"
mc:Ignorable="xamarin">
<ResourceDictionary.MergedDictionaries>
<!--
@ -254,7 +257,8 @@
<x:Double x:Key="AppMinWindowHeight">500</x:Double>
<x:Double x:Key="AppMinWindowWidth">320</x:Double>
<FontFamily x:Key="CalculatorFontFamily">ms-appx:///Assets/CalcMDL2.ttf#Calculator MDL2 Assets</FontFamily>
<win:FontFamily x:Key="CalculatorFontFamily">ms-appx:///Assets/CalcMDL2.ttf#Calculator MDL2 Assets</win:FontFamily>
<xamarin:FontFamily x:Key="CalculatorFontFamily">Calculator MDL2 Assets</xamarin:FontFamily>
<x:Double x:Key="SplitViewOpenPaneLength">256</x:Double>
<Thickness x:Key="PivotPortraitThemePadding">0,1,0,0</Thickness>

View file

@ -110,10 +110,13 @@ namespace CalculatorApp.ViewModel
try
{
Console.WriteLine($"ApplicationViewModel.Mode1={mode}");
Mode = mode;
Console.WriteLine($"ApplicationViewModel.Mode2={Mode}");
}
catch (Exception e)
{
Console.WriteLine($"ApplicationViewModel.Mode3={e}");
// TraceLogger.GetInstance().LogPlatformException(__FUNCTIONW__, e);
if (!TryRecoverFromNavigationModeFailure())
{
@ -152,6 +155,7 @@ namespace CalculatorApp.ViewModel
m_CalculatorViewModel = new StandardCalculatorViewModel();
}
m_CalculatorViewModel.SetCalculatorType(m_mode);
Console.WriteLine($"m_CalculatorViewMode = {m_CalculatorViewModel}");
}
else if (NavCategory.IsDateCalculatorViewMode(m_mode))
{

View file

@ -510,6 +510,8 @@ namespace CalculatorApp.ViewModel
public StandardCalculatorViewModel()
{
Console.WriteLine("new StandardCalculatorViewModel()");
m_DisplayValue = "0";
m_DecimalDisplayValue = "0";
m_HexDisplayValue = "0";
@ -571,11 +573,13 @@ namespace CalculatorApp.ViewModel
m_decimalSeparator = LocalizationSettings.GetInstance().GetDecimalSeparator();
#if !__WASM__
if (CoreWindow.GetForCurrentThread() != null)
{
// Must have a CoreWindow to access the resource context.
m_isRtlLanguage = LocalizationService.GetInstance().IsRtlLayout();
}
#endif
IsEditingEnabled = false;
IsUnaryOperatorEnabled = true;

View file

@ -75,6 +75,10 @@ namespace CalculatorApp
protected override void OnNavigatedTo(NavigationEventArgs e)
{
initialized = true;
NavView.DataContext = m_model;
if (m_model.CalculatorViewModel != null)
{
m_model.CalculatorViewModel.HistoryVM.ClearHistory();
@ -102,6 +106,12 @@ namespace CalculatorApp
}
m_model.Initialize(initialMode);
EnsureCalculator();
m_calculator.DataContext = m_model.CalculatorViewModel;
Initialize();
}
void WindowSizeChanged(object sender, Windows.UI.Core.WindowSizeChangedEventArgs e)
@ -229,6 +239,15 @@ namespace CalculatorApp
}
void OnPageLoaded(object sender, RoutedEventArgs args)
{
Initialize();
}
bool initialized = false;
private void Initialize()
{
// UNO TODO Check for Initialized (Load/OnNavigatedTo order is different)
if (initialized)
{
if (m_converter == null && m_calculator == null && m_dateCalculator == null)
{
@ -237,6 +256,7 @@ namespace CalculatorApp
m_model.CalculatorViewModel.IsStandard = true;
}
Windows.UI.Xaml.Window.Current.SizeChanged += WindowSizeChanged;
UpdateViewState();
@ -245,7 +265,8 @@ namespace CalculatorApp
// Delay load things later when we get a chance.
this.Dispatcher.RunAsync(
CoreDispatcherPriority.Normal, () => {
CoreDispatcherPriority.Normal, () =>
{
// UNO TODO
//if (TraceLogger.GetInstance().UpdateWindowIdLog(ApplicationView.GetApplicationViewIdForWindow(CoreWindow.GetForCurrentThread())))
//{
@ -255,6 +276,7 @@ namespace CalculatorApp
//}
});
}
}
void SetDefaultFocus()
{

View file

@ -1,4 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<?xml version="1.0" encoding="utf-8"?>
<Project Sdk="Microsoft.NET.Sdk.Web">
<PropertyGroup>
<OutputType>Exe</OutputType>
@ -6,15 +6,18 @@
<WasmHead>true</WasmHead>
<DefineConstants>$(DefineConstants);__WASM__</DefineConstants>
<NoWarn>NU1701</NoWarn>
<WasmShellGenerateCompressedFiles Condition="'$(Configuration)'=='DEBUG'">false</WasmShellGenerateCompressedFiles>
<WasmShellGenerateCompressedFiles Condition="'$(Configuration)'=='Debug'">false</WasmShellGenerateCompressedFiles>
<!--<BuildingInsideUnoSourceGenerator>true</BuildingInsideUnoSourceGenerator>-->
<MonoRuntimeDebuggerEnabled Condition="'$(Configuration)'=='Debug'">true</MonoRuntimeDebuggerEnabled>
<MonoWasmRuntimeConfiguration>release-dynamic</MonoWasmRuntimeConfiguration>
<MonoWasmSDKUri>C:\Users\jerome.laban\Downloads\mono-wasm-4d023b6bf84.zip</MonoWasmSDKUri>
</PropertyGroup>
<ItemGroup>
<Content Include="..\Calculator.UWP\Assets\*.png" Link="Assets\%(FileName)%(Extension)" />
</ItemGroup>
<ItemGroup>
<EmbeddedResource Include="WasmCSS\Fonts.css" />
<EmbeddedResource Include="WasmScripts\AppManifest.js" />
<EmbeddedResource Include="WasmScripts\*.js" />
</ItemGroup>
<ItemGroup>
<LinkerDescriptor Include="LinkerConfig.xml" />
@ -27,6 +30,7 @@
You can safely remove this ItemGroup completely.
-->
<Compile Remove="Program.cs" />
<None Remove="WasmScripts\CalcManager.js" />
<Compile Include="Program.cs" />
<Content Include="LinkerConfig.xml" />
</ItemGroup>
@ -37,5 +41,8 @@
<PackageReference Include="Uno.Wasm.Bootstrap" Version="1.0.0-dev.269" />
<DotNetCliToolReference Include="Uno.Wasm.Bootstrap.Cli" Version="1.0.0-dev.269" />
</ItemGroup>
<ItemGroup>
<Content Include="..\CalcManager\CalcManager.wasm" Link="CalcManager.wasm" />
</ItemGroup>
<Import Project="..\Calculator.Shared\Calculator.Shared.projitems" Label="Shared" Condition="Exists('..\Calculator.Shared\Calculator.Shared.projitems')" />
</Project>

View file

@ -12,6 +12,8 @@ namespace WindowsCalculator.Wasm
static void Main(string[] args)
{
Console.WriteLine("Program.Main");
ConfigureFilters(LogExtensionPoint.AmbientLoggerFactory);
Windows.UI.Xaml.Application.Start(_ => _app = new App());

File diff suppressed because one or more lines are too long

View file

@ -0,0 +1,44 @@
class CalcManager {
static registerCallbacks() {
var _getCEngineStringCallback = Module.mono_bind_static_method("[Calculator.Wasm] CalculationManager.NativeDispatch:GetCEngineStringCallback");
var _binaryOperatorReceivedCallback = Module.mono_bind_static_method("[Calculator.Wasm] CalculationManager.NativeDispatch:BinaryOperatorReceivedCallback");
var _setPrimaryDisplayCallback = Module.mono_bind_static_method("[Calculator.Wasm] CalculationManager.NativeDispatch:SetPrimaryDisplayCallback");
var _setIsInErrorCallback = Module.mono_bind_static_method("[Calculator.Wasm] CalculationManager.NativeDispatch:SetIsInErrorCallback");
var _setParenthesisNumberCallback = Module.mono_bind_static_method("[Calculator.Wasm] CalculationManager.NativeDispatch:SetParenthesisNumberCallback");
var _maxDigitsReachedCallback = Module.mono_bind_static_method("[Calculator.Wasm] CalculationManager.NativeDispatch:MaxDigitsReachedCallback");
var _memoryItemChangedCallback = Module.mono_bind_static_method("[Calculator.Wasm] CalculationManager.NativeDispatch:MemoryItemChangedCallback");
var _onHistoryItemAddedCallback = Module.mono_bind_static_method("[Calculator.Wasm] CalculationManager.NativeDispatch:OnHistoryItemAddedCallback");
var _onNoRightParenAddedCallback = Module.mono_bind_static_method("[Calculator.Wasm] CalculationManager.NativeDispatch:OnNoRightParenAddedCallback");
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 fBinaryOperatorReceivedCallback = Module.addFunction((state) => _binaryOperatorReceivedCallback(state), 'vi');
var fSetPrimaryDisplayCallback = Module.addFunction((state, displayStringValue, isError) => _setPrimaryDisplayCallback(state, Module.UTF8ToString(displayStringValue), isError), 'viii');
var fSetIsInErrorCallback = Module.addFunction((state, isError) => _setIsInErrorCallback(state, isError), 'vii');
var fSetParenthesisNumberCallback = Module.addFunction((state, parenthesisCount) => _setParenthesisNumberCallback(state, parenthesisCount), 'vii');
var fMaxDigitsReachedCallback = Module.addFunction((state) => _maxDigitsReachedCallback(state), 'vii');
var fMemoryItemChangedCallback = Module.addFunction((state, indexOfMemory) => _memoryItemChangedCallback(state, indexOfMemory), 'vii');
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 ret = `${fGetCEngineStringCallback};`
+ `${fBinaryOperatorReceivedCallback};`
+ `${fSetPrimaryDisplayCallback};`
+ `${fSetIsInErrorCallback};`
+ `${fSetParenthesisNumberCallback};`
+ `${fMaxDigitsReachedCallback};`
+ `${fMemoryItemChangedCallback};`
+ `${fOnHistoryItemAddedCallback};`
+ `${fOnNoRightParenAddedCallback};`
+ `${fSetExpressionDisplayCallback};`
+ `${fSetMemorizedNumbersCallback};`
;
return ret;
}
}