using Sandbox.Diagnostics; using System.Collections.Generic; using System.Threading.Tasks; namespace Sandbox.Mounting; /// /// The base class for all mounts. Your mount should implement the abstract methods from this class. /// public abstract class BaseGameMount { /// /// True if this source is installed on the system and can be mounted. /// public bool IsInstalled { get; protected set; } /// /// True if this is currently active and mounted /// public bool IsMounted { get; protected set; } /// /// A short, lowercase string that will be used to uniquely identify this asset source /// ie "rust" /// public abstract string Ident { get; } /// /// The display name of the game this mounts, ie "Rust" /// public abstract string Title { get; } /// /// Allows logging for this specific asset source /// protected Logger Log { get; init; } internal MountHost _host; public BaseGameMount() { Log = new Logger( Ident ); } internal void InitializeInternal( MountHost system ) { _host = system; Initialize( new InitializeContext( system ) ); } /// /// Called on startup, in parallel with other sources. Use this to check for the presence of the game on disk and /// set the IsInstalled property if it is. /// protected abstract void Initialize( InitializeContext context ); internal async Task MountInternal() { RootFolder = ResourceFolder.CreateRoot(); if ( !IsInstalled ) return; await Mount( new MountContext( this ) ); foreach ( var entry in _entries.Values ) { RootFolder.AddResource( entry ); } } /// /// Try to mount. Should set Mounted to true if success. /// protected abstract Task Mount( MountContext context ); internal void ShutdownInternal() { IsMounted = false; Shutdown(); foreach ( var entry in _entries.Values ) { entry?.ShutdownInternal(); } _entries.Clear(); RootFolder = null; } /// /// Called on destroy, if you have any files open, now is the time to close them. /// protected virtual void Shutdown() { } readonly Dictionary _entries = []; /// /// All of the resources in this game /// public IReadOnlyCollection Resources => _entries.Values; public ResourceFolder RootFolder { get; internal set; } internal void RegisterFileInternal( ResourceLoader entry ) { _entries[entry.Path] = entry; } /// /// Unmount and re-mount the source. Used during development to update the files. /// public async Task RefreshInternal() { // If we're not mounted, just initialize again, mount might be installed now. if ( IsMounted == false ) { InitializeInternal( _host ); return; } ShutdownInternal(); IsInstalled = false; InitializeInternal( _host ); await MountInternal(); } }