misc: chore: Android: Clean up .NET code, resolve warnings

This commit is contained in:
KeatonTheBot 2025-06-21 18:11:23 -05:00
parent 9955191651
commit a9954c23cc
33 changed files with 166 additions and 156 deletions

View file

@ -22,7 +22,7 @@ namespace LibKenjinx.Android
throw new NotImplementedException();
}
public bool DisplayErrorAppletDialog(string title, string message, string[] buttonsText)
public bool DisplayErrorAppletDialog(string? title, string? message, string[] buttonsText)
{
Interop.UpdateUiHandler(title ?? "",
message ?? "",
@ -58,7 +58,7 @@ namespace LibKenjinx.Android
return _isOkPressed;
}
public bool DisplayMessageDialog(string title, string message)
public bool DisplayMessageDialog(string? title, string? message)
{
Interop.UpdateUiHandler(title ?? "",
message ?? "",

View file

@ -20,15 +20,15 @@ namespace LibKenjinx.Android
private static JGlobalRef? _classId;
private static ConcurrentDictionary<(string method, string descriptor), JMethodId> _methodCache = new ConcurrentDictionary<(string method, string descriptor), JMethodId>();
private static (string name, string descriptor)[] _methods = new[]
{
private static (string name, string descriptor)[] _methods =
[
("test", "()V"),
("updateUiHandler", "(JJJIIIIJJ)V"),
("frameEnded", "()V"),
("updateProgress", "(JF)V"),
("getSurfacePtr", "()J"),
("getWindowHandle", "()J")
};
];
internal static void Initialize(JEnvRef jniEnv)
{
@ -67,14 +67,18 @@ namespace LibKenjinx.Android
using (IReadOnlyFixedMemory<Byte>.IDisposable dName = descriptorId.GetUnsafeValPtr()
.GetUnsafeFixedContext(descriptorId.Length))
{
var methodId = JniHelper.GetStaticMethodId(jEnv, (JClassLocalRef)(_classId.Value.Value), mName, dName);
if (methodId == null)
if (_classId != null)
{
Logger.Warning?.Print(LogClass.Application, $"Java Method Id {name} not found");
return;
var methodId = JniHelper.GetStaticMethodId(jEnv, (JClassLocalRef)(_classId.Value.Value), mName, dName);
if (methodId == null)
{
Logger.Warning?.Print(LogClass.Application, $"Java Method Id {name} not found");
return;
}
method = methodId.Value;
}
method = methodId.Value;
_methodCache[(name, descriptor)] = method;
}
}
@ -87,7 +91,10 @@ namespace LibKenjinx.Android
{
if (descriptor.EndsWith("V"))
{
JniHelper.CallStaticVoidMethod(env.Env, (JClassLocalRef)(_classId.Value.Value), method, values);
if (env != null && _classId != null)
{
JniHelper.CallStaticVoidMethod(env.Env, (JClassLocalRef)(_classId.Value.Value), method, values);
}
}
}
}
@ -98,10 +105,14 @@ namespace LibKenjinx.Android
if (_methodCache.TryGetValue((name, descriptor), out var method))
{
if (descriptor.EndsWith("J"))
return JniHelper.CallStaticLongMethod(env.Env, (JClassLocalRef)(_classId.Value.Value), method, values) ?? (JLong)(-1);
if (env != null && _classId != null)
{
return JniHelper.CallStaticLongMethod(env.Env, (JClassLocalRef)(_classId.Value.Value), method,
values) ?? -1;
}
}
return (JLong)(-1);
return -1;
}
public static void Test()
@ -117,11 +128,9 @@ namespace LibKenjinx.Android
public static void UpdateProgress(string info, float progress)
{
using var infoPtr = new TempNativeString(info);
CallVoidMethod("updateProgress", "(JF)V", new JValue[]
{
CallVoidMethod("updateProgress", "(JF)V",
JValue.Create(infoPtr.AsBytes()),
JValue.Create(progress.AsBytes())
});
JValue.Create(progress.AsBytes()));
}
public static JLong GetSurfacePtr()
@ -149,8 +158,7 @@ namespace LibKenjinx.Android
using var watermarkPointer = new TempNativeString(newWatermark);
using var subtitlePointer = new TempNativeString(newSubtitle);
using var newInitialPointer = new TempNativeString(newInitialText);
CallVoidMethod("updateUiHandler", "(JJJIIIIJJ)V", new JValue[]
{
CallVoidMethod("updateUiHandler", "(JJJIIIIJJ)V",
JValue.Create(titlePointer.AsBytes()),
JValue.Create(messagePointer.AsBytes()),
JValue.Create(watermarkPointer.AsBytes()),
@ -159,8 +167,7 @@ namespace LibKenjinx.Android
JValue.Create(max.AsBytes()),
JValue.Create(nMode.AsBytes()),
JValue.Create(subtitlePointer.AsBytes()),
JValue.Create(newInitialPointer.AsBytes())
});
JValue.Create(newInitialPointer.AsBytes()));
}
private class TempNativeString : IDisposable
@ -170,7 +177,7 @@ namespace LibKenjinx.Android
public TempNativeString(string value)
{
Pointer = Marshal.StringToHGlobalAuto(value);
JPointer = (JLong)Pointer;
JPointer = Pointer;
}
public nint Pointer { get; private set; }

View file

@ -3,9 +3,8 @@ using LibKenjinx.Jni.Pointers;
using LibKenjinx.Jni.Primitives;
using LibKenjinx.Jni.References;
using LibKenjinx.Jni.Values;
using System;
using Rxmxnx.PInvoke;
using System;
namespace LibKenjinx.Jni;

View file

