diff options
| author | Jesse Plamondon-Willard <github@jplamondonw.com> | 2018-03-13 20:25:06 -0400 |
|---|---|---|
| committer | Jesse Plamondon-Willard <github@jplamondonw.com> | 2018-03-13 20:25:06 -0400 |
| commit | afb3c49bbaab07f3148f70d54f5140cdd83f8c20 (patch) | |
| tree | dd60902c878c38617f97644b912afb38c568755e /src/SMAPI | |
| parent | 833d98f49136325edfc4463097710cf2391dd5b2 (diff) | |
| parent | 76445dc3589265ba259070300120e96a17957e50 (diff) | |
| download | SMAPI-afb3c49bbaab07f3148f70d54f5140cdd83f8c20.tar.gz SMAPI-afb3c49bbaab07f3148f70d54f5140cdd83f8c20.tar.bz2 SMAPI-afb3c49bbaab07f3148f70d54f5140cdd83f8c20.zip | |
Merge branch 'develop' into stable
Diffstat (limited to 'src/SMAPI')
35 files changed, 1718 insertions, 389 deletions
diff --git a/src/SMAPI/Constants.cs b/src/SMAPI/Constants.cs index fe9fdf9b..d91fa5fb 100644 --- a/src/SMAPI/Constants.cs +++ b/src/SMAPI/Constants.cs @@ -37,13 +37,28 @@ namespace StardewModdingAPI ** Public ****/ /// <summary>SMAPI's current semantic version.</summary> - public static ISemanticVersion ApiVersion { get; } = new SemanticVersion("2.5.2"); + public static ISemanticVersion ApiVersion { get; } = +#if STARDEW_VALLEY_1_3 + new SemanticVersion($"2.6-alpha.{DateTime.UtcNow:yyyyMMddHHmm}"); +#else + new SemanticVersion($"2.5.3"); +#endif /// <summary>The minimum supported version of Stardew Valley.</summary> - public static ISemanticVersion MinimumGameVersion { get; } = new SemanticVersion("1.2.30"); + public static ISemanticVersion MinimumGameVersion { get; } = +#if STARDEW_VALLEY_1_3 + new GameVersion("1.3.0.4"); +#else + new SemanticVersion("1.2.33"); +#endif /// <summary>The maximum supported version of Stardew Valley.</summary> - public static ISemanticVersion MaximumGameVersion { get; } = null; + public static ISemanticVersion MaximumGameVersion { get; } = +#if STARDEW_VALLEY_1_3 + null; +#else + new SemanticVersion("1.2.33"); +#endif /// <summary>The path to the game folder.</summary> public static string ExecutionPath { get; } = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location); @@ -169,7 +184,12 @@ namespace StardewModdingAPI /// <summary>Get the name of a save directory for the current player.</summary> private static string GetSaveFolderName() { - string prefix = new string(Game1.player.name.Where(char.IsLetterOrDigit).ToArray()); + string prefix = +#if STARDEW_VALLEY_1_3 + new string(Game1.player.name.Value.Where(char.IsLetterOrDigit).ToArray()); +#else + new string(Game1.player.name.Where(char.IsLetterOrDigit).ToArray()); +#endif return $"{prefix}_{Game1.uniqueIDForThisGame}"; } diff --git a/src/SMAPI/Events/EventArgsGameLocationsChanged.cs b/src/SMAPI/Events/EventArgsGameLocationsChanged.cs index fb8c821e..78ba38fa 100644 --- a/src/SMAPI/Events/EventArgsGameLocationsChanged.cs +++ b/src/SMAPI/Events/EventArgsGameLocationsChanged.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.Collections.Generic; using StardewValley; @@ -11,7 +11,7 @@ namespace StardewModdingAPI.Events ** Accessors *********/ /// <summary>The current list of game locations.</summary> - public List<GameLocation> NewLocations { get; } + public IList<GameLocation> NewLocations { get; } /********* @@ -19,7 +19,7 @@ namespace StardewModdingAPI.Events *********/ /// <summary>Construct an instance.</summary> /// <param name="newLocations">The current list of game locations.</param> - public EventArgsGameLocationsChanged(List<GameLocation> newLocations) + public EventArgsGameLocationsChanged(IList<GameLocation> newLocations) { this.NewLocations = newLocations; } diff --git a/src/SMAPI/Events/EventArgsInput.cs b/src/SMAPI/Events/EventArgsInput.cs index a5325b76..75b9b8cd 100644 --- a/src/SMAPI/Events/EventArgsInput.cs +++ b/src/SMAPI/Events/EventArgsInput.cs @@ -18,9 +18,11 @@ namespace StardewModdingAPI.Events /// <summary>The current cursor position.</summary> public ICursorPosition Cursor { get; } +#if !STARDEW_VALLEY_1_3 /// <summary>Whether the input is considered a 'click' by the game for enabling action.</summary> [Obsolete("Use " + nameof(EventArgsInput.IsActionButton) + " or " + nameof(EventArgsInput.IsUseToolButton) + " instead")] // deprecated in SMAPI 2.1 public bool IsClick => this.IsActionButton; +#endif /// <summary>Whether the input should trigger actions on the affected tile.</summary> public bool IsActionButton { get; } diff --git a/src/SMAPI/Events/EventArgsInventoryChanged.cs b/src/SMAPI/Events/EventArgsInventoryChanged.cs index 1ee02842..b85ae9db 100644 --- a/src/SMAPI/Events/EventArgsInventoryChanged.cs +++ b/src/SMAPI/Events/EventArgsInventoryChanged.cs @@ -12,7 +12,11 @@ namespace StardewModdingAPI.Events ** Accessors *********/ /// <summary>The player's inventory.</summary> +#if STARDEW_VALLEY_1_3 + public IList<Item> Inventory { get; } +#else public List<Item> Inventory { get; } +#endif /// <summary>The added items.</summary> public List<ItemStackChange> Added { get; } @@ -30,7 +34,13 @@ namespace StardewModdingAPI.Events /// <summary>Construct an instance.</summary> /// <param name="inventory">The player's inventory.</param> /// <param name="changedItems">The inventory changes.</param> - public EventArgsInventoryChanged(List<Item> inventory, List<ItemStackChange> changedItems) + public EventArgsInventoryChanged( +#if STARDEW_VALLEY_1_3 + IList<Item> inventory, +#else + List<Item> inventory, +#endif + List<ItemStackChange> changedItems) { this.Inventory = inventory; this.Added = changedItems.Where(n => n.ChangeType == ChangeType.Added).ToList(); diff --git a/src/SMAPI/Events/EventArgsLocationObjectsChanged.cs b/src/SMAPI/Events/EventArgsLocationObjectsChanged.cs index 058999e9..180e9d78 100644 --- a/src/SMAPI/Events/EventArgsLocationObjectsChanged.cs +++ b/src/SMAPI/Events/EventArgsLocationObjectsChanged.cs @@ -1,6 +1,11 @@ -using System; +using System; using Microsoft.Xna.Framework; +#if STARDEW_VALLEY_1_3 +using System.Collections.Generic; +using Netcode; +#else using StardewValley; +#endif using Object = StardewValley.Object; namespace StardewModdingAPI.Events @@ -12,7 +17,11 @@ namespace StardewModdingAPI.Events ** Accessors *********/ /// <summary>The current list of objects in the current location.</summary> +#if STARDEW_VALLEY_1_3 + public IDictionary<Vector2, NetRef<Object>> NewObjects { get; } +#else public SerializableDictionary<Vector2, Object> NewObjects { get; } +#endif /********* @@ -20,7 +29,13 @@ namespace StardewModdingAPI.Events *********/ /// <summary>Construct an instance.</summary> /// <param name="newObjects">The current list of objects in the current location.</param> - public EventArgsLocationObjectsChanged(SerializableDictionary<Vector2, Object> newObjects) + public EventArgsLocationObjectsChanged( +#if STARDEW_VALLEY_1_3 + IDictionary<Vector2, NetRef<Object>> newObjects +#else + SerializableDictionary<Vector2, Object> newObjects +#endif + ) { this.NewObjects = newObjects; } diff --git a/src/SMAPI/Framework/SContentManager.cs b/src/SMAPI/Framework/ContentCore.cs index fa51bd53..85b8db8f 100644 --- a/src/SMAPI/Framework/SContentManager.cs +++ b/src/SMAPI/Framework/ContentCore.cs @@ -19,9 +19,9 @@ using StardewValley; namespace StardewModdingAPI.Framework { - /// <summary>A thread-safe content manager which intercepts assets being loaded to let SMAPI mods inject or edit them.</summary> + /// <summary>A thread-safe content handler which loads assets with support for mod injection and editing.</summary> /// <remarks> - /// This is the centralised content manager which manages all game assets. The game and mods don't use this class + /// This is the centralised content logic which manages all game assets. The game and mods don't use this class /// directly; instead they use one of several <see cref="ContentManagerShim"/> instances, which proxy requests to /// this class. That ensures that when the game disposes one content manager, the others can continue unaffected. /// That notably requires this class to be thread-safe, since the content managers can be disposed asynchronously. @@ -30,22 +30,25 @@ namespace StardewModdingAPI.Framework /// For English and non-translatable assets, these have the same value. The underlying cache only knows about asset /// keys, and the game and mods only know about asset names. The content manager handles resolving them. /// </remarks> - internal class SContentManager : LocalizedContentManager + internal class ContentCore : IDisposable { /********* ** Properties *********/ + /// <summary>The underlying content manager.</summary> + private readonly LocalizedContentManager Content; + /// <summary>Encapsulates monitoring and logging.</summary> private readonly IMonitor Monitor; /// <summary>The underlying asset cache.</summary> private readonly ContentCache Cache; - /// <summary>The private <see cref="LocalizedContentManager"/> method which generates the locale portion of an asset name.</summary> - private readonly IReflectedMethod GetKeyLocale; + /// <summary>The locale codes used in asset keys indexed by enum value.</summary> + private readonly IDictionary<LocalizedContentManager.LanguageCode, string> Locales; - /// <summary>The language codes used in asset keys.</summary> - private readonly IDictionary<string, LanguageCode> KeyLocales; + /// <summary>The language enum values indexed by locale code.</summary> + private readonly IDictionary<string, LocalizedContentManager.LanguageCode> LanguageCodes; /// <summary>Provides metadata for core game assets.</summary> private readonly CoreAssets CoreAssets; @@ -66,15 +69,17 @@ namespace StardewModdingAPI.Framework /********* ** Accessors *********/ + /// <summary>The current language as a constant.</summary> + public LocalizedContentManager.LanguageCode Language => this.Content.GetCurrentLanguage(); + /// <summary>Interceptors which provide the initial versions of matching assets.</summary> - internal IDictionary<IModMetadata, IList<IAssetLoader>> Loaders { get; } = new Dictionary<IModMetadata, IList<IAssetLoader>>(); + public IDictionary<IModMetadata, IList<IAssetLoader>> Loaders { get; } = new Dictionary<IModMetadata, IList<IAssetLoader>>(); /// <summary>Interceptors which edit matching assets after they're loaded.</summary> - internal IDictionary<IModMetadata, IList<IAssetEditor>> Editors { get; } = new Dictionary<IModMetadata, IList<IAssetEditor>>(); + public IDictionary<IModMetadata, IList<IAssetEditor>> Editors { get; } = new Dictionary<IModMetadata, IList<IAssetEditor>>(); /// <summary>The absolute path to the <see cref="ContentManager.RootDirectory"/>.</summary> - internal string FullRootDirectory => Path.Combine(Constants.ExecutionPath, this.RootDirectory); - + public string FullRootDirectory => Path.Combine(Constants.ExecutionPath, this.Content.RootDirectory); /********* ** Public methods @@ -89,18 +94,26 @@ namespace StardewModdingAPI.Framework /// <param name="languageCodeOverride">The current language code for which to localise content.</param> /// <param name="monitor">Encapsulates monitoring and logging.</param> /// <param name="reflection">Simplifies access to private code.</param> - public SContentManager(IServiceProvider serviceProvider, string rootDirectory, CultureInfo currentCulture, string languageCodeOverride, IMonitor monitor, Reflector reflection) - : base(serviceProvider, rootDirectory, currentCulture, languageCodeOverride) + public ContentCore(IServiceProvider serviceProvider, string rootDirectory, CultureInfo currentCulture, string languageCodeOverride, IMonitor monitor, Reflector reflection) { // init this.Monitor = monitor ?? throw new ArgumentNullException(nameof(monitor)); - this.Cache = new ContentCache(this, reflection); - this.GetKeyLocale = reflection.GetMethod(this, "languageCode"); + this.Content = new LocalizedContentManager(serviceProvider, rootDirectory, currentCulture, languageCodeOverride); + this.Cache = new ContentCache(this.Content, reflection); this.ModContentPrefix = this.GetAssetNameFromFilePath(Constants.ModPath); // get asset data - this.CoreAssets = new CoreAssets(this.NormaliseAssetName); - this.KeyLocales = this.GetKeyLocales(reflection); + this.CoreAssets = new CoreAssets(this.NormaliseAssetName, reflection); + this.Locales = this.GetKeyLocales(reflection); + this.LanguageCodes = this.Locales.ToDictionary(p => p.Value, p => p.Key, StringComparer.InvariantCultureIgnoreCase); + } + + /// <summary>Get a new content manager which defers loading to the content core.</summary> + /// <param name="name">The content manager's name for logs (if any).</param> + /// <param name="rootDirectory">The root directory to search for content (or <c>null</c>. for the default)</param> + public ContentManagerShim CreateContentManager(string name, string rootDirectory = null) + { + return new ContentManagerShim(this, name, this.Content.ServiceProvider, rootDirectory ?? this.Content.RootDirectory, this.Content.CurrentCulture, this.Content.LanguageCodeOverride); } /**** @@ -153,7 +166,14 @@ namespace StardewModdingAPI.Framework /// <summary>Get the current content locale.</summary> public string GetLocale() { - return this.GetKeyLocale.Invoke<string>(); + return this.GetLocale(this.Content.GetCurrentLanguage()); + } + + /// <summary>The locale for a language.</summary> + /// <param name="language">The language.</param> + public string GetLocale(LocalizedContentManager.LanguageCode language) + { + return this.Locales[language]; } /// <summary>Get whether the content manager has already loaded and cached the given asset.</summary> @@ -177,18 +197,15 @@ namespace StardewModdingAPI.Framework /// <summary>Load an asset through the content pipeline. When loading a <c>.png</c> file, this must be called outside the game's draw loop.</summary> /// <typeparam name="T">The expected asset type.</typeparam> /// <param name="assetName">The asset path relative to the content directory.</param> - public override T Load<T>(string assetName) - { - return this.LoadFor<T>(assetName, this); - } - - /// <summary>Load an asset through the content pipeline. When loading a <c>.png</c> file, this must be called outside the game's draw loop.</summary> - /// <typeparam name="T">The expected asset type.</typeparam> - /// <param name="assetName">The asset path relative to the content directory.</param> /// <param name="instance">The content manager instance for which to load the asset.</param> + /// <param name="language">The language code for which to load content.</param> /// <exception cref="ArgumentException">The <paramref name="assetName"/> is empty or contains invalid characters.</exception> /// <exception cref="ContentLoadException">The content asset couldn't be loaded (e.g. because it doesn't exist).</exception> - public T LoadFor<T>(string assetName, ContentManager instance) + public T Load<T>(string assetName, ContentManager instance +#if STARDEW_VALLEY_1_3 + , LocalizedContentManager.LanguageCode language +#endif + ) { // normalise asset key this.AssertValidAssetKeyFormat(assetName); @@ -196,7 +213,11 @@ namespace StardewModdingAPI.Framework // load game content if (!assetName.StartsWith(this.ModContentPrefix)) +#if STARDEW_VALLEY_1_3 + return this.LoadImpl<T>(assetName, instance, language); +#else return this.LoadImpl<T>(assetName, instance); +#endif // load mod content SContentLoadException GetContentError(string reasonPhrase) => new SContentLoadException($"Failed loading content asset '{assetName}': {reasonPhrase}"); @@ -206,7 +227,11 @@ namespace StardewModdingAPI.Framework { // try cache if (this.IsLoaded(assetName)) +#if STARDEW_VALLEY_1_3 + return this.LoadImpl<T>(assetName, instance, language); +#else return this.LoadImpl<T>(assetName, instance); +#endif // get file FileInfo file = this.GetModFile(assetName); @@ -218,7 +243,11 @@ namespace StardewModdingAPI.Framework { // XNB file case ".xnb": +#if STARDEW_VALLEY_1_3 + return this.LoadImpl<T>(assetName, instance, language); +#else return this.LoadImpl<T>(assetName, instance); +#endif // unpacked map case ".tbin": @@ -339,7 +368,7 @@ namespace StardewModdingAPI.Framework int reloaded = 0; foreach (string key in removeAssetNames) { - if (this.CoreAssets.ReloadForKey(this, key)) + if (this.CoreAssets.ReloadForKey(Game1.content, key)) // use an intercepted content manager reloaded++; } @@ -379,11 +408,10 @@ namespace StardewModdingAPI.Framework ** Disposal ****/ /// <summary>Dispose held resources.</summary> - /// <param name="disposing">Whether the content manager is disposing (rather than finalising).</param> - protected override void Dispose(bool disposing) + public void Dispose() { this.Monitor.Log("Disposing SMAPI's main content manager. It will no longer be usable after this point.", LogLevel.Trace); - base.Dispose(disposing); + this.Content.Dispose(); } /**** @@ -398,29 +426,48 @@ namespace StardewModdingAPI.Framework /// <summary>Get the locale codes (like <c>ja-JP</c>) used in asset keys.</summary> /// <param name="reflection">Simplifies access to private game code.</param> - private IDictionary<string, LanguageCode> GetKeyLocales(Reflector reflection) + private IDictionary<LocalizedContentManager.LanguageCode, string> GetKeyLocales(Reflector reflection) { - // get the private code field directly to avoid changed-code logic - IReflectedField<LanguageCode> codeField = reflection.GetField<LanguageCode>(typeof(LocalizedContentManager), "_currentLangCode"); - - // remember previous settings - LanguageCode previousCode = codeField.GetValue(); - string previousOverride = this.LanguageCodeOverride; +#if !STARDEW_VALLEY_1_3 + IReflectedField<LocalizedContentManager.LanguageCode> codeField = reflection.GetField<LocalizedContentManager.LanguageCode>(typeof(LocalizedContentManager), "_currentLangCode"); + LocalizedContentManager.LanguageCode previousCode = codeField.GetValue(); +#endif + string previousOverride = this.Content.LanguageCodeOverride; - // create locale => code map - IDictionary<string, LanguageCode> map = new Dictionary<string, LanguageCode>(StringComparer.InvariantCultureIgnoreCase); - this.LanguageCodeOverride = null; - foreach (LanguageCode code in Enum.GetValues(typeof(LanguageCode))) + try { - codeField.SetValue(code); - map[this.GetKeyLocale.Invoke<string>()] = code; - } + // temporarily disable language override + this.Content.LanguageCodeOverride = null; + + // create locale => code map + IReflectedMethod languageCodeString = reflection +#if STARDEW_VALLEY_1_3 + .GetMethod(this.Content, "languageCodeString"); +#else + .GetMethod(this.Content, "languageCode"); +#endif + IDictionary<LocalizedContentManager.LanguageCode, string> map = new Dictionary<LocalizedContentManager.LanguageCode, string>(); + foreach (LocalizedContentManager.LanguageCode code in Enum.GetValues(typeof(LocalizedContentManager.LanguageCode))) + { +#if STARDEW_VALLEY_1_3 + map[code] = languageCodeString.Invoke<string>(code); +#else + codeField.SetValue(code); + map[code] = languageCodeString.Invoke<string>(); +#endif + } - // restore previous settings - codeField.SetValue(previousCode); - this.LanguageCodeOverride = previousOverride; + return map; + } + finally + { + // restore previous settings + this.Content.LanguageCodeOverride = previousOverride; +#if !STARDEW_VALLEY_1_3 + codeField.SetValue(previousCode); +#endif - return map; + } } /// <summary>Get the asset name from a cache key.</summary> @@ -444,7 +491,7 @@ namespace StardewModdingAPI.Framework if (lastSepIndex >= 0) { string suffix = cacheKey.Substring(lastSepIndex + 1, cacheKey.Length - lastSepIndex - 1); - if (this.KeyLocales.ContainsKey(suffix)) + if (this.LanguageCodes.ContainsKey(suffix)) { assetName = cacheKey.Substring(0, lastSepIndex); localeCode = cacheKey.Substring(lastSepIndex + 1, cacheKey.Length - lastSepIndex - 1); @@ -466,7 +513,7 @@ namespace StardewModdingAPI.Framework private bool IsNormalisedKeyLoaded(string normalisedAssetName) { return this.Cache.ContainsKey(normalisedAssetName) - || this.Cache.ContainsKey($"{normalisedAssetName}.{this.GetKeyLocale.Invoke<string>()}"); // translated asset + || this.Cache.ContainsKey($"{normalisedAssetName}.{this.Locales[this.Content.GetCurrentLanguage()]}"); // translated asset } /// <summary>Track that a content manager loaded an asset.</summary> @@ -486,7 +533,12 @@ namespace StardewModdingAPI.Framework /// <typeparam name="T">The type of asset to load.</typeparam> /// <param name="assetName">The asset path relative to the loader root directory, not including the <c>.xnb</c> extension.</param> /// <param name="instance">The content manager instance for which to load the asset.</param> - private T LoadImpl<T>(string assetName, ContentManager instance) + /// <param name="language">The language code for which to load content.</param> + private T LoadImpl<T>(string assetName, ContentManager instance +#if STARDEW_VALLEY_1_3 + , LocalizedContentManager.LanguageCode language +#endif + ) { return this.WithWriteLock(() => { @@ -494,7 +546,13 @@ namespace StardewModdingAPI.Framework if (this.IsNormalisedKeyLoaded(assetName)) { this.TrackAssetLoader(assetName, instance); - return base.Load<T>(assetName); + return this.Content + +#if STARDEW_VALLEY_1_3 + .Load<T>(assetName, language); +#else + .Load<T>(assetName); +#endif } // load asset @@ -503,14 +561,30 @@ namespace StardewModdingAPI.Framework { this.Monitor.Log($"Broke loop while loading asset '{assetName}'.", LogLevel.Warn); this.Monitor.Log($"Bypassing mod loaders for this asset. Stack trace:\n{Environment.StackTrace}", LogLevel.Trace); - data = base.Load<T>(assetName); + data = this.Content +#if STARDEW_VALLEY_1_3 + .Load<T>(assetName, language); +#else + .Load<T>(assetName); +#endif } else { data = this.AssetsBeingLoaded.Track(assetName, () => { - IAssetInfo info = new AssetInfo(this.GetLocale(), assetName, typeof(T), this.NormaliseAssetName); - IAssetData asset = this.ApplyLoader<T>(info) ?? new AssetDataForObject(info, base.Load<T>(assetName), this.NormaliseAssetName); + string locale = +#if STARDEW_VALLEY_1_3 + this.GetLocale(language); +#else + this.GetLocale(); +#endif + IAssetInfo info = new AssetInfo(locale, assetName, typeof(T), this.NormaliseAssetName); + IAssetData asset = this.ApplyLoader<T>(info) +#if STARDEW_VALLEY_1_3 + ?? new AssetDataForObject(info, this.Content.Load<T>(assetName, language), this.NormaliseAssetName); +#else + ?? new AssetDataForObject(info, this.Content.Load<T>(assetName), this.NormaliseAssetName); +#endif asset = this.ApplyEditors<T>(info, asset); return (T)asset.Data; }); diff --git a/src/SMAPI/Framework/ContentManagerShim.cs b/src/SMAPI/Framework/ContentManagerShim.cs index d46f23a3..8f88fc2d 100644 --- a/src/SMAPI/Framework/ContentManagerShim.cs +++ b/src/SMAPI/Framework/ContentManagerShim.cs @@ -1,15 +1,17 @@ +using System; +using System.Globalization; using StardewValley; namespace StardewModdingAPI.Framework { - /// <summary>A minimal content manager which defers to SMAPI's main content manager.</summary> + /// <summary>A minimal content manager which defers to SMAPI's core content logic.</summary> internal class ContentManagerShim : LocalizedContentManager { /********* ** Properties *********/ - /// <summary>SMAPI's underlying content manager.</summary> - private readonly SContentManager ContentManager; + /// <summary>SMAPI's core content logic.</summary> + private readonly ContentCore ContentCore; /********* @@ -23,12 +25,16 @@ namespace StardewModdingAPI.Framework ** Public methods *********/ /// <summary>Construct an instance.</summary> - /// <param name="contentManager">SMAPI's underlying content manager.</param> + /// <param name="contentCore">SMAPI's core content logic.</param> /// <param name="name">The content manager's name for logs (if any).</param> - public ContentManagerShim(SContentManager contentManager, string name) - : base(contentManager.ServiceProvider, contentManager.RootDirectory, contentManager.CurrentCulture, contentManager.LanguageCodeOverride) + /// <param name="serviceProvider">The service provider to use to locate services.</param> + /// <param name="rootDirectory">The root directory to search for content.</param> + /// <param name="currentCulture">The current culture for which to localise content.</param> + /// <param name="languageCodeOverride">The current language code for which to localise content.</param> + |
