Game.Modding.Toolchain.Dependencies.CombinedDependency
Assembly:
Namespace: Game.Modding.Toolchain.Dependencies
Type: abstract class
Base: IToolchainDependency
Summary:
CombinedDependency is an abstract helper base class that implements IToolchainDependency by delegating most operations to a collection of child IToolchainDependency instances (the "dependencies"). It provides a way to combine those child results using logical combine modes (OR, AND, ALL) and supports both synchronous and asynchronous child dependency implementations. The class also forwards progress notifications and exposes common metadata (name, localizedName, version, installation options, etc.). It centralizes logic for running the same operation across multiple dependencies, handling cancellation and aggregation of results or exceptions.
Fields
-
private IToolchainDependency.State m_State
This private field stores the current combined state of this dependency. Setting the public state property updates this field and fires the onNotifyProgress event. -
private System.Version m_Version
Internal storage for a parsed version if needed by derived implementations (not used directly by the base class except to hold a Version instance).
Properties
-
public abstract IEnumerable<IToolchainDependency> dependencies { get; }
Must be implemented by subclasses to return the set of child dependencies that should be combined. -
protected abstract bool isAsync { get; }
Indicates whether the child dependencies should be treated as asynchronous (true) or synchronous (false). Affects how the base class dispatches and waits for the child tasks. Implement in subclasses. -
public abstract CombineType type { get; }
The combination strategy (OR, AND, ALL) used when executing or evaluating children. Implemented by subclasses. -
public string name => GetType().Name
A simple name derived from the concrete type. -
public virtual LocalizedString localizedName => LocalizedString.Id("Options.OPTION[ModdingSettings." + GetType().Name + "]")
Default localized name; can be overridden to provide custom localization. -
public virtual string version { get; protected set; }
String representation of version for the combined dependency. Also exposed via the explicit interface implementation. -
string IToolchainDependency.version
(explicit interface implementation)
Explicit implementation that delegates to the public version property. -
public string icon => null
Default icon (null). Override if an icon is required. -
public virtual bool confirmUninstallation => false
Whether uninstall requires confirmation by default (false). Can be overridden. -
public virtual bool canBeInstalled => true
Indicates if the dependency supports installation operations (default true). -
public virtual bool canBeUninstalled => true
Indicates if the dependency supports uninstallation operations (default true). -
public virtual bool canChangeInstallationDirectory => false
Whether the installation directory can be changed (default false). -
public virtual string installationDirectory { get; set; } = string.Empty
Installation directory path (default empty). Can be set/overridden. -
public virtual LocalizedString description => default(LocalizedString)
Optional localized description. -
public virtual LocalizedString installDescr => default(LocalizedString)
Optional localized installation description. -
public virtual LocalizedString uninstallDescr => default(LocalizedString)
Optional localized uninstallation description. -
public virtual LocalizedString uninstallMessage => default(LocalizedString)
Optional localized uninstall message. -
public IToolchainDependency.State state
Public property for the current state. Setting this updates m_State and invokes onNotifyProgress to notify listeners of the new state and progress. -
public bool needDownload { get; protected set; }
Indicates whether this combined dependency needs download. Backed by a property so subclasses can set it. -
bool IToolchainDependency.needDownload
(explicit interface implementation)
Explicit interface getter/setter that uses the needDownload property. -
public List<IToolchainDependency.DiskSpaceRequirements> spaceRequirements { get; protected set; } = new List<IToolchainDependency.DiskSpaceRequirements>()
List of disk space requirements for this dependency. Populated by subclasses as needed. -
List<IToolchainDependency.DiskSpaceRequirements> IToolchainDependency.spaceRequirements
(explicit interface implementation)
Explicit interface getter/setter that uses the spaceRequirements property. -
IEnumerable<string> IToolchainDependency.envVariables
(explicit interface implementation)
Enumerates environment variables required by all child dependencies by iterating dependencies and yielding their envVariables. -
public virtual Type[] dependsOnInstallation => Array.Empty<Type>()
Types this dependency depends on for installation order (default none). -
public virtual Type[] dependsOnUninstallation => Array.Empty<Type>()
Types this dependency depends on for uninstallation order (default none). -
public event IToolchainDependency.ProgressDelegate onNotifyProgress
Event fired when the state changes (used by the state property setter).
Constructors
public CombinedDependency()
No explicit constructor is defined in the source; the default parameterless constructor is used. Subclasses typically initialize their dependency list and other settings.
Methods
private async Task<bool> GetCombinedResult(CancellationToken token, Func<IToolchainDependency, CancellationToken, Task<bool>> getTaskPredicate)
Core helper that evaluates a boolean-returning operation across child dependencies according to the combine type and the isAsync flag.- For isAsync == true: launches tasks for each dependency (using a linked CancellationTokenSource so one successful/failed result can cancel the rest where applicable). For CombineType.OR it returns true as soon as any child returns true. For CombineType.AND it returns false on the first false or faulted child. Uses Task.WhenAny to process completion ordering.
- For isAsync == false: iterates children sequentially awaiting each child's task before proceeding and applies the combine semantics sequentially.
-
Used by IsInstalled, IsUpToDate, NeedDownload.
-
private async Task GetCombinedResult(CombineType combineType, CancellationToken token, Func<IToolchainDependency, CancellationToken, Task> getTaskPredicate)
Core helper that executes a void-returning operation (Task) across children. Behavior varies by combineType and isAsync: - CombineType.OR: returns as soon as any child completes successfully; collects exceptions from failed children and throws AggregateException if none succeed.
- CombineType.AND: waits for all until a fault occurs, then propagates the fault.
- CombineType.ALL: waits for all tasks to complete (Task.WhenAll).
-
If isAsync == false, executes child tasks sequentially and applies same semantics.
-
public virtual async Task Refresh(CancellationToken token)
Calls Refresh on all child dependencies with CombineType.ALL (i.e., waits for all children to refresh), then calls the IToolchainDependency.Refresh extension/static helper for this instance. Designed to ensure children are up-to-date before performing any combined refresh logic. -
public Task<bool> IsInstalled(CancellationToken token)
Returns the combined IsInstalled result according to the combine semantics using the boolean GetCombinedResult helper. -
public Task<bool> IsUpToDate(CancellationToken token)
Returns the combined IsUpToDate result according to the combine semantics. -
public Task<bool> NeedDownload(CancellationToken token)
Returns the combined NeedDownload result according to the combine semantics. -
public Task Download(CancellationToken token)
Executes Download across children using the configured combine type and semantics. -
public Task Install(CancellationToken token)
Executes Install across children using the configured combine type and semantics. -
public Task Uninstall(CancellationToken token)
NOTE: In the provided source, Uninstall delegates to d.Download(t) for each child. This looks like a likely bug (it should call d.Uninstall). Be aware: as written, calling Uninstall on a CombinedDependency runs the children Download operation instead of Uninstall. -
public Task<List<IToolchainDependency.DiskSpaceRequirements>> GetRequiredDiskSpace(CancellationToken token)
Returns an empty list by default. Subclasses can override to provide aggregated disk space requirements. -
public virtual LocalizedString GetLocalizedState(bool includeProgress)
Returns a localized representation of the current state by calling IToolchainDependency.GetLocalizedState(state, includeProgress). Subclasses can override for custom localization. -
public enum CombineType { OR, AND, ALL }
Combination strategies: - OR: succeed if any child succeeds (short-circuit on first success).
- AND: succeed only if all children succeed (short-circuit on first failure).
- ALL: execute all children and aggregate results/exceptions (used only for Task-returning helper).
Usage Example
// Example of a simple combined dependency that requires two child dependencies to be installed (AND),
// where child operations are treated asynchronously.
public class MyCombinedDependency : CombinedDependency
{
private readonly IToolchainDependency[] m_children;
public MyCombinedDependency(IToolchainDependency[] children)
{
m_children = children;
}
public override IEnumerable<IToolchainDependency> dependencies => m_children;
protected override bool isAsync => true;
public override CombineType type => CombineType.AND;
public override string version { get; protected set; } = "1.0.0";
}
// Using the combined dependency:
var combined = new MyCombinedDependency(new IToolchainDependency[] { depA, depB });
CancellationToken ct = CancellationToken.None;
bool installed = await combined.IsInstalled(ct);
if (!installed && await combined.NeedDownload(ct))
{
await combined.Download(ct);
await combined.Install(ct);
}
Notes and tips: - Implementations must supply the dependencies enumerable and choose an appropriate CombineType and isAsync flag for the child dependency implementations. - The base class handles cancellation by creating linked CancellationTokenSources when running tasks in parallel (isAsync == true). When one child short-circuits the result (e.g., OR found a success) the remaining tasks are canceled via that linked token source. - Watch for the Uninstall/Download delegation bug in the base source if you rely on combined uninstallation behavior — consider overriding Uninstall in your subclass to call child.Uninstall explicitly until that is fixed.