@ -15,7 +15,7 @@ namespace LibKenjinx.Jni.Identifiers
#endregion
#region Override Methods
public override Boolean Equals([NotNullWhen(true)] Object obj)
public override Boolean Equals([NotNullWhen(true)] object? obj)
=> obj is JFieldId other && this.Equals(other);
public override Int32 GetHashCode() => this._value.GetHashCode();
#endregion

View file

@ -15,7 +15,7 @@ namespace LibKenjinx.Jni.Identifiers
#endregion
#region Override Methods
public override Boolean Equals([NotNullWhen(true)] Object obj)
public override Boolean Equals([NotNullWhen(true)] object? obj)
=> obj is JMethodId other && this.Equals(other);
public override Int32 GetHashCode() => this._value.GetHashCode();
#endregion

View file

@ -3,9 +3,8 @@ using LibKenjinx.Jni.Pointers;
using LibKenjinx.Jni.Primitives;
using LibKenjinx.Jni.References;
using LibKenjinx.Jni.Values;
using System;
using Rxmxnx.PInvoke;
using System;
namespace LibKenjinx.Jni
{
@ -21,13 +20,13 @@ namespace LibKenjinx.Jni
IntPtr getEnvPtr = jInvoke.GetEnvPointer;
GetEnvDelegate getEnv = getEnvPtr.GetUnsafeDelegate<GetEnvDelegate>()!;
if (getEnv(javaVm, out JEnvRef jEnv, JniHelper.JniVersion) == JResult.Ok)
if (getEnv(javaVm, out JEnvRef jEnv, JniVersion) == JResult.Ok)
{
newAttach = false;
return jEnv;
}
JavaVMAttachArgs args = new() { Version = JniHelper.JniVersion, Name = threadName.ValuePointer, };
JavaVMAttachArgs args = new() { Version = JniVersion, Name = threadName.ValuePointer, };
IntPtr attachCurrentThreadPtr = jInvoke.AttachCurrentThreadPointer;
AttachCurrentThreadDelegate attachCurrentThread =
attachCurrentThreadPtr.GetUnsafeDelegate<AttachCurrentThreadDelegate>()!;
@ -40,7 +39,7 @@ namespace LibKenjinx.Jni
ref JavaVMValue value = ref javaVm.VirtualMachine;
ref JInvokeInterface jInvoke = ref value.Functions;
JavaVMAttachArgs args = new() { Version = JniHelper.JniVersion, Name = daemonName.ValuePointer, };
JavaVMAttachArgs args = new() { Version = JniVersion, Name = daemonName.ValuePointer, };
IntPtr attachCurrentThreadAsDaemonPtr = jInvoke.AttachCurrentThreadAsDaemonPointer;
AttachCurrentThreadAsDaemonDelegate attachCurrentThreadAsDaemon =
attachCurrentThreadAsDaemonPtr.GetUnsafeDelegate<AttachCurrentThreadAsDaemonDelegate>()!;
@ -67,16 +66,16 @@ namespace LibKenjinx.Jni
FindClassDelegate findClass = findClassPtr.GetUnsafeDelegate<FindClassDelegate>()!;
JClassLocalRef jClass = findClass(jEnv, className.ValuePointer);
if (JniHelper.ExceptionCheck(jEnv))
if (ExceptionCheck(jEnv))
return default;
IntPtr newGlobalRefPtr = jInterface.NewGlobalRefPointer;
NewGlobalRefDelegate newGlobalRef = newGlobalRefPtr.GetUnsafeDelegate<NewGlobalRefDelegate>()!;
JGlobalRef jGlobal = newGlobalRef(jEnv, (JObjectLocalRef)jClass);
JniHelper.RemoveLocal(jEnv, (JObjectLocalRef)jClass);
RemoveLocal(jEnv, (JObjectLocalRef)jClass);
return !JniHelper.ExceptionCheck(jEnv) ? jGlobal : null;
return !ExceptionCheck(jEnv) ? jGlobal : null;
}
public static void RemoveLocal(JEnvRef jEnv, JObjectLocalRef jObject)
{
@ -119,7 +118,7 @@ namespace LibKenjinx.Jni
using IReadOnlyFixedMemory<Char>.IDisposable ctx = textValue.AsMemory().GetFixedContext();
JStringLocalRef jString = newString(jEnv, ctx.ValuePointer, ctx.Values.Length);
return !JniHelper.ExceptionCheck(jEnv) ? jString : null;
return !ExceptionCheck(jEnv) ? jString : null;
}
public static JWeakRef? CreateWeakGlobal(JEnvRef jEnv, JObjectLocalRef jObject)
{
@ -130,7 +129,7 @@ namespace LibKenjinx.Jni
NewWeakGlobalRefDelegate newWeakGlobalRef = newWeakGlobalRefPtr.GetUnsafeDelegate<NewWeakGlobalRefDelegate>()!;
JWeakRef jWeak = newWeakGlobalRef(jEnv, jObject);
return !JniHelper.ExceptionCheck(jEnv) ? jWeak : null;
return !ExceptionCheck(jEnv) ? jWeak : null;
}
private static Boolean ExceptionCheck(JEnvRef jEnv)
{
@ -170,7 +169,7 @@ namespace LibKenjinx.Jni
IntPtr isSameObjectPtr = jInterface.IsSameObjectPointer;
IsSameObjectDelegate isSameObject = isSameObjectPtr.GetUnsafeDelegate<IsSameObjectDelegate>()!;
JBoolean result = isSameObject(jEnv, (JObjectLocalRef)jWeak, default);
return !JniHelper.ExceptionCheck(jEnv) ? !result : null;
return !ExceptionCheck(jEnv) ? !result : null;
}
public static JMethodId? GetMethodId(JEnvRef jEnv, JClassLocalRef jClass, IReadOnlyFixedMemory<Byte> methodName,
IReadOnlyFixedMemory<Byte> descriptor)
@ -181,7 +180,7 @@ namespace LibKenjinx.Jni
IntPtr getMethodIdPtr = jInterface.GetMethodIdPointer;
GetMethodIdDelegate getMethodId = getMethodIdPtr.GetUnsafeDelegate<GetMethodIdDelegate>()!;
JMethodId methodId = getMethodId(jEnv, jClass, methodName.ValuePointer, descriptor.ValuePointer);
return !JniHelper.ExceptionCheck(jEnv) ? methodId : null;
return !ExceptionCheck(jEnv) ? methodId : null;
}
public static JMethodId? GetStaticMethodId(JEnvRef jEnv, JClassLocalRef jClass,
IReadOnlyFixedMemory<Byte> methodName, IReadOnlyFixedMemory<Byte> descriptor)
@ -193,7 +192,7 @@ namespace LibKenjinx.Jni
GetStaticMethodIdDelegate getStaticMethodId =
getStaticMethodIdPtr.GetUnsafeDelegate<GetStaticMethodIdDelegate>()!;
JMethodId jMethodId = getStaticMethodId(jEnv, jClass, methodName.ValuePointer, descriptor.ValuePointer);
return !JniHelper.ExceptionCheck(jEnv) ? jMethodId : null;
return !ExceptionCheck(jEnv) ? jMethodId : null;
}
public static void CallStaticVoidMethod(JEnvRef jEnv, JClassLocalRef jClass, JMethodId jMethodId,
params JValue[] args)
@ -220,7 +219,7 @@ namespace LibKenjinx.Jni
using IReadOnlyFixedMemory<JValue>.IDisposable fArgs = args.AsMemory().GetFixedContext();
JObjectLocalRef jObject = callStaticObjectMethod(jEnv, jClass, jMethodId, fArgs.ValuePointer);
return !JniHelper.ExceptionCheck(jEnv) ? jObject : null;
return !ExceptionCheck(jEnv) ? jObject : null;
}
public static JLong? CallStaticLongMethod(JEnvRef jEnv, JClassLocalRef jClass, JMethodId jMethodId,
params JValue[] args)
@ -234,7 +233,7 @@ namespace LibKenjinx.Jni
using IReadOnlyFixedMemory<JValue>.IDisposable fArgs = args.AsMemory().GetFixedContext();
JLong jLong = callStaticLongMethod(jEnv, jClass, jMethodId, fArgs.ValuePointer);
return !JniHelper.ExceptionCheck(jEnv) ? jLong : null;
return !ExceptionCheck(jEnv) ? jLong : null;
}
public static void CallVoidMethod(JEnvRef jEnv, JObjectLocalRef jObject, JMethodId jMethodId, params JValue[] args)
{

View file

@ -30,7 +30,7 @@ namespace LibKenjinx.Jni.Pointers
#endregion
#region Overrided Methods
public override Boolean Equals(Object obj) => obj is JEnvRef other && this.Equals(other);
public override Boolean Equals(object? obj) => obj is JEnvRef other && this.Equals(other);
public override Int32 GetHashCode() => this._value.GetHashCode();
#endregion
}

