diff options
author | Jesse Plamondon-Willard <github@jplamondonw.com> | 2017-05-07 13:09:32 -0400 |
---|---|---|
committer | Jesse Plamondon-Willard <github@jplamondonw.com> | 2017-05-07 13:09:32 -0400 |
commit | 624840efe5f3d4135dafeb2939b182cfeb4ec6c3 (patch) | |
tree | 0a791fae54d20320efc4c7cf55bc34f51ddf2d10 /src/StardewModdingAPI | |
parent | 8963793bf854bee368b5cd08a3e0eb410ee8e1a9 (diff) | |
download | SMAPI-624840efe5f3d4135dafeb2939b182cfeb4ec6c3.tar.gz SMAPI-624840efe5f3d4135dafeb2939b182cfeb4ec6c3.tar.bz2 SMAPI-624840efe5f3d4135dafeb2939b182cfeb4ec6c3.zip |
use more robust sprite batch recovery logic (#283)
Diffstat (limited to 'src/StardewModdingAPI')
-rw-r--r-- | src/StardewModdingAPI/Framework/InternalExtensions.cs | 22 | ||||
-rw-r--r-- | src/StardewModdingAPI/Framework/SGame.cs | 27 |
2 files changed, 36 insertions, 13 deletions
diff --git a/src/StardewModdingAPI/Framework/InternalExtensions.cs b/src/StardewModdingAPI/Framework/InternalExtensions.cs index 5199c72d..cadf6598 100644 --- a/src/StardewModdingAPI/Framework/InternalExtensions.cs +++ b/src/StardewModdingAPI/Framework/InternalExtensions.cs @@ -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); + } } } diff --git a/src/StardewModdingAPI/Framework/SGame.cs b/src/StardewModdingAPI/Framework/SGame.cs index f8226529..7dae937b 100644 --- a/src/StardewModdingAPI/Framework/SGame.cs +++ b/src/StardewModdingAPI/Framework/SGame.cs @@ -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,22 +967,20 @@ 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); - Game1.spriteBatch.End(); + try + { + Game1.spriteBatch.End(); + } + catch + { + Game1.spriteBatch = new SpriteBatch(this.GraphicsDevice); // sprite batch is broken, try replacing it + } } } catch (Exception innerEx) |