Class SystemAdoptionClosureRules
The pure decisions behind SystemAdoptionPlanner: which dependency-closure paths are
content (never scripts/assemblies), where a source path mirrors to under an adoption's output root,
and how the already-adopted entries seed a later clone's GUID map. No AssetDatabase calls —
existing-destination lookup is a caller-supplied delegate — so this is testable without a project.
Inheritance
SystemAdoptionClosureRules
Assembly: Serenity.UnityCreateGame.Infrastructure.Editor.dll
Syntax
public static class SystemAdoptionClosureRules
Fields
ExcludedExtensions
Extensions a dependency closure never clones: source and assembly-definition files. The
goal is content-only adoption — the adopted system's runtime TYPE stays in the package; only its
DATA moves.
Declaration
public static readonly string[] ExcludedExtensions
Field Value
Methods
BuildEntry(string, string, string, IReadOnlyList<string>, Func<string, string>)
Builds one closure entry: mirrors the destination, then asks resolveExistingDestinationGuid
(an AssetDatabase-backed lookup in production, a fake in a pure test) whether that
destination already exists.
Declaration
public static SystemAdoptionEntry BuildEntry(string sourcePath, string sourceGuid, string outputRoot, IReadOnlyList<string> packageRoots, Func<string, string> resolveExistingDestinationGuid)
Parameters
Returns
BuildSeedGuidMap(IReadOnlyList<SystemAdoptionEntry>)
Source GUID → existing destination GUID for every already-adopted entry.
Declaration
public static IReadOnlyDictionary<string, string> BuildSeedGuidMap(IReadOnlyList<SystemAdoptionEntry> entries)
Parameters
Returns
IsExcludedByExtension(string)
True when assetPath's extension is one a closure never clones.
Declaration
public static bool IsExcludedByExtension(string assetPath)
Parameters
| Type |
Name |
Description |
| string |
assetPath |
|
Returns
MirrorDestinationPath(string, string, IReadOnlyList<string>)
Mirrors sourcePath under outputRoot, relative to
whichever packageRoots entry contains it — the theme/module folder keeps its
own name; adoption never renames. Null when sourcePath is not under any of
packageRoots.
Declaration
public static string MirrorDestinationPath(string sourcePath, string outputRoot, IReadOnlyList<string> packageRoots)
Parameters
Returns
SourcePathFromMirror(string, string, IReadOnlyList<string>, Func<string, bool>)
The reverse of MirrorDestinationPath(string, string, IReadOnlyList<string>): strips outputRoot
from destinationPath, then prepends each of packageRoots in
turn, returning the single candidate exists reports as real — null when
destinationPath is not under outputRoot, or when zero or more
than one candidate exists (an adoption mirror is never ambiguous by construction, but a caller
must not guess when it somehow is).
Declaration
public static string SourcePathFromMirror(string destinationPath, string outputRoot, IReadOnlyList<string> packageRoots, Func<string, bool> exists)
Parameters
Returns
WalkClosure(IEnumerable<string>, Func<string, IReadOnlyList<string>>, Func<string, bool>, Func<string, bool>)
Breadth-first walk of the dependency closure shared by every path in rootPaths.
At each visited node, getDirectDependencies (an
AssetDatabase.GetDependencies(path, recursive: false) call in production) supplies the
next candidates; isClosureCandidate filters out anything that is not
package content (scripts, assemblies, project-owned assets); isExcludedFromClosure
(an identity-carrying-prefab check in production) marks a candidate as excluded instead of
visiting it — an excluded node's own dependencies never enter the walk. Every root seeds both the
seen set and the descend queue up front, so a dependency shared by two roots yields a single visit,
and a root that happens to be another root's dependency is never visited (or descended into) twice.
A HashSet of seen paths also makes a diamond (two paths converging on one asset) yield a
single visit and a cycle terminate instead of looping.
Declaration
public static SystemAdoptionClosureWalkResult WalkClosure(IEnumerable<string> rootPaths, Func<string, IReadOnlyList<string>> getDirectDependencies, Func<string, bool> isClosureCandidate, Func<string, bool> isExcludedFromClosure)
Parameters
Returns
WalkClosure(string, Func<string, IReadOnlyList<string>>, Func<string, bool>, Func<string, bool>)
Declaration
public static SystemAdoptionClosureWalkResult WalkClosure(string rootPath, Func<string, IReadOnlyList<string>> getDirectDependencies, Func<string, bool> isClosureCandidate, Func<string, bool> isExcludedFromClosure)
Parameters
Returns