-- Squash:
- In progress implementation of services model.
This commit is contained in:
@@ -0,0 +1,16 @@
|
||||
using Microsoft.Xna.Framework;
|
||||
|
||||
namespace Barotrauma.LuaCs.Configuration;
|
||||
|
||||
public class DisplayableData : IDisplayableData
|
||||
{
|
||||
public string Name { get; private set; }
|
||||
public string ModName { get; private set; }
|
||||
public string DisplayName { get; private set; }
|
||||
public string DisplayModName { get; private set; }
|
||||
public string DisplayCategory { get; private set; }
|
||||
public string Tooltip { get; private set; }
|
||||
public string ImageIcon { get; private set; }
|
||||
public Point IconResolution { get; private set; }
|
||||
public bool ShowWhenNotLoaded { get; private set; }
|
||||
}
|
||||
+6
@@ -0,0 +1,6 @@
|
||||
using Barotrauma.LuaCs.Configuration;
|
||||
using Barotrauma.LuaCs.Data;
|
||||
|
||||
namespace Barotrauma.LuaCs.Configuration;
|
||||
|
||||
public partial interface IConfigBase : IDisplayableData, IDisplayableInitialize { }
|
||||
@@ -0,0 +1,66 @@
|
||||
using System.Numerics;
|
||||
using Microsoft.Xna.Framework;
|
||||
|
||||
namespace Barotrauma.LuaCs.Configuration;
|
||||
|
||||
/// <summary>
|
||||
/// Contains the Display Data for use with Menus.
|
||||
/// </summary>
|
||||
public interface IDisplayableData
|
||||
{
|
||||
/// <summary>
|
||||
/// Internal name of the instance.
|
||||
/// </summary>
|
||||
string Name { get; }
|
||||
/// <summary>
|
||||
/// Internal mod name of the instance. ContentPackage name will be used by default.
|
||||
/// </summary>
|
||||
string ModName { get; }
|
||||
/// <summary>
|
||||
/// The name to display in GUIs and Menus.
|
||||
/// </summary>
|
||||
string DisplayName { get; }
|
||||
/// <summary>
|
||||
/// The mod name to display in GUIs and Menus.
|
||||
/// </summary>
|
||||
string DisplayModName { get; }
|
||||
/// <summary>
|
||||
/// Category this instance falls under. Used by menus when filtering by category.
|
||||
/// </summary>
|
||||
string DisplayCategory { get; }
|
||||
/// <summary>
|
||||
/// The tooltip shown on hover.
|
||||
/// </summary>
|
||||
string Tooltip { get; }
|
||||
/// <summary>
|
||||
/// The fully qualified filepath to the image icon for this config.
|
||||
/// </summary>
|
||||
string ImageIcon { get; }
|
||||
/// <summary>
|
||||
/// Required if ImageIcon is set. X,Y resolution of the image.
|
||||
/// </summary>
|
||||
Point IconResolution { get; }
|
||||
/// <summary>
|
||||
/// Whether to show the entry in the menu when not loaded.
|
||||
/// </summary>
|
||||
bool ShowWhenNotLoaded { get; }
|
||||
}
|
||||
|
||||
public interface IDisplayableInitialize
|
||||
{
|
||||
void Initialize(IDisplayableData values);
|
||||
|
||||
// copy this as needed
|
||||
/*public void Initialize(IDisplayableData values)
|
||||
{
|
||||
this.Name = values.Name;
|
||||
this.ModName = values.ModName;
|
||||
this.DisplayName = values.DisplayName;
|
||||
this.DisplayModName = values.DisplayModName;
|
||||
this.DisplayCategory = values.DisplayCategory;
|
||||
this.Tooltip = values.Tooltip;
|
||||
this.ImageIcon = values.ImageIcon;
|
||||
this.IconResolution = values.IconResolution;
|
||||
this.ShowWhenNotLoaded = values.ShowWhenNotLoaded;
|
||||
}*/
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
using System.Collections.Immutable;
|
||||
using System.Globalization;
|
||||
|
||||
namespace Barotrauma.LuaCs.Data;
|
||||
|
||||
public partial record ModConfigInfo : IModConfigInfo
|
||||
{
|
||||
public ImmutableArray<IStylesResourceInfo> StylesResourceInfos { get; init; }
|
||||
}
|
||||
|
||||
public record StylesResourceInfo : IStylesResourceInfo
|
||||
{
|
||||
public Platform SupportedPlatforms { get; init; }
|
||||
public Target SupportedTargets { get; init; }
|
||||
public int LoadPriority { get; init; }
|
||||
public ImmutableArray<string> FilePaths { get; init; }
|
||||
public bool Optional { get; init; }
|
||||
public ImmutableArray<CultureInfo> SupportedCultures { get; init; }
|
||||
public string InternalName { get; init; }
|
||||
public ImmutableArray<IPackageDependencyInfo> Dependencies { get; init; }
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
using Barotrauma.LuaCs.Configuration;
|
||||
|
||||
namespace Barotrauma.LuaCs.Data;
|
||||
|
||||
public partial interface IConfigInfo : IDisplayableData { }
|
||||
@@ -0,0 +1,15 @@
|
||||
using System.Collections.Immutable;
|
||||
|
||||
namespace Barotrauma.LuaCs.Data;
|
||||
|
||||
public partial interface IModConfigInfo : IStylesResourcesInfo { }
|
||||
|
||||
public interface IStylesResourceInfo : IResourceInfo, IResourceCultureInfo, ILoadableResourceInfo, IPackageDependenciesInfo { }
|
||||
|
||||
public interface IStylesResourcesInfo
|
||||
{
|
||||
/// <summary>
|
||||
/// Collection of loadable styles data.
|
||||
/// </summary>
|
||||
ImmutableArray<IStylesResourceInfo> StylesResourceInfos { get; }
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
namespace Barotrauma.LuaCs.Data;
|
||||
|
||||
public interface IStylesInfo
|
||||
{
|
||||
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
namespace Barotrauma.LuaCs.Services;
|
||||
|
||||
public interface IClientLoggerService : IService
|
||||
{
|
||||
void AddToGUIUpdateList();
|
||||
void ShowErrorOverlay(string message, float time = 5f, float duration = 1.5f);
|
||||
}
|
||||
@@ -0,0 +1,51 @@
|
||||
namespace Barotrauma.LuaCs.Services;
|
||||
|
||||
// TODO: Rework interface to support resource infos.
|
||||
/// <summary>
|
||||
/// Loads XML Style assets from the given content package.
|
||||
/// </summary>
|
||||
public interface IStylesService : IService
|
||||
{
|
||||
/// <summary>
|
||||
/// Tries to load the styles file for the given contentpackage and path into a new UIStylesProcessor instance.
|
||||
/// </summary>
|
||||
/// <param name="package"></param>
|
||||
/// <param name="path"></param>
|
||||
/// <returns></returns>
|
||||
bool TryLoadStylesFile(ContentPackage package, ContentPath path);
|
||||
/// <summary>
|
||||
/// Unloads all styles assets and UIStyleProcessor instances.
|
||||
/// </summary>
|
||||
void UnloadAllStyles();
|
||||
|
||||
/// <summary>
|
||||
/// Tries to the get the font asset by xml asset name, returns null on failure.
|
||||
/// </summary>
|
||||
/// <param name="fontName">XML Name of the asset.</param>
|
||||
/// <returns>The asset or null if none are found.</returns>
|
||||
GUIFont GetFont(string fontName);
|
||||
/// <summary>
|
||||
/// Tries to the get the sprite asset by xml asset name, returns null on failure.
|
||||
/// </summary>
|
||||
/// <param name="spriteName">XML Name of the asset.</param>
|
||||
/// <returns>The asset or null if none are found.</returns>
|
||||
GUISprite GetSprite(string spriteName);
|
||||
/// <summary>
|
||||
/// Tries to the get the sprite sheet asset by xml asset name, returns null on failure.
|
||||
/// </summary>
|
||||
/// <param name="spriteSheetName">XML Name of the asset.</param>
|
||||
/// <returns>The asset or null if none are found.</returns>
|
||||
GUISpriteSheet GetSpriteSheet(string spriteSheetName);
|
||||
/// <summary>
|
||||
/// Tries to the get the cursor asset by xml asset name, returns null on failure.
|
||||
/// </summary>
|
||||
/// <param name="cursorName">XML Name of the asset.</param>
|
||||
/// <returns>The asset or null if none are found.</returns>
|
||||
GUICursor GetCursor(string cursorName);
|
||||
/// <summary>
|
||||
/// Tries to the get the color asset by xml asset name, returns null on failure.
|
||||
/// </summary>
|
||||
/// <param name="colorName">XML Name of the asset.</param>
|
||||
/// <returns>The asset or null if none are found.</returns>
|
||||
GUIColor GetColor(string colorName);
|
||||
}
|
||||
@@ -0,0 +1,50 @@
|
||||
using Microsoft.Xna.Framework;
|
||||
|
||||
namespace Barotrauma.LuaCs.Services;
|
||||
|
||||
public partial class LoggerService : ILoggerService, IClientLoggerService
|
||||
{
|
||||
private GUIFrame _overlayFrame;
|
||||
private GUITextBlock _textBlock;
|
||||
private double _showTimer = 0;
|
||||
|
||||
|
||||
private void CreateOverlay(string message)
|
||||
{
|
||||
_overlayFrame = new GUIFrame(new RectTransform(new Vector2(0.4f, 0.03f), null), null, new Color(50, 50, 50, 100))
|
||||
{
|
||||
CanBeFocused = false
|
||||
};
|
||||
|
||||
GUILayoutGroup layout =
|
||||
new GUILayoutGroup(
|
||||
new RectTransform(new Vector2(0.8f, 0.8f), _overlayFrame.RectTransform, Anchor.CenterLeft), false,
|
||||
Anchor.Center);
|
||||
|
||||
_textBlock = new GUITextBlock(new RectTransform(new Vector2(1f, 0f), layout.RectTransform), message);
|
||||
_overlayFrame.RectTransform.MinSize = new Point((int)(_textBlock.TextSize.X * 1.2), 0);
|
||||
|
||||
layout.Recalculate();
|
||||
}
|
||||
|
||||
public void AddToGUIUpdateList()
|
||||
{
|
||||
if (_overlayFrame != null && Timing.TotalTime <= _showTimer)
|
||||
{
|
||||
_overlayFrame.AddToGUIUpdateList();
|
||||
}
|
||||
}
|
||||
|
||||
public void ShowErrorOverlay(string message, float time = 5f, float duration = 1.5f)
|
||||
{
|
||||
if (Timing.TotalTime <= _showTimer)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
CreateOverlay(message);
|
||||
|
||||
_overlayFrame.Flash(Color.Red, duration, true);
|
||||
_showTimer = Timing.TotalTime + time;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,43 @@
|
||||
using System;
|
||||
using System.Collections.Immutable;
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
using Barotrauma.LuaCs.Data;
|
||||
using Barotrauma.LuaCs.Services.Processing;
|
||||
|
||||
namespace Barotrauma.LuaCs.Services;
|
||||
|
||||
public partial class PackageService : IStylesResourcesInfo
|
||||
{
|
||||
private readonly Lazy<IStylesService> _stylesService;
|
||||
|
||||
public PackageService(
|
||||
Lazy<IXmlModConfigConverterService> converterService,
|
||||
Lazy<ILegacyConfigService> legacyConfigService,
|
||||
Lazy<ILuaScriptService> luaScriptService,
|
||||
Lazy<ILocalizationService> localizationService,
|
||||
Lazy<IPluginService> pluginService,
|
||||
Lazy<IStylesService> stylesService,
|
||||
Lazy<IConfigService> configService,
|
||||
IPackageManagementService packageManagementService,
|
||||
IStorageService storageService,
|
||||
ILoggerService loggerService)
|
||||
{
|
||||
_modConfigConverterService = converterService;
|
||||
_legacyConfigService = legacyConfigService;
|
||||
_luaScriptService = luaScriptService;
|
||||
_localizationService = localizationService;
|
||||
_pluginService = pluginService;
|
||||
_stylesService = stylesService;
|
||||
_configService = configService;
|
||||
_packageManagementService = packageManagementService;
|
||||
_storageService = storageService;
|
||||
_loggerService = loggerService;
|
||||
}
|
||||
|
||||
public ImmutableArray<IStylesResourceInfo> StylesResourceInfos => ModConfigInfo?.StylesResourceInfos ?? ImmutableArray<IStylesResourceInfo>.Empty;
|
||||
|
||||
public void LoadStyles([NotNull]IStylesResourcesInfo stylesInfo)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
}
|
||||
+9
@@ -0,0 +1,9 @@
|
||||
using System.Xml.Linq;
|
||||
using Barotrauma.LuaCs.Data;
|
||||
|
||||
namespace Barotrauma.LuaCs.Services.Processing;
|
||||
|
||||
#region XmlToResourceParsers
|
||||
public interface IXmlStylesToResConverterService : IXmlResourceConverterService<IStylesResourceInfo> { }
|
||||
|
||||
#endregion
|
||||
@@ -0,0 +1,138 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Xml.Linq;
|
||||
|
||||
namespace Barotrauma.LuaCs.Services;
|
||||
|
||||
public class StylesService : IStylesService
|
||||
{
|
||||
private readonly Dictionary<string, UIStyleProcessor> _loadedProcessors = new();
|
||||
private readonly IStorageService _storageService;
|
||||
private readonly ILoggerService _loggerService;
|
||||
|
||||
public StylesService(IStorageService storageService, ILoggerService loggerService)
|
||||
{
|
||||
_storageService = storageService;
|
||||
_loggerService = loggerService;
|
||||
}
|
||||
|
||||
public bool TryLoadStylesFile(ContentPackage package, ContentPath path)
|
||||
{
|
||||
//check if file already in dict
|
||||
if (_loadedProcessors.ContainsKey(path.FullPath))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
//check if file exists
|
||||
if (_storageService.FileExists(path.FullPath))
|
||||
{
|
||||
try
|
||||
{
|
||||
var styleProcessor = new UIStyleProcessor(package, path);
|
||||
styleProcessor.LoadFile();
|
||||
_loadedProcessors.Add(path.FullPath, styleProcessor);
|
||||
}
|
||||
catch (InvalidDataException exception)
|
||||
{
|
||||
_loggerService.LogError($"XmlAssetService.TryLoadStylesFile failed for ContentPackage {package.Name}: Exception: {exception.Message}");
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public void UnloadAllStyles()
|
||||
{
|
||||
if (NoProcessorsLoaded)
|
||||
return;
|
||||
|
||||
foreach (var processor in _loadedProcessors)
|
||||
{
|
||||
processor.Value.UnloadFile();
|
||||
}
|
||||
_loadedProcessors.Clear();
|
||||
}
|
||||
|
||||
public GUIFont GetFont(string fontName)
|
||||
{
|
||||
if (NoProcessorsLoaded)
|
||||
return null;
|
||||
foreach (var processor in _loadedProcessors.Values)
|
||||
{
|
||||
if (processor.Fonts.TryGetValue(fontName, out var asset))
|
||||
return asset;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public GUISprite GetSprite(string spriteName)
|
||||
{
|
||||
if (NoProcessorsLoaded)
|
||||
return null;
|
||||
foreach (var processor in _loadedProcessors.Values)
|
||||
{
|
||||
if (processor.Sprites.TryGetValue(spriteName, out var asset))
|
||||
return asset;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public GUISpriteSheet GetSpriteSheet(string spriteSheetName)
|
||||
{
|
||||
if (NoProcessorsLoaded)
|
||||
return null;
|
||||
foreach (var processor in _loadedProcessors.Values)
|
||||
{
|
||||
if (processor.SpriteSheets.TryGetValue(spriteSheetName, out var asset))
|
||||
return asset;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public GUICursor GetCursor(string cursorName)
|
||||
{
|
||||
if (NoProcessorsLoaded)
|
||||
return null;
|
||||
foreach (var processor in _loadedProcessors.Values)
|
||||
{
|
||||
if (processor.Cursors.TryGetValue(cursorName, out var asset))
|
||||
return asset;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public GUIColor GetColor(string colorName)
|
||||
{
|
||||
if (NoProcessorsLoaded)
|
||||
return null;
|
||||
foreach (var processor in _loadedProcessors.Values)
|
||||
{
|
||||
if (processor.Colors.TryGetValue(colorName, out var asset))
|
||||
return asset;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
private bool NoProcessorsLoaded => _loadedProcessors.Count < 1;
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
UnloadAllStyles();
|
||||
GC.SuppressFinalize(this);
|
||||
}
|
||||
|
||||
public void Reset()
|
||||
{
|
||||
UnloadAllStyles();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,93 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Xml.Linq;
|
||||
using Barotrauma.Extensions;
|
||||
|
||||
namespace Barotrauma.LuaCs.Services;
|
||||
|
||||
public class UIStyleProcessor : HashlessFile
|
||||
{
|
||||
private readonly UIStyleFile _fake;
|
||||
public readonly Dictionary<string, GUIFont> Fonts = new();
|
||||
public readonly Dictionary<string, GUISprite> Sprites = new();
|
||||
public readonly Dictionary<string, GUISpriteSheet> SpriteSheets = new();
|
||||
public readonly Dictionary<string, GUICursor> Cursors = new();
|
||||
public readonly Dictionary<string, GUIColor> Colors = new();
|
||||
|
||||
public UIStyleProcessor(ContentPackage contentPackage, ContentPath path) : base(contentPackage, path)
|
||||
{
|
||||
_fake = new UIStyleFile(contentPackage, path);
|
||||
}
|
||||
|
||||
public override void LoadFile()
|
||||
{
|
||||
var element = XMLExtensions.TryLoadXml(path: Path)?.Root?.FromPackage(ContentPackage);
|
||||
if (element is null)
|
||||
throw new InvalidDataException($"UIStyleProcessor: Failed to load UI style file: {Path}");
|
||||
|
||||
var styleElement = element.Name.LocalName.ToLowerInvariant() == "style" ? element : element.GetChildElement("style");
|
||||
if (styleElement is null)
|
||||
throw new InvalidDataException($"UIStyleProcessor: no 'style' XmlElement found in file: {Path}");
|
||||
|
||||
var childElements = styleElement.GetChildElements("Font");
|
||||
if (childElements is not null)
|
||||
AddToList<GUIFont, GUIFontPrefab>(Fonts, childElements, _fake);
|
||||
|
||||
childElements = styleElement.GetChildElements("Sprite");
|
||||
if (childElements is not null)
|
||||
AddToList<GUISprite, GUISpritePrefab>(Sprites, childElements, _fake);
|
||||
|
||||
childElements = styleElement.GetChildElements("Spritesheet");
|
||||
if (childElements is not null)
|
||||
AddToList<GUISpriteSheet, GUISpriteSheetPrefab>(SpriteSheets, childElements, _fake);
|
||||
|
||||
childElements = styleElement.GetChildElements("Cursor");
|
||||
if (childElements is not null)
|
||||
AddToList<GUICursor, GUICursorPrefab>(Cursors, childElements, _fake);
|
||||
|
||||
childElements = styleElement.GetChildElements("Color");
|
||||
if (childElements is not null)
|
||||
AddToList<GUIColor, GUIColorPrefab>(Colors, childElements, _fake);
|
||||
|
||||
|
||||
void AddToList<T1, T2>(Dictionary<string, T1> dict, IEnumerable<ContentXElement> ele, UIStyleFile file) where T1 : GUISelector<T2> where T2 : GUIPrefab
|
||||
{
|
||||
foreach (ContentXElement prefabElement in ele)
|
||||
{
|
||||
string name = prefabElement.GetAttributeString("name", string.Empty);
|
||||
if (name != string.Empty)
|
||||
{
|
||||
var prefab = (T2)Activator.CreateInstance(typeof(T2), new object[]{ prefabElement, file })!;
|
||||
if (!dict.ContainsKey(name))
|
||||
dict[name] = (T1)Activator.CreateInstance(typeof(T1), new object[] { name })!;
|
||||
dict[name].Prefabs.Add(prefab, false);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public override void UnloadFile()
|
||||
{
|
||||
Fonts.Values.ForEach(p => p.Prefabs.RemoveByFile(_fake));
|
||||
Sprites.Values.ForEach(p => p.Prefabs.RemoveByFile(_fake));
|
||||
SpriteSheets.Values.ForEach(p => p.Prefabs.RemoveByFile(_fake));
|
||||
Cursors.Values.ForEach(p => p.Prefabs.RemoveByFile(_fake));
|
||||
Colors.Values.ForEach(p => p.Prefabs.RemoveByFile(_fake));
|
||||
|
||||
Fonts.Clear();
|
||||
Sprites.Clear();
|
||||
SpriteSheets.Clear();
|
||||
Cursors.Clear();
|
||||
Colors.Clear();
|
||||
}
|
||||
|
||||
public override void Sort()
|
||||
{
|
||||
Fonts.Values.ForEach(p => p.Prefabs.Sort());
|
||||
Sprites.Values.ForEach(p => p.Prefabs.Sort());
|
||||
SpriteSheets.Values.ForEach(p => p.Prefabs.Sort());
|
||||
Cursors.Values.ForEach(p => p.Prefabs.Sort());
|
||||
Colors.Values.ForEach(p => p.Prefabs.Sort());
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user