Skip to content

Commit

Permalink
Improved performance of IsPackedToApp implementation for expecially c…
Browse files Browse the repository at this point in the history
…ircular dependencies and fixed other small bugs
  • Loading branch information
pak762 committed Sep 8, 2021
1 parent 185a729 commit a61923d
Show file tree
Hide file tree
Showing 11 changed files with 64 additions and 58 deletions.
4 changes: 3 additions & 1 deletion AssetRelationsViewer/Editor/AssetRelationsViewerWindow.cs
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@ private class MergedNode
private Dictionary<string, VisualizationNodeData> _cachedVisualizationNodeDatas = new Dictionary<string, VisualizationNodeData>();
private Dictionary<string, AssetCacheData> _cachedNodes = new Dictionary<string, AssetCacheData>();
private Dictionary<string, int> _cachedSizes = new Dictionary<string, int>();
private Dictionary<string, bool> _cachedPackedInfo = new Dictionary<string, bool>();

private Stack<UndoStep> _undoSteps = new Stack<UndoStep>();

Expand Down Expand Up @@ -788,7 +789,7 @@ private VisualizationNodeData AddNodeCacheForNode(string id, string type)

data.Name = typeHandler.GetName(id);
data.IsEditorAsset = nodeHandler.IsNodeEditorOnly(id, type);
data.IsPackedToApp = NodeDependencyLookupUtility.IsNodePackedToApp(id, type, _nodeDependencyLookupContext, new HashSet<string>());
data.IsPackedToApp = NodeDependencyLookupUtility.IsNodePackedToApp(id, type, _nodeDependencyLookupContext, _cachedPackedInfo);

