Skip to content

Commit

Permalink
Back to old invokeUnmarshalled call, no callback, no serialization (#105
Browse files Browse the repository at this point in the history
)

* Fixes #104 - Back to old invokeUnmarshalled call, no callback, no serialization

* Remove unused class

* Remove unused class

* Remove unused js members

* Update setup extensions with fail early.Removed console outputs. Demo projects yield and v2.1. version up

* Update readme
  • Loading branch information
Tewr authored Feb 2, 2020
1 parent 4d2ffb9 commit 476d6df
Show file tree
Hide file tree
Showing 15 changed files with 231 additions and 179 deletions.
37 changes: 19 additions & 18 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -119,40 +119,41 @@ The code for views looks the same for both [client](src/Demo/Blazor.FileReader.W
```

### Version notes
Version ```1.2.0.19363``` fixes a bug in how the offset parameter is interpreted - now represents target buffer offset, not source buffer offset. The setup option ```InitializeOnFirstCall``` now defaults to ```true```.

Version ```1.1.0.19274``` adds a parameter to ```IFileReaderRef.RegisterDropEventsAsync``` for specifying additive drag n drop: When called with parameter set to true, will not reset file list of drop target (see [demo](https://github.com/Tewr/BlazorFileReader/blob/821a8307743d23375642bf9db505d3377dcdf8f3/src/Demo/Blazor.FileReader.Demo.Common/DragnDropCommon.razor#L72) for usage). Thanks [@DNF-SaS](https://github.com/DNF-Sas) for the [feature suggestion](https://github.com/Tewr/BlazorFileReader/issues/91).
Version ```1.3.0.20033``` adds compatibility with Blazor 3.2 (CSB / Wasm). Attention, ```ReadAsync``` is no longer fulla async and may run on the UI thread. If you are using a progress bar or similar progress reporting§ it might be necessary to yield back to the renderer. See the demo project for an example using ```await Task.Delay(1);```.

Version ```1.0.0.19267``` adds support for ```v3.0.100```
<details><summary>Version ```1.2.0.19363```</summary> fixes a bug in how the offset parameter is interpreted - now represents target buffer offset, not source buffer offset. The setup option ```InitializeOnFirstCall``` now defaults to ```true```.</details>

Version ```0.16.0.19262``` fixes [a packaging issue](https://github.com/Tewr/BlazorFileReader/issues/55).
<details><summary>Version ```1.1.0.19274```</summary> adds a parameter to ```IFileReaderRef.RegisterDropEventsAsync``` for specifying additive drag n drop: When called with parameter set to true, will not reset file list of drop target (see [demo](https://github.com/Tewr/BlazorFileReader/blob/821a8307743d23375642bf9db505d3377dcdf8f3/src/Demo/Blazor.FileReader.Demo.Common/DragnDropCommon.razor#L72) for usage). Thanks [@DNF-SaS](https://github.com/DNF-Sas) for the [feature suggestion](https://github.com/Tewr/BlazorFileReader/issues/91).</details>
Version ```0.16.0.19261``` adds support for ```v3.0.100-rc1-014190```
<details><summary>Version ```1.0.0.19267```</summary> adds support for ```v3.0.100```</details>

Version ```0.15.0.19242``` adds support for ```v3.0.0-preview9-014004```. Also fixes [a minor packaging issue](https://github.com/Tewr/BlazorFileReader/issues/55). New API: [IBase64Stream](https://github.com/Tewr/BlazorFileReader/blob/d9cdea5d954eeac6f3ba2a99ec5dbc9181bc23de/src/Blazor.FileReader/FileReaderRef.cs#L50), for optimizing third-party cloud uploads (data exposed as raw base64 strings). Mostly interesting for server-side deployments.
<details><summary>Version ```0.16.0.19262```</summary> fixes [a packaging issue](https://github.com/Tewr/BlazorFileReader/issues/55).</details>
Version ```0.14.19242``` fixes [a possible race condition for server-side initialization](https://github.com/Tewr/BlazorFileReader/issues/71).
<details><summary>Version ```0.16.0.19261```</summary> adds support for ```v3.0.100-rc1-014190```</details>

Version ```0.14.19226``` adds support for sdk ```3.0.0-preview8-013656```. Adds shared Buffer back again for WASM, this can be activated by setting the ```UseWasmSharedBuffer``` option to true (recommended).
<details><summary>Version ```0.15.0.19242```</summary> adds support for ```v3.0.0-preview9-014004```. Also fixes [a minor packaging issue](https://github.com/Tewr/BlazorFileReader/issues/55). New API: [IBase64Stream](https://github.com/Tewr/BlazorFileReader/blob/d9cdea5d954eeac6f3ba2a99ec5dbc9181bc23de/src/Blazor.FileReader/FileReaderRef.cs#L50), for optimizing third-party cloud uploads (data exposed as raw base64 strings). Mostly interesting for server-side deployments.</details>
Version ```0.13.19207``` Fixes a regression with the ```ClearValue``` method and adds some essential events to the drag and drop api.
<details><summary>Version ```0.14.19242```</summary> fixes [a possible race condition for server-side initialization](https://github.com/Tewr/BlazorFileReader/issues/71).</details>
Version ```0.13.19206``` adds support for sdk ```3.0.0-preview7.19365.7```. New feature: Drag and drop (contribution by [@catlan](https://github.com/catlan))
<details><summary>Version ```0.14.19226```</summary> adds support for sdk ```3.0.0-preview8-013656```. Adds shared Buffer back again for WASM, this can be activated by setting the ```UseWasmSharedBuffer``` option to true (recommended).</details>

Version ```0.12.19186``` fixes an issue with server-side setup which was only visible when having multiple users.
<details><summary>Version ```0.13.19207``</summary>` Fixes a regression with the ```ClearValue``` method and adds some essential events to the drag and drop api.</details>

Version ```0.12.19168``` adds support for sdk ```3.0.0-preview6.19307.2```, and several issues are resolved with this release, notably meticulous setup and issues with buffer size for server-side projects. Also, the Wasm helper package has been deprecated.
<details><summary>Version ```0.13.19206```</summary> adds support for sdk ```3.0.0-preview7.19365.7```. New feature: Drag and drop (contribution by [@catlan](https://github.com/catlan))</details>
Version ```0.11.0``` adds support for sdk ```3.0.0-preview5-19227-01```. It also introduces a tiny feature: The ```IFileReaderRef.ClearValue()``` method, used to clear the value of a referenced file input. Also, fixes a bug in Edge and a package issue.
<details><summary>Version ```0.12.19186```</summary> fixes an issue with server-side setup which was only visible when having multiple users.</details>

Version ```0.10.0``` adds support for sdk ```v3.0.0-preview-4-19216-03```
<details><summary>Version ```0.12.19168```</summary> adds support for sdk ```3.0.0-preview6.19307.2```, and several issues are resolved with this release, notably meticulous setup and issues with buffer size for server-side projects. Also, the Wasm helper package has been deprecated.</details>

Versions ```0.9.0``` introduces a small helper-package for the IoC setup of Wasm, injecting an implementation of ```IInvokeUnmarshalled```.
<details><summary>Version ```0.11.0```</summary> adds support for sdk ```3.0.0-preview5-19227-01```. It also introduces a tiny feature: The ```IFileReaderRef.ClearValue()``` method, used to clear the value of a referenced file input. Also, fixes a bug in Edge and a package issue.</details>

Versions ```0.8.0``` requires copy-paste implementation of ```IInvokeUnmarshalled```.
<details><summary>Version ```0.10.0```</summary> adds support for sdk ```v3.0.0-preview-4-19216-03```</details>

Versions previous to ```0.7.1``` did not support server-side Blazor and would throw ```[System.PlatformNotSupportedException] Requires MonoWebAssemblyJSRuntime as the JSRuntime```.
<details><summary>Versions ```0.9.0```</summary> introduces a small helper-package for the IoC setup of Wasm, injecting an implementation of ```IInvokeUnmarshalled```.</details>

Versions previous to ```0.5.1``` wrapped the input element in a Blazor Component, this has been removed for better configurability and general lack of value.
<details><summary>Versions ```0.8.0```</summary> requires copy-paste implementation of ```IInvokeUnmarshalled```.</details>

<details><summary>Versions previous to ```0.7.1```</summary> did not support server-side Blazor and would throw ```[System.PlatformNotSupportedException] Requires MonoWebAssemblyJSRuntime as the JSRuntime```.</details>

<details><summary>Versions previous to ```0.5.1```</summary> wrapped the input element in a Blazor Component, this has been removed for better configurability and general lack of value.</details>
2 changes: 1 addition & 1 deletion src/Blazor.FileReader/Blazor.FileReader.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
<TypeScriptToolsVersion>2.8</TypeScriptToolsVersion>
<LangVersion>latest</LangVersion>
<GeneratePackageOnBuild>false</GeneratePackageOnBuild>
<Version>1.2.0.19363</Version>
<Version>1.3.0.20033</Version>
<Authors>Tor Knutsson (Tewr)</Authors>
<PackageProjectUrl>https://github.com/Tewr/BlazorFileReader</PackageProjectUrl>
<RepositoryUrl>https://github.com/Tewr/BlazorFileReader</RepositoryUrl>
Expand Down
38 changes: 10 additions & 28 deletions src/Blazor.FileReader/FileReaderJsInterop.cs
Original file line number Diff line number Diff line change
Expand Up @@ -16,10 +16,6 @@ internal partial class FileReaderJsInterop
private readonly bool _needsInitialization = false;
private readonly IFileReaderServiceOptions _options;

private static readonly object _bufferIdLock = new object();
private static readonly IDictionary<int, byte[]> buffers = new Dictionary<int, byte[]>();
private static int _nextBufferId = 0;

internal IJSRuntime CurrentJSRuntime { get; }

public FileReaderJsInterop(IJSRuntime jsRuntime, IFileReaderServiceOptions options)
Expand Down Expand Up @@ -133,22 +129,17 @@ private async Task<int> ReadFileUnmarshalledAsync(
int fileRef, byte[] buffer, long position, long bufferOffset, int count,
CancellationToken cancellationToken)
{
var callBackId = 0;
lock (_bufferIdLock)
{
callBackId = _nextBufferId++;
buffers.Add(callBackId, buffer);
}
var bytesRead = await CurrentJSRuntime.InvokeAsync<long>(

var bytesRead = await Task.Run(() => CurrentJSRuntime.InvokeUnmarshalled<ReadFileParams, int>(
$"FileReaderComponent.ReadFileUnmarshalledAsync",
new { position, count, fileRef, callBackId, bufferOffset });

lock (_bufferIdLock)
{
buffers.Remove(callBackId);
}

return (int)bytesRead;
new ReadFileParams {
Buffer = buffer,
BufferOffset = bufferOffset,
Count = count,
FileRef = fileRef,
Position = position
}));
return bytesRead;
}

private async Task Initialize()
Expand Down Expand Up @@ -196,14 +187,5 @@ private async Task<T> ExecuteRawScriptAsync<T>(string scriptContent)
var bootStrapScript = $"(function(){{var d = document; var s = d.createElement('script'); s.src={blob}; s.async=false; d.head.appendChild(s); d.head.removeChild(s);}})();";
return await CurrentJSRuntime.InvokeAsync<T>("eval", bootStrapScript);
}

/// <remarks>
/// While it may be tempting to remove this method because it appears to be unused,
/// this method is referenced by client code and must persist.
/// </remarks>
#pragma warning disable IDE0051 // Remove unused private members
private static byte[] GetStreamBuffer(string bufferId) => buffers[int.Parse(bufferId)];
#pragma warning restore IDE0051 // Remove unused private members

}
}
56 changes: 56 additions & 0 deletions src/Blazor.FileReader/IJSRuntimeExtensions.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
using Microsoft.JSInterop;
using System;
using System.Collections.Generic;
using System.Reflection;
using System.Text;

namespace Blazor.FileReader
{
internal static class IJSRuntimeExtensions
{
private readonly static Type WebAssemblyJSRuntime
= Type.GetType("Mono.WebAssembly.Interop.MonoWebAssemblyJSRuntime, Mono.WebAssembly.Interop");

private readonly static MethodInfo _invokeUnmarshalled = GetInvokeUnmarshalled();
private readonly static Dictionary<string, MethodInfo> _genericinvokeUnmarshalledMethods
= new Dictionary<string, MethodInfo>();

public static bool IsInvokeUnmarshalledSupported()
{
return _invokeUnmarshalled != null;
}

public static TReturn InvokeUnmarshalled<TParam, TReturn>(this IJSRuntime jsRuntime, string methodName, TParam parameter)
{
var cacheKey = $"{typeof(TReturn)}|{typeof(TParam)}";
if (!_genericinvokeUnmarshalledMethods.TryGetValue(cacheKey, out var genericMethodInfo))
{
genericMethodInfo = _invokeUnmarshalled.MakeGenericMethod(typeof(TParam), typeof(TReturn));
_genericinvokeUnmarshalledMethods.Add(cacheKey, genericMethodInfo);
}

return (TReturn)genericMethodInfo.Invoke(jsRuntime, new object[] { methodName, parameter });
}

private static MethodInfo GetInvokeUnmarshalled()
{
if (WebAssemblyJSRuntime == null)
{
System.Diagnostics.Debug.WriteLine($"{nameof(IJSRuntimeExtensions)} : MonoWebAssemblyJSRuntime not found.");
return null;
}

foreach (var methodInfo in WebAssemblyJSRuntime.GetMethods())
{
if (methodInfo.Name == "InvokeUnmarshalled" && methodInfo.GetParameters().Length == 2)
{
return methodInfo;
}
}

System.Diagnostics.Debug.WriteLine($"{nameof(IJSRuntimeExtensions)} : MonoWebAssemblyJSRuntime.InvokeUnmarshalled method not found.");

return null;
}
}
}
21 changes: 21 additions & 0 deletions src/Blazor.FileReader/ReadFileParams.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
using System.Runtime.InteropServices;

namespace Blazor.FileReader
{

[StructLayout(LayoutKind.Explicit)]
struct ReadFileParams
{
[FieldOffset(0)]
public byte[] Buffer;
[FieldOffset(4)]
internal long BufferOffset;
[FieldOffset(12)]
internal int Count;
[FieldOffset(16)]
internal int FileRef;
[FieldOffset(20)]
public long Position;
}

}
4 changes: 4 additions & 0 deletions src/Blazor.FileReader/SetupExtension.cs
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,10 @@ public static IServiceCollection AddFileReaderService(this IServiceCollection se
services.AddSingleton<IFileReaderServiceOptions, FileReaderServiceOptions>(si => {
var o = new FileReaderServiceOptions();
setOptions(o);
if (o.UseWasmSharedBuffer && !IJSRuntimeExtensions.IsInvokeUnmarshalledSupported())
{
throw new PlatformNotSupportedException($"{nameof(o.UseWasmSharedBuffer)}=true is not supported on this platform.");
}
return o;
});

Expand Down
Loading

0 comments on commit 476d6df

Please sign in to comment.