diff --git a/code/client/clrcore-v2/Coroutine/CoroutineMethods.cs b/code/client/clrcore-v2/Coroutine/CoroutineMethods.cs index bb873d87e6..0ed357cf1c 100644 --- a/code/client/clrcore-v2/Coroutine/CoroutineMethods.cs +++ b/code/client/clrcore-v2/Coroutine/CoroutineMethods.cs @@ -1,6 +1,7 @@ using System.Collections.Generic; using System; using System.Runtime.InteropServices; +using System.Threading; namespace CitizenFX.Core { @@ -208,25 +209,37 @@ public static Coroutine Schedule(Action function, ulong delay, ulong iterations, #region Run /// - /// Runs given function directly and allows the caller to await it. + /// Runs given function on the main thread; will be scheduled if we're not on the main thread, otherwise it'll be run directly. /// /// Function to run /// Awaitable - public static Coroutine Run(Func function) => function(); - - /// public static Coroutine Run(Action function) { - function(); - return Completed(); + if (Thread.CurrentThread == Scheduler.MainThread) + { + function(); + return Completed(); + } + + return RunNextFrame(function); } - /// - /// Runs given function directly and allows the caller to await it. - /// - /// Function to run - /// Awaitable - public static Coroutine Run(Func> function) => function(); + /// + public static Coroutine Run(Func function) + { + return Thread.CurrentThread == Scheduler.MainThread + ? function() + : RunNextFrame(function); + } + + /// Awaitable + /// + public static Coroutine Run(Func> function) + { + return Thread.CurrentThread == Scheduler.MainThread + ? function() + : RunNextFrame(function); + } /// /// Runs given function next frame and allows the caller to await it. @@ -260,7 +273,7 @@ public static Coroutine RunNextFrame(Action function) /// Runs given function directly and allows the caller to await it. /// /// Function to run - /// Awaitable + /// Awaitable public static Coroutine RunNextFrame(Func> function) { var coroutine = new Coroutine(); diff --git a/code/client/clrcore-v2/Interop/EventsManager.cs b/code/client/clrcore-v2/Interop/EventsManager.cs index f77cb2c443..58ce9878f6 100644 --- a/code/client/clrcore-v2/Interop/EventsManager.cs +++ b/code/client/clrcore-v2/Interop/EventsManager.cs @@ -181,7 +181,7 @@ public EventHandlerSet Remove(Delegate deleg) /// this event handler set /// delegate to register /// itself - public static EventHandlerSet operator +(EventHandlerSet entry, Delegate deleg) => entry.Add(Func.Create(deleg.Target, deleg.Method)); + public static EventHandlerSet operator +(EventHandlerSet entry, Delegate deleg) => entry.Add(Func.Create(deleg)); /// /// Unregister an event handler diff --git a/code/client/clrcore-v2/Interop/Types/CString.cs b/code/client/clrcore-v2/Interop/Types/CString.cs index 59cc707eaf..bc677a563c 100644 --- a/code/client/clrcore-v2/Interop/Types/CString.cs +++ b/code/client/clrcore-v2/Interop/Types/CString.cs @@ -315,6 +315,13 @@ public int CompareTo(CString other) /// null-terminated c-string public static explicit operator string(CString str) => str?.ToString(); + /// + /// Copy into a null-terminated c-string + /// + /// OutString to copy + /// + public static implicit operator CString(OutString str) => str.ToCString(); + #endregion #region ASCII operations diff --git a/code/client/clrcore-v2/Native/Types/OutString.cs b/code/client/clrcore-v2/Native/Types/OutString.cs index f433171c7b..78e4e71625 100644 --- a/code/client/clrcore-v2/Native/Types/OutString.cs +++ b/code/client/clrcore-v2/Native/Types/OutString.cs @@ -19,13 +19,6 @@ namespace CitizenFX.Core [SecuritySafeCritical] public static unsafe implicit operator string(in OutString str) => Marshal.PtrToStringAnsi((IntPtr)str.data); - /// - /// A managed string that holds a copy of the unmanaged ANSI string. If ptr is null, the method returns a null string. - /// - /// - [SecuritySafeCritical] - public static unsafe explicit operator CString(in OutString str) => CString.Create(str.data); - /// /// A managed byte[] that holds a copy of the unmanaged ANSI string. If ptr is null, the method returns a null string. /// @@ -50,7 +43,12 @@ namespace CitizenFX.Core public override string ToString() => (string)this; - public CString ToCString() => (CString)this; + /// + /// Creates a null terminated C-string out of the returned string + /// + /// null terminated C-string + [SecuritySafeCritical] + public unsafe CString ToCString() => CString.Create(data); /// /// Retrieves a substring from this string. Starting at the specified in strides of