use new mod hooks to synchronize tasks

This commit is contained in:
Jesse Plamondon-Willard 2021-08-12 21:26:12 -04:00
parent e16d6e98dc
commit 3a3688e094
No known key found for this signature in database
GPG Key ID: CF8B1456B3E29F49
2 changed files with 31 additions and 11 deletions

View File

@ -11,7 +11,6 @@ using System.Runtime.ExceptionServices;
using System.Security;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.Xna.Framework;
#if SMAPI_FOR_WINDOWS
using Microsoft.Win32;
@ -236,7 +235,7 @@ namespace StardewModdingAPI.Framework
monitor: this.Monitor,
reflection: this.Reflection,
eventManager: this.EventManager,
modHooks: new SModHooks(this.OnNewDayAfterFade),
modHooks: new SModHooks(this.OnNewDayAfterFade, this.Monitor),
multiplayer: this.Multiplayer,
exitGameImmediately: this.ExitGameImmediately,
@ -650,13 +649,6 @@ namespace StardewModdingAPI.Framework
this.Monitor.Log("Game loader done.");
}
if (instance.NewDayTask?.Status == TaskStatus.Created)
{
this.Monitor.Log("New day task synchronizing...");
instance.NewDayTask.RunSynchronously();
this.Monitor.Log("New day task done.");
}
// While a background task is in progress, the game may make changes to the game
// state while mods are running their code. This is risky, because data changes can
// conflict (e.g. collection changed during enumeration errors) and data may change
@ -666,7 +658,7 @@ namespace StardewModdingAPI.Framework
// a small chance that the task will finish after we defer but before the game checks,
// which means technically events should be raised, but the effects of missing one
// update tick are negligible and not worth the complications of bypassing Game1.Update.
if (instance.NewDayTask != null || Game1.gameMode == Game1.loadingMode)
if (Game1.gameMode == Game1.loadingMode)
{
events.UnvalidatedUpdateTicking.RaiseEmpty();
runUpdate();

View File

@ -1,4 +1,5 @@
using System;
using System.Threading.Tasks;
using StardewValley;
namespace StardewModdingAPI.Framework
@ -12,15 +13,20 @@ namespace StardewModdingAPI.Framework
/// <summary>A callback to invoke before <see cref="Game1.newDayAfterFade"/> runs.</summary>
private readonly Action BeforeNewDayAfterFade;
/// <summary>Writes messages to the console.</summary>
private readonly IMonitor Monitor;
/*********
** Public methods
*********/
/// <summary>Construct an instance.</summary>
/// <param name="beforeNewDayAfterFade">A callback to invoke before <see cref="Game1.newDayAfterFade"/> runs.</param>
public SModHooks(Action beforeNewDayAfterFade)
/// <param name="monitor">Writes messages to the console.</param>
public SModHooks(Action beforeNewDayAfterFade, IMonitor monitor)
{
this.BeforeNewDayAfterFade = beforeNewDayAfterFade;
this.Monitor = monitor;
}
/// <summary>A hook invoked when <see cref="Game1.newDayAfterFade"/> is called.</summary>
@ -30,5 +36,27 @@ namespace StardewModdingAPI.Framework
this.BeforeNewDayAfterFade?.Invoke();
action();
}
/// <summary>Start an asynchronous task for the game.</summary>
/// <param name="task">The task to start.</param>
/// <param name="id">A unique key which identifies the task.</param>
public override Task StartTask(Task task, string id)
{
this.Monitor.Log($"Synchronizing '{id}' task...");
task.RunSynchronously();
this.Monitor.Log(" task complete.");
return task;
}
/// <summary>Start an asynchronous task for the game.</summary>
/// <param name="task">The task to start.</param>
/// <param name="id">A unique key which identifies the task.</param>
public override Task<T> StartTask<T>(Task<T> task, string id)
{
this.Monitor.Log($"Synchronizing '{id}' task...");
task.RunSynchronously();
this.Monitor.Log(" task complete.");
return task;
}
}
}