Skip to content

Commit

Permalink
Project updates
Browse files Browse the repository at this point in the history
- Refactor to use JS module style
- Improved JS interp
- Added samples for communicating changes
  • Loading branch information
AshleighAdams committed Jul 12, 2023
1 parent 3724e43 commit 71db8e2
Show file tree
Hide file tree
Showing 7 changed files with 300 additions and 75 deletions.
61 changes: 48 additions & 13 deletions Program.cs
Original file line number Diff line number Diff line change
@@ -1,20 +1,11 @@
using System;
using System.Runtime.InteropServices;
using System.Runtime.InteropServices.JavaScript;

using Microsoft.JSInterop.WebAssembly;
using Evergine.Bindings.OpenGL;
using Microsoft.JSInterop;

namespace WasmTest;

internal class MyRuntime : WebAssemblyJSRuntime
{
public MyRuntime()
{
}
}

[System.Diagnostics.CodeAnalysis.SuppressMessage("Globalization", "CA2101:Specify marshaling for P/Invoke string arguments", Justification = "Incorrect warning generated")]
internal static class EGL
{
public const string LibEgl = "libEGL";
Expand Down Expand Up @@ -105,6 +96,52 @@ internal static class Emscripten
internal static extern unsafe void RequestAnimationFrameLoop(void* f, nint userDataPtr);
}

internal static partial class Interop
{
[JSImport("initialize", "main.js")]
public static partial void Initialize();

[JSExport]

Check warning on line 104 in Program.cs

View workflow job for this annotation

GitHub Actions / Build

This call site is reachable on all platforms. 'JSExportAttribute' is only supported on: 'browser'.
public static void OnKeyDown(bool shift, bool ctrl, bool alt, bool repeat, int code)
{
}

[JSExport]

Check warning on line 109 in Program.cs

View workflow job for this annotation

GitHub Actions / Build

This call site is reachable on all platforms. 'JSExportAttribute' is only supported on: 'browser'.
public static void OnKeyUp(bool shift, bool ctrl, bool alt, int code)
{
}

[JSExport]

Check warning on line 114 in Program.cs

View workflow job for this annotation

GitHub Actions / Build

This call site is reachable on all platforms. 'JSExportAttribute' is only supported on: 'browser'.
public static void OnMouseMove(float x, float y)
{
}

[JSExport]

Check warning on line 119 in Program.cs

View workflow job for this annotation

GitHub Actions / Build

This call site is reachable on all platforms. 'JSExportAttribute' is only supported on: 'browser'.
public static void OnMouseDown(bool shift, bool ctrl, bool alt, int button)
{
}

[JSExport]

Check warning on line 124 in Program.cs

View workflow job for this annotation

GitHub Actions / Build

This call site is reachable on all platforms. 'JSExportAttribute' is only supported on: 'browser'.
public static void OnMouseUp(bool shift, bool ctrl, bool alt, int button)
{
}

[JSExport]

Check warning on line 129 in Program.cs

View workflow job for this annotation

GitHub Actions / Build

This call site is reachable on all platforms. 'JSExportAttribute' is only supported on: 'browser'.
public static void OnCanvasResize(float width, float height, float devicePixelRatio)
{
}

[JSExport]

Check warning on line 134 in Program.cs

View workflow job for this annotation

GitHub Actions / Build

This call site is reachable on all platforms. 'JSExportAttribute' is only supported on: 'browser'.
public static void SetRootUri(string uri)
{
}

[JSExport]

Check warning on line 139 in Program.cs

View workflow job for this annotation

GitHub Actions / Build

This call site is reachable on all platforms. 'JSExportAttribute' is only supported on: 'browser'.
public static void AddLocale(string locale)
{
}
}