View file

@ -25,7 +25,7 @@ public readonly struct JavaVMRef : IEquatable<JavaVMRef>
#endregion
#region Overrided Methods
public override Boolean Equals(Object obj) => obj is JavaVMRef other && this.Equals(other);
public override Boolean Equals(object? obj) => obj is JavaVMRef other && this.Equals(other);
public override Int32 GetHashCode() => this._value.GetHashCode();
#endregion
}

View file

@ -12,9 +12,9 @@ public readonly struct JBoolean : IComparable<Boolean>, IEquatable<Boolean>
public static readonly CString Signature = (CString)"Z";
private readonly Byte _value;
private Boolean Value => this._value == JBoolean.trueByte;
private Boolean Value => this._value == trueByte;
private JBoolean(Boolean value) => this._value = value ? JBoolean.trueByte : JBoolean.falseByte;
private JBoolean(Boolean value) => this._value = value ? trueByte : falseByte;
#region Operators
public static implicit operator JBoolean(Boolean value) => new(value);
@ -59,7 +59,7 @@ public readonly struct JBoolean : IComparable<Boolean>, IEquatable<Boolean>
#region Overrided Methods
public override String ToString() => this._value.ToString();
public override Boolean Equals(Object obj)
public override Boolean Equals(object? obj)
=> obj is JBoolean jvalue ? this.Equals(jvalue) :
obj is Boolean value ? this.Equals(value) : this._value.Equals(obj);
public override Int32 GetHashCode() => this._value.GetHashCode();

View file

@ -62,12 +62,12 @@ namespace LibKenjinx.Jni.Primitives
public Int32 CompareTo(Object obj) => obj is JByte jValue ? this.CompareTo(jValue) : obj is SByte value ? this.CompareTo(value) : this._value.CompareTo(obj);
public Boolean Equals(SByte other) => this._value.Equals(other);
public Boolean Equals(JByte other) => this._value.Equals(other._value);
public String ToString(String format, IFormatProvider formatProvider) => this._value.ToString(format, formatProvider);
public String ToString(string? format, IFormatProvider? formatProvider) => this._value.ToString(format, formatProvider);
#endregion
#region Overrided Methods
public override String ToString() => this._value.ToString();
public override Boolean Equals(Object obj) => obj is JByte jvalue ? this.Equals(jvalue) : obj is SByte value ? this.Equals(value) : this._value.Equals(obj);
public override Boolean Equals(object? obj) => obj is JByte jvalue ? this.Equals(jvalue) : obj is SByte value ? this.Equals(value) : this._value.Equals(obj);
public override Int32 GetHashCode() => this._value.GetHashCode();
#endregion
}

View file

