public static JavaScriptValue CreateArrayBuffer(this IJSValueService valueService, JSArrayBuffer source) { IContextSwitchService switchService = valueService.CurrentNode.GetService <IRuntimeService>().InternalContextSwitchService; return(switchService.With <JavaScriptValue>(() => { if (source.JSSource.IsValid) { return source.JSSource; } switch (source.BufferSource) { case SharedBufferSourceEnum.CreateByJavascript: throw new InvalidOperationException("invalid source array buffer"); //create by javascript should already have JavaScriptValue assigned case SharedBufferSourceEnum.CreateInJavascript: { JavaScriptValue result = JavaScriptValue.CreateArrayBuffer((uint)source.Size); source.SetJSSource(result, switchService); //hold the varient var data = JavaScriptValue.GetArrayBufferStorage(result, out uint bufferSize); source.InitWindow(data, false); source.InitBeforeConvert(source.Buffer); return result; } case SharedBufferSourceEnum.CreateByDotnet: case SharedBufferSourceEnum.CreateByExternal: { var result = JavaScriptValue.CreateExternalArrayBuffer(source.Buffer.Handle, (uint)source.Buffer.ByteLength, null, IntPtr.Zero); //do not handle GC callback, user should control the varient life cycle source.SetJSSource(result, switchService); //hold the varient return result; } default: throw new ArgumentOutOfRangeException("Invalid BufferSource property in JSArryBuffer object"); } } )); }
} // Register static Action <UnityWebRequest> MakeHttpCallback(JavaScriptValue callback, bool wantsArrayBuffer = false) { return((www) => { if (www.isNetworkError || www.isHttpError) { Engine.With(() => { try { callback.CallFunction( JavaScriptValue.Undefined, JavaScriptValue.FromString(www.error), JavaScriptValue.Null ); } catch (Exception e) { Debug.LogError(e); } finally { callback.Release(); } }); return; } if (!wantsArrayBuffer) { string text = www.downloadHandler.text; Engine.With(() => { try { callback.CallFunction( JavaScriptValue.Undefined, JavaScriptValue.Null, JavaScriptValue.FromString(text) ); } catch (Exception e) { Debug.LogError(e); } finally { callback.Release(); } }); } else // ArrayBuffer { byte[] bytes = www.downloadHandler.data; IntPtr unmanagedPointer = Marshal.AllocHGlobal(bytes.Length); Marshal.Copy(bytes, 0, unmanagedPointer, bytes.Length); Engine.With(() => { Debug.Log("created ptr " + unmanagedPointer); JavaScriptValue buffer = JavaScriptValue.CreateExternalArrayBuffer( unmanagedPointer, (uint)bytes.Length, (ptr) => { Debug.Log("freeing " + ptr); Marshal.FreeHGlobal(ptr); }, unmanagedPointer // pass it in since the upvalue will die! (probably) ); try { callback.CallFunction( JavaScriptValue.Undefined, JavaScriptValue.Null, buffer ); } catch (Exception e) { Debug.LogError(e); } finally { callback.Release(); } }); } }); }