mirror of
https://github.com/goatcorp/Dalamud.git
synced 2026-01-02 05:43:40 +01:00
IGameConfig: fix load-time race condition
As some public properties of `IGameConfig` are being set on the first `Framework` tick, there was a short window that those properties were null, which goes against the interface declaration. This commit fixes that, by making those properties block for the full initialization of the class. A possible side effect is that a plugin that is set to block the game from loading until it loads will now hang the game if it tries to access the game configuration from its constructor, instead of throwing a `NullReferenceException`. As it would mean that the plugin was buggy at the first place and it would have sometimes failed to load anyway, it might as well be a non-breaking change.
This commit is contained in:
parent
ac59f73b59
commit
c27422384f
3 changed files with 126 additions and 23 deletions
|
|
@ -1,14 +1,20 @@
|
|||
using System;
|
||||
using System.Diagnostics;
|
||||
using System.Diagnostics;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
using Dalamud.Game.Config;
|
||||
using FFXIVClientStructs.FFXIV.Common.Configuration;
|
||||
using Dalamud.Plugin.Internal.Types;
|
||||
|
||||
namespace Dalamud.Plugin.Services;
|
||||
|
||||
/// <summary>
|
||||
/// This class represents the game's configuration.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Avoid accessing configuration from your plugin constructor, especially if your plugin sets
|
||||
/// <see cref="PluginManifest.LoadRequiredState"/> to <c>2</c> and <see cref="PluginManifest.LoadSync"/> to <c>true</c>.
|
||||
/// If property access from the plugin constructor is desired, do the value retrieval asynchronously via
|
||||
/// <see cref="IFramework.RunOnFrameworkThread{T}(Func{T})"/>; do not wait for the result right away.
|
||||
/// </remarks>
|
||||
public interface IGameConfig
|
||||
{
|
||||
/// <summary>
|
||||
|
|
@ -31,6 +37,16 @@ public interface IGameConfig
|
|||
/// </summary>
|
||||
public event EventHandler<ConfigChangeEvent> UiControlChanged;
|
||||
|
||||
/// <summary>
|
||||
/// Gets a task representing the initialization state of this instance of <see cref="IGameConfig"/>.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Accessing <see cref="GameConfigSection"/>-typed properties such as <see cref="System"/>, directly or indirectly
|
||||
/// via <see cref="TryGet(Game.Config.SystemConfigOption,out bool)"/>,
|
||||
/// <see cref="Set(Game.Config.SystemConfigOption,bool)"/>, or alike will block, if this task is incomplete.
|
||||
/// </remarks>
|
||||
public Task InitializationTask { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the collection of config options that persist between characters.
|
||||
/// </summary>
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue