logo SERENITY
Game Systems Foundation
Search Results for

    Show / Hide Table of Contents

    Class PrefetchPolicyCreator

    Generates (or updates) a PrefetchPolicyRegistry asset and the set of PrefetchPolicyProfile assets it references, from a single description. Mirrors Serenity.GameCamera.Infrastructure.Editor.Builder.GameCameraSettingsCreator: static class, Input/Result DTOs, Validate, Create with created-paths rollback on failure — resolved and folder-provisioned through the shared SettingsAssetAuthoring engine rather than a private copy of its logic. Every validation rule lives in PrefetchPolicyValidator instead — this class keeps only resolution and the actual write path.

    Unlike the registry — a single project-wide asset resolved the same way Serenity.GameCamera.Infrastructure.Settings.UnityGameCameraSettings is — the profiles are a set of N assets. A row built from the flat PrefetchPolicyCreator.Input/PrefetchPolicyCreator.ProfileRow shape (the Create(Input) entry point — headless/programmatic callers) resolves to an existing PrefetchPolicyProfile asset with a matching Id already living in ProfilesFolderPath (updated in place) or a brand-new asset created there — an intentional, documented "update by Id" feature. A row CreatePrefetchPolicyWindow itself seeds from an existing profile is different: it stays bound to THAT SAME asset regardless of what its Id field gets retyped to — see CreateFromDrafts(IReadOnlyList<SerenityWizardScratchDraft<PrefetchPolicyProfile>>, string, string, bool, UnboundRowWriteMode)'s own doc for the identity rule and the finding it closes.

    CreatePrefetchPolicyWindow only collects input and renders results; every asset mutation lives here.
    Inheritance
    object
    PrefetchPolicyCreator
    Inherited Members
    object.ToString()
    object.Equals(object)
    object.Equals(object, object)
    object.ReferenceEquals(object, object)
    object.GetHashCode()
    object.GetType()
    object.MemberwiseClone()
    Namespace: Serenity.AssetPrefetcher.Infrastructure.Editor.Builder
    Assembly: Serenity.UnityAssetPrefetcher.Infrastructure.Editor.dll
    Syntax
    public static class PrefetchPolicyCreator

    Fields

    DefaultOutputFolder

    Folder brand-new profile/registry assets are created under when the caller names none.

    Declaration
    public const string DefaultOutputFolder = "Assets/Game/Media/AssetPrefetcher"
    Field Value
    Type Description
    string

    DefaultProfileId

    The Id the registry's GetDefault() looks up.

    Declaration
    public const string DefaultProfileId = "default"
    Field Value
    Type Description
    string

    ProfileAssetFileNameFallback

    Fallback file name for a brand-new profile asset when a Id sanitizes to nothing usable.

    Declaration
    public const string ProfileAssetFileNameFallback = "PrefetchPolicyProfile"
    Field Value
    Type Description
    string

    RegistryAssetFileNameFallback

    Fallback (and only) file name for a brand-new registry asset — the registry carries no authored "name" field, so this is always the resolved file name when RegistryAssetPath is empty.

    Declaration
    public const string RegistryAssetFileNameFallback = "PrefetchPolicyRegistry"
    Field Value
    Type Description
    string

    RuntimeMinimumMaxSizeMB

    The runtime service floor-clamps the memory budget to this many megabytes.

    Declaration
    public const int RuntimeMinimumMaxSizeMB = 16
    Field Value
    Type Description
    int

    Methods

    Create(Input)

    Validates the request, then maps every PrefetchPolicyCreator.ProfileRow onto a throwaway scratch draft and hands the set to CreateFromDrafts(IReadOnlyList<SerenityWizardScratchDraft<PrefetchPolicyProfile>>, string, string, bool, UnboundRowWriteMode) — the single place that ever writes a field onto a real profile asset. Kept for headless/test callers that only have the flat PrefetchPolicyCreator.Input shape; CreatePrefetchPolicyWindow itself skips this DTO entirely and calls CreateFromDrafts(IReadOnlyList<SerenityWizardScratchDraft<PrefetchPolicyProfile>>, string, string, bool, UnboundRowWriteMode) with its own per-row SerenityWizardScratchDraft<PrefetchPolicyProfile> drafts directly.

    Declaration
    public static PrefetchPolicyCreator.Result Create(PrefetchPolicyCreator.Input input)
    Parameters
    Type Name Description
    PrefetchPolicyCreator.Input input
    Returns
    Type Description
    PrefetchPolicyCreator.Result

    CreateFromDrafts(IReadOnlyList<SerenityWizardScratchDraft<PrefetchPolicyProfile>>, string, string, bool, UnboundRowWriteMode)

    The single write path: resolves each row's profile asset, then the PrefetchPolicyRegistry itself, then commits every field on each draft onto its resolved profile via Serenity.Global.Infrastructure.Editor.SerenityWizardScratchDraft`1.CopyOnto(`0,`0) — serialization decides what gets written, not a hand-maintained field list. On any failure — including the pre-flight refusal below — every mutation is rolled back through the transaction's existing-asset restores, or nothing is ever written at all when the refusal fires before the transaction begins. Each row's own CALLER-OWNED draft — a long-lived window row for CreatePrefetchPolicyWindow — is captured via Serenity.Global.Infrastructure.Editor.SerenityExistingAssetRestore before its Id trim, and restored on failure, so the window's own rows are left exactly as the author had them typed.

    A row's own Serenity.Global.Infrastructure.Editor.SerenityWizardScratchDraft`1.SourceAsset is the write target when set — never an Id lookup. A row seeded from an existing profile (CreatePrefetchPolicyWindow's own FromExisting rows) stays bound to that SAME asset regardless of what the author retypes its Id field to: an Id edit on a seeded row renames that one asset, it never re-targets the write onto whatever a DIFFERENT existing profile the new Id string happens to match — retyping the Id never resolves-and-overwrites that OTHER asset, so the original stays in the registry untouched. Only a row with no source (Serenity.Global.Infrastructure.Editor.SerenityWizardScratchDraft`1.CreateNew — a genuinely new row, or every row Create(Input) builds from the flat PrefetchPolicyCreator.Input DTO, which carries no "seeded from" concept of its own) resolves by Id-in-folder, exactly as it always has.

    Defense in depth: a bound row can never touch another asset by construction, but an UNBOUND row resolving by Id could still collide with an asset a DIFFERENT row in the same batch already owns as its own source — the exact shape the caller-side wizard validation (CreatePrefetchPolicyWindow's ValidateRowBindings, built on ValidateRowIdNotBoundToADifferentAsset(IReadOnlyDictionary<string, PrefetchPolicyProfile>, string, string)) exists to catch before this ever runs. This method does not simply trust that: Serenity.AssetPrefetcher.Infrastructure.Editor.Builder.PrefetchPolicyCreator.ValidateNoUnboundRowClaimsAnotherRowsSource(System.Collections.Generic.IReadOnlyList{Serenity.Global.Infrastructure.Editor.SerenityWizardScratchDraft{Serenity.AssetPrefetcher.Infrastructure.Settings.PrefetchPolicyProfile}},System.String) re-checks it independently, before the transaction opens, so a caller-side validation gap can never turn into a written file.

    Create-only, at the write boundary: the WINDOW's own row-binding validation reads a cached folder scan that nothing invalidates when the UnityEditor.AssetDatabase changes externally between recomputes — a fresher cache narrows that window but can never close it. unboundRowWriteMode closes it here instead: with CreateOnly, Serenity.AssetPrefetcher.Infrastructure.Editor.Builder.PrefetchPolicyCreator.ValidateUnboundRowsAreCreateOnly(System.Collections.Generic.IReadOnlyList{Serenity.Global.Infrastructure.Editor.SerenityWizardScratchDraft{Serenity.AssetPrefetcher.Infrastructure.Settings.PrefetchPolicyProfile}},System.String) re-resolves every unbound row's Id against disk one more time, independent of whatever the caller already checked, and refuses before the transaction opens when it matches ANY existing profile — not only one owned by another row in this batch.

    Declaration
    public static PrefetchPolicyCreator.Result CreateFromDrafts(IReadOnlyList<SerenityWizardScratchDraft<PrefetchPolicyProfile>> profileDrafts, string registryAssetPath, string profilesFolderPath, bool registerAsAddressables, PrefetchPolicyCreator.UnboundRowWriteMode unboundRowWriteMode)
    Parameters
    Type Name Description
    IReadOnlyList<SerenityWizardScratchDraft<PrefetchPolicyProfile>> profileDrafts

    Every profile row to write, already resolved (an already-seeded scratch draft from an existing profile for an update-in-place row, or a freshly populated one for a new row). Each draft's own Guid is ignored on purpose — this method owns identity via Serenity.Global.Infrastructure.Editor.SerenityWizardScratchDraft`1.EnsureIdentity(`0,`0).

    string registryAssetPath

    Explicit registry asset path — see RegistryAssetPath.

    string profilesFolderPath

    Folder new profile assets are created under, and searched for an existing same-Id asset to update in place. Also the fallback folder for a brand-new registry asset.

    bool registerAsAddressables

    Whether to register newly created assets as Addressable.

    PrefetchPolicyCreator.UnboundRowWriteMode unboundRowWriteMode

    How an unbound row's Id-in-folder resolution is allowed to behave. No default on purpose — every caller states its own intent explicitly: Create(Input) passes the documented headless UpdateExistingById behavior; CreatePrefetchPolicyWindow passes CreateOnly.

    Returns
    Type Description
    PrefetchPolicyCreator.Result

    PlannedProfilePath(string, string)

    Where a NEW profile with id is created in profilesFolderPath.

    Declaration
    public static string PlannedProfilePath(string profilesFolderPath, string id)
    Parameters
    Type Name Description
    string profilesFolderPath
    string id
    Returns
    Type Description
    string

    Preview(Input)

    Computes what Create(Input) would do without mutating the project — the same resolution helpers, read-only.

    Declaration
    public static PrefetchPolicyCreator.PreviewResult Preview(PrefetchPolicyCreator.Input input)
    Parameters
    Type Name Description
    PrefetchPolicyCreator.Input input
    Returns
    Type Description
    PrefetchPolicyCreator.PreviewResult

    ResolveRegistryContext(string)

    Thin wrapper over the shared ResolveSettingsContext<TSettings>(string, string), exposed so CreatePrefetchPolicyWindow can auto-detect the project-wide singleton for its "Edit existing" field. A second (or later) PrefetchPolicyRegistry asset does not break anything at runtime — the composition root's serialized field is assigned by hand, not discovered — so ambiguity here is surfaced as a warning (see Validate(Input)), never a hard error.

    Declaration
    public static SettingsAssetAuthoring.SettingsResolution<PrefetchPolicyRegistry> ResolveRegistryContext(string explicitRegistryAssetPath = "")
    Parameters
    Type Name Description
    string explicitRegistryAssetPath
    Returns
    Type Description
    SettingsResolution<PrefetchPolicyRegistry>

    Validate(Input)

    Thin forward to Validate(Input) — kept here so existing callers of PrefetchPolicyCreator.Validate (headless/test call sites) do not need to know the validation family moved to its own collaborator.

    Declaration
    public static SerenityCreationValidationResult Validate(PrefetchPolicyCreator.Input input)
    Parameters
    Type Name Description
    PrefetchPolicyCreator.Input input
    Returns
    Type Description
    SerenityCreationValidationResult
    In this article
    © 2026 Serenity. All Rights Reserved