public static class Test
{
[UnmanagedCallersOnly]
Expand Down Expand Up @@ -169,9 +206,7 @@ public static int Main(string[] args)

GL.LoadAllFunctions(EGL.GetProcAddress);

// https://github.com/emepetres/dotnet-wasm-sample/blob/main/src/jsinteraction/wasm/WebAssemblyRuntime.cs
using var runtime = new MyRuntime();
runtime.InvokeVoid("initialize");
Interop.Initialize();

unsafe
{
Expand Down
22 changes: 3 additions & 19 deletions Properties/launchSettings.json
Original file line number Diff line number Diff line change
@@ -1,29 +1,13 @@
{
"iisSettings": {
"windowsAuthentication": false,
"anonymousAuthentication": true,
"iisExpress": {
"applicationUrl": "http://localhost:49458/",
"sslPort": 44384
}
},
"profiles": {
"WasmTest": {
"commandName": "Project",
"launchBrowser": true,
"inspectUri": "{wsProtocol}://{url.hostname}:{url.port}/_framework/debug/ws-proxy?browser={browserInspectUri}",
"applicationUrl": "https://localhost:5001;http://localhost:5000",
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development"
}
},
"IIS Express": {
"commandName": "IISExpress",
"launchBrowser": true,
"inspectUri": "{wsProtocol}://{url.hostname}:{url.port}/_framework/debug/ws-proxy?browser={browserInspectUri}",
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development"
}
},
"applicationUrl": "https://localhost:7010;http://localhost:5076",
"inspectUri": "{wsProtocol}://{url.hostname}:{url.port}/debug?browser={browserInspectUri}"
}
}
}
40 changes: 26 additions & 14 deletions WasmTest.csproj
Original file line number Diff line number Diff line change
@@ -1,37 +1,49 @@
<Project Sdk="Microsoft.NET.Sdk.BlazorWebAssembly">
<Project Sdk="Microsoft.NET.Sdk">
<!-- https://github.com/emepetres/dotnet-wasm-sample/blob/main/src/console-native/Wasm.ConsoleNative.Sample.csproj -->
<PropertyGroup>
<TargetFramework>net7.0</TargetFramework>
<LangVersion>11</LangVersion>
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
<EmccFlags>-s FULL_ES3=1 -lopenal -lGL</EmccFlags>
<OutputType>Exe</OutputType>
<RuntimeIdentifier>browser-wasm</RuntimeIdentifier>
<NoWarn>$(NoWarn);RCS1090</NoWarn>
<InvariantGlobalization>true</InvariantGlobalization>
<!--<EmccFlags>-s MAX_WEBGL_VERSION=2</EmccFlags>-->
<EmccFlags>-s FULL_ES3=1 -lopenal -lGL -s</EmccFlags>
<WasmMainJSPath>main.js</WasmMainJSPath>
</PropertyGroup>

<PropertyGroup>
<PublishTrimmed Condition="'$(Configuration)' == 'Debug'">false</PublishTrimmed>
<PublishTrimmed Condition="'$(Configuration)' == 'Release'">true</PublishTrimmed>
<BlazorEnableCompression Condition="'$(Configuration)' == 'Debug'">false</BlazorEnableCompression>
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
<WasmBuildNative>true</WasmBuildNative>
<RunAOTCompilation>true</RunAOTCompilation>
<!--<AOTMode>LLVMOnly</AOTMode> -->
<!-- Disable SIMD support as it's prerelease only on Safari -->
<!--<WasmEnableSIMD>true</WasmEnableSIMD>-->
<AOTMode>AotInterp</AOTMode>
</PropertyGroup>

<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|AnyCPU'">
<DefineConstants>DEBUG;TRACE</DefineConstants>
</PropertyGroup>

<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|AnyCPU'">
<DebugType>none</DebugType>
<DebugSymbols>false</DebugSymbols>
</PropertyGroup>

<!--<ItemGroup>
<WasmExtraFilesToDeploy Include="$(MSBuildThisFileDirectory)Assets\**" TargetPath="Assets/%(RecursiveDir)%(Filename)%(Extension)" />
</ItemGroup>-->

<ItemGroup>
<NativeFileReference Include="libEGL.c" ScanForPInvokes="true" />
<NativeFileReference Include="openal32.c" ScanForPInvokes="true" />
<NativeFileReference Include="emscripten.c" ScanForPInvokes="true" />
</ItemGroup>

<ItemGroup>
<TrimmerRootAssembly Include="Microsoft.AspNetCore.Components.WebAssembly" />
</ItemGroup>
<WasmExtraFilesToDeploy Include="index.html" />
<WasmExtraFilesToDeploy Include="main.js" />

<ItemGroup>
<PackageReference Include="Verlite.MsBuild" Version="2.4.0" PrivateAssets="All" />
<PackageReference Include="Microsoft.AspNetCore.Components.WebAssembly" Version="7.0.8" />
<PackageReference Include="Microsoft.AspNetCore.Components.WebAssembly.DevServer" Version="7.0.8" PrivateAssets="all" />
<PackageReference Include="Evergine.Bindings.OpenGL" Version="2023.2.19.1" />
</ItemGroup>

Expand Down
54 changes: 54 additions & 0 deletions index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no" />
<link rel="modulepreload" href="./main.js" />
<link rel="modulepreload" href="./dotnet.js" />
<title>dotnet + WebGL = 💖</title>
<style>
body
{
margin: 0;
background-color: black;
overflow: hidden;
}

canvas#canvas
{
width: 100vw;
height: 100vh;
outline: none;
margin: 0;
position: absolute;
left: 50%;
top: 50%;
transform: translate(-50%, -50%);
}

@media (min-aspect-ratio: 16/9)
{
canvas#canvas
{
height: 100vh;
width: calc(100vh * (16 / 9));
}
}

@media (max-aspect-ratio: 4/3)
{
canvas#canvas
{
width: 100vw;
height: calc(100vw / (4 / 3));
}
}
</style>
</head>
<body>
<canvas id="canvas" width="16" height="9">
</canvas>