@ -49,7 +49,7 @@ namespace LibKenjinx.Jni.Primitives
#region Overrided Methods
public override String ToString() => this._value.ToString();
public override Boolean Equals(Object obj) => obj is JChar jvalue ? this.Equals(jvalue) : obj is Char value ? this.Equals(value) : this._value.Equals(obj);
public override Boolean Equals(object? obj) => obj is JChar jvalue ? this.Equals(jvalue) : obj is Char value ? this.Equals(value) : this._value.Equals(obj);
public override Int32 GetHashCode() => this._value.GetHashCode();
#endregion
}

View file

@ -58,12 +58,12 @@ namespace LibKenjinx.Jni.Primitives
public Int32 CompareTo(Object obj) => obj is JDouble jvalue ? this.CompareTo(jvalue) : obj is Double value ? this.CompareTo(value) : this._value.CompareTo(obj);
public Boolean Equals(Double other) => this._value.Equals(other);
public Boolean Equals(JDouble other) => this._value.Equals(other._value);
public String ToString(String format, IFormatProvider formatProvider) => this._value.ToString(format, formatProvider);
public String ToString(string? format, IFormatProvider? formatProvider) => this._value.ToString(format, formatProvider);
#endregion
#region Overrided Methods
public override String ToString() => this._value.ToString();
public override Boolean Equals(Object obj) => obj is JDouble jvalue ? this.Equals(jvalue) : obj is Double value ? this.Equals(value) : this._value.Equals(obj);
public override Boolean Equals(object? obj) => obj is JDouble jvalue ? this.Equals(jvalue) : obj is Double value ? this.Equals(value) : this._value.Equals(obj);
public override Int32 GetHashCode() => this._value.GetHashCode();
#endregion
}

View file

@ -58,12 +58,12 @@ namespace LibKenjinx.Jni.Primitives
public Int32 CompareTo(Object obj) => obj is JFloat jvalue ? this.CompareTo(jvalue) : obj is Single value ? this.CompareTo(value) : this._value.CompareTo(obj);
public Boolean Equals(Single other) => this._value.Equals(other);
public Boolean Equals(JFloat other) => this._value.Equals(other._value);
public String ToString(String format, IFormatProvider formatProvider) => this._value.ToString(format, formatProvider);
public String ToString(string? format, IFormatProvider? formatProvider) => this._value.ToString(format, formatProvider);
#endregion
#region Overrided Methods
public override String ToString() => this._value.ToString();
public override Boolean Equals(Object obj) => obj is JFloat jvalue ? this.Equals(jvalue) : obj is Single value ? this.Equals(value) : this._value.Equals(obj);
public override Boolean Equals(object? obj) => obj is JFloat jvalue ? this.Equals(jvalue) : obj is Single value ? this.Equals(value) : this._value.Equals(obj);
public override Int32 GetHashCode() => this._value.GetHashCode();
#endregion
}

View file

@ -61,12 +61,12 @@ namespace LibKenjinx.Jni.Primitives
public Int32 CompareTo(Object obj) => obj is JInt jValue ? this.CompareTo(jValue) : obj is Int32 value ? this.CompareTo(value) : this._value.CompareTo(obj);
public Boolean Equals(Int32 other) => this._value.Equals(other);
public Boolean Equals(JInt other) => this._value.Equals(other._value);
public String ToString(String format, IFormatProvider formatProvider) => this._value.ToString(format, formatProvider);
public String ToString(string? format, IFormatProvider? formatProvider) => this._value.ToString(format, formatProvider);
#endregion
#region Overrided Methods
public override String ToString() => this._value.ToString();
public override Boolean Equals(Object obj) => obj is JInt jvalue ? this.Equals(jvalue) : obj is Int32 value ? this.Equals(value) : this._value.Equals(obj);
public override Boolean Equals(object? obj) => obj is JInt jvalue ? this.Equals(jvalue) : obj is Int32 value ? this.Equals(value) : this._value.Equals(obj);
public override Int32 GetHashCode() => this._value.GetHashCode();
#endregion
}

View file

@ -61,12 +61,12 @@ namespace LibKenjinx.Jni.Primitives
public Int32 CompareTo(Object obj) => obj is JLong jvalue ? this.CompareTo(jvalue) : obj is Int64 value ? this.CompareTo(value) : this._value.CompareTo(obj);
public Boolean Equals(Int64 other) => this._value.Equals(other);
public Boolean Equals(JLong other) => this._value.Equals(other._value);
public String ToString(String format, IFormatProvider formatProvider) => this._value.ToString(format, formatProvider);
public String ToString(string? format, IFormatProvider? formatProvider) => this._value.ToString(format, formatProvider);
#endregion
#region Overrided Methods
public override String ToString() => this._value.ToString();
public override Boolean Equals(Object obj) => obj is JLong jvalue ? this.Equals(jvalue) : obj is Int64 value ? this.Equals(value) : this._value.Equals(obj);
public override Boolean Equals(object? obj) => obj is JLong jvalue ? this.Equals(jvalue) : obj is Int64 value ? this.Equals(value) : this._value.Equals(obj);
public override Int32 GetHashCode() => this._value.GetHashCode();
#endregion
}

View file

