mirror of
https://github.com/space-wizards/RobustToolbox.git
synced 2026-02-15 03:30:53 +01:00
Various performance optimizations.
This commit is contained in:
@@ -87,7 +87,6 @@ namespace Robust.Client
|
||||
IoCManager.Register<IClydeInternal, ClydeHeadless>();
|
||||
IoCManager.Register<IInputManager, InputManager>();
|
||||
IoCManager.Register<IFileDialogManager, DummyFileDialogManager>();
|
||||
IoCManager.Register<IFileDialogManagerInternal, DummyFileDialogManager>();
|
||||
IoCManager.Register<IUriOpener, UriOpenerDummy>();
|
||||
break;
|
||||
case GameController.DisplayMode.Clyde:
|
||||
@@ -96,7 +95,6 @@ namespace Robust.Client
|
||||
IoCManager.Register<IClydeInternal, Clyde>();
|
||||
IoCManager.Register<IInputManager, ClydeInputManager>();
|
||||
IoCManager.Register<IFileDialogManager, FileDialogManager>();
|
||||
IoCManager.Register<IFileDialogManagerInternal, FileDialogManager>();
|
||||
#if LINUX
|
||||
IoCManager.Register<IUriOpener, UriOpenerLinux>();
|
||||
#elif MACOS
|
||||
@@ -119,10 +117,13 @@ namespace Robust.Client
|
||||
|
||||
#if LINUX
|
||||
IoCManager.Register<IClipboardManager, ClipboardManagerLinux>();
|
||||
IoCManager.Register<IClipboardManagerInternal, ClipboardManagerLinux>();
|
||||
#elif WINDOWS
|
||||
IoCManager.Register<IClipboardManager, ClipboardManagerWindows>();
|
||||
IoCManager.Register<IClipboardManagerInternal, ClipboardManagerWindows>();
|
||||
#else
|
||||
IoCManager.Register<IClipboardManager, ClipboardManagerUnsupported>();
|
||||
IoCManager.Register<IClipboardManagerInternal, ClipboardManagerUnsupported>();
|
||||
#endif
|
||||
|
||||
IoCManager.Register<ISignalHandler, ClientSignalHandler>();
|
||||
|
||||
@@ -42,6 +42,7 @@ namespace Robust.Client
|
||||
{
|
||||
#pragma warning disable 649
|
||||
[Dependency] private readonly IConfigurationManager _configurationManager;
|
||||
[Dependency] private readonly IClipboardManagerInternal _clipboardManager;
|
||||
[Dependency] private readonly IResourceCacheInternal _resourceCache;
|
||||
[Dependency] private readonly IResourceManager _resourceManager;
|
||||
[Dependency] private readonly IRobustSerializer _serializer;
|
||||
@@ -68,7 +69,6 @@ namespace Robust.Client
|
||||
[Dependency] private readonly ILocalizationManager _localizationManager;
|
||||
[Dependency] private readonly IModLoader _modLoader;
|
||||
[Dependency] private readonly ISignalHandler _signalHandler;
|
||||
[Dependency] private readonly IFileDialogManagerInternal _fileDialogManager;
|
||||
#pragma warning restore 649
|
||||
|
||||
public string ContentRootDir { get; set; } = "../../../";
|
||||
@@ -122,6 +122,7 @@ namespace Robust.Client
|
||||
_clyde.SetWindowTitle("Space Station 14");
|
||||
|
||||
_fontManager.Initialize();
|
||||
_clipboardManager.Initialize();
|
||||
|
||||
//identical code for server in baseserver
|
||||
if (!_modLoader.TryLoadAssembly<GameShared>(_resourceManager, $"Content.Shared"))
|
||||
@@ -139,7 +140,6 @@ namespace Robust.Client
|
||||
// Call Init in game assemblies.
|
||||
_modLoader.BroadcastRunLevel(ModRunLevel.Init);
|
||||
|
||||
_fileDialogManager.Initialize();
|
||||
_eyeManager.Initialize();
|
||||
_serializer.Initialize();
|
||||
_userInterfaceManager.Initialize();
|
||||
|
||||
@@ -1,16 +1,17 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using JetBrains.Annotations;
|
||||
using SharpFont;
|
||||
using SixLabors.ImageSharp;
|
||||
using SixLabors.ImageSharp.PixelFormats;
|
||||
using SixLabors.ImageSharp.Processing;
|
||||
using SixLabors.Primitives;
|
||||
using Robust.Client.Interfaces.Graphics;
|
||||
using Robust.Shared.Interfaces.Configuration;
|
||||
using Robust.Shared.IoC;
|
||||
using Robust.Shared.Maths;
|
||||
using Robust.Shared.Utility;
|
||||
using SharpFont;
|
||||
using SixLabors.ImageSharp;
|
||||
using SixLabors.ImageSharp.PixelFormats;
|
||||
using SixLabors.ImageSharp.Processing;
|
||||
using SixLabors.Primitives;
|
||||
|
||||
namespace Robust.Client.Graphics
|
||||
{
|
||||
@@ -32,9 +33,9 @@ namespace Robust.Client.Graphics
|
||||
_library = new Library();
|
||||
}
|
||||
|
||||
public IFontFaceHandle Load(ReadOnlySpan<byte> data)
|
||||
public IFontFaceHandle Load(Stream stream)
|
||||
{
|
||||
var face = new Face(_library, data.ToArray(), 0);
|
||||
var face = new Face(_library, stream.CopyToArray(), 0);
|
||||
var handle = new FontFaceHandle(face);
|
||||
return handle;
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
using System;
|
||||
using System.IO;
|
||||
using Robust.Client.Graphics;
|
||||
|
||||
namespace Robust.Client.Interfaces.Graphics
|
||||
@@ -10,7 +10,7 @@ namespace Robust.Client.Interfaces.Graphics
|
||||
|
||||
internal interface IFontManagerInternal : IFontManager
|
||||
{
|
||||
IFontFaceHandle Load(ReadOnlySpan<byte> data);
|
||||
IFontFaceHandle Load(Stream stream);
|
||||
IFontInstanceHandle MakeInstance(IFontFaceHandle handle, int size);
|
||||
void Initialize();
|
||||
}
|
||||
|
||||
@@ -8,4 +8,9 @@ namespace Robust.Client.Interfaces.UserInterface
|
||||
string GetText();
|
||||
void SetText(string text);
|
||||
}
|
||||
|
||||
internal interface IClipboardManagerInternal : IClipboardManager
|
||||
{
|
||||
void Initialize();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -29,9 +29,4 @@ namespace Robust.Client.Interfaces.UserInterface
|
||||
/// <returns>The path the user selected to open. Null if the user cancelled the action.</returns>
|
||||
Task<string> OpenFolder();
|
||||
}
|
||||
|
||||
internal interface IFileDialogManagerInternal : IFileDialogManager
|
||||
{
|
||||
void Initialize();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,20 +1,16 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using SixLabors.ImageSharp;
|
||||
using SixLabors.ImageSharp.PixelFormats;
|
||||
using SixLabors.ImageSharp.Processing;
|
||||
using SixLabors.Primitives;
|
||||
using Robust.Client.Graphics;
|
||||
using Robust.Client.Graphics.ClientEye;
|
||||
using Robust.Client.Interfaces.Map;
|
||||
using Robust.Client.Interfaces.ResourceManagement;
|
||||
using Robust.Shared.GameObjects.Components.Renderable;
|
||||
using Robust.Client.Utility;
|
||||
using Robust.Shared.IoC;
|
||||
using Robust.Shared.Map;
|
||||
using Robust.Shared.Maths;
|
||||
using Robust.Shared.Utility;
|
||||
using Image = SixLabors.ImageSharp.Image;
|
||||
using SixLabors.ImageSharp;
|
||||
using SixLabors.ImageSharp.PixelFormats;
|
||||
|
||||
namespace Robust.Client.Map
|
||||
{
|
||||
@@ -72,10 +68,9 @@ namespace Robust.Client.Map
|
||||
throw new NotImplementedException("Unable to use tiles with a dimension other than 32x32.");
|
||||
}
|
||||
|
||||
var point = new Point(column * tileSize, row * tileSize);
|
||||
var point = new Vector2i(column * tileSize, row * tileSize);
|
||||
|
||||
sheet.Mutate(x => x.DrawImage(image, point,
|
||||
PixelColorBlendingMode.Overlay, 1));
|
||||
image.Blit(new UIBox2i(0, 0, image.Width, image.Height), sheet, point);
|
||||
|
||||
_tileRegions.Add(def.TileId,
|
||||
UIBox2.FromDimensions(
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
using Robust.Client.Interfaces.ResourceManagement;
|
||||
using System.IO;
|
||||
using Robust.Shared.Utility;
|
||||
using System.IO;
|
||||
using Robust.Client.Graphics;
|
||||
using Robust.Client.Interfaces.Graphics;
|
||||
using Robust.Client.Interfaces.ResourceManagement;
|
||||
using Robust.Shared.IoC;
|
||||
using Robust.Shared.Utility;
|
||||
|
||||
namespace Robust.Client.ResourceManagement
|
||||
{
|
||||
@@ -18,7 +18,7 @@ namespace Robust.Client.ResourceManagement
|
||||
throw new FileNotFoundException("Content file does not exist for font");
|
||||
}
|
||||
|
||||
FontFaceHandle = IoCManager.Resolve<IFontManagerInternal>().Load(cache.ContentFileRead(path).ToArray());
|
||||
FontFaceHandle = IoCManager.Resolve<IFontManagerInternal>().Load(cache.ContentFileRead(path));
|
||||
}
|
||||
|
||||
public VectorFont MakeDefault()
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
using Robust.Client.Graphics;
|
||||
using System.IO;
|
||||
using Robust.Client.Graphics;
|
||||
using Robust.Client.Interfaces.Graphics;
|
||||
using Robust.Client.Interfaces.ResourceManagement;
|
||||
using Robust.Shared.IoC;
|
||||
using Robust.Shared.Log;
|
||||
using Robust.Shared.Utility;
|
||||
using System.IO;
|
||||
using Robust.Client.Interfaces.Graphics;
|
||||
using Robust.Shared.IoC;
|
||||
using YamlDotNet.RepresentationModel;
|
||||
|
||||
namespace Robust.Client.ResourceManagement
|
||||
@@ -16,7 +16,7 @@ namespace Robust.Client.ResourceManagement
|
||||
|
||||
public override void Load(IResourceCache cache, ResourcePath path)
|
||||
{
|
||||
if (!cache.ContentFileExists(path))
|
||||
if (!cache.TryContentFileRead(path, out var stream))
|
||||
{
|
||||
throw new FileNotFoundException("Content file does not exist for texture");
|
||||
}
|
||||
@@ -26,7 +26,7 @@ namespace Robust.Client.ResourceManagement
|
||||
|
||||
var loadParameters = _tryLoadTextureParameters(cache, path) ?? TextureLoadParameters.Default;
|
||||
|
||||
_loadOpenGL(cache, path, loadParameters);
|
||||
_loadOpenGL(cache, stream, path, loadParameters);
|
||||
}
|
||||
|
||||
private static TextureLoadParameters? _tryLoadTextureParameters(IResourceCache cache, ResourcePath path)
|
||||
@@ -52,11 +52,11 @@ namespace Robust.Client.ResourceManagement
|
||||
return null;
|
||||
}
|
||||
|
||||
private void _loadOpenGL(IResourceCache cache, ResourcePath path, TextureLoadParameters? parameters)
|
||||
private void _loadOpenGL(IResourceCache cache, Stream stream, ResourcePath path, TextureLoadParameters? parameters)
|
||||
{
|
||||
var manager = IoCManager.Resolve<IClyde>();
|
||||
|
||||
Texture = manager.LoadTextureFromPNGStream(cache.ContentFileRead(path), path.ToString(), parameters);
|
||||
Texture = manager.LoadTextureFromPNGStream(stream, path.ToString(), parameters);
|
||||
}
|
||||
|
||||
public static implicit operator Texture(TextureResource res)
|
||||
|
||||
@@ -1,14 +1,13 @@
|
||||
using System;
|
||||
using System.Diagnostics;
|
||||
using System.Text;
|
||||
using Robust.Client.Interfaces.UserInterface;
|
||||
using Robust.Shared.Utility;
|
||||
|
||||
namespace Robust.Client.UserInterface
|
||||
{
|
||||
internal sealed class ClipboardManagerLinux : IClipboardManager
|
||||
internal sealed class ClipboardManagerLinux : IClipboardManagerInternal
|
||||
{
|
||||
public bool Available { get; }
|
||||
public bool Available { get; private set; }
|
||||
|
||||
public string NotAvailableReason =>
|
||||
// ReSharper disable once StringLiteralTypo
|
||||
@@ -58,7 +57,7 @@ namespace Robust.Client.UserInterface
|
||||
process.WaitForExit();
|
||||
}
|
||||
|
||||
public ClipboardManagerLinux()
|
||||
public async void Initialize()
|
||||
{
|
||||
try
|
||||
{
|
||||
@@ -71,13 +70,14 @@ namespace Robust.Client.UserInterface
|
||||
RedirectStandardError = true,
|
||||
UseShellExecute = false
|
||||
});
|
||||
|
||||
if (process == null)
|
||||
{
|
||||
Available = false;
|
||||
return;
|
||||
}
|
||||
|
||||
process.WaitForExit();
|
||||
await process.WaitForExitAsync();
|
||||
Available = process.ExitCode == 0;
|
||||
}
|
||||
catch (Exception)
|
||||
|
||||
@@ -3,7 +3,7 @@ using Robust.Client.Interfaces.UserInterface;
|
||||
|
||||
namespace Robust.Client.UserInterface
|
||||
{
|
||||
internal sealed class ClipboardManagerUnsupported : IClipboardManager
|
||||
internal sealed class ClipboardManagerUnsupported : IClipboardManagerInternal
|
||||
{
|
||||
public bool Available => false;
|
||||
public string NotAvailableReason => "Sorry, the clipboard is not supported on your platform.";
|
||||
@@ -17,5 +17,10 @@ namespace Robust.Client.UserInterface
|
||||
{
|
||||
throw new NotSupportedException();
|
||||
}
|
||||
|
||||
public void Initialize()
|
||||
{
|
||||
// Nothing.
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -8,7 +8,7 @@ using Robust.Shared.IoC;
|
||||
namespace Robust.Client.UserInterface
|
||||
{
|
||||
// Yay Windows API!
|
||||
sealed class ClipboardManagerWindows : IClipboardManager
|
||||
sealed class ClipboardManagerWindows : IClipboardManagerInternal
|
||||
{
|
||||
[Dependency]
|
||||
#pragma warning disable 649
|
||||
@@ -166,6 +166,11 @@ namespace Robust.Client.UserInterface
|
||||
}
|
||||
}
|
||||
|
||||
public void Initialize()
|
||||
{
|
||||
// Nothing.
|
||||
}
|
||||
|
||||
private const uint CF_UNICODETEXT = 13;
|
||||
private const uint CF_TEXT = 1;
|
||||
private const uint GMEM_MOVEABLE = 2;
|
||||
|
||||
@@ -7,7 +7,6 @@ using Robust.Client.Graphics.Drawing;
|
||||
using Robust.Client.Input;
|
||||
using Robust.Client.Interfaces.Console;
|
||||
using Robust.Client.UserInterface.Controls;
|
||||
using Robust.Client.Utility;
|
||||
using Robust.Shared.Interfaces.Resources;
|
||||
using Robust.Shared.Maths;
|
||||
using Robust.Shared.Utility;
|
||||
@@ -219,7 +218,7 @@ namespace Robust.Client.UserInterface.CustomControls
|
||||
}
|
||||
}
|
||||
|
||||
private void _loadHistoryFromDisk()
|
||||
private async void _loadHistoryFromDisk()
|
||||
{
|
||||
CommandHistory.Clear();
|
||||
Stream stream;
|
||||
@@ -237,7 +236,7 @@ namespace Robust.Client.UserInterface.CustomControls
|
||||
{
|
||||
using (var reader = new StreamReader(stream, EncodingHelpers.UTF8))
|
||||
{
|
||||
var data = JsonConvert.DeserializeObject<List<string>>(reader.ReadToEnd());
|
||||
var data = JsonConvert.DeserializeObject<List<string>>(await reader.ReadToEndAsync());
|
||||
CommandHistory.Clear();
|
||||
CommandHistory.AddRange(data);
|
||||
_historyPosition = CommandHistory.Count;
|
||||
|
||||
@@ -6,7 +6,7 @@ namespace Robust.Client.UserInterface
|
||||
/// <summary>
|
||||
/// Treats ever file dialog operation as cancelled.
|
||||
/// </summary>
|
||||
internal sealed class DummyFileDialogManager : IFileDialogManagerInternal
|
||||
internal sealed class DummyFileDialogManager : IFileDialogManager
|
||||
{
|
||||
public Task<string> OpenFile()
|
||||
{
|
||||
@@ -22,10 +22,5 @@ namespace Robust.Client.UserInterface
|
||||
{
|
||||
return Task.FromResult<string>(null);
|
||||
}
|
||||
|
||||
public void Initialize()
|
||||
{
|
||||
// Nothing.
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -16,7 +16,7 @@ namespace Robust.Client.UserInterface
|
||||
[SuppressMessage("ReSharper", "IdentifierTypo")]
|
||||
[SuppressMessage("ReSharper", "CommentTypo")]
|
||||
[SuppressMessage("ReSharper", "StringLiteralTypo")]
|
||||
internal sealed class FileDialogManager : IFileDialogManagerInternal
|
||||
internal sealed class FileDialogManager : IFileDialogManager
|
||||
{
|
||||
// Uses nativefiledialog to open the file dialogs cross platform.
|
||||
// On Linux, if the kdialog command is found, it will be used instead.
|
||||
@@ -28,46 +28,40 @@ namespace Robust.Client.UserInterface
|
||||
|
||||
#if LINUX
|
||||
private bool _kDialogAvailable;
|
||||
private bool _checkedKDialogAvailable;
|
||||
#endif
|
||||
|
||||
public Task<string> OpenFile()
|
||||
public async Task<string> OpenFile()
|
||||
{
|
||||
#if LINUX
|
||||
if (_kDialogAvailable)
|
||||
if (await IsKDialogAvailable())
|
||||
{
|
||||
return OpenFileKDialog();
|
||||
return await OpenFileKDialog();
|
||||
}
|
||||
#endif
|
||||
return OpenFileNfd();
|
||||
return await OpenFileNfd();
|
||||
}
|
||||
|
||||
public Task<string> SaveFile()
|
||||
public async Task<string> SaveFile()
|
||||
{
|
||||
#if LINUX
|
||||
if (_kDialogAvailable)
|
||||
if (await IsKDialogAvailable())
|
||||
{
|
||||
return SaveFileKDialog();
|
||||
return await SaveFileKDialog();
|
||||
}
|
||||
#endif
|
||||
return SaveFileNfd();
|
||||
return await SaveFileNfd();
|
||||
}
|
||||
|
||||
public Task<string> OpenFolder()
|
||||
public async Task<string> OpenFolder()
|
||||
{
|
||||
#if LINUX
|
||||
if (_kDialogAvailable)
|
||||
if (await IsKDialogAvailable())
|
||||
{
|
||||
return OpenFolderKDialog();
|
||||
return await OpenFolderKDialog();
|
||||
}
|
||||
#endif
|
||||
return OpenFolderNfd();
|
||||
}
|
||||
|
||||
public void Initialize()
|
||||
{
|
||||
#if LINUX
|
||||
CheckKDialogSupport();
|
||||
#endif
|
||||
return await OpenFolderNfd();
|
||||
}
|
||||
|
||||
private unsafe Task<string> OpenFileNfd()
|
||||
@@ -150,7 +144,7 @@ namespace Robust.Client.UserInterface
|
||||
}
|
||||
|
||||
#if LINUX
|
||||
private void CheckKDialogSupport()
|
||||
private async Task CheckKDialogSupport()
|
||||
{
|
||||
try
|
||||
{
|
||||
@@ -170,7 +164,7 @@ namespace Robust.Client.UserInterface
|
||||
return;
|
||||
}
|
||||
|
||||
process.WaitForExit();
|
||||
await process.WaitForExitAsync();
|
||||
_kDialogAvailable = process.ExitCode == 0;
|
||||
|
||||
if (_kDialogAvailable)
|
||||
@@ -223,6 +217,17 @@ namespace Robust.Client.UserInterface
|
||||
|
||||
return (await process.StandardOutput.ReadLineAsync()).Trim();
|
||||
}
|
||||
|
||||
private async Task<bool> IsKDialogAvailable()
|
||||
{
|
||||
if (!_checkedKDialogAvailable)
|
||||
{
|
||||
await CheckKDialogSupport();
|
||||
_checkedKDialogAvailable = true;
|
||||
}
|
||||
|
||||
return _kDialogAvailable;
|
||||
}
|
||||
#endif
|
||||
|
||||
[DllImport("swnfd.dll")]
|
||||
|
||||
@@ -21,15 +21,15 @@ using FrameEventArgs = Robust.Client.FrameEventArgs;
|
||||
|
||||
namespace Robust.Lite
|
||||
{
|
||||
internal class LiteGameController : IGameController, IGameControllerInternal
|
||||
internal class LiteGameController : IGameControllerInternal
|
||||
{
|
||||
private IGameLoop _mainLoop;
|
||||
|
||||
#pragma warning disable 649
|
||||
[Dependency] private readonly IClipboardManagerInternal _clipboardManager;
|
||||
[Dependency] private readonly IClydeInternal _clyde;
|
||||
[Dependency] private readonly IConfigurationManager _configurationManager;
|
||||
[Dependency] private readonly IEyeManager _eyeManager;
|
||||
[Dependency] private readonly IFileDialogManagerInternal _fileDialogManager;
|
||||
[Dependency] private readonly IFontManagerInternal _fontManager;
|
||||
[Dependency] private readonly IGameTiming _gameTiming;
|
||||
[Dependency] private readonly ILocalizationManager _localizationManager;
|
||||
@@ -91,8 +91,7 @@ namespace Robust.Lite
|
||||
}
|
||||
|
||||
_fontManager.Initialize();
|
||||
|
||||
_fileDialogManager.Initialize();
|
||||
_clipboardManager.Initialize();
|
||||
|
||||
_eyeManager.Initialize();
|
||||
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
using Robust.Shared.Log;
|
||||
using Robust.Shared.Utility;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using Robust.Shared.Utility;
|
||||
|
||||
namespace Robust.Shared.ContentPack
|
||||
{
|
||||
@@ -31,7 +30,7 @@ namespace Robust.Shared.ContentPack
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public bool TryGetFile(ResourcePath relPath, out MemoryStream stream)
|
||||
public bool TryGetFile(ResourcePath relPath, out Stream stream)
|
||||
{
|
||||
var path = GetPath(relPath);
|
||||
if (!File.Exists(path))
|
||||
@@ -40,8 +39,7 @@ namespace Robust.Shared.ContentPack
|
||||
return false;
|
||||
}
|
||||
|
||||
var bytes = File.ReadAllBytes(path);
|
||||
stream = new MemoryStream(bytes, false);
|
||||
stream = File.OpenRead(path);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
using Robust.Shared.Utility;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using Robust.Shared.Utility;
|
||||
|
||||
namespace Robust.Shared.ContentPack
|
||||
{
|
||||
@@ -21,8 +21,9 @@ namespace Robust.Shared.ContentPack
|
||||
/// Gets a file from the content root using the relative path.
|
||||
/// </summary>
|
||||
/// <param name="relPath">Relative path from the root directory.</param>
|
||||
/// <param name="stream"></param>
|
||||
/// <returns>A stream of the file loaded into memory.</returns>
|
||||
bool TryGetFile(ResourcePath relPath, out MemoryStream stream);
|
||||
bool TryGetFile(ResourcePath relPath, out Stream stream);
|
||||
|
||||
/// <summary>
|
||||
/// Recursively finds all files in a directory and all sub directories.
|
||||
|
||||
@@ -199,7 +199,7 @@ namespace Robust.Shared.ContentPack
|
||||
try
|
||||
{
|
||||
// load the assembly into the process, and bootstrap the GameServer entry point.
|
||||
LoadGameAssembly<T>(gameDll.ToArray(), gamePdb.ToArray());
|
||||
LoadGameAssembly<T>(gameDll.CopyToArray(), gamePdb.CopyToArray());
|
||||
return true;
|
||||
}
|
||||
catch (Exception e)
|
||||
@@ -213,7 +213,7 @@ namespace Robust.Shared.ContentPack
|
||||
try
|
||||
{
|
||||
// load the assembly into the process, and bootstrap the GameServer entry point.
|
||||
LoadGameAssembly<T>(gameDll.ToArray());
|
||||
LoadGameAssembly<T>(gameDll.CopyToArray());
|
||||
return true;
|
||||
}
|
||||
catch (Exception e)
|
||||
|
||||
@@ -35,7 +35,7 @@ namespace Robust.Shared.ContentPack
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public bool TryGetFile(ResourcePath relPath, out MemoryStream stream)
|
||||
public bool TryGetFile(ResourcePath relPath, out Stream stream)
|
||||
{
|
||||
var entry = _zip.GetEntry(relPath.ToRootedPath().ToString());
|
||||
|
||||
|
||||
@@ -22,7 +22,7 @@ namespace Robust.Shared.ContentPack
|
||||
// Nothing to do here I'm pretty sure.
|
||||
}
|
||||
|
||||
public bool TryGetFile(ResourcePath relPath, out MemoryStream stream)
|
||||
public bool TryGetFile(ResourcePath relPath, out Stream stream)
|
||||
{
|
||||
if (relPath == _resourcePath)
|
||||
{
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using Robust.Shared.Configuration;
|
||||
using Robust.Shared.Interfaces.Configuration;
|
||||
using Robust.Shared.Interfaces.Resources;
|
||||
using Robust.Shared.IoC;
|
||||
@@ -107,13 +106,13 @@ namespace Robust.Shared.ContentPack
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public MemoryStream ContentFileRead(string path)
|
||||
public Stream ContentFileRead(string path)
|
||||
{
|
||||
return ContentFileRead(new ResourcePath(path));
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public MemoryStream ContentFileRead(ResourcePath path)
|
||||
public Stream ContentFileRead(ResourcePath path)
|
||||
{
|
||||
if (TryContentFileRead(path, out var fileStream))
|
||||
{
|
||||
@@ -123,13 +122,13 @@ namespace Robust.Shared.ContentPack
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public bool TryContentFileRead(string path, out MemoryStream fileStream)
|
||||
public bool TryContentFileRead(string path, out Stream fileStream)
|
||||
{
|
||||
return TryContentFileRead(new ResourcePath(path), out fileStream);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public bool TryContentFileRead(ResourcePath path, out MemoryStream fileStream)
|
||||
public bool TryContentFileRead(ResourcePath path, out Stream fileStream)
|
||||
{
|
||||
if (path == null)
|
||||
{
|
||||
|
||||
@@ -50,7 +50,7 @@ namespace Robust.Shared.Interfaces.Resources
|
||||
/// <exception cref="FileNotFoundException">Thrown if <paramref name="path"/> does not exist in the VFS.</exception>
|
||||
/// <exception cref="ArgumentException">Thrown if <paramref name="path"/> is not rooted.</exception>
|
||||
/// <exception cref="ArgumentNullException">Thrown if <paramref name="path"/> is null.</exception>
|
||||
MemoryStream ContentFileRead(ResourcePath path);
|
||||
Stream ContentFileRead(ResourcePath path);
|
||||
|
||||
/// <summary>
|
||||
/// Read a file from the mounted content roots.
|
||||
@@ -60,7 +60,7 @@ namespace Robust.Shared.Interfaces.Resources
|
||||
/// <exception cref="FileNotFoundException">Thrown if <paramref name="path"/> does not exist in the VFS.</exception>
|
||||
/// <exception cref="ArgumentException">Thrown if <paramref name="path"/> is not rooted.</exception>
|
||||
/// <exception cref="ArgumentNullException">Thrown if <paramref name="path"/> is null.</exception>
|
||||
MemoryStream ContentFileRead(string path);
|
||||
Stream ContentFileRead(string path);
|
||||
|
||||
/// <summary>
|
||||
/// Check if a file exists in any of the mounted content roots.
|
||||
@@ -88,7 +88,7 @@ namespace Robust.Shared.Interfaces.Resources
|
||||
/// <returns>True if the file could be loaded, false otherwise.</returns>
|
||||
/// <exception cref="ArgumentException">Thrown if <paramref name="path"/> is not rooted.</exception>
|
||||
/// <exception cref="ArgumentNullException">Thrown if <paramref name="path"/> is null.</exception>
|
||||
bool TryContentFileRead(ResourcePath path, out MemoryStream fileStream);
|
||||
bool TryContentFileRead(ResourcePath path, out Stream fileStream);
|
||||
|
||||
/// <summary>
|
||||
/// Try to read a file from the mounted content roots.
|
||||
@@ -98,7 +98,7 @@ namespace Robust.Shared.Interfaces.Resources
|
||||
/// <returns>True if the file could be loaded, false otherwise.</returns>
|
||||
/// <exception cref="ArgumentException">Thrown if <paramref name="path"/> is not rooted.</exception>
|
||||
/// <exception cref="ArgumentNullException">Thrown if <paramref name="path"/> is null.</exception>
|
||||
bool TryContentFileRead(string path, out MemoryStream fileStream);
|
||||
bool TryContentFileRead(string path, out Stream fileStream);
|
||||
|
||||
/// <summary>
|
||||
/// Recursively finds all files in a directory and all sub directories.
|
||||
|
||||
@@ -162,9 +162,13 @@ namespace Robust.Shared.IoC
|
||||
/// <inheritdoc />
|
||||
public void InjectDependencies(object obj)
|
||||
{
|
||||
foreach (var field in obj.GetType().GetAllFields()
|
||||
.Where(p => Attribute.GetCustomAttribute(p, typeof(DependencyAttribute)) != null))
|
||||
foreach (var field in obj.GetType().GetAllFields())
|
||||
{
|
||||
if (Attribute.GetCustomAttribute(field, typeof(DependencyAttribute)) == null)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
// Not using Resolve<T>() because we're literally building it right now.
|
||||
if (!_services.ContainsKey(field.FieldType))
|
||||
{
|
||||
|
||||
@@ -50,7 +50,7 @@ namespace Robust.Shared.Map
|
||||
|
||||
/// <inheritdoc />
|
||||
public MapIndices Indices => _gridIndices;
|
||||
|
||||
|
||||
/// <inheritdoc />
|
||||
public TileRef GetTileRef(ushort xIndex, ushort yIndex)
|
||||
{
|
||||
@@ -174,12 +174,11 @@ namespace Robust.Shared.Map
|
||||
var list = offset == SnapGridOffset.Center ? cell.Center : cell.Edge;
|
||||
|
||||
if (list == null)
|
||||
yield break;
|
||||
|
||||
foreach (var element in list)
|
||||
{
|
||||
yield return element;
|
||||
return Array.Empty<SnapGridComponent>();
|
||||
}
|
||||
|
||||
return list;
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
@@ -276,7 +275,7 @@ namespace Robust.Shared.Map
|
||||
newRight = cBounds.Right - 1;
|
||||
tBounds = tBounds.Translated(new Vector2i(-1, 0));
|
||||
}
|
||||
|
||||
|
||||
cBounds = new Box2i(newLeft, cBounds.Bottom, newRight, cBounds.Top);
|
||||
}
|
||||
}
|
||||
@@ -310,11 +309,11 @@ namespace Robust.Shared.Map
|
||||
newTop = cBounds.Top - 1;
|
||||
tBounds = tBounds.Translated(new Vector2i(0, -1));
|
||||
}
|
||||
|
||||
|
||||
cBounds = new Box2i(cBounds.Left, newBottom, cBounds.Right, newTop);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private static bool AnyTileOnX(in Tile[,] tiles, Vector2i extents, in Vector2i indices)
|
||||
{
|
||||
var y = indices.Y;
|
||||
@@ -322,7 +321,7 @@ namespace Robust.Shared.Map
|
||||
{
|
||||
if(tiles[x, y].IsEmpty)
|
||||
continue;
|
||||
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -336,7 +335,7 @@ namespace Robust.Shared.Map
|
||||
{
|
||||
if(tiles[x, y].IsEmpty)
|
||||
continue;
|
||||
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
using System;
|
||||
using System.Linq;
|
||||
using System.Collections.Generic;
|
||||
using Robust.Shared.Interfaces.Map;
|
||||
|
||||
|
||||
@@ -264,7 +264,8 @@ namespace Robust.Shared.Prototypes
|
||||
|
||||
if (prototypeTypes.ContainsKey(attribute.Type))
|
||||
{
|
||||
throw new InvalidImplementationException(type, typeof(IPrototype), string.Format("Duplicate prototype type ID: {0}. Current: {1}", attribute.Type, prototypeTypes[attribute.Type]));
|
||||
throw new InvalidImplementationException(type, typeof(IPrototype),
|
||||
$"Duplicate prototype type ID: {attribute.Type}. Current: {prototypeTypes[attribute.Type]}");
|
||||
}
|
||||
|
||||
prototypeTypes[attribute.Type] = type;
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
using Robust.Shared.Interfaces.Reflection;
|
||||
using System;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
using Robust.Shared.Interfaces.Reflection;
|
||||
using Robust.Shared.Log;
|
||||
|
||||
namespace Robust.Shared.Reflection
|
||||
@@ -17,6 +17,7 @@ namespace Robust.Shared.Reflection
|
||||
/// First prefix should probably be <code>""</code>.
|
||||
/// </remarks>
|
||||
protected abstract IEnumerable<string> TypePrefixes { get; }
|
||||
|
||||
private readonly List<Assembly> assemblies = new List<Assembly>();
|
||||
|
||||
public event EventHandler<ReflectionUpdateEventArgs> OnAssemblyAdded;
|
||||
@@ -25,20 +26,16 @@ namespace Robust.Shared.Reflection
|
||||
|
||||
public IEnumerable<Type> GetAllChildren<T>(bool inclusive = false)
|
||||
{
|
||||
var typeLists = new List<Type[]>(Assemblies.Count);
|
||||
try
|
||||
{
|
||||
// There's very little assemblies, so storing these temporarily is cheap.
|
||||
// We need to do it ahead of time so that we can catch ReflectionTypeLoadException HERE,
|
||||
// so whoever is using us doesn't have to handle them.
|
||||
var TypeLists = new List<Type[]>(Assemblies.Count);
|
||||
TypeLists.AddRange(Assemblies.Select(t => t.GetTypes()));
|
||||
|
||||
return TypeLists.SelectMany(t => t)
|
||||
.Where(t => typeof(T).IsAssignableFrom(t)
|
||||
&& !t.IsAbstract
|
||||
&& ((Attribute.GetCustomAttribute(t, typeof(ReflectAttribute)) as ReflectAttribute)
|
||||
?.Discoverable ?? ReflectAttribute.DEFAULT_DISCOVERABLE)
|
||||
&& (inclusive || typeof(T) != t));
|
||||
foreach (var assembly in Assemblies)
|
||||
{
|
||||
typeLists.Add(assembly.GetTypes());
|
||||
}
|
||||
}
|
||||
catch (ReflectionTypeLoadException e)
|
||||
{
|
||||
@@ -47,11 +44,38 @@ namespace Robust.Shared.Reflection
|
||||
{
|
||||
Logger.Error(inner.ToString());
|
||||
}
|
||||
|
||||
throw;
|
||||
}
|
||||
|
||||
foreach (var t in typeLists)
|
||||
{
|
||||
foreach (var type in t)
|
||||
{
|
||||
if (!typeof(T).IsAssignableFrom(type) || type.IsAbstract)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
var attribute = (ReflectAttribute) Attribute.GetCustomAttribute(type, typeof(ReflectAttribute));
|
||||
|
||||
if (!(attribute?.Discoverable ?? ReflectAttribute.DEFAULT_DISCOVERABLE))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if (typeof(T) == type && !inclusive)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
yield return type;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void LoadAssemblies(params Assembly[] args) => LoadAssemblies(args.AsEnumerable());
|
||||
|
||||
public void LoadAssemblies(IEnumerable<Assembly> assemblies)
|
||||
{
|
||||
this.assemblies.AddRange(assemblies);
|
||||
@@ -86,6 +110,7 @@ namespace Robust.Shared.Reflection
|
||||
{
|
||||
return ret;
|
||||
}
|
||||
|
||||
throw new ArgumentException("Unable to find type.");
|
||||
}
|
||||
|
||||
@@ -143,7 +168,7 @@ namespace Robust.Shared.Reflection
|
||||
continue;
|
||||
}
|
||||
|
||||
@enum = (Enum)Enum.Parse(type, value);
|
||||
@enum = (Enum) Enum.Parse(type, value);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
24
Robust.Shared/Utility/StreamExt.cs
Normal file
24
Robust.Shared/Utility/StreamExt.cs
Normal file
@@ -0,0 +1,24 @@
|
||||
using System.IO;
|
||||
|
||||
namespace Robust.Shared.Utility
|
||||
{
|
||||
/// <summary>
|
||||
/// Extension methods for working with streams.
|
||||
/// </summary>
|
||||
public static class StreamExt
|
||||
{
|
||||
/// <summary>
|
||||
/// Copies any stream into a byte array.
|
||||
/// </summary>
|
||||
/// <param name="stream">The stream to copy.</param>
|
||||
/// <returns>The byte array.</returns>
|
||||
public static byte[] CopyToArray(this Stream stream)
|
||||
{
|
||||
using (var memStream = new MemoryStream())
|
||||
{
|
||||
stream.CopyTo(memStream);
|
||||
return memStream.GetBuffer();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -36,7 +36,14 @@ namespace Robust.Shared.Utility
|
||||
// We need to fetch the entire class hierarchy and SelectMany(),
|
||||
// Because BindingFlags.FlattenHierarchy doesn't read privates,
|
||||
// Even when you pass BindingFlags.NonPublic.
|
||||
return GetClassHierarchy(t).SelectMany(p => p.GetFields(BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly | BindingFlags.Public));
|
||||
foreach (var p in GetClassHierarchy(t))
|
||||
{
|
||||
foreach (var field in p.GetFields(BindingFlags.NonPublic | BindingFlags.Instance |
|
||||
BindingFlags.DeclaredOnly | BindingFlags.Public))
|
||||
{
|
||||
yield return field;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -44,7 +51,9 @@ namespace Robust.Shared.Utility
|
||||
/// </summary>
|
||||
public static IEnumerable<PropertyInfo> GetAllProperties(this Type t)
|
||||
{
|
||||
return GetClassHierarchy(t).SelectMany(p => p.GetProperties(BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly | BindingFlags.Public));
|
||||
return GetClassHierarchy(t).SelectMany(p =>
|
||||
p.GetProperties(BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly |
|
||||
BindingFlags.Public));
|
||||
}
|
||||
|
||||
public static IEnumerable<Type> GetClassHierarchy(this Type t)
|
||||
|
||||
@@ -28,7 +28,7 @@ namespace Robust.UnitTesting.Shared.ContentPack
|
||||
var resourceManager = IoCManager.Resolve<IResourceManagerInternal>();
|
||||
using (var stream = resourceManager.ContentFileRead("/a/b/c.dat"))
|
||||
{
|
||||
Assert.That(stream.ToArray(), Is.EqualTo(Data));
|
||||
Assert.That(stream.CopyToArray(), Is.EqualTo(Data));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user