logo SERENITY
Game Systems Foundation
Search Results for

    Show / Hide Table of Contents

    Class SingletonSettingsSelection

    The ownership rule every singleton settings lookup applies, both at runtime (UnitySingletonSettingsLoader) and in editor validation (SerenitySystemConfigurationResolver): a project-owned settings asset beats a shipped one with the same Id, and among equally-owned candidates an identified asset beats one whose Id was never filled in. Engine-agnostic and Unity-free — the caller decides what "project-owned" and "Id" mean for its own candidate type.

    Not the rule a COLLECTION lookup applies. This one asks "which candidate is authoritative for one slot" and answers by OWNERSHIP; CollectionSettingsSelection asks "is this asset the one another was cloned from" and answers by ID PAIRING, without consulting ownership at all. Two questions, two rules — do not merge them.

    Inheritance
    object
    SingletonSettingsSelection
    Inherited Members
    object.ToString()
    object.Equals(object)
    object.Equals(object, object)
    object.ReferenceEquals(object, object)
    object.GetHashCode()
    object.GetType()
    object.MemberwiseClone()
    Namespace: Serenity.Shared.Utils
    Assembly: Serenity.Shared.dll
    Syntax
    public static class SingletonSettingsSelection

    Methods

    OrderByOwnership<T>(IEnumerable<T>, Func<T, bool>, Func<T, string>)

    Orders every candidate for display when more than one exists and a human — not this rule — must resolve which one counts: every project-owned candidate first (a human is meant to resolve those; a shipped default merely explains why the runtime never picked it), then every non-project-owned one, each group ordered by sortKeyOf ordinally — deterministic across machines and stable across an unrelated reimport, unlike an AssetDatabase.FindAssets scan's own unordered result. The one ordering rule shared by every "list an ambiguous set of candidates for the reader to pick from" surface (settings-asset ambiguity, the Boot pipeline row's own candidate list) so none of them re-derive it slightly differently.

    Declaration
    public static List<T> OrderByOwnership<T>(IEnumerable<T> candidates, Func<T, bool> isProjectOwned, Func<T, string> sortKeyOf)
    Parameters
    Type Name Description
    IEnumerable<T> candidates

    Every candidate to order, in any order.

    Func<T, bool> isProjectOwned

    True when a candidate lives in the user's own project content.

    Func<T, string> sortKeyOf

    The ordinal sort key within each ownership group — typically the candidate's own asset path, since a serialized display name can drift from it.

    Returns
    Type Description
    List<T>
    Type Parameters
    Name Description
    T

    Pick<T>(IReadOnlyList<T>, Func<T, bool>, Func<T, string>, out SingletonSelectionOutcome)

    Picks the single candidate a singleton settings lookup should use. Keeps only the winner; use Resolve<T>(IReadOnlyList<T>, Func<T, bool>, Func<T, string>, Func<T, string>) when the losing candidates must be reported to an author.

    Declaration
    public static T Pick<T>(IReadOnlyList<T> candidates, Func<T, bool> isProjectOwned, Func<T, string> idOf, out SingletonSelectionOutcome outcome)
    Parameters
    Type Name Description
    IReadOnlyList<T> candidates

    Every candidate found for the settings type, in any order.

    Func<T, bool> isProjectOwned

    True when a candidate lives in the user's own project content.

    Func<T, string> idOf

    The candidate's IFoundationSettings.Id (or equivalent).

    SingletonSelectionOutcome outcome

    How the pick was made — see SingletonSelectionOutcome.

    Returns
    Type Description
    T

    The picked candidate, or default when candidates is empty.

    Type Parameters
    Name Description
    T

    Resolve<T>(IReadOnlyList<T>, Func<T, bool>, Func<T, string>, Func<T, string>)

    Resolves a singleton settings lookup to its winner, its shadowed candidates and the outcome that explains the pick.

    The winner is the first candidate under one ordering: project-owned before shipped, then an asset carrying an Id before one whose Id is blank, then lowest Id ordinal, then lowest tieBreakKeyOf ordinal. The blank-Id rung is what keeps a stray scaffold from winning: an asset created without an author ever opening it has no Id, and an Id-ordinal sort alone puts the empty string first, so the unconfigured clone would shadow the configured asset.

    Declaration
    public static SingletonSelectionResult<T> Resolve<T>(IReadOnlyList<T> candidates, Func<T, bool> isProjectOwned, Func<T, string> idOf, Func<T, string> tieBreakKeyOf = null)
    Parameters
    Type Name Description
    IReadOnlyList<T> candidates

    Every candidate found for the settings type, in any order.

    Func<T, bool> isProjectOwned

    True when a candidate lives in the user's own project content.

    Func<T, string> idOf

    The candidate's IFoundationSettings.Id (or equivalent).

    Func<T, string> tieBreakKeyOf

    A key that is stable across machines — an asset path or file name — deciding candidates that are otherwise indistinguishable. Null falls back to idOf, which leaves two blank-Id candidates in their incoming order.

    Returns
    Type Description
    SingletonSelectionResult<T>
    Type Parameters
    Name Description
    T
    In this article
    © 2026 Serenity. All Rights Reserved