mirror of
https://github.com/xivdev/Penumbra.git
synced 2026-02-23 08:17:59 +01:00
ResourceTree: Avoid enumerating the whole object table in some cases
This commit is contained in:
parent
22966e648d
commit
a241b933ca
4 changed files with 48 additions and 29 deletions
|
|
@ -27,49 +27,46 @@ public class ResourceTreeFactory
|
|||
_actors = actors;
|
||||
}
|
||||
|
||||
private TreeBuildCache CreateTreeBuildCache()
|
||||
=> new(_objects, _gameData, _actors);
|
||||
private TreeBuildCache CreateTreeBuildCache(bool withCharacters)
|
||||
=> new(_objects, _gameData, _actors, withCharacters);
|
||||
|
||||
public IEnumerable<Dalamud.Game.ClientState.Objects.Types.Character> GetLocalPlayerRelatedCharacters()
|
||||
{
|
||||
var cache = CreateTreeBuildCache();
|
||||
var cache = CreateTreeBuildCache(true);
|
||||
|
||||
return cache.Characters.Where(cache.IsLocalPlayerRelated);
|
||||
}
|
||||
|
||||
public IEnumerable<(Dalamud.Game.ClientState.Objects.Types.Character Character, ResourceTree ResourceTree)> FromObjectTable(
|
||||
bool localPlayerRelatedOnly = false, bool withUIData = true, bool redactExternalPaths = true)
|
||||
Flags flags)
|
||||
{
|
||||
var cache = CreateTreeBuildCache();
|
||||
var characters = localPlayerRelatedOnly ? cache.Characters.Where(cache.IsLocalPlayerRelated) : cache.Characters;
|
||||
var cache = CreateTreeBuildCache(true);
|
||||
var characters = (flags & Flags.LocalPlayerRelatedOnly) != 0 ? cache.Characters.Where(cache.IsLocalPlayerRelated) : cache.Characters;
|
||||
|
||||
foreach (var character in characters)
|
||||
{
|
||||
var tree = FromCharacter(character, cache, withUIData, redactExternalPaths);
|
||||
var tree = FromCharacter(character, cache, flags);
|
||||
if (tree != null)
|
||||
yield return (character, tree);
|
||||
}
|
||||
}
|
||||
|
||||
public IEnumerable<(Dalamud.Game.ClientState.Objects.Types.Character Character, ResourceTree ResourceTree)> FromCharacters(
|
||||
IEnumerable<Dalamud.Game.ClientState.Objects.Types.Character> characters,
|
||||
bool withUIData = true, bool redactExternalPaths = true)
|
||||
IEnumerable<Dalamud.Game.ClientState.Objects.Types.Character> characters, Flags flags)
|
||||
{
|
||||
var cache = CreateTreeBuildCache();
|
||||
var cache = CreateTreeBuildCache((flags & Flags.WithOwnership) != 0);
|
||||
foreach (var character in characters)
|
||||
{
|
||||
var tree = FromCharacter(character, cache, withUIData, redactExternalPaths);
|
||||
var tree = FromCharacter(character, cache, flags);
|
||||
if (tree != null)
|
||||
yield return (character, tree);
|
||||
}
|
||||
}
|
||||
|
||||
public ResourceTree? FromCharacter(Dalamud.Game.ClientState.Objects.Types.Character character, bool withUIData = true,
|
||||
bool redactExternalPaths = true)
|
||||
=> FromCharacter(character, CreateTreeBuildCache(), withUIData, redactExternalPaths);
|
||||
public ResourceTree? FromCharacter(Dalamud.Game.ClientState.Objects.Types.Character character, Flags flags)
|
||||
=> FromCharacter(character, CreateTreeBuildCache((flags & Flags.WithOwnership) != 0), flags);
|
||||
|
||||
private unsafe ResourceTree? FromCharacter(Dalamud.Game.ClientState.Objects.Types.Character character, TreeBuildCache cache,
|
||||
bool withUIData = true, bool redactExternalPaths = true)
|
||||
private unsafe ResourceTree? FromCharacter(Dalamud.Game.ClientState.Objects.Types.Character character, TreeBuildCache cache, Flags flags)
|
||||
{
|
||||
if (!character.IsValid())
|
||||
return null;
|
||||
|
|
@ -88,7 +85,7 @@ public class ResourceTreeFactory
|
|||
var networked = character.ObjectId != Dalamud.Game.ClientState.Objects.Types.GameObject.InvalidGameObjectId;
|
||||
var tree = new ResourceTree(name, character.ObjectIndex, (nint)gameObjStruct, (nint)drawObjStruct, localPlayerRelated, related, networked, collectionResolveData.ModCollection.Name);
|
||||
var globalContext = new GlobalResolveContext(_config, _identifier.AwaitedService, cache, collectionResolveData.ModCollection,
|
||||
((Character*)gameObjStruct)->CharacterData.ModelCharaId, withUIData, redactExternalPaths);
|
||||
((Character*)gameObjStruct)->CharacterData.ModelCharaId, (flags & Flags.WithUIData) != 0, (flags & Flags.RedactExternalPaths) != 0);
|
||||
tree.LoadResources(globalContext);
|
||||
tree.FlatNodes.UnionWith(globalContext.Nodes.Values);
|
||||
return tree;
|
||||
|
|
@ -119,4 +116,13 @@ public class ResourceTreeFactory
|
|||
|
||||
return (name, playerRelated);
|
||||
}
|
||||
|
||||
[Flags]
|
||||
public enum Flags
|
||||
{
|
||||
RedactExternalPaths = 1,
|
||||
WithUIData = 2,
|
||||
LocalPlayerRelatedOnly = 4,
|
||||
WithOwnership = 8,
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -16,16 +16,24 @@ internal class TreeBuildCache
|
|||
public readonly List<Character> Characters;
|
||||
public readonly Dictionary<uint, Character> CharactersById;
|
||||
|
||||
public TreeBuildCache(IObjectTable objects, IDataManager dataManager, ActorService actors)
|
||||
public TreeBuildCache(IObjectTable objects, IDataManager dataManager, ActorService actors, bool withCharacters)
|
||||
{
|
||||
_dataManager = dataManager;
|
||||
_actors = actors;
|
||||
Characters = objects.OfType<Character>().Where(ch => ch.IsValid()).ToList();
|
||||
CharactersById = Characters
|
||||
.Where(c => c.ObjectId != GameObject.InvalidGameObjectId)
|
||||
.GroupBy(c => c.ObjectId)
|
||||
.ToDictionary(c => c.Key, c => c.First());
|
||||
_localPlayerId = Characters.Count > 0 && Characters[0].ObjectIndex == 0 ? Characters[0].ObjectId : GameObject.InvalidGameObjectId;
|
||||
_localPlayerId = objects[0]?.ObjectId ?? GameObject.InvalidGameObjectId;
|
||||
if (withCharacters)
|
||||
{
|
||||
Characters = objects.OfType<Character>().Where(ch => ch.IsValid()).ToList();
|
||||
CharactersById = Characters
|
||||
.Where(c => c.ObjectId != GameObject.InvalidGameObjectId)
|
||||
.GroupBy(c => c.ObjectId)
|
||||
.ToDictionary(c => c.Key, c => c.First());
|
||||
}
|
||||
else
|
||||
{
|
||||
Characters = new();
|
||||
CharactersById = new();
|
||||
}
|
||||
}
|
||||
|
||||
public unsafe bool IsLocalPlayerRelated(Character character)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue