Created
June 7, 2018 09:10
-
-
Save Frooxius/c923996857ecec936f3b27545efeb7f4 to your computer and use it in GitHub Desktop.
Asset Cleanup
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System; | |
using System.Collections.Generic; | |
using System.Linq; | |
using System.Text; | |
using System.Threading.Tasks; | |
namespace FrooxEngine | |
{ | |
public static partial class WorldOptimizer | |
{ | |
public static void CleanupAssets(World world) | |
{ | |
var assets = world.RootSlot.Find("Assets"); | |
if (assets == null) | |
return; | |
// cleanup the assets first | |
CleanupUnreferencedAssets(assets); | |
// cleanup leftover empty slots | |
CleanupSlotsWithNonpersistentComponents(assets, false); | |
} | |
public static void CleanupUnreferencedAssets(Slot root, bool ignoreNonpersistentUsers = true) | |
{ | |
foreach (var assetProvider in root.GetComponentsInChildren<IAssetProvider>()) | |
if (!IsReferencedOutsideHierarchy(assetProvider, root, ignoreNonpersistentUsers)) | |
((Component)assetProvider).Persistent = false; | |
} | |
public static bool IsReferencedOutsideHierarchy(IAssetProvider assetProvider, Slot hierarchyRoot, bool ignoreNonpersistentUsers = true, | |
HashSet<IAssetProvider> walked = null) | |
{ | |
if (walked == null) | |
walked = new HashSet<IAssetProvider>(); | |
if (walked.Contains(assetProvider)) | |
return false; | |
walked.Add(assetProvider); | |
foreach(var reference in assetProvider.References) | |
{ | |
if (ignoreNonpersistentUsers && !reference.IsPersistent) | |
continue; | |
if (!reference.FindNearestParent<Slot>().IsChildOf(hierarchyRoot, true)) | |
return true; | |
// check if the referencing component is also an asset provider, which might be on itself referenced outside | |
// the hiearchy | |
var referencingProvider = reference.FindNearestParent<Component>() as IAssetProvider; | |
if (referencingProvider != null) | |
if (IsReferencedOutsideHierarchy(referencingProvider, hierarchyRoot, ignoreNonpersistentUsers, walked)) | |
return true; | |
} | |
// didn't find any reference outside the hierchy | |
return false; | |
} | |
public static void CleanupSlotsWithNonpersistentComponents(Slot root, bool includingSelf = true) | |
{ | |
// run recursively on children first | |
for (int i = root.ChildrenCount-1; i >= 0; i--) | |
CleanupSlotsWithNonpersistentComponents(root[i]); | |
if(includingSelf) | |
{ | |
if (root.Components.Count(c => c.Persistent) == 0 && root.Children.Count(ch => ch.PersistentSelf) == 0) | |
root.PersistentSelf = false; | |
} | |
} | |
public static void CleanupEmptySlots(Slot root, bool includingSelf = true) | |
{ | |
// run it recursively on children first | |
for(int i = root.ChildrenCount-1; i >= 0; i--) | |
CleanupEmptySlots(root[i]); | |
// the current slot has no componets and children, delete it | |
if(includingSelf) | |
{ | |
if (root.ComponentCount == 0 && root.ChildrenCount == 0) | |
root.Destroy(); | |
} | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment