thread safety and performance improv

This commit is contained in:
rootdarkarchon
2023-04-04 13:54:33 +02:00
parent a4d9207506
commit 1e9d4998ce
4 changed files with 42 additions and 24 deletions

View File

@@ -12,6 +12,7 @@ using MareSynchronos.Utils;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging;
using System.Numerics;
using System.Runtime.CompilerServices;
using GameObject = FFXIVClientStructs.FFXIV.Client.Game.Object.GameObject;
namespace MareSynchronos.Services;
@@ -53,6 +54,7 @@ public class DalamudUtilService : IHostedService
public unsafe GameObject* GposeTarget => TargetSystem.Instance()->GPoseTarget;
public unsafe Dalamud.Game.ClientState.Objects.Types.GameObject? GposeTargetGameObject => GposeTarget == null ? null : _objectTable[GposeTarget->ObjectIndex];
public bool IsInCutscene { get; private set; } = false;
public bool IsInFrameworkThread => _framework.IsInFrameworkUpdateThread;
public bool IsInGpose { get; private set; } = false;
public bool IsLoggedIn { get; private set; }
public bool IsPlayerPresent => _clientState.LocalPlayer != null && _clientState.LocalPlayer.IsValid();
@@ -146,20 +148,37 @@ public class DalamudUtilService : IHostedService
return false;
}
public async Task RunOnFrameworkThread(Action act)
public async Task RunOnFrameworkThread(Action act, [CallerMemberName] string callerMember = "",
[CallerFilePath] string callerFilePath = "", [CallerLineNumber] int lineNumber = 0)
{
_logger.LogTrace("Running Action on framework thread (FrameworkContext: {ctx}): {act}", _framework.IsInFrameworkUpdateThread, act);
_logger.LogTrace("Running Action on framework thread (FrameworkContext: {ctx}): {member} in {file}:{line}", _framework.IsInFrameworkUpdateThread, callerMember, callerFilePath, lineNumber);
if (!_framework.IsInFrameworkUpdateThread)
await _framework.RunOnFrameworkThread(act).ConfigureAwait(false);
{
await _framework.RunOnFrameworkThread(act).ContinueWith((_) => Task.CompletedTask).ConfigureAwait(false);
while (_framework.IsInFrameworkUpdateThread) // yield the thread again, should technically never be triggered
{
_logger.LogTrace("Still on framework");
await Task.Delay(1).ConfigureAwait(false);
}
}
else
act();
}
public async Task<T> RunOnFrameworkThread<T>(Func<T> func)
public async Task<T> RunOnFrameworkThread<T>(Func<T> func, [CallerMemberName] string callerMember = "",
[CallerFilePath] string callerFilePath = "", [CallerLineNumber] int lineNumber = 0)
{
_logger.LogTrace("Running Func on framework thread (FrameworkContext: {ctx}): {act}", _framework.IsInFrameworkUpdateThread, func);
_logger.LogTrace("Running Func on framework thread (FrameworkContext: {ctx}): {member} in {file}:{line}", _framework.IsInFrameworkUpdateThread, callerMember, callerFilePath, lineNumber);
if (!_framework.IsInFrameworkUpdateThread)
return await _framework.RunOnFrameworkThread(func).ConfigureAwait(false);
{
var result = await _framework.RunOnFrameworkThread(func).ContinueWith((task) => task.Result).ConfigureAwait(false);
while (_framework.IsInFrameworkUpdateThread) // yield the thread again, should technically never be triggered
{
_logger.LogTrace("Still on framework");
await Task.Delay(1).ConfigureAwait(false);
}
return result;
}
else
return func.Invoke();
}