@ -62,12 +62,12 @@ namespace LibKenjinx.Jni.Primitives
public Int32 CompareTo(Object obj) => obj is JShort jvalue ? this.CompareTo(jvalue) : obj is Int16 value ? this.CompareTo(value) : this._value.CompareTo(obj);
public Boolean Equals(Int16 other) => this._value.Equals(other);
public Boolean Equals(JShort other) => this._value.Equals(other._value);
public String ToString(String format, IFormatProvider formatProvider) => this._value.ToString(format, formatProvider);
public String ToString(string? format, IFormatProvider? formatProvider) => this._value.ToString(format, formatProvider);
#endregion
#region Overrided Methods
public override String ToString() => this._value.ToString();
public override Boolean Equals(Object obj) => obj is JShort jvalue ? this.Equals(jvalue) : obj is Int16 value ? this.Equals(value) : this._value.Equals(obj);
public override Boolean Equals(object? obj) => obj is JShort jvalue ? this.Equals(jvalue) : obj is Int16 value ? this.Equals(value) : this._value.Equals(obj);
public override Int32 GetHashCode() => this._value.GetHashCode();
#endregion
}

View file

@ -14,7 +14,7 @@ public readonly struct JArrayLocalRef : IEquatable<JArrayLocalRef>
#endregion
#region Override Methods
public override Boolean Equals([NotNullWhen(true)] Object obj) => obj is JArrayLocalRef other && this.Equals(other);
public override Boolean Equals([NotNullWhen(true)] object? obj) => obj is JArrayLocalRef other && this.Equals(other);
public override Int32 GetHashCode() => this._value.GetHashCode();
#endregion

View file

@ -16,7 +16,7 @@ public readonly struct JClassLocalRef : IEquatable<JClassLocalRef>
#endregion
#region Override Methods
public override Boolean Equals([NotNullWhen(true)] Object obj) => obj is JClassLocalRef other && this.Equals(other);
public override Boolean Equals([NotNullWhen(true)] object? obj) => obj is JClassLocalRef other && this.Equals(other);
public override Int32 GetHashCode() => this._value.GetHashCode();
#endregion

View file

@ -16,7 +16,7 @@ public readonly struct JGlobalRef : IEquatable<JGlobalRef>
#endregion
#region Override Methods
public override Boolean Equals([NotNullWhen(true)] Object obj) => obj is JGlobalRef other && this.Equals(other);
public override Boolean Equals([NotNullWhen(true)] object? obj) => obj is JGlobalRef other && this.Equals(other);
public override Int32 GetHashCode() => this._value.GetHashCode();
#endregion

View file

@ -15,7 +15,7 @@ namespace LibKenjinx.Jni.References
#endregion
#region Override Methods
public override Boolean Equals([NotNullWhen(true)] Object obj)
public override Boolean Equals([NotNullWhen(true)] object? obj)
=> obj is JObjectLocalRef other && this.Equals(other);
public override Int32 GetHashCode() => this._value.GetHashCode();
#endregion

View file

@ -14,7 +14,7 @@ public readonly struct JStringLocalRef : IEquatable<JStringLocalRef>
#endregion
#region Override Methods
public override Boolean Equals([NotNullWhen(true)] Object obj)
public override Boolean Equals([NotNullWhen(true)] object? obj)
=> obj is JStringLocalRef other && this.Equals(other);
public override Int32 GetHashCode() => this._value.GetHashCode();
#endregion

View file

@ -14,7 +14,7 @@ public readonly struct JThrowableLocalRef : IEquatable<JThrowableLocalRef>
#endregion
#region Override Methods
public override Boolean Equals([NotNullWhen(true)] Object obj)
public override Boolean Equals([NotNullWhen(true)] object? obj)
=> obj is JThrowableLocalRef other && this.Equals(other);
public override Int32 GetHashCode() => this._value.GetHashCode();
#endregion

View file

@ -14,7 +14,7 @@ public readonly struct JWeakRef : IEquatable<JWeakRef>
#endregion
#region Override Methods
public override Boolean Equals([NotNullWhen(true)] Object obj) => obj is JWeakRef other && this.Equals(other);
public override Boolean Equals([NotNullWhen(true)] object? obj) => obj is JWeakRef other && this.Equals(other);
public override Int32 GetHashCode() => this._value.GetHashCode();
#endregion

View file

@ -23,7 +23,7 @@ namespace LibKenjinx.Jni.Values
#endregion
#region Overrided Methods
public override Boolean Equals(Object obj) => obj is JEnvValue other && this.Equals(other);
public override Boolean Equals(object? obj) => obj is JEnvValue other && this.Equals(other);
public override Int32 GetHashCode() => this._value.GetHashCode();
#endregion
}

View file

@ -1,10 +1,8 @@
using LibKenjinx.Jni.References;
using Rxmxnx.PInvoke;
using System;
using System.Runtime.CompilerServices;
using LibKenjinx.Jni.References;
using Rxmxnx.PInvoke;
namespace LibKenjinx.Jni.Values;
internal readonly struct JValue
@ -13,7 +11,7 @@ internal readonly struct JValue
private static readonly Int32 size = NativeUtilities.SizeOf<JValue>();
private static readonly IsDefaultDelegate isDefault = JValue.GetIsDefault();
private static readonly IsDefaultDelegate isDefault = GetIsDefault();
#pragma warning disable 0649
#pragma warning disable 0169
@ -24,17 +22,17 @@ internal readonly struct JValue
#pragma warning restore 0169
#pragma warning restore 0649
public Boolean IsDefault => JValue.isDefault(this);
public Boolean IsDefault => isDefault(this);
public static JValue Create(in ReadOnlySpan<Byte> source)
{
Byte[] result = new Byte[JValue.size];
Byte[] result = new Byte[size];
for (Int32 i = 0; i < source.Length; i++)
result[i] = source[i];
return result.ToValue<JValue>();
}
private static IsDefaultDelegate GetIsDefault() => Environment.Is64BitProcess ? JValue.DefaultLong : JValue.Default;
private static IsDefaultDelegate GetIsDefault() => Environment.Is64BitProcess ? DefaultLong : Default;
private static Boolean Default(in JValue jValue)
=> jValue._value1 + jValue._value2 + jValue._value3 == default && jValue._value4 == default;
@ -42,5 +40,5 @@ internal readonly struct JValue
private static Boolean DefaultLong(in JValue jValue)
=> Unsafe.AsRef(in jValue).Transform<JValue, Int64>() == default;
public static explicit operator JValue(JObjectLocalRef a) => JValue.Create(NativeUtilities.AsBytes(in a));
public static explicit operator JValue(JObjectLocalRef a) => Create(NativeUtilities.AsBytes(in a));
}

