Skip to content

Commit 3b3bf05

Browse files
committed
Updates to caching, item name string comparisons, and Simple Creator/Importer UIs(Partial).
1 parent 2d00299 commit 3b3bf05

File tree

4 files changed

+143
-68
lines changed

4 files changed

+143
-68
lines changed

xivModdingFramework/Cache/XivCache.cs

Lines changed: 69 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -133,13 +133,6 @@ public static void SetGameInfo(GameInfo gameInfo = null)
133133
}
134134

135135

136-
bool restartCacheWorker = false;
137-
if(gameInfo.GameDirectory != _gameInfo.GameDirectory)
138-
{
139-
// Have to restart cache worker if we're changing directories.
140-
CacheWorkerEnabled = false;
141-
restartCacheWorker = true;
142-
}
143136

144137
_dbPath = new DirectoryInfo(Path.Combine(_gameInfo.GameDirectory.Parent.Parent.FullName, dbFileName));
145138
_rootCachePath = new DirectoryInfo(Path.Combine(_gameInfo.GameDirectory.Parent.Parent.FullName, rootCacheFileName));
@@ -155,9 +148,6 @@ public static void SetGameInfo(GameInfo gameInfo = null)
155148

156149
CacheWorkerEnabled = true;
157150

158-
// This just triggers the cache worker to start if it's not already.
159-
CacheWorkerEnabled = CacheWorkerEnabled || restartCacheWorker;
160-
161151
}
162152

163153
/// <summary>
@@ -231,7 +221,9 @@ private static bool CacheNeedsRebuild()
231221
/// </summary>
232222
public static void RebuildCache()
233223
{
224+
CacheWorkerEnabled = false;
234225
_REBUILDING = true;
226+
235227
Task.Run(async () =>
236228
{
237229
if (_gameInfo.GameLanguage == XivLanguage.None)
@@ -271,6 +263,7 @@ public static void RebuildCache()
271263
}
272264
}).Wait();
273265
_REBUILDING = false;
266+
CacheWorkerEnabled = true;
274267
}
275268

276269
#region Cache Rebuilding
@@ -1150,14 +1143,12 @@ public static async Task<List<string>> GetChildFiles(string internalFilePath, bo
11501143
}
11511144

11521145

1146+
11531147
if (list.Count == 0)
11541148
{
1155-
// Need to pull the raw data to verify a 0 count entry.
1149+
// No cache data, have to update.
11561150
list = await XivDependencyGraph.GetChildFiles(internalFilePath);
1157-
if (list != null && list.Count > 0)
1158-
{
1159-
await UpdateChildFiles(internalFilePath, list);
1160-
}
1151+
await UpdateChildFiles(internalFilePath, list);
11611152
}
11621153
return list;
11631154
}
@@ -1190,10 +1181,14 @@ public static async Task<List<string>> GetParentFiles(string internalFilePath, b
11901181
{
11911182
// Need to pull the raw data to verify a 0 count entry.
11921183
list = await XivDependencyGraph.GetParentFiles(internalFilePath);
1193-
if (list != null && list.Count > 0)
1194-
{
1195-
await UpdateParentFiles(internalFilePath, list);
1196-
}
1184+
await UpdateParentFiles(internalFilePath, list);
1185+
1186+
// So if we updated our own parents, we have to update our children's parents too.
1187+
// Because we may be a previously orphaned node, that now is re-attached to the main tree.
1188+
var children = await GetChildFiles(internalFilePath);
1189+
1190+
// In short, any parent calculation is always cascading downwards.
1191+
QueueParentFilesUpdate(children);
11971192
}
11981193
return list;
11991194
}
@@ -1440,6 +1435,10 @@ public static Dictionary<string, List<string>> GetModListParents()
14401435
var modding = new Modding(GameInfo.GameDirectory);
14411436
var modList = modding.GetModList();
14421437
var dict = new Dictionary<string, List<string>>(modList.Mods.Count);
1438+
if(modList.Mods.Count == 0)
1439+
{
1440+
return dict;
1441+
}
14431442

14441443
var query = "select child, parent from dependencies_parents where child in(";
14451444
foreach(var mod in modList.Mods)
@@ -1643,11 +1642,18 @@ private static async Task UpdateParentFiles(string internalFilePath, List<string
16431642
}
16441643

16451644

1645+
/// <summary>
1646+
/// Qeuues a given file up for cache parent file updating.
1647+
/// </summary>
1648+
/// <param name="file"></param>
16461649
public static void QueueParentFilesUpdate(string file)
16471650
{
16481651
QueueParentFilesUpdate(new List<string>() { file });
16491652
}
16501653

