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