diff --git a/src/UltralightNet/JavaScript/JSBase.cs b/src/UltralightNet/JavaScript/JSBase.cs index f8f285f69..f263ff627 100644 --- a/src/UltralightNet/JavaScript/JSBase.cs +++ b/src/UltralightNet/JavaScript/JSBase.cs @@ -2,6 +2,8 @@ using System.Runtime.CompilerServices; using System.Runtime.InteropServices; +using UltralightNet.JavaScript.Low; +using UltralightNet.LowStuff; namespace UltralightNet.JavaScript { @@ -42,4 +44,15 @@ public static bool JSCheckScriptSyntax(JSContextRef context, JSStringRef script, public static partial void JSGarbageCollect(JSContextRef context); } } + namespace LowStuff + { + public abstract unsafe class JSNativeContainer : NativeContainer where NativeHandle : unmanaged + { + public NativeHandle JSHandle + { + get => JavaScriptMethods.BitCast((nuint)Handle); + protected init => Handle = (void*)JavaScriptMethods.BitCast(value); + } + } + } } diff --git a/src/UltralightNet/JavaScript/JSContext.cs b/src/UltralightNet/JavaScript/JSContext.cs index 2b2cc2733..92094d826 100644 --- a/src/UltralightNet/JavaScript/JSContext.cs +++ b/src/UltralightNet/JavaScript/JSContext.cs @@ -1,6 +1,8 @@ // JSContextRef.h using System.Runtime.InteropServices; +using UltralightNet.JavaScript.Low; +using UltralightNet.JavaScript.LowStuff; namespace UltralightNet.JavaScript { @@ -66,6 +68,7 @@ public readonly struct JSGlobalContextRef public static bool operator !=(JSGlobalContextRef left, JSGlobalContextRef right) => left._handle != right._handle; public static implicit operator JSContextRef(JSGlobalContextRef globalContextRef) => JavaScriptMethods.BitCast(globalContextRef); + public static explicit operator JSGlobalContextRef(JSContextRef contextRef) => JavaScriptMethods.BitCast(contextRef); } public readonly struct JSContextRef { @@ -78,18 +81,41 @@ public readonly struct JSContextRef public static bool operator !=(JSContextRef left, JSContextRef right) => left._handle != right._handle; } } - /*public unsafe class JSContext : IDisposable + + public unsafe sealed class JSContextGroup : JSNativeContainer, ICloneable { - public JSContext() { } + private JSContextGroup() { } + + public JSContextGroup Clone() + { + JSContextGroup returnValue = FromHandle(JavaScriptMethods.JSContextGroupRetain(JSHandle), true); + GC.KeepAlive(this); + return returnValue; + } + object ICloneable.Clone() => Clone(); - internal void* handle; - internal bool isGlobalContext = false; - private bool isDisposed = false; - private bool dispose = true; + public JSGlobalContext CreateGlobalContext(JSNativeContainer? globalObject = null) + { + var handle = JavaScriptMethods.JSGlobalContextCreateInGroup(JSHandle, globalObject?.JSHandle ?? default); + GC.KeepAlive(this); + GC.KeepAlive(globalObject); + return JSGlobalContext.FromHandle(handle, true); + } + + public static JSContextGroup FromHandle(JSContextGroupRef handle, bool dispose) => new() { JSHandle = handle, Owns = dispose }; + + public override void Dispose() + { + if (!IsDisposed && Owns) JavaScriptMethods.JSContextGroupRelease(JSHandle); + base.Dispose(); + } + } - public void* Handle => handle; + public unsafe class JSContext : JSNativeContainer + { + internal protected JSContext() { } - internal void OnLocked(void* actualHandle) + /*internal void OnLocked(void* actualHandle) { handle = actualHandle; } @@ -160,6 +186,63 @@ public void Dispose() isDisposed = true; GC.SuppressFinalize(this); } + }*/ + + // TODO: GlobalObject + public JSContextGroup Group + { + get + { + var returnValue = JSContextGroup.FromHandle(JavaScriptMethods.JSContextGroupRetain(JavaScriptMethods.JSContextGetGroup(JSHandle)), true); + GC.KeepAlive(this); + return returnValue; + } + } + public JSGlobalContext GlobalContext + { + get + { + throw new NotSupportedException("Returned instance of view's locked context is invalid."); + var returnValue = JSGlobalContext.FromHandle(JavaScriptMethods.JSGlobalContextRetain(JavaScriptMethods.JSContextGetGlobalContext(JSHandle)), true); + GC.KeepAlive(this); + return returnValue; + } } - }*/ + + public static JSContext FromHandle(JSContextRef handle, bool dispose) => new() { JSHandle = handle, Owns = dispose }; + } + public unsafe sealed class JSGlobalContext : JSContext + { + private JSGlobalContext() { } + + public new JSGlobalContextRef JSHandle + { + get => (JSGlobalContextRef)base.JSHandle; + private init => base.JSHandle = value; + } + + public JSString Name + { + get + { + var returnValue = JSString.FromHandle(JavaScriptMethods.JSGlobalContextCopyName(JSHandle), true); + GC.KeepAlive(this); + return returnValue; + } + set + { + JavaScriptMethods.JSGlobalContextSetName(JSHandle, value.JSHandle); + GC.KeepAlive(this); + GC.KeepAlive(value); + } + } + + public static JSGlobalContext FromHandle(JSGlobalContextRef handle, bool dispose) => new() { JSHandle = handle, Owns = dispose }; + + public override void Dispose() + { + if (!IsDisposed && Owns) JavaScriptMethods.JSGlobalContextRelease(JSHandle); + base.Dispose(); + } + } } diff --git a/src/UltralightNet/JavaScript/JSContextGroup.cs b/src/UltralightNet/JavaScript/JSContextGroup.cs deleted file mode 100644 index 0310a2cd5..000000000 --- a/src/UltralightNet/JavaScript/JSContextGroup.cs +++ /dev/null @@ -1,36 +0,0 @@ -// JSContextRef.h -using System; - -namespace UltralightNet.JavaScript; - -/*public unsafe class JSContextGroup : IDisposable -{ - public JSContextGroup() { - handle = JavaScriptMethods.JSContextGroupCreate(); - } - private JSContextGroup(void* handle){ - this.handle = handle; - } - - private void* handle; - private bool isDisposed = false; - private bool dispose = true; - - public void* Handle => handle; - - // public JSContext CreateGlobalContext(JSObject globalObject) => new() { isGlobalContext = true, handle = JavaScriptMethods.JSGlobalContextCreateInGroup(Handle, globalObject) }; - - public JSContextGroup Retain() => new(JavaScriptMethods.JSContextGroupRetain(Handle)); - - public static JSContextGroup CreateFromPointer(void* ptr) => new(ptr); - - public void Dispose() - { - if (!isDisposed && dispose) - { - JavaScriptMethods.JSContextGroupRelease(Handle); - isDisposed = true; - GC.SuppressFinalize(this); - } - } -}*/ diff --git a/src/UltralightNet/JavaScript/JSString.cs b/src/UltralightNet/JavaScript/JSString.cs index f32855a7c..4c493ddfb 100644 --- a/src/UltralightNet/JavaScript/JSString.cs +++ b/src/UltralightNet/JavaScript/JSString.cs @@ -59,21 +59,12 @@ public readonly struct JSStringRef public static bool operator !=(JSStringRef left, JSStringRef right) => left._handle != right._handle; } } - namespace LowStuff - { - public abstract unsafe class JSNativeContainer : NativeContainer where NativeHandle : unmanaged - { - public NativeHandle JSHandle - { - get => JavaScriptMethods.BitCast((nuint)Handle); - protected init => Handle = (void*)JavaScriptMethods.BitCast(value); - } - } - } [DebuggerDisplay("{ToString(),raw}")] public unsafe sealed class JSString : JSNativeContainer, IEquatable, IEquatable, ICloneable { + private JSString() { } + public JSString Clone() { JSString returnValue = FromHandle(JavaScriptMethods.JSStringRetain(JSHandle), true);