1654+
/// <summary>
1655+
/// Qeuues a given set of files up for cache parent file updating.
1656+
/// </summary>
16511657
public static void QueueParentFilesUpdate(List<string> files)
16521658
{
16531659
try
@@ -1657,29 +1663,37 @@ public static void QueueParentFilesUpdate(List<string> files)
16571663
db.Open();
16581664
using (var transaction = db.BeginTransaction())
16591665
{
1660-
// First, clear out all the old data. This is the most important point.
1661-
var query = "delete from dependencies_parents where child = $child";
1662-
using (var delCmd = new SQLiteCommand(query, db))
1666+
foreach (var file in files)
16631667
{
1664-
// Then insert us into the queue.
1668+
// First, clear out all the old data.
1669+
var query = "delete from dependencies_parents where child = $child";
1670+
using (var delCmd = new SQLiteCommand(query, db))
1671+
{
1672+
delCmd.Parameters.AddWithValue("child", file);
1673+
delCmd.ExecuteScalar();
1674+
}
1675+
1676+
query = "delete from dependencies_update_queue where file = $file";
1677+
using (var delCmd = new SQLiteCommand(query, db))
1678+
{
1679+
delCmd.Parameters.AddWithValue("$file", file);
1680+
delCmd.ExecuteScalar();
1681+
}
1682+
1683+
// Then insert us into the back of the queue.
16651684
query = "insert into dependencies_update_queue (file) values ($file)";
16661685
using (var insertCmd = new SQLiteCommand(query, db))
16671686
{
16681687

1669-
foreach (var file in files)
1688+
var level = XivDependencyGraph.GetDependencyLevel(file);
1689+
if (level == XivDependencyLevel.Invalid || level == XivDependencyLevel.Root)
16701690
{
1671-
var level = XivDependencyGraph.GetDependencyLevel(file);
1672-
if (level == XivDependencyLevel.Invalid || level == XivDependencyLevel.Root)
1673-
{
1674-
continue;
1675-
}
1691+
continue;
1692+
}
16761693

1677-
delCmd.Parameters.AddWithValue("child", file);
1678-
delCmd.ExecuteScalar();
16791694

1680-
insertCmd.Parameters.AddWithValue("file", file);
1681-
insertCmd.ExecuteScalar();
1682-
}
1695+
insertCmd.Parameters.AddWithValue("file", file);
1696+
insertCmd.ExecuteScalar();
16831697
}
16841698
}
16851699
transaction.Commit();
@@ -1761,15 +1775,10 @@ private static void ProcessDependencyQueue(object sender, DoWorkEventArgs e)
17611775
level = XivDependencyGraph.GetDependencyLevel(file);
17621776
if (level == XivDependencyLevel.Invalid || level == XivDependencyLevel.Root ) continue;
17631777

1764-
// See if we actually need an update.
1765-
var task = GetParentFiles(file, true);
1778+
// The get call will automatically cache the data, if it needs updating.
1779+
var task = GetParentFiles(file, false);
17661780
task.Wait();
1767-
var parentFiles = task.Result;
1768-
if (parentFiles == null || parentFiles.Count == 0)
1769-
{
1770-
// Update us if we do.
1771-
UpdateParentFiles(file).Wait();
1772-
}
1781+
var parents = task.Result;
17731782
}
17741783
} catch( Exception ex)
17751784
{
@@ -1787,6 +1796,24 @@ private static void ProcessDependencyQueue(object sender, DoWorkEventArgs e)
17871796
}
17881797

17891798

1799+
/// <summary>
1800+
/// Internal function used in generating the cached parent data.
1801+
/// This checks the child cache to help see if any orphaned modded items
1802+
/// may reference this file still. Ex. An unused Material
1803+
/// referencing an unused Texture File.
1804+
/// </summary>
1805+
/// <param name="internalFilePath"></param>
1806+
/// <returns></returns>
1807+
internal static async Task<List<string>> GetCacheParents(string internalFilePath)
1808+
{
1809+
var wc = new WhereClause() { Column = "child", Comparer = WhereClause.ComparisonType.Equal, Value = internalFilePath };
1810+
return await BuildListFromTable("dependencies_children", wc, async (reader) =>
1811+
{
1812+
return reader.GetString("parent");
1813+
});
1814+
1815+
}
1816+
17901817
/// <summary>
17911818
/// Gets the current length of the dependency processing queue.
17921819
/// </summary>

xivModdingFramework/Cache/XivDependencyGraph.cs