View file

@ -23,7 +23,7 @@ internal readonly struct JavaVMValue : IEquatable<JavaVMValue>
#endregion
#region Overrided Methods
public override Boolean Equals(Object obj) => obj is JavaVMValue other && this.Equals(other);
public override Boolean Equals(object? obj) => obj is JavaVMValue other && this.Equals(other);
public override Int32 GetHashCode() => this._value.GetHashCode();
#endregion
}

View file

@ -282,7 +282,7 @@ namespace LibKenjinx
return false;
}
List<string?> extensions = new();
List<string?> extensions = [];
for (int i = 0; i < extensionsLength; i++)
{
@ -332,8 +332,11 @@ namespace LibKenjinx
Logger.Trace?.Print(LogClass.Application, "Jni Function Call");
SetSwapBuffersCallback(() =>
{
var time = SwitchDevice.EmulationContext.Statistics.GetGameFrameTime();
Interop.FrameEnded(time);
if (SwitchDevice?.EmulationContext != null)
{
var time = SwitchDevice.EmulationContext.Statistics.GetGameFrameTime();
Interop.FrameEnded(time);
}
});
RunLoop();
}
@ -356,7 +359,7 @@ namespace LibKenjinx
Logger.Trace?.Print(LogClass.Application, "Jni Function Call");
using var stream = OpenFile(fileDescriptor);
var ext = Marshal.PtrToStringAnsi(extension);
var info = GetGameInfo(stream, ext.ToLower()) ?? GetDefaultInfo(stream);
var info = GetGameInfo(stream, ext?.ToLower() ?? string.Empty) ?? GetDefaultInfo(stream);
var i = (GameInfoNative*)infoPtr;
var n = new GameInfoNative(info);
i->TitleId = n.TitleId;

View file

