Skip to content

Commit a3dbc0f

Browse files
committed
Updated iswall and invertbehavior attributes to remove their hyphen. Introduced defaulttoggle attribute. Updated manifest.
1 parent 789fec5 commit a3dbc0f

File tree

4 files changed

+106
-52
lines changed

4 files changed

+106
-52
lines changed

Entity/StandardMarker[invert-behavior].cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,12 +6,12 @@
66
namespace BhModule.Community.Pathing.Entity {
77
public partial class StandardMarker {
88

9-
private const string ATTR_INVERTBEHAVIOR = "invert-behavior";
9+
private const string ATTR_INVERTBEHAVIOR = "invertbehavior";
1010

1111
public bool InvertBehavior { get; set; }
1212

1313
/// <summary>
14-
/// invert-behavior
14+
/// invertbehavior
1515
/// </summary>
1616
[MethodImpl(MethodImplOptions.AggressiveInlining)]
1717
private void Populate_InvertBehavior(AttributeCollection collection, IPackResourceManager resourceManager) {

Entity/StandardTrail[wall].cs

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,21 @@
11
using System.Runtime.CompilerServices;
22
using BhModule.Community.Pathing.Utility;
3-
using Microsoft.Xna.Framework;
43
using TmfLib;
54
using TmfLib.Prototype;
65

76
namespace BhModule.Community.Pathing.Entity {
87
public partial class StandardTrail {
98

10-
private const string ATTR_WALL = "is-wall";
9+
private const string ATTR_ISWALL = "iswall";
1110

1211
public bool IsWall { get; set; }
1312

1413
/// <summary>
15-
/// is-wall
14+
/// iswall
1615
/// </summary>
1716
[MethodImpl(MethodImplOptions.AggressiveInlining)]
1817
private void Populate_IsWall(AttributeCollection collection, IPackResourceManager resourceManager) {
19-
{ if (collection.TryPopAttribute(ATTR_WALL, out var attribute)) this.IsWall = attribute.GetValueAsBool(); }
18+
{ if (collection.TryPopAttribute(ATTR_ISWALL, out var attribute)) this.IsWall = attribute.GetValueAsBool(); }
2019
}
2120

2221
}

State/CategoryStates.cs

Lines changed: 100 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -15,14 +15,16 @@ public class CategoryStates : ManagedState {
1515

1616
private static readonly Logger Logger = Logger.GetLogger<CategoryStates>();
1717

18-
private const string STATE_FILE = "categories.txt";
18+
private const string STATE_FILE = "categories.txt";
19+
private const string INVERTEDSTATE_FILE = "invcategories.txt";
1920

2021
private const double INTERVAL_SAVESTATE = 5000; // 5.0 seconds
2122
private const double INTERVAL_UPDATEINACTIVECATEGORIES = 100; // 0.1 seconds
2223

2324
private HashSet<string> _inactiveCategories = new(StringComparer.OrdinalIgnoreCase);
2425

25-
private readonly SafeList<PathingCategory> _rawInactiveCategories = new();
26+
private readonly SafeList<PathingCategory> _rawInactiveCategories = new(); // Contains all categories which have been explicitly unchecked.
27+
private readonly SafeList<PathingCategory> _rawInvertedCategories = new(); // Contains all categories which have been explicitly checked and by default are toggled off.
2628

2729
private double _lastSaveState = 0;
2830
private double _lastInactiveCategoriesCalculation = 0;
@@ -32,115 +34,168 @@ public class CategoryStates : ManagedState {
3234

3335
public CategoryStates(IRootPackState packState) : base(packState) { /* NOOP */ }
3436

35-
private async Task LoadState() {
36-
string categoryStatesPath = Path.Combine(DataDirUtil.GetSafeDataDir(DataDirUtil.COMMON_STATE), STATE_FILE);
37+
private async Task LoadCategoryState(string stateFileName, SafeList<PathingCategory> rawCategoriesList, PathingCategory rootCategory) {
38+
string categoryStatePath = Path.Combine(DataDirUtil.GetSafeDataDir(DataDirUtil.COMMON_STATE), stateFileName);
3739

38-
if (!File.Exists(categoryStatesPath)) return;
40+
if (!File.Exists(categoryStatePath))
41+
return; // Early skip if this state file doesn't exist yet.
3942

4043
string[] recordedCategories = Array.Empty<string>();
4144

4245
try {
43-
recordedCategories = await FileUtil.ReadLinesAsync(categoryStatesPath);
46+
recordedCategories = await FileUtil.ReadLinesAsync(categoryStatePath);
4447
} catch (Exception e) {
45-
Logger.Error(e, $"Failed to read {STATE_FILE} ({categoryStatesPath}).");
48+
Logger.Error(e, $"Failed to read {STATE_FILE} ({categoryStatePath}).");
4649
}
47-
48-
_rawInactiveCategories.Clear();
49-
50-
var rootCategory = _rootPackState.RootCategory;
5150

52-
if (rootCategory == null) return; // Early skip if the pack is already getting repopulated.
51+
rawCategoriesList.Clear();
5352

5453
foreach (string categoryNamespace in recordedCategories) {
5554
// TODO: Consider the case where a category no longer exists - this will create it.
56-
// Luckily, it shouldn't display anyways because it will not have a displayname.
57-
_rawInactiveCategories.Add(rootCategory.GetOrAddCategoryFromNamespace(categoryNamespace));
55+
// We end up ignoring it, though, as it is known that it was not pulled from a pack based on the LoadedFromPack property.
56+
rawCategoriesList.Add(rootCategory.GetOrAddCategoryFromNamespace(categoryNamespace));
5857
}
59-
60-
_calculationDirty = true;
6158
}
6259

63-
private async Task SaveState(GameTime gameTime) {
64-
if (!_stateDirty) return;
60+
private async Task LoadStates() {
61+
var rootCategory = _rootPackState.RootCategory;
6562

66-
Logger.Debug($"Saving {nameof(CategoryStates)} state.");
63+
if (rootCategory == null)
64+
return; // Early skip if the pack is already getting repopulated.
65+
66+
Logger.Debug($"Loading {nameof(CategoryStates)} state.");
67+
68+
await LoadCategoryState(STATE_FILE, _rawInactiveCategories, rootCategory);
69+
await LoadCategoryState(INVERTEDSTATE_FILE, _rawInvertedCategories, rootCategory);
6770

68-
PathingCategory[] inactiveCategories = _rawInactiveCategories.ToArray();
71+
_calculationDirty = true;
72+
}
73+
74+
private async Task SaveCategoryState(string stateFileName, SafeList<PathingCategory> rawCategoriesList) {
75+
PathingCategory[] toggledCategories = rawCategoriesList.ToArray();
6976

70-
string categoryStatesPath = Path.Combine(DataDirUtil.GetSafeDataDir(DataDirUtil.COMMON_STATE), STATE_FILE);
77+
string categoryStatePath = Path.Combine(DataDirUtil.GetSafeDataDir(DataDirUtil.COMMON_STATE), stateFileName);
7178

7279
try {
73-
await FileUtil.WriteLinesAsync(categoryStatesPath, inactiveCategories.Select(c => c.Namespace));
80+
await FileUtil.WriteLinesAsync(categoryStatePath, toggledCategories.Select(c => c.Namespace));
7481
} catch (Exception e) {
75-
Logger.Error(e, $"Failed to write {STATE_FILE} ({categoryStatesPath}).");
82+
Logger.Error(e, $"Failed to write {stateFileName} ({categoryStatePath}).");
7683
}
84+
}
85+
86+
private async Task SaveStates(GameTime gameTime) {
87+
if (!_stateDirty) return;
88+
89+
Logger.Debug($"Saving {nameof(CategoryStates)} state.");
90+
91+
await SaveCategoryState(STATE_FILE, _rawInactiveCategories); // Standard categories.
92+
await SaveCategoryState(INVERTEDSTATE_FILE, _rawInvertedCategories); // Inverted categories.
7793

7894
_stateDirty = false;
7995
}
8096

97+
private void AddAllSubCategories(HashSet<string> categories, PathingCategory topCategory) {
98+
var remainingCategories = new Queue<PathingCategory>(topCategory);
99+
100+
while (remainingCategories.Count > 0) {
101+
var category = remainingCategories.Dequeue();
102+
103+
categories.Add(category.Namespace);
104+
105+
foreach (var subCategory in category) {
106+
remainingCategories.Enqueue(subCategory);
107+
}
108+
}
109+
}
110+
81111
private void CalculateOptimizedCategoryStates(GameTime gameTime) {
82112
if (!_calculationDirty) return;
83113

84-
PathingCategory[] inactiveCategories = _rawInactiveCategories.ToArray();
114+
if (_rootPackState.RootCategory == null) return;
85115

86-
var preCalcInactiveCategories = new HashSet<string>(StringComparer.OrdinalIgnoreCase);
116+
PathingCategory[] inactiveCategories = _rawInactiveCategories.ToArray();
117+
PathingCategory[] activeInvertedCategories = _rawInvertedCategories.ToArray();
87118

88-
foreach (var inactiveCategory in inactiveCategories) {
89-
AddAllSubCategories(preCalcInactiveCategories, inactiveCategory);
90-
}
119+
var remainingCategories = new Queue<PathingCategory>();
120+
remainingCategories.Enqueue(_rootPackState.RootCategory);
91121

92-
_inactiveCategories = preCalcInactiveCategories;
122+
var preCalcInactiveCategories = new HashSet<string>(StringComparer.OrdinalIgnoreCase);
93123

94-
_calculationDirty = false;
95-
}
124+
while (remainingCategories.Count > 0) {
125+
var category = remainingCategories.Dequeue();
96126

97-
private void AddAllSubCategories(HashSet<string> categories, PathingCategory currentCategory) {
98-
categories.Add(currentCategory.Namespace);
127+
if (inactiveCategories.Contains(category) // Standard toggled categories.
128+
|| (!category.DefaultToggle && !activeInvertedCategories.Contains(category))) { // Inverted toggled categories.
129+
preCalcInactiveCategories.Add(category.Namespace);
130+
AddAllSubCategories(preCalcInactiveCategories, category);
131+
continue;
132+
}
99133

100-
foreach (var subCategory in currentCategory) {
101-
AddAllSubCategories(categories, subCategory);
134+
foreach (var subCategory in category) {
135+
remainingCategories.Enqueue(subCategory);
136+
}
102137
}
138+
139+
_inactiveCategories = preCalcInactiveCategories;
140+
_calculationDirty = false;
103141
}
104142

105143
protected override async Task<bool> Initialize() {
106-
await LoadState();
144+
await LoadStates();
107145

108146
return true;
109147
}
110148

111149
public override async Task Reload() {
112150
_inactiveCategories.Clear();
113151
_rawInactiveCategories.Clear();
152+
_rawInvertedCategories.Clear();
114153

115-
await LoadState();
154+
await LoadStates();
116155
}
117156

118157
public override void Update(GameTime gameTime) {
119158
UpdateCadenceUtil.UpdateWithCadence(CalculateOptimizedCategoryStates, gameTime, INTERVAL_UPDATEINACTIVECATEGORIES, ref _lastInactiveCategoriesCalculation);
120-
UpdateCadenceUtil.UpdateAsyncWithCadence(SaveState, gameTime, INTERVAL_SAVESTATE, ref _lastSaveState);
159+
UpdateCadenceUtil.UpdateAsyncWithCadence(SaveStates, gameTime, INTERVAL_SAVESTATE, ref _lastSaveState);
121160
}
122161

123162
public override async Task Unload() {
124-
await SaveState(null);
163+
await SaveStates(null);
125164
}
126165

127166
public bool GetNamespaceInactive(string categoryNamespace) {
128167
return _inactiveCategories.Contains(categoryNamespace);
129168
}
130169

170+
private bool GetCategoryInactive(PathingCategory category, SafeList<PathingCategory> rawCategoriesList) {
171+
return rawCategoriesList.Contains(category);
172+
}
173+
131174
public bool GetCategoryInactive(PathingCategory category) {
132-
return _rawInactiveCategories.Contains(category);
175+
if (category.DefaultToggle) {
176+
return GetCategoryInactive(category, _rawInactiveCategories);
177+
} else {
178+
return !GetCategoryInactive(category, _rawInvertedCategories);
179+
}
133180
}
134181

135-
public void SetInactive(PathingCategory category, bool isInactive) {
136-
_rawInactiveCategories.Remove(category);
182+
private void SetInactive(PathingCategory category, bool isInactive, SafeList<PathingCategory> rawCategoriesList) {
183+
rawCategoriesList.Remove(category);
137184

138185
if (isInactive) {
139-
_rawInactiveCategories.Add(category);
186+
rawCategoriesList.Add(category);
140187
}
141188

142-
_stateDirty = true;
143-
_calculationDirty = true;
189+
_stateDirty = true; // Ensure that we save the new state.
190+
_calculationDirty = true; // Ensure that the hashset is recalculated.
191+
}
192+
193+
public void SetInactive(PathingCategory category, bool isInactive) {
194+
if (category.DefaultToggle) {
195+
SetInactive(category, isInactive, _rawInactiveCategories);
196+
} else {
197+
SetInactive(category, !isInactive, _rawInvertedCategories);
198+
}
144199
}
145200

146201
public void SetInactive(string categoryNamespace, bool isInactive) => SetInactive(_rootPackState.RootCategory.GetOrAddCategoryFromNamespace(categoryNamespace), isInactive);

manifest.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "Pathing",
3-
"version": "0.14.0",
3+
"version": "0.15.0",
44
"namespace": "bh.community.pathing",
55
"package": "Pathing.dll",
66
"manifest_version": 1,

0 commit comments

Comments
 (0)