Class SettingsAssetResolution
Resolve-or-create for a settings asset identified BY ID WITHIN A FOLDER — the shape every creator that
authors many assets of one type needs, and the counterpart to
ResolveSettingsContext<TSettings>(string, string), which answers the opposite
question: where is the ONE project-wide settings asset?
Replaces the byte-identical private helper WaveCreator, SequencePlayerCreator and
PlayerInputCreator each declared, plus the concrete twins in
InitializationPipelineProfileCreator and LoggingProfileCreator. Those five differed only
in whether the fallback file name arrived as a parameter or as a class constant.
Lives beside SettingsAssetAuthoring rather than beside
Serenity.Global.Infrastructure.Editor.SerenityAssetIdLookup because it needs
EnsureProjectFolderExists(string, ICollection<string>) and
VerifyAssetWasWrittenToDisk(string), and this assembly already depends on
the one those two lookups live in — the reverse would be a cycle. Reaching past
EnsureProjectFolderExists to the EnsureFolder it wraps would drop its
Assets-path-shape guard, which for some callers is the only validation the path gets.
ResolveOrCreateAtPath<TSettings>(SettingsResolution<TSettings>, string, string, string, SerenityAssetCreationTransaction, out bool) is the by-type twin: resolve-or-create for the ONE
project-wide settings asset a wizard resolves via
ResolveSettingsContext<TSettings>(string, string), identified by an explicit or
fallback path rather than by Id within a folder. It is extracted from the byte-identical private helper
GameGraphicsSettingsCreator, LocalizationSettingsCreator, LoggingProfileCreator and
GameProgressCreator each declare today; the adopter PRs migrate them to it. Like ResolveOrCreateByIdInFolder<TSettings>(string, string, string, SerenityAssetCreationTransaction, out bool) it
ensures the folder lazily — only on the create path, never when an existing asset is returned — but it
constrains only UnityEngine.ScriptableObject, not IFoundationSettings, so it never
assigns an Id or a Guid; the caller seeds both on the returned asset afterward, exactly like the four
copies do.
Inheritance
SettingsAssetResolution
Assembly: Serenity.UnityStructuredPersistence.Infrastructure.Editor.dll
Syntax
public static class SettingsAssetResolution
Methods
DescribeWriteBoundaryCollision<TSettings>(string, string, string)
Pure query form of ResolveOrCreateByIdInFolder<TSettings>(string, string, string, SerenityAssetCreationTransaction, out bool)'s own write-boundary check:
describes the exact same collision, without throwing — null when nothing collides, INCLUDING the
index-lag case where the planned path already holds the exact asset being resolved (same type, same
Id ordinally). Lets a preflight validator (see ValidateNoWriteBoundaryCollision<TSettings>(string, string, string, SerenityCreationValidationResult))
surface this refusal to the author as a blocking validation error BEFORE the primary action ever calls
ResolveOrCreateByIdInFolder<TSettings>(string, string, string, SerenityAssetCreationTransaction, out bool), instead of only after a rolled-back transaction.
The message text is built in DescribeCollision(string, string) so the
thrown and the validated wording never drift apart.
Declaration
public static string DescribeWriteBoundaryCollision<TSettings>(string folderPath, string id, string fileNameFallback) where TSettings : ScriptableObject, IFoundationSettings
Parameters
Returns
Type Parameters
| Name |
Description |
| TSettings |
|
PlannedAssetPath(string, string, string)
Declaration
public static string PlannedAssetPath(string explicitAssetPath, string fallbackFolderPath, string fallbackFileName)
Parameters
| Type |
Name |
Description |
| string |
explicitAssetPath |
|
| string |
fallbackFolderPath |
|
| string |
fallbackFileName |
|
Returns
PlannedByIdPath(string, string, string)
Declaration
public static string PlannedByIdPath(string folderPath, string id, string fileNameFallback)
Parameters
Returns
ResolveOrCreateAtPath<TSettings>(SettingsResolution<TSettings>, string, string, string, SerenityAssetCreationTransaction, out bool)
Returns resolution.Existing untouched when set — no folder is ensured and nothing
is written to disk; otherwise creates a new TSettings at
explicitAssetPath when given, or at
fallbackFolderPath/fallbackFileName.asset otherwise.
The folder ensured is always the CHOSEN path's own parent folder, not necessarily
fallbackFolderPath itself — an explicit path pointing somewhere else is honored
as given, exactly like the four private copies it is extracted from. The caller is responsible for
sanitizing fallbackFileName (via FileNameSafe(string, string) or
equivalent) before calling, since the desired sanitization fallback differs per caller.
Unlike ResolveOrCreateByIdInFolder<TSettings>(string, string, string, SerenityAssetCreationTransaction, out bool) this never assumes
IFoundationSettings and never assigns an Id or a Guid — the caller seeds both on the
returned asset AFTER this call, exactly like the four copies do.
Declaration
public static TSettings ResolveOrCreateAtPath<TSettings>(SettingsAssetAuthoring.SettingsResolution<TSettings> resolution, string explicitAssetPath, string fallbackFolderPath, string fallbackFileName, SerenityAssetCreationTransaction transaction, out bool createdNew) where TSettings : ScriptableObject
Parameters
Returns
| Type |
Description |
| TSettings |
|
Type Parameters
| Name |
Description |
| TSettings |
|
ResolveOrCreateByIdInFolder<TSettings>(string, string, string, SerenityAssetCreationTransaction, out bool)
Returns the existing TSettings asset in folderPath (and
its subfolders) whose Id equals id ordinally, so the caller updates it in place;
otherwise creates one named after id — falling back to
fileNameFallback when the Id yields no usable file name — assigns it a fresh
Guid, and hands the path to transaction, which
registers it with Addressables on commit and deletes it on rollback.
The folder is ensured on the create path even when the caller already ensured it. That is not a
redundant write: UnityEditorUtils.ResourceUtils.EnsureFolder returns before touching the
AssetDatabase — and before recording anything for rollback — as soon as
UnityEditor.AssetDatabase.IsValidFolder(System.String) reports the folder exists. Paying that check unconditionally
is what lets one method serve callers that ensure beforehand and callers that do not, instead of two
near-identical overloads encoding nothing but the caller's own statement order.
Declaration
public static TSettings ResolveOrCreateByIdInFolder<TSettings>(string folderPath, string id, string fileNameFallback, SerenityAssetCreationTransaction transaction, out bool createdNew) where TSettings : ScriptableObject, IFoundationSettings
Parameters
| Type |
Name |
Description |
| string |
folderPath |
|
| string |
id |
|
| string |
fileNameFallback |
|
| SerenityAssetCreationTransaction |
transaction |
|
| bool |
createdNew |
|
Returns
| Type |
Description |
| TSettings |
|
Type Parameters
| Name |
Description |
| TSettings |
|
ValidateCreateDestinationFolder<TSettings>(string, IEnumerable<string>, string, SerenityCreationValidationResult)
Declaration
public static void ValidateCreateDestinationFolder<TSettings>(string folderPath, IEnumerable<string> ids, string fieldName, SerenityCreationValidationResult result) where TSettings : ScriptableObject, IFoundationSettings
Parameters
Type Parameters
| Name |
Description |
| TSettings |
|
ValidateCreateDestinationFolder<TSettings>(string, string, string, SerenityCreationValidationResult)
Adds Serenity.Global.Infrastructure.Editor.SerenityProjectOutputFolderRules's rejection as a blocking error when this run
would CREATE a new TSettings in folderPath and that folder
is not one a project may write generated assets into — the destination half of the shipped-content
contract, for the creators that resolve-or-create by Id within one folder.
Deliberately a no-op when the by-Id lookup already resolves an asset there: that folder is then not
a destination at all, it is where an asset this run UPDATES happens to live, and whether the update
may proceed is Serenity.Global.Infrastructure.Editor.ShippedContentWriteGate's question —
ResolveOrCreateByIdInFolder<TSettings>(string, string, string, SerenityAssetCreationTransaction, out bool) asks it through
Serenity.StructuredPersistence.Infrastructure.Editor.Authoring.SettingsAssetResolution.OpenForWriting``1(``0) a moment later. Rejecting the folder here instead would
refuse an update the author has confirmed in the tool's own window, which is the one way through
that gate deliberately leaves open.
Declaration
public static void ValidateCreateDestinationFolder<TSettings>(string folderPath, string id, string fieldName, SerenityCreationValidationResult result) where TSettings : ScriptableObject, IFoundationSettings
Parameters
| Type |
Name |
Description |
| string |
folderPath |
|
| string |
id |
|
| string |
fieldName |
The folder picker as the author reads it on the tool's own form.
|
| SerenityCreationValidationResult |
result |
|
Type Parameters
| Name |
Description |
| TSettings |
|
ValidateNoWriteBoundaryCollision<TSettings>(string, string, string, SerenityCreationValidationResult)
Declaration
public static void ValidateNoWriteBoundaryCollision<TSettings>(string folderPath, string id, string fileNameFallback, SerenityCreationValidationResult result) where TSettings : ScriptableObject, IFoundationSettings
Parameters
| Type |
Name |
Description |
| string |
folderPath |
|
| string |
id |
|
| string |
fileNameFallback |
|
| SerenityCreationValidationResult |
result |
|
Type Parameters
| Name |
Description |
| TSettings |
|