mirror of
https://github.com/xivdev/Penumbra.git
synced 2025-12-15 05:04:15 +01:00
Add try-catch and locking to framework manager.
This commit is contained in:
parent
ff5e72e979
commit
2ca90f2518
1 changed files with 45 additions and 20 deletions
|
|
@ -3,6 +3,7 @@ using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using Dalamud.Game;
|
using Dalamud.Game;
|
||||||
|
using Dalamud.Logging;
|
||||||
|
|
||||||
namespace Penumbra.Util;
|
namespace Penumbra.Util;
|
||||||
|
|
||||||
|
|
@ -19,57 +20,81 @@ public class FrameworkManager : IDisposable
|
||||||
// One action per frame will be executed.
|
// One action per frame will be executed.
|
||||||
// On dispose, any remaining actions will be executed.
|
// On dispose, any remaining actions will be executed.
|
||||||
public void RegisterDelayed( string tag, Action action )
|
public void RegisterDelayed( string tag, Action action )
|
||||||
=> _delayed[ tag ] = action;
|
{
|
||||||
|
lock( _delayed )
|
||||||
|
{
|
||||||
|
_delayed[ tag ] = action;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Register an action that should be executed on the next frame.
|
// Register an action that should be executed on the next frame.
|
||||||
// All of those actions will be executed in the next frame.
|
// All of those actions will be executed in the next frame.
|
||||||
// If there are more than one, they will be launched in separated tasks, but waited for.
|
// If there are more than one, they will be launched in separated tasks, but waited for.
|
||||||
public void RegisterImportant( string tag, Action action )
|
public void RegisterImportant( string tag, Action action )
|
||||||
=> _important[ tag ] = action;
|
{
|
||||||
|
lock( _important )
|
||||||
|
{
|
||||||
|
_important[ tag ] = action;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public void Dispose()
|
public void Dispose()
|
||||||
{
|
{
|
||||||
Dalamud.Framework.Update -= OnUpdate;
|
Dalamud.Framework.Update -= OnUpdate;
|
||||||
HandleAll( _delayed );
|
foreach( var (_, action) in _delayed )
|
||||||
|
{
|
||||||
|
action();
|
||||||
|
}
|
||||||
|
|
||||||
|
_delayed.Clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void OnUpdate( Framework _ )
|
private void OnUpdate( Framework _ )
|
||||||
{
|
{
|
||||||
HandleOne();
|
try
|
||||||
HandleAllTasks( _important );
|
|
||||||
}
|
|
||||||
|
|
||||||
private void HandleOne()
|
|
||||||
{
|
|
||||||
if( _delayed.Count > 0 )
|
|
||||||
{
|
{
|
||||||
var (key, action) = _delayed.First();
|
HandleOne( _delayed );
|
||||||
action();
|
HandleAllTasks( _important );
|
||||||
_delayed.Remove( key );
|
}
|
||||||
|
catch( Exception e )
|
||||||
|
{
|
||||||
|
PluginLog.Error( $"Problem saving data:\n{e}" );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void HandleAll( IDictionary< string, Action > dict )
|
private static void HandleOne( IDictionary< string, Action > dict )
|
||||||
{
|
{
|
||||||
foreach( var (_, action) in dict )
|
if( dict.Count == 0 )
|
||||||
{
|
{
|
||||||
action();
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
dict.Clear();
|
Action action;
|
||||||
|
lock( dict )
|
||||||
|
{
|
||||||
|
( var key, action ) = dict.First();
|
||||||
|
dict.Remove( key );
|
||||||
|
}
|
||||||
|
|
||||||
|
action();
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void HandleAllTasks( IDictionary< string, Action > dict )
|
private static void HandleAllTasks( IDictionary< string, Action > dict )
|
||||||
{
|
{
|
||||||
if( dict.Count < 2 )
|
if( dict.Count < 2 )
|
||||||
{
|
{
|
||||||
HandleAll( dict );
|
HandleOne( dict );
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
var tasks = dict.Values.Select( Task.Run ).ToArray();
|
Task[] tasks;
|
||||||
|
lock( dict )
|
||||||
|
{
|
||||||
|
tasks = dict.Values.Select( Task.Run ).ToArray();
|
||||||
|
dict.Clear();
|
||||||
|
}
|
||||||
|
|
||||||
Task.WaitAll( tasks );
|
Task.WaitAll( tasks );
|
||||||
dict.Clear();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Loading…
Add table
Add a link
Reference in a new issue