@ -71,12 +71,12 @@ namespace LibKenjinx
public static SystemVersion? VerifyFirmware(Stream stream, bool isXci)
{
return SwitchDevice?.ContentManager?.VerifyFirmwarePackage(stream, isXci) ?? null;
return SwitchDevice?.ContentManager.VerifyFirmwarePackage(stream, isXci) ?? null;
}
public static bool LoadApplication(Stream stream, FileType type, Stream? updateStream = null)
{
var emulationContext = SwitchDevice.EmulationContext;
var emulationContext = SwitchDevice?.EmulationContext;
return type switch
{
@ -84,19 +84,20 @@ namespace LibKenjinx
FileType.Nsp => emulationContext?.LoadNsp(stream, 0, updateStream) ?? false,
FileType.Xci => emulationContext?.LoadXci(stream, 0, updateStream) ?? false,
FileType.Nro => emulationContext?.LoadProgram(stream, true, "") ?? false,
_ => throw new ArgumentOutOfRangeException(nameof(type), type, null)
};
}
public static bool LaunchMiiEditApplet()
{
string contentPath = SwitchDevice.ContentManager.GetInstalledContentPath(0x0100000000001009, StorageId.BuiltInSystem, NcaContentType.Program);
string? contentPath = SwitchDevice?.ContentManager.GetInstalledContentPath(0x0100000000001009, StorageId.BuiltInSystem, NcaContentType.Program);
return LoadApplication(contentPath);
}
public static bool LoadApplication(string? path)
{
var emulationContext = SwitchDevice.EmulationContext;
var emulationContext = SwitchDevice?.EmulationContext;
if (Directory.Exists(path))
{
@ -111,9 +112,9 @@ namespace LibKenjinx
{
Logger.Info?.Print(LogClass.Application, "Loading as cart with RomFS.");
if (!emulationContext.LoadCart(path, romFsFiles[0]))
if (emulationContext != null && !emulationContext.LoadCart(path, romFsFiles[0]))
{
SwitchDevice.DisposeContext();
SwitchDevice?.DisposeContext();
return false;
}
}
@ -121,9 +122,9 @@ namespace LibKenjinx
{
Logger.Info?.Print(LogClass.Application, "Loading as cart WITHOUT RomFS.");
if (!emulationContext.LoadCart(path))
if (emulationContext != null && !emulationContext.LoadCart(path))
{
SwitchDevice.DisposeContext();
SwitchDevice?.DisposeContext();
return false;
}
}
@ -135,18 +136,18 @@ namespace LibKenjinx
case ".xci":
Logger.Info?.Print(LogClass.Application, "Loading as XCI.");
if (!emulationContext.LoadXci(path))
if (emulationContext != null && !emulationContext.LoadXci(path))
{
SwitchDevice.DisposeContext();
SwitchDevice?.DisposeContext();
return false;
}
break;
case ".nca":
Logger.Info?.Print(LogClass.Application, "Loading as NCA.");
if (!emulationContext.LoadNca(path))
if (emulationContext != null && !emulationContext.LoadNca(path))
{
SwitchDevice.DisposeContext();
SwitchDevice?.DisposeContext();
return false;
}
break;
@ -154,9 +155,9 @@ namespace LibKenjinx
case ".pfs0":
Logger.Info?.Print(LogClass.Application, "Loading as NSP.");
if (!emulationContext.LoadNsp(path))
if (emulationContext != null && !emulationContext.LoadNsp(path))
{
SwitchDevice.DisposeContext();
SwitchDevice?.DisposeContext();
return false;
}
break;
@ -164,16 +165,16 @@ namespace LibKenjinx
Logger.Info?.Print(LogClass.Application, "Loading as Homebrew.");
try
{
if (!emulationContext.LoadProgram(path))
if (emulationContext != null && !emulationContext.LoadProgram(path))
{
SwitchDevice.DisposeContext();
SwitchDevice?.DisposeContext();
return false;
}
}
catch (ArgumentOutOfRangeException)
{
Logger.Error?.Print(LogClass.Application, "The specified file is not supported by Ryujinx.");
SwitchDevice.DisposeContext();
SwitchDevice?.DisposeContext();
return false;
}
break;
@ -182,7 +183,7 @@ namespace LibKenjinx
else
{
Logger.Warning?.Print(LogClass.Application, $"Couldn't load '{path}'. Please specify a valid XCI/NCA/NSP/PFS0/NRO file.");
SwitchDevice.DisposeContext();
SwitchDevice?.DisposeContext();
return false;
}
@ -211,15 +212,15 @@ namespace LibKenjinx
_touchScreenManager?.Dispose();
_touchScreenManager = null;
_gpuDoneEvent?.WaitOne(3000);
_gpuDoneEvent?.Dispose();
_gpuDoneEvent.WaitOne(3000);
_gpuDoneEvent.Dispose();
_gpuDoneEvent = null;
_gpuCancellationTokenSource?.Cancel();
_gpuCancellationTokenSource?.Dispose();
_gpuCancellationTokenSource.Cancel();
_gpuCancellationTokenSource.Dispose();
_gpuCancellationTokenSource = null;
SwitchDevice?.Dispose();
SwitchDevice.Dispose();
SwitchDevice = null;
Renderer = null;
@ -236,7 +237,10 @@ namespace LibKenjinx
if (SwitchDevice == null)
{
Logger.Info?.Print(LogClass.Application, "Resetting device");
SwitchDevice = new SwitchDevice(AndroidFileSystem);
if (AndroidFileSystem != null)
{
SwitchDevice = new SwitchDevice(AndroidFileSystem);
}
}
_isStopped = false;

View file

@ -18,10 +18,10 @@ namespace LibKenjinx
{
private static bool _isActive;
private static bool _isStopped;
private static CancellationTokenSource _gpuCancellationTokenSource;
private static CancellationTokenSource? _gpuCancellationTokenSource;
private static SwapBuffersCallback? _swapBuffersCallback;
private static NativeGraphicsInterop _nativeGraphicsInterop;
private static ManualResetEvent _gpuDoneEvent;
private static ManualResetEvent? _gpuDoneEvent;
private static bool _enableGraphicsLogging;
public delegate void SwapBuffersCallback();
@ -91,9 +91,9 @@ namespace LibKenjinx
return;
}
ARMeilleure.Optimizations.EcoFriendly = SwitchDevice!.EnableLowPowerPtc;
ARMeilleure.Optimizations.CacheEviction = SwitchDevice!.EnableJitCacheEviction;
ARMeilleure.Optimizations.CacheEviction = SwitchDevice.EnableJitCacheEviction;
var device = SwitchDevice!.EmulationContext!;
var device = SwitchDevice.EmulationContext!;
_gpuDoneEvent = new ManualResetEvent(true);
device.Gpu.Renderer.Initialize(_enableGraphicsLogging ? GraphicsDebugLevel.All : GraphicsDebugLevel.None);

View file

@ -40,12 +40,12 @@ namespace LibKenjinx
_inputManager.SetMouseDriver(_touchScreenDriver);
_npadManager = _inputManager.CreateNpadManager();
SwitchDevice!.InputManager = _inputManager;
SwitchDevice.InputManager = _inputManager;
_touchScreenManager = _inputManager.CreateTouchScreenManager();
_touchScreenManager.Initialize(SwitchDevice!.EmulationContext);
_touchScreenManager.Initialize(SwitchDevice.EmulationContext);
_npadManager.Initialize(SwitchDevice.EmulationContext, new List<InputConfig>(), false, false);
_npadManager.Initialize(SwitchDevice.EmulationContext, [], false, false);
_virtualTouchScreen.ClientSize = new Size(width, height);
}
@ -253,7 +253,7 @@ namespace LibKenjinx
throw new NotImplementedException();
}
public (float, float) GetStick(Ryujinx.Input.StickInputId inputId)
public (float, float) GetStick(StickInputId inputId)
{
throw new NotImplementedException();
}
@ -329,8 +329,8 @@ namespace LibKenjinx
public string DriverName => "Virtual";
public event Action<string> OnGamepadConnected;
public event Action<string> OnGamepadDisconnected;
public event Action<string>? OnGamepadConnected;
public event Action<string>? OnGamepadDisconnected;
private Dictionary<int, VirtualGamepad> _gamePads;

View file