<script type="module" src="./main.js"></script>
</body>
</html>
158 changes: 158 additions & 0 deletions main.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,158 @@
import { dotnet } from './dotnet.js'

const { setModuleImports, getAssemblyExports, getConfig } = await dotnet
.withDiagnosticTracing(false)
.withApplicationArgumentsFromQuery()
.create();

const config = getConfig();
const exports = await getAssemblyExports(config.mainAssemblyName);
const interop = exports.WasmTest.Interop;

var canvas = globalThis.document.getElementById("canvas");
dotnet.instance.Module["canvas"] = canvas;

setModuleImports("main.js", {
initialize: () => {

var checkCanvasResize = (dispatch) => {
var devicePixelRatio = window.devicePixelRatio || 1.0;
var displayWidth = canvas.clientWidth * devicePixelRatio;
var displayHeight = canvas.clientHeight * devicePixelRatio;

if (canvas.width != displayWidth || canvas.height != displayHeight) {
canvas.width = displayWidth;
canvas.height = displayHeight;
dispatch = true;
}

if (dispatch)
interop.OnCanvasResize(displayWidth, displayHeight, devicePixelRatio);
}

function checkCanvasResizeFrame() {
checkCanvasResize(false);
requestAnimationFrame(checkCanvasResizeFrame);
}

var keyDown = (e) => {
e.stopPropagation();
var shift = e.shiftKey;
var ctrl = e.ctrlKey;
var alt = e.altKey;
var repeat = e.repeat;
var code = e.keyCode;

interop.OnKeyDown(shift, ctrl, alt, repeat, code);
}

var keyUp = (e) => {
e.stopPropagation();
var shift = e.shiftKey;
var ctrl = e.ctrlKey;
var alt = e.altKey;
var code = e.keyCode;

interop.OnKeyUp(shift, ctrl, alt, code);
}

var mouseMove = (e) => {
var x = e.offsetX;
var y = e.offsetY;
interop.OnMouseMove(x, y);
}

var mouseDown = (e) => {
var shift = e.shiftKey;
var ctrl = e.ctrlKey;
var alt = e.altKey;
var button = e.button;

interop.OnMouseDown(shift, ctrl, alt, button);
}

var mouseUp = (e) => {
var shift = e.shiftKey;
var ctrl = e.ctrlKey;
var alt = e.altKey;
var button = e.button;

interop.OnMouseUp(shift, ctrl, alt, button);
}

var shouldIgnore = (e) => {
e.preventDefault();
return e.touches.length > 1 || e.type == "touchend" && e.touches.length > 0;
}

var touchStart = (e) => {
if (shouldIgnore(e))
return;

var shift = e.shiftKey;
var ctrl = e.ctrlKey;
var alt = e.altKey;
var button = 0;
var touch = e.changedTouches[0];
var bcr = e.target.getBoundingClientRect();
var x = touch.clientX - bcr.x;
var y = touch.clientY - bcr.y;

interop.OnMouseMove(x, y);
interop.OnMouseDown(shift, ctrl, alt, button);
}

var touchMove = (e) => {
if (shouldIgnore(e))
return;

var touch = e.changedTouches[0];
var bcr = e.target.getBoundingClientRect();
var x = touch.clientX - bcr.x;
var y = touch.clientY - bcr.y;

interop.OnMouseMove(x, y);
}

var touchEnd = (e) => {
if (shouldIgnore(e))
return;

var shift = e.shiftKey;
var ctrl = e.ctrlKey;
var alt = e.altKey;
var button = 0;
var touch = e.changedTouches[0];
var bcr = e.target.getBoundingClientRect();
var x = touch.clientX - bcr.x;
var y = touch.clientY - bcr.y;

interop.OnMouseMove(x, y);
interop.OnMouseUp(shift, ctrl, alt, button);
}

//canvas.addEventListener("contextmenu", (e) => e.preventDefault(), false);
canvas.addEventListener("keydown", keyDown, false);
canvas.addEventListener("keyup", keyUp, false);
canvas.addEventListener("mousemove", mouseMove, false);
canvas.addEventListener("mousedown", mouseDown, false);
canvas.addEventListener("mouseup", mouseUp, false);
canvas.addEventListener("touchstart", touchStart, false);
canvas.addEventListener("touchmove", touchMove, false);
canvas.addEventListener("touchend", touchEnd, false);
checkCanvasResize(true);
checkCanvasResizeFrame();

canvas.tabIndex = 1000;

interop.SetRootUri(window.location.toString());

var langs = navigator.languages || [];
for (var i = 0; i < langs.length; i++)
interop.AddLocale(langs[i]);
interop.AddLocale(navigator.language);
interop.AddLocale(navigator.userLanguage);
}
});

await dotnet.run();
Loading

0 comments on commit 71db8e2

Please sign in to comment.