Lines changed: 26 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -62,14 +62,7 @@ public static async Task<List<IItemModel>> GetSharedImcSubsetItems(this IItemMod
6262
}
6363
public static async Task<List<IItemModel>> GetSharedMaterialItems(this IItemModel item)
6464
{
65-
// Todo - Could do with cleaning this up to make it work for monsters/etc. too.
6665
var sameModelItems = new List<IItemModel>();
67-
if (!item.PrimaryCategory.Equals(XivStrings.Gear))
68-
69-
{
70-
sameModelItems.Add((IItemModel)item.Clone());
71-
return sameModelItems;
72-
}
7366
sameModelItems = await item.GetSharedModelItems();
7467

7568
var imc = new Imc(XivCache.GameInfo.GameDirectory);
@@ -1026,28 +1019,32 @@ public static async Task<List<string>> GetParentFiles(string internalFilePath)
10261019

10271020
} else if(level == XivDependencyLevel.Material)
10281021
{
1029-
var root = roots[0];
1022+
var parents = new HashSet<string>();
10301023

1031-
var parents = new List<string>();
1032-
1033-
// Get all models in this depedency tree.
1034-
var models = await root.GetModelFiles();
1035-
foreach (var model in models)
1024+
// For all our roots (Really just 1)
1025+
foreach (var root in roots)
10361026
{
1037-
// And check which materials they use.
1038-
var materials = await XivCache.GetChildFiles(model);
1039-
if (materials.Contains(internalFilePath))
1027+
// Get all models in this depedency tree.
1028+
var models = await root.GetModelFiles();
1029+
foreach (var model in models)
10401030
{
1041-
// If we're used in the model, it's one of our parents.
1042-
parents.Add(model);
1031+
// And make sure their child files are fully cached.
1032+
var materials = await XivCache.GetChildFiles(model);
10431033
}
10441034
}
10451035

1046-
return parents;
1036+
// Now we can go to the cache and pull all of our potential parents directly.
1037+
var cachedParents = await XivCache.GetCacheParents(internalFilePath);
1038+
foreach(var p in cachedParents)
1039+
{
1040+
parents.Add(p);
1041+
}
1042+
1043+
return parents.ToList();
10471044

10481045
} else if(level == XivDependencyLevel.Texture)
10491046
{
1050-
var parents = new List<string>();
1047+
var parents = new HashSet<string>();
10511048

10521049
// So, textures are the fun case where it's possible for them to have multiple roots.
10531050
foreach (var root in roots)
@@ -1056,16 +1053,19 @@ public static async Task<List<string>> GetParentFiles(string internalFilePath)
10561053
var materials = await root.GetMaterialFiles();
10571054
foreach(var mat in materials)
10581055
{
1059-
// Get all the textures they use.
1056+
// And make sure their child files are fully cached.
10601057
var textures = await XivCache.GetChildFiles(mat);
1061-
if(textures.Contains(internalFilePath))
1062-
{
1063-
parents.Add(mat);
1064-
}
10651058
}
10661059
}
10671060

1068-
return parents;
1061+
// Now we can go to the cache and pull all of our potential parents directly.
1062+
var cachedParents = await XivCache.GetCacheParents(internalFilePath);
1063+
foreach (var p in cachedParents)
1064+
{
1065+
parents.Add(p);
1066+
}
1067+
1068+
return parents.ToList();
10691069
}
10701070

10711071
// Shouldn't actually be possible to get here, but null to be safe.

xivModdingFramework/Items/Interfaces/IItem.cs

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
// along with this program. If not, see <http://www.gnu.org/licenses/>.
1616

1717
using System;
18+
using System.Collections.Generic;
1819
using xivModdingFramework.General.Enums;
1920

2021
namespace xivModdingFramework.Items.Interfaces
@@ -64,4 +65,50 @@ public interface IItem : IComparable
6465
/// </remarks>
6566
XivDataFile DataFile { get; }
6667
}
68+
69+
70+
/// <summary>
71+
/// Custom item name comparator.
72+
/// [Human Readable Names] => [NPC Names] => [Nulls/Invalids]
73+
/// </summary>
74+
public class ItemNameComparer : IComparer<string>
75+
{
76+
public ItemNameComparer()
77+
{
78+
}
79+
80+
public int Compare(string x, string y)
81+
{
82+
// Nulls
83+
var xNull = String.IsNullOrEmpty(x);
84+
var yNull = String.IsNullOrEmpty(y);
85+
if ( xNull && yNull )
86+
{
87+
return 0;
88+
} else if(xNull)
89+
{
90+
return 1;
91+
} else if(yNull)
92+
{
93+
return -1;
94+
}
95+
96+
// Both NPC Items.
97+
var xNpc = x.Contains("_v");
98+
var yNpc = y.Contains("_v");
99+
if (xNpc && yNpc)
100+
{
101+
return String.Compare(x, y, StringComparison.InvariantCultureIgnoreCase);
102+
} else if(xNpc)
103+
{
104+
return 1;
105+
} else if (yNpc)
106+
{
107+
return -1;
108+
}
109+
110+
111+
return String.Compare(x, y, StringComparison.InvariantCultureIgnoreCase);
112+
}
113+
}
67114
}

xivModdingFramework/Textures/Enums/XivTexType.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ public enum XivTexType
3232
Map,
3333
Icon,
3434
Vfx,
35+
UI,
3536
Other
3637
}
3738
}

0 commit comments

Comments
 (0)