@ -131,7 +131,7 @@ namespace LibKenjinx
return false;
}
List<string> extensions = new List<string>();
List<string> extensions = [];
var size = Marshal.SizeOf<IntPtr>();
var extPtr = (IntPtr*)nativeGraphicsInterop.VkRequiredExtensions;
for (int i = 0; i < nativeGraphicsInterop.VkRequiredExtensionsCount; i++)
@ -157,7 +157,7 @@ namespace LibKenjinx
if (Renderer is OpenGLRenderer)
{
var proc = Marshal.GetDelegateForFunctionPointer<GetProcAddress>(_nativeGraphicsInterop.GlGetProcAddress);
GL.LoadBindings(new OpenTKBindingsContext(x => proc!.Invoke(x)));
GL.LoadBindings(new OpenTKBindingsContext(x => proc.Invoke(x)));
}
RunLoop();
}
@ -373,7 +373,7 @@ namespace LibKenjinx
{
using var stream = OpenFile(fileDescriptor);
var ext = Marshal.PtrToStringAnsi(extension);
var info = GetGameInfo(stream, ext.ToLower()) ?? GetDefaultInfo(stream);
var info = GetGameInfo(stream, ext?.ToLower() ?? string.Empty) ?? GetDefaultInfo(stream);
var i = (GameInfoNative*)infoPtr;
var n = new GameInfoNative(info);
i->TitleId = n.TitleId;

View file

@ -53,7 +53,7 @@ namespace LibKenjinx
public static string[] GetAllUsers()
{
return SwitchDevice?.AccountManager.GetAllUsers().Select(x => x.UserId.ToString()).ToArray() ??
Array.Empty<string>();
[];
}
public static void AddUser(string userName, string picture)

View file

@ -1,41 +1,41 @@
// State class for the library
using Ryujinx.HLE.FileSystem;
using Ryujinx.HLE.HOS.Services.Account.Acc;
using Ryujinx.HLE.HOS;
using Ryujinx.Input.HLE;
using Ryujinx.HLE;
using System;
using System.Runtime.InteropServices;
using Ryujinx.Common.Configuration;
using LibHac.Tools.FsSystem;
using Ryujinx.Graphics.GAL.Multithreading;
using Ryujinx.Audio.Backends.Dummy;
using Ryujinx.HLE.HOS.SystemState;
using Ryujinx.UI.Common.Configuration;
using Ryujinx.Common.Logging;
using Ryujinx.Audio.Integration;
using Ryujinx.Audio.Backends.SDL2;
using System.IO;
using Gommon;
using LibHac.Account;
using LibHac.Common;
using LibHac.Common.Keys;
using LibHac.Fs;
using LibHac.Fs.Fsa;
using LibHac.FsSystem;
using LibHac.Tools.Fs;
using LibHac.Common.Keys;
using LibHac.Tools.FsSystem;
using LibHac.Tools.FsSystem.NcaUtils;
using Path = System.IO.Path;
using OpenTK.Audio.OpenAL;
using Ryujinx.HLE.Loaders.Npdm;
using Ryujinx.Common.Utilities;
using System.Globalization;
using Ryujinx.UI.Common.Configuration.System;
using Ryujinx.Common.Logging.Targets;
using System.Collections.Generic;
using System.Text;
using Ryujinx.HLE.UI;
using LibKenjinx.Android;
using LibHac.Account;
using Gommon;
using OpenTK.Audio.OpenAL;
using Ryujinx.Audio.Backends.Dummy;
using Ryujinx.Audio.Backends.SDL2;
using Ryujinx.Audio.Integration;
using Ryujinx.Common.Configuration;
using Ryujinx.Common.Logging;
using Ryujinx.Common.Logging.Targets;
using Ryujinx.Common.Utilities;
using Ryujinx.Graphics.GAL.Multithreading;
using Ryujinx.HLE;
using Ryujinx.HLE.FileSystem;
using Ryujinx.HLE.HOS;
using Ryujinx.HLE.HOS.Services.Account.Acc;
using Ryujinx.HLE.HOS.SystemState;
using Ryujinx.HLE.Loaders.Npdm;
using Ryujinx.HLE.UI;
using Ryujinx.Input.HLE;
using Ryujinx.UI.Common.Configuration;
using Ryujinx.UI.Common.Configuration.System;
using System;
using System.Collections.Generic;
using System.Globalization;
using System.IO;
using System.Runtime.InteropServices;
using System.Text;
using Path = System.IO.Path;
namespace LibKenjinx
{
@ -264,7 +264,7 @@ namespace LibKenjinx
}
}
SwitchDevice?.CreateSaveDir(id.ToULong(16), controlHolder);
SwitchDevice.CreateSaveDir(id.ToULong(16), controlHolder);
}
}
else if (extension == "nro")
@ -602,7 +602,7 @@ namespace LibKenjinx
PartitionFileSystem partitionFileSystem = new();
partitionFileSystem.Initialize(containerFile.AsStorage()).ThrowIfFailure();
SwitchDevice.VirtualFileSystem.ImportTickets(partitionFileSystem);
SwitchDevice?.VirtualFileSystem.ImportTickets(partitionFileSystem);
using UniqueRef<IFile> ncaFile = new();
@ -623,7 +623,7 @@ namespace LibKenjinx
{
try
{
return new Nca(SwitchDevice.VirtualFileSystem.KeySet, ncaStorage);
return new Nca(SwitchDevice?.VirtualFileSystem.KeySet, ncaStorage);
}
catch (Exception ex)
{
@ -636,7 +636,7 @@ namespace LibKenjinx
{
if (!File.Exists(path))
{
return new List<string>();
return [];
}
using FileStream containerFile = File.OpenRead(path);
@ -644,8 +644,8 @@ namespace LibKenjinx
PartitionFileSystem partitionFileSystem = new();
partitionFileSystem.Initialize(containerFile.AsStorage()).ThrowIfFailure();
SwitchDevice.VirtualFileSystem.ImportTickets(partitionFileSystem);
List<string> paths = new List<string>();
SwitchDevice?.VirtualFileSystem.ImportTickets(partitionFileSystem);
List<string> paths = [];
foreach (DirectoryEntryEx fileEntry in partitionFileSystem.EnumerateEntries("/", "*.nca"))
{
@ -871,7 +871,7 @@ namespace LibKenjinx
ref LibHac.Ns.ApplicationControlProperty control = ref nacpData.Value;
if (LibHac.Common.Utilities.IsZeros(nacpData.ByteSpan))
if (Utilities.IsZeros(nacpData.ByteSpan))
{
control = ref new BlitStruct<LibHac.Ns.ApplicationControlProperty>(1).Value;
control.UserAccountSaveDataSize = 0x4000;