use more robust sprite batch recovery logic (#283)
This commit is contained in:
parent
8963793bf8
commit
624840efe5
|
@ -2,6 +2,8 @@
|
|||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
using Microsoft.Xna.Framework.Graphics;
|
||||
using StardewValley;
|
||||
|
||||
namespace StardewModdingAPI.Framework
|
||||
{
|
||||
|
@ -128,5 +130,25 @@ namespace StardewModdingAPI.Framework
|
|||
deprecationManager.Warn(modName, nounPhrase, version, severity);
|
||||
}
|
||||
}
|
||||
|
||||
/****
|
||||
** Sprite batch
|
||||
****/
|
||||
/// <summary>Get whether the sprite batch is between a begin and end pair.</summary>
|
||||
/// <param name="spriteBatch">The sprite batch to check.</param>
|
||||
/// <param name="reflection">The reflection helper with which to access private fields.</param>
|
||||
public static bool IsOpen(this SpriteBatch spriteBatch, IReflectionHelper reflection)
|
||||
{
|
||||
// get field name
|
||||
const string fieldName =
|
||||
#if SMAPI_FOR_WINDOWS
|
||||
"inBeginEndPair";
|
||||
#else
|
||||
"_beginCalled";
|
||||
#endif
|
||||
|
||||
// get result
|
||||
return reflection.GetPrivateValue<bool>(Game1.spriteBatch, fieldName);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -38,7 +38,7 @@ namespace StardewModdingAPI.Framework
|
|||
private readonly int MaxFailedDraws = 120; // roughly two seconds
|
||||
|
||||
/// <summary>The number of consecutive failed draws.</summary>
|
||||
private int FailedDraws = 0;
|
||||
private int FailedDraws;
|
||||
|
||||
/// <summary>Whether the player has loaded a save and the world has finished initialising.</summary>
|
||||
private bool IsWorldReady => this.AfterLoadTimer < 0;
|
||||
|
@ -956,6 +956,9 @@ namespace StardewModdingAPI.Framework
|
|||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
// log error
|
||||
this.Monitor.Log($"An error occured in the overridden draw loop: {ex.GetLogSummary()}", LogLevel.Error);
|
||||
|
||||
// exit if irrecoverable
|
||||
if (this.FailedDraws >= this.MaxFailedDraws)
|
||||
{
|
||||
|
@ -964,23 +967,21 @@ namespace StardewModdingAPI.Framework
|
|||
}
|
||||
this.FailedDraws++;
|
||||
|
||||
// log error
|
||||
this.Monitor.Log($"An error occured in the overridden draw loop: {ex.GetLogSummary()}", LogLevel.Error);
|
||||
|
||||
// fix sprite batch
|
||||
// recover sprite batch
|
||||
try
|
||||
{
|
||||
bool isSpriteBatchOpen =
|
||||
#if SMAPI_FOR_WINDOWS
|
||||
SGame.Reflection.GetPrivateValue<bool>(Game1.spriteBatch, "inBeginEndPair");
|
||||
#else
|
||||
SGame.Reflection.GetPrivateValue<bool>(Game1.spriteBatch, "_beginCalled");
|
||||
#endif
|
||||
if (isSpriteBatchOpen)
|
||||
if (Game1.spriteBatch.IsOpen(SGame.Reflection))
|
||||
{
|
||||
this.Monitor.Log("Recovering sprite batch from error...", LogLevel.Trace);
|
||||
try
|
||||
{
|
||||
Game1.spriteBatch.End();
|
||||
}
|
||||
catch
|
||||
{
|
||||
Game1.spriteBatch = new SpriteBatch(this.GraphicsDevice); // sprite batch is broken, try replacing it
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (Exception innerEx)
|
||||
{
|
||||
|
|
Loading…
Reference in New Issue