_cachedVisualizationNodeDatas.Add(key, data);
}
Expand All @@ -804,6 +805,7 @@ private void InvalidateTreeVisualization()
private void Refresh()
{
_cachedSizes.Clear();
_cachedPackedInfo.Clear();
_cachedVisualizationNodeDatas.Clear();
_cachedNodes.Clear();
InvalidateNodeStructure();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -94,16 +94,8 @@ public override void TraverseObject(string id, Object obj, Stack<PathSegment> st
do
{
SerializedPropertyType propertyType = property.propertyType;

if (propertyType == SerializedPropertyType.Character |
propertyType == SerializedPropertyType.Integer |
propertyType == SerializedPropertyType.Float |
propertyType == SerializedPropertyType.String |
propertyType == SerializedPropertyType.Vector4 |
propertyType == SerializedPropertyType.Vector2 |
propertyType == SerializedPropertyType.Vector3 |
propertyType == SerializedPropertyType.ArraySize
)

if (propertyType != SerializedPropertyType.ObjectReference && propertyType != SerializedPropertyType.Generic)
{
continue;
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using System.Collections.Generic;
using System.Linq;
using UnityEditor;
using UnityEditor.SceneManagement;
using UnityEngine;
Expand Down Expand Up @@ -66,6 +67,7 @@ public void TraverseScene(string id, Object obj, Stack<PathSegment> stack)
public void TraverseGameObject(string id, Object obj, Stack<PathSegment> stack, Object currentPrefab, bool isRoot)
{
var go = obj as GameObject;
bool isPrefabInstance = false;
bool onlyOverriden = false;

#if UNITY_2018_3_OR_NEWER
Expand All @@ -76,6 +78,7 @@ public void TraverseGameObject(string id, Object obj, Stack<PathSegment> stack,
if (PrefabUtility.GetCorrespondingObjectFromSource(go))
{
onlyOverriden = true;
isPrefabInstance = true;
var prefabObj = PrefabUtility.GetPrefabInstanceHandle(obj);

if(prefabObj != currentPrefab)
Expand Down Expand Up @@ -111,7 +114,9 @@ public void TraverseGameObject(string id, Object obj, Stack<PathSegment> stack,
}
#endif

Dictionary<string, int> componentToCount = new Dictionary<string, int>();
Dictionary<string, int> componentToCount = new Dictionary<string, int>();

List<AddedComponent> addedComponents = isPrefabInstance ? PrefabUtility.GetAddedComponents(go) : null;

foreach (Component component in go.GetComponents<Component>())
{
Expand All @@ -120,19 +125,26 @@ public void TraverseGameObject(string id, Object obj, Stack<PathSegment> stack,
continue;
}

bool componentOverriden = onlyOverriden;

if (isPrefabInstance)
{
bool isAddedComponent = addedComponents.Any(addedComponent => addedComponent.instanceComponent == component);
componentOverriden &= !isAddedComponent;
}

string componentName = component.GetType().Name;

if (!componentToCount.ContainsKey(componentName))
{
componentToCount.Add(componentName, 1);
}

int count = componentToCount[componentName]++;
int sameComponentCount = componentToCount[componentName]++;
string segmentName = sameComponentCount > 1 ? $"{componentName}_{sameComponentCount}" : componentName;

string segmentName = count > 1 ? string.Format("{0}_{1}", componentName, count) : componentName;

stack.Push(new PathSegment(segmentName, PathSegmentType.Component));
TraverseObject(id, component, stack, onlyOverriden);
TraverseObject(id, component, stack, componentOverriden);
stack.Pop();
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -312,9 +312,9 @@ public int GetOwnFileSize(string id, string type, NodeDependencyLookupContext st
return 0;
}

public bool IsNodePackedToApp(string id, string type)
public bool IsNodePackedToApp(string id, string type, bool alwaysExcluded)
{
return true;
return false;
}

public bool IsNodeEditorOnly(string id, string type)
Expand Down
20 changes: 7 additions & 13 deletions NodeDependencyLookup/Editor/NodeHandler/AssetNodeHandler.cs
Original file line number Diff line number Diff line change
Expand Up @@ -26,26 +26,20 @@ public int GetOwnFileSize(string id, string type, NodeDependencyLookupContext st
return 0;
}

public bool IsNodePackedToApp(string id, string type)
public bool IsNodePackedToApp(string id, string type, bool alwaysExcluded = false)
{
string path = AssetDatabase.GUIDToAssetPath(id);

if (IsNodeEditorOnly(id, type))
if (alwaysExcluded)
{
return false;
return !IsNodeEditorOnly(id, type);
}

/*if (IsSceneAndPacked(path) || IsInResources(path))
{
return true;
}*/

return false;

string path = AssetDatabase.GUIDToAssetPath(NodeDependencyLookupUtility.GetGuidFromAssetId(id));
return IsSceneAndPacked(path) || IsInResources(path) || id.StartsWith("0000000");
}

public bool IsNodeEditorOnly(string id, string type)
{
string path = AssetDatabase.GUIDToAssetPath(id);
string path = AssetDatabase.GUIDToAssetPath(NodeDependencyLookupUtility.GetGuidFromAssetId(id));
return path.Contains("/Editor/");
}

Expand Down
18 changes: 6 additions & 12 deletions NodeDependencyLookup/Editor/NodeHandler/FileNodeHandler.cs
Original file line number Diff line number Diff line change
Expand Up @@ -26,21 +26,15 @@ public int GetOwnFileSize(string id, string type, NodeDependencyLookupContext st
return NodeDependencyLookupUtility.GetPackedAssetSize(id);
}

public bool IsNodePackedToApp(string id, string type)
public bool IsNodePackedToApp(string id, string type, bool alwaysExcluded)
{
string path = AssetDatabase.GUIDToAssetPath(id);

if (IsNodeEditorOnly(id, type))
{
return false;
}

if (IsSceneAndPacked(path) || IsInResources(path))
if (alwaysExcluded)
{
return true;
return !IsNodeEditorOnly(id, type);
}

return false;

string path = AssetDatabase.GUIDToAssetPath(id);
return IsSceneAndPacked(path) || IsInResources(path) || id.StartsWith("0000000");
}

public bool IsNodeEditorOnly(string id, string type)
Expand Down
2 changes: 1 addition & 1 deletion NodeDependencyLookup/Editor/NodeHandler/INodeHandler.cs
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ public interface INodeHandler
// Returns the filesize if the node. In case of an asset it would be the serialized filesize
int GetOwnFileSize(string id, string type, NodeDependencyLookupContext stateContext);
// Returns if a node is packed to the app or not. Helpful to find out if an asset is actually used in the final game or not
bool IsNodePackedToApp(string id, string type);
bool IsNodePackedToApp(string id, string type, bool alwaysExcluded = false);
// Returns if a node it just used within the editor. For assets this would be case if its in an editor folder
bool IsNodeEditorOnly(string id, string type);
// Returns if the assets contributes to the overall tree size (size of all dependencies together)
Expand Down
32 changes: 20 additions & 12 deletions NodeDependencyLookup/Editor/Utility/NodeDependencyLookupUtility.cs
Original file line number Diff line number Diff line change
Expand Up @@ -234,23 +234,23 @@ private static string GetAssetDatabaseVersion1LibraryDataPath(string guid)
/// </summary>
public static bool IsNodePackedToApp(string id, string type, NodeDependencyLookupContext stateContext)
{
return IsNodePackedToApp(id, type, stateContext, new HashSet<string>());
return IsNodePackedToApp(id, type, stateContext, new Dictionary<string, bool>());
}

/// <summary>
/// Right now this only works if the asset or one of its parents (referencers) are in a packaged scene or in a resources folder.
/// If the asset is just in a bundle this is currently not tracked. Trying to find a solution for this.
/// </summary>
public static bool IsNodePackedToApp(string id, string type, NodeDependencyLookupContext stateContext,
HashSet<string> visitedKeys)
Dictionary<string, bool> checkedPackedStates)
{
if (visitedKeys.Contains(id))
if (checkedPackedStates.ContainsKey(id))
{
return false;
return checkedPackedStates[id];
}

visitedKeys.Add(id);

checkedPackedStates.Add(id, false);
Node node = stateContext.RelationsLookup.GetNode(id, type);

if (node == null)
Expand All @@ -262,9 +262,18 @@ public static bool IsNodePackedToApp(string id, string type, NodeDependencyLooku
{
INodeHandler nodeHandler = pair.Value;

if (nodeHandler.GetHandledNodeTypes().Contains(type) && nodeHandler.IsNodePackedToApp(id, type))
if (nodeHandler.GetHandledNodeTypes().Contains(type))
{
return true;
if (!nodeHandler.IsNodePackedToApp(id, type, true))
{
return false;
}

if (nodeHandler.IsNodePackedToApp(id, type, false))
{
checkedPackedStates[id] = true;
return true;
}
}
}

Expand All @@ -273,8 +282,9 @@ public static bool IsNodePackedToApp(string id, string type, NodeDependencyLooku
Node refNode = connection.Node;

if (!stateContext.ConnectionTypeLookup.GetDependencyType(connection.Type).IsIndirect &&
IsNodePackedToApp(refNode.Id, refNode.Type, stateContext, visitedKeys))
IsNodePackedToApp(refNode.Id, refNode.Type, stateContext, checkedPackedStates))
{
checkedPackedStates[id] = true;
return true;
}
}
Expand Down Expand Up @@ -397,8 +407,6 @@ public static string[] GetAllAssetPathes(ProgressBase progress, bool unityBuilti
{
string[] pathes = AssetDatabase.GetAllAssetPaths();

pathes = AssetDatabase.GetAllAssetPaths();

List<string> pathList = new List<string>();

foreach (string path in pathes)
Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ If you are in production and not want to get automatic updates always use a tagg

```js
...
"com.innogames.asset-relations-viewer": "https://github.com/innogames/asset-relations-viewer.git#1.2.4",
"com.innogames.asset-relations-viewer": "https://github.com/innogames/asset-relations-viewer.git#1.3.0",
...

```
Expand Down
4 changes: 4 additions & 0 deletions changelog.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
**1.3.0**
- Fixed several bugs regarding detection of if an asset is packed into the app or not and added cache to speed up the detection
- Fixed issue that added components to a PrefabInstance didnt show the usage of their script as a dependency

**1.2.4**
- Increased version to make a new release

Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
"name": "com.innogames.asset-relations-viewer",
"displayName": "Asset Relations Viewer",
"description": "Editor UI for displaying dependencies between assets in a tree based view",
"version": "1.2.4",
"version": "1.3.0",
"unity": "2018.4",
"license": "MIT",
"repository": {
Expand Down

0 comments on commit a61923d

Please sign in to comment.