Skip to content

Commit

Permalink
Use names for option lookups
Browse files Browse the repository at this point in the history
- Adds resiliency for patch-day updates
  • Loading branch information
KazWolfe committed Mar 8, 2023
1 parent 748ceef commit 3dbe4ec
Show file tree
Hide file tree
Showing 4 changed files with 60 additions and 22 deletions.
76 changes: 57 additions & 19 deletions FFXIVPlugin/Game/GameConfig.cs
Original file line number Diff line number Diff line change
@@ -1,20 +1,53 @@
using System;
using System.Collections.Generic;
using Dalamud.Logging;
using Dalamud.Memory;
using FFXIVClientStructs.FFXIV.Client.System.Framework;
using FFXIVClientStructs.FFXIV.Client.UI.Misc;
using FFXIVClientStructs.FFXIV.Common.Configuration;
using XIVDeck.FFXIVPlugin.Utils;

namespace XIVDeck.FFXIVPlugin.Game;
namespace XIVDeck.FFXIVPlugin.Game;

// Shamelessly stolen from SimpleTweaks, again. Thank you for the work, Cara!
// https://github.com/Caraxi/SimpleTweaksPlugin/blob/main/Utility/GameConfig.cs
public static unsafe class GameConfig {
public class GameConfigSection {

private readonly Dictionary<string, uint> _indexCache = new();
private readonly ConfigBase* _configBase;

// Note for future me: This class operates on the *names* of keys, not the values as defined by the enum.
// This may be confusing and honestly I don't like the fact that I do it this way, but I like the correctness
// guarantee, so... this is what we get.

public GameConfigSection(ConfigBase* configBase) {
this._configBase = configBase;

// Preload cache for performance
var e = this._configBase->ConfigEntry;
for (var i = 0U; i < this._configBase->ConfigCount; i++, e++) {
if (e->Name == null) continue;
this._indexCache[MemoryHelper.ReadStringNullTerminated((nint) e->Name)] = i;
}
}

private bool TryGetIndex(string name, out uint index) {
if (this._indexCache.TryGetValue(name, out index)) return true;

PluginLog.Verbose($"Cache miss on TryGetIndex for {name}!");
var e = this._configBase->ConfigEntry;
for (var i = 0U; i < this._configBase->ConfigCount; i++, e++) {
if (e->Name == null) continue;
var eName = MemoryHelper.ReadStringNullTerminated((nint) e->Name);

if (eName.Equals(name)) {
this._indexCache.Add(name, i);
index = i;
return true;
}
}

return false;
}

private bool TryGetEntry(uint index, out ConfigEntry* entry) {
Expand All @@ -24,53 +57,58 @@ private bool TryGetEntry(uint index, out ConfigEntry* entry) {
entry += index;
return true;
}


private bool TryGetEntry(ConfigOption option, out ConfigEntry* entry, bool searchByName = true) {
entry = null;
var index = (uint) option;
if (searchByName && !this.TryGetIndex(option.ToString(), out index)) return false;

return this.TryGetEntry(index, out entry);
}

public bool TryGetBool(ConfigOption option, out bool value) {
value = false;
if (!this.TryGetEntry((uint) option, out var entry)) return false;
if (!this.TryGetEntry(option, out var entry)) return false;
value = entry->Value.UInt != 0;
return true;
}

public bool GetBool(ConfigOption option) {
if (!this.TryGetBool(option, out var value))
throw new Exception($"Failed to get Bool '{nameof(option)}'");
if (!this.TryGetBool(option, out var value))
throw new ArgumentOutOfRangeException(nameof(option), @$"No option {option} was found.");

return value;
}

public void Set(ConfigOption option, bool value) {
if (!this.TryGetEntry((uint) option, out var entry)) return;
if (!this.TryGetEntry(option, out var entry)) return;
entry->SetValue(value ? 1U : 0U);
}

public bool TryGetUInt(ConfigOption option, out uint value) {
value = 0;
if (!this.TryGetEntry((uint) option, out var entry)) return false;
if (!this.TryGetEntry(option, out var entry)) return false;
value = entry->Value.UInt;
return true;
}

public uint GetUInt(ConfigOption option) {
if (!this.TryGetUInt(option, out var value))
throw new Exception($"Failed to get UInt '{nameof(option)}'");
if (!this.TryGetUInt(option, out var value))
throw new ArgumentOutOfRangeException(nameof(option), @$"No option {option} was found.");

return value;
}

public void Set(ConfigOption option, uint value) {
if (!this.TryGetEntry((uint) option, out var entry)) return;
if (!this.TryGetEntry(option, out var entry)) return;
entry->SetValue(value);
}

public IDisposable TemporarySet(ConfigOption option, bool value) {
var oldValue = this.GetBool(option);

return new DisposableWrapper(delegate {
this.Set(option, value);
}, delegate {
this.Set(option, oldValue);
});
this.Set(option, value);
return new DisposableWrapper(() => { this.Set(option, oldValue); });
}
}

Expand All @@ -84,4 +122,4 @@ static GameConfig() {
public static readonly GameConfigSection System;
public static readonly GameConfigSection UiConfig;
public static readonly GameConfigSection UiControl;
}
}
2 changes: 1 addition & 1 deletion FFXIVPlugin/Game/Watchers/VolumeWatcher.cs
Original file line number Diff line number Diff line change
Expand Up @@ -105,7 +105,7 @@ private static uint GetVolumeRaw(SoundChannel channel) {
}

private static bool IsMutedRaw(SoundChannel channel) {
return GameConfig.System.GetUInt(Channels[channel].MuteState) == 1u;
return GameConfig.System.GetBool(Channels[channel].MuteState);
}

private static void SetVolume(SoundChannel channel, uint level) {
Expand Down
2 changes: 1 addition & 1 deletion FFXIVPlugin/XIVDeck.FFXIVPlugin.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
<Product>XIVDeck Game Plugin</Product>
<Authors>Kaz Wolfe</Authors>
<Company>Blacksite Technologies</Company>
<Version>0.3.9</Version>
<Version>0.3.10</Version>

<AssemblyName>XIVDeck.FFXIVPlugin</AssemblyName>

Expand Down
2 changes: 1 addition & 1 deletion SDPlugin/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@kazwolfe/xivdeck-sdplugin",
"version": "0.3.9",
"version": "0.3.10",
"private": true,
"license": "MPL",
"scripts": {
Expand Down

0 comments on commit 3dbe4ec

Please sign in to comment.