Merge pull request #81 from TorchAPI/sessions-manager-71
Session Management System
This commit is contained in:
@@ -4,6 +4,7 @@ using System.Linq;
|
|||||||
using System.Text;
|
using System.Text;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using Torch.API.Managers;
|
using Torch.API.Managers;
|
||||||
|
using Torch.API.Session;
|
||||||
using VRage.Game.ModAPI;
|
using VRage.Game.ModAPI;
|
||||||
|
|
||||||
namespace Torch.API
|
namespace Torch.API
|
||||||
@@ -33,15 +34,22 @@ namespace Torch.API
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
event Action SessionUnloaded;
|
event Action SessionUnloaded;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the currently running session instance, or null if none exists.
|
||||||
|
/// </summary>
|
||||||
|
ITorchSession CurrentSession { get; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Configuration for the current instance.
|
/// Configuration for the current instance.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
ITorchConfig Config { get; }
|
ITorchConfig Config { get; }
|
||||||
|
|
||||||
/// <inheritdoc cref="IMultiplayerManager"/>
|
/// <inheritdoc cref="IMultiplayerManager"/>
|
||||||
|
[Obsolete]
|
||||||
IMultiplayerManager Multiplayer { get; }
|
IMultiplayerManager Multiplayer { get; }
|
||||||
|
|
||||||
/// <inheritdoc cref="IPluginManager"/>
|
/// <inheritdoc cref="IPluginManager"/>
|
||||||
|
[Obsolete]
|
||||||
IPluginManager Plugins { get; }
|
IPluginManager Plugins { get; }
|
||||||
|
|
||||||
/// <inheritdoc cref="IDependencyManager"/>
|
/// <inheritdoc cref="IDependencyManager"/>
|
||||||
|
29
Torch.API/Session/ITorchSession.cs
Normal file
29
Torch.API/Session/ITorchSession.cs
Normal file
@@ -0,0 +1,29 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using Sandbox.Game.World;
|
||||||
|
using Torch.API.Managers;
|
||||||
|
|
||||||
|
namespace Torch.API.Session
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Represents the Torch code working with a single game session
|
||||||
|
/// </summary>
|
||||||
|
public interface ITorchSession
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// The Torch instance this session is bound to
|
||||||
|
/// </summary>
|
||||||
|
ITorchBase Torch { get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The Space Engineers game session this session is bound to.
|
||||||
|
/// </summary>
|
||||||
|
MySession KeenSession { get; }
|
||||||
|
|
||||||
|
/// <inheritdoc cref="IDependencyManager"/>
|
||||||
|
IDependencyManager Managers { get; }
|
||||||
|
}
|
||||||
|
}
|
46
Torch.API/Session/ITorchSessionManager.cs
Normal file
46
Torch.API/Session/ITorchSessionManager.cs
Normal file
@@ -0,0 +1,46 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using Torch.API.Managers;
|
||||||
|
|
||||||
|
namespace Torch.API.Session
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Creates a manager for the given session if applicable.
|
||||||
|
/// </summary>
|
||||||
|
/// <remarks>
|
||||||
|
/// This is for creating managers that will live inside the session, not the manager that controls sesssions.
|
||||||
|
/// </remarks>
|
||||||
|
/// <param name="session">The session to construct a bound manager for</param>
|
||||||
|
/// <returns>The manager that will live in the session, or null if none.</returns>
|
||||||
|
public delegate IManager SessionManagerFactoryDel(ITorchSession session);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Manages the creation and destruction of <see cref="ITorchSession"/> instances for each <see cref="Sandbox.Game.World.MySession"/> created by Space Engineers.
|
||||||
|
/// </summary>
|
||||||
|
public interface ITorchSessionManager : IManager
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// The currently running session
|
||||||
|
/// </summary>
|
||||||
|
ITorchSession CurrentSession { get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Adds the given factory as a supplier for session based managers
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="factory">Session based manager supplier</param>
|
||||||
|
/// <returns>true if added, false if already present</returns>
|
||||||
|
/// <exception cref="ArgumentNullException">If the factory is null</exception>
|
||||||
|
bool AddFactory(SessionManagerFactoryDel factory);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Remove the given factory from the suppliers for session based managers
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="factory">Session based manager supplier</param>
|
||||||
|
/// <returns>true if removed, false if not present</returns>
|
||||||
|
/// <exception cref="ArgumentNullException">If the factory is null</exception>
|
||||||
|
bool RemoveFactory(SessionManagerFactoryDel factory);
|
||||||
|
}
|
||||||
|
}
|
@@ -175,6 +175,8 @@
|
|||||||
<Compile Include="Properties\AssemblyInfo.cs" />
|
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||||
<Compile Include="ServerState.cs" />
|
<Compile Include="ServerState.cs" />
|
||||||
<Compile Include="ModAPI\TorchAPI.cs" />
|
<Compile Include="ModAPI\TorchAPI.cs" />
|
||||||
|
<Compile Include="Session\ITorchSession.cs" />
|
||||||
|
<Compile Include="Session\ITorchSessionManager.cs" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<None Include="packages.config" />
|
<None Include="packages.config" />
|
||||||
|
@@ -12,6 +12,7 @@ using VRage.Steam;
|
|||||||
using Torch.API;
|
using Torch.API;
|
||||||
using VRage;
|
using VRage;
|
||||||
using VRage.FileSystem;
|
using VRage.FileSystem;
|
||||||
|
using VRage.GameServices;
|
||||||
using VRageRender;
|
using VRageRender;
|
||||||
using VRageRender.ExternalApp;
|
using VRageRender.ExternalApp;
|
||||||
|
|
||||||
@@ -53,7 +54,7 @@ namespace Torch.Client
|
|||||||
|
|
||||||
_startup.DetectSharpDxLeaksBeforeRun();
|
_startup.DetectSharpDxLeaksBeforeRun();
|
||||||
var steamService = new SteamService(Game.IsDedicated, APP_ID);
|
var steamService = new SteamService(Game.IsDedicated, APP_ID);
|
||||||
MyServiceManager.Instance.AddService(steamService);
|
MyServiceManager.Instance.AddService<IMyGameService>(steamService);
|
||||||
_renderer = null;
|
_renderer = null;
|
||||||
SpaceEngineersGame.SetupPerGameSettings();
|
SpaceEngineersGame.SetupPerGameSettings();
|
||||||
// I'm sorry, but it's what Keen does in SpaceEngineers.MyProgram
|
// I'm sorry, but it's what Keen does in SpaceEngineers.MyProgram
|
||||||
|
49
Torch/Session/TorchSession.cs
Normal file
49
Torch/Session/TorchSession.cs
Normal file
@@ -0,0 +1,49 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using NLog;
|
||||||
|
using Sandbox.Game.World;
|
||||||
|
using Torch.API;
|
||||||
|
using Torch.API.Managers;
|
||||||
|
using Torch.API.Session;
|
||||||
|
using Torch.Managers;
|
||||||
|
|
||||||
|
namespace Torch.Session
|
||||||
|
{
|
||||||
|
public class TorchSession : ITorchSession
|
||||||
|
{
|
||||||
|
private static readonly Logger _log = LogManager.GetCurrentClassLogger();
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The Torch instance this session is bound to
|
||||||
|
/// </summary>
|
||||||
|
public ITorchBase Torch { get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The Space Engineers game session this session is bound to.
|
||||||
|
/// </summary>
|
||||||
|
public MySession KeenSession { get; }
|
||||||
|
|
||||||
|
/// <inheritdoc cref="IDependencyManager"/>
|
||||||
|
public IDependencyManager Managers { get; }
|
||||||
|
|
||||||
|
public TorchSession(ITorchBase torch, MySession keenSession)
|
||||||
|
{
|
||||||
|
Torch = torch;
|
||||||
|
KeenSession = keenSession;
|
||||||
|
Managers = new DependencyManager(torch.Managers);
|
||||||
|
}
|
||||||
|
|
||||||
|
internal void Attach()
|
||||||
|
{
|
||||||
|
Managers.Attach();
|
||||||
|
}
|
||||||
|
|
||||||
|
internal void Detach()
|
||||||
|
{
|
||||||
|
Managers.Detach();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
93
Torch/Session/TorchSessionManager.cs
Normal file
93
Torch/Session/TorchSessionManager.cs
Normal file
@@ -0,0 +1,93 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using NLog;
|
||||||
|
using Sandbox.Game.World;
|
||||||
|
using Torch.API;
|
||||||
|
using Torch.API.Managers;
|
||||||
|
using Torch.API.Session;
|
||||||
|
using Torch.Managers;
|
||||||
|
using Torch.Session;
|
||||||
|
|
||||||
|
namespace Torch.Session
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Manages the creation and destruction of <see cref="TorchSession"/> instances for each <see cref="MySession"/> created by Space Engineers.
|
||||||
|
/// </summary>
|
||||||
|
public class TorchSessionManager : Manager, ITorchSessionManager
|
||||||
|
{
|
||||||
|
private static readonly Logger _log = LogManager.GetCurrentClassLogger();
|
||||||
|
private TorchSession _currentSession;
|
||||||
|
|
||||||
|
/// <inheritdoc/>
|
||||||
|
public ITorchSession CurrentSession => _currentSession;
|
||||||
|
|
||||||
|
private readonly HashSet<SessionManagerFactoryDel> _factories = new HashSet<SessionManagerFactoryDel>();
|
||||||
|
|
||||||
|
public TorchSessionManager(ITorchBase torchInstance) : base(torchInstance)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc/>
|
||||||
|
public bool AddFactory(SessionManagerFactoryDel factory)
|
||||||
|
{
|
||||||
|
if (factory == null)
|
||||||
|
throw new ArgumentNullException(nameof(factory), "Factory must be non-null");
|
||||||
|
return _factories.Add(factory);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc/>
|
||||||
|
public bool RemoveFactory(SessionManagerFactoryDel factory)
|
||||||
|
{
|
||||||
|
if (factory == null)
|
||||||
|
throw new ArgumentNullException(nameof(factory), "Factory must be non-null");
|
||||||
|
return _factories.Remove(factory);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void SessionLoaded()
|
||||||
|
{
|
||||||
|
if (_currentSession != null)
|
||||||
|
{
|
||||||
|
_log.Warn($"Override old torch session {_currentSession.KeenSession.Name}");
|
||||||
|
_currentSession.Detach();
|
||||||
|
}
|
||||||
|
|
||||||
|
_log.Info($"Starting new torch session for {MySession.Static.Name}");
|
||||||
|
_currentSession = new TorchSession(Torch, MySession.Static);
|
||||||
|
foreach (SessionManagerFactoryDel factory in _factories)
|
||||||
|
{
|
||||||
|
IManager manager = factory(CurrentSession);
|
||||||
|
if (manager != null)
|
||||||
|
CurrentSession.Managers.AddManager(manager);
|
||||||
|
}
|
||||||
|
(CurrentSession as TorchSession)?.Attach();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void SessionUnloaded()
|
||||||
|
{
|
||||||
|
if (_currentSession == null)
|
||||||
|
return;
|
||||||
|
_log.Info($"Unloading torch session for {_currentSession.KeenSession.Name}");
|
||||||
|
_currentSession.Detach();
|
||||||
|
_currentSession = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc/>
|
||||||
|
public override void Attach()
|
||||||
|
{
|
||||||
|
MySession.AfterLoading += SessionLoaded;
|
||||||
|
MySession.OnUnloaded += SessionUnloaded;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc/>
|
||||||
|
public override void Detach()
|
||||||
|
{
|
||||||
|
_currentSession?.Detach();
|
||||||
|
_currentSession = null;
|
||||||
|
MySession.AfterLoading -= SessionLoaded;
|
||||||
|
MySession.OnUnloaded -= SessionUnloaded;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@@ -3,9 +3,11 @@ using System.Collections.Generic;
|
|||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
|
using NLog;
|
||||||
using SteamSDK;
|
using SteamSDK;
|
||||||
using VRage.Steam;
|
using VRage.Steam;
|
||||||
using Sandbox;
|
using Sandbox;
|
||||||
|
using Sandbox.Engine.Networking;
|
||||||
using Torch.Utils;
|
using Torch.Utils;
|
||||||
using VRage.GameServices;
|
using VRage.GameServices;
|
||||||
|
|
||||||
@@ -19,6 +21,9 @@ namespace Torch
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public class SteamService : MySteamService
|
public class SteamService : MySteamService
|
||||||
{
|
{
|
||||||
|
private static readonly Logger _log = LogManager.GetCurrentClassLogger();
|
||||||
|
|
||||||
|
#pragma warning disable 649
|
||||||
[ReflectedSetter(Name = nameof(SteamServerAPI))]
|
[ReflectedSetter(Name = nameof(SteamServerAPI))]
|
||||||
private static Action<MySteamService, SteamServerAPI> _steamServerAPISetter;
|
private static Action<MySteamService, SteamServerAPI> _steamServerAPISetter;
|
||||||
[ReflectedSetter(Name = "m_gameServer")]
|
[ReflectedSetter(Name = "m_gameServer")]
|
||||||
@@ -45,6 +50,7 @@ namespace Torch
|
|||||||
private static Action<MySteamService> RegisterCallbacks;
|
private static Action<MySteamService> RegisterCallbacks;
|
||||||
[ReflectedSetter(Name = nameof(Peer2Peer))]
|
[ReflectedSetter(Name = nameof(Peer2Peer))]
|
||||||
private static Action<MySteamService, IMyPeer2Peer> _steamPeer2PeerSetter;
|
private static Action<MySteamService, IMyPeer2Peer> _steamPeer2PeerSetter;
|
||||||
|
#pragma warning restore 649
|
||||||
|
|
||||||
public SteamService(bool isDedicated, uint appId)
|
public SteamService(bool isDedicated, uint appId)
|
||||||
: base(true, appId)
|
: base(true, appId)
|
||||||
@@ -63,7 +69,10 @@ namespace Torch
|
|||||||
{
|
{
|
||||||
SteamAPI steamApi = SteamAPI.Instance;
|
SteamAPI steamApi = SteamAPI.Instance;
|
||||||
_steamApiSetter.Invoke(this, steamApi);
|
_steamApiSetter.Invoke(this, steamApi);
|
||||||
_steamIsActiveSetter.Invoke(this, steamApi.Init());
|
bool initResult = steamApi.Init();
|
||||||
|
if (!initResult)
|
||||||
|
_log.Warn("Failed to initialize SteamService");
|
||||||
|
_steamIsActiveSetter.Invoke(this, initResult);
|
||||||
|
|
||||||
if (IsActive)
|
if (IsActive)
|
||||||
{
|
{
|
||||||
@@ -76,7 +85,8 @@ namespace Torch
|
|||||||
|
|
||||||
_steamInventoryAPISetter.Invoke(this, new MySteamInventory());
|
_steamInventoryAPISetter.Invoke(this, new MySteamInventory());
|
||||||
RegisterCallbacks(this);
|
RegisterCallbacks(this);
|
||||||
}
|
} else
|
||||||
|
_log.Warn("SteamService isn't initialized; Torch Client won't start");
|
||||||
}
|
}
|
||||||
|
|
||||||
_steamPeer2PeerSetter.Invoke(this, new MySteamPeer2Peer());
|
_steamPeer2PeerSetter.Invoke(this, new MySteamPeer2Peer());
|
||||||
|
@@ -151,7 +151,6 @@
|
|||||||
<Compile Include="Collections\ObservableList.cs" />
|
<Compile Include="Collections\ObservableList.cs" />
|
||||||
<Compile Include="DispatcherExtensions.cs" />
|
<Compile Include="DispatcherExtensions.cs" />
|
||||||
<Compile Include="Managers\DependencyManager.cs" />
|
<Compile Include="Managers\DependencyManager.cs" />
|
||||||
<Compile Include="Utils\ReflectedManager.cs" />
|
|
||||||
<Compile Include="SaveGameStatus.cs" />
|
<Compile Include="SaveGameStatus.cs" />
|
||||||
<Compile Include="Collections\KeyTree.cs" />
|
<Compile Include="Collections\KeyTree.cs" />
|
||||||
<Compile Include="Collections\ObservableDictionary.cs" />
|
<Compile Include="Collections\ObservableDictionary.cs" />
|
||||||
@@ -180,9 +179,12 @@
|
|||||||
<Compile Include="Utils\Reflection.cs" />
|
<Compile Include="Utils\Reflection.cs" />
|
||||||
<Compile Include="Managers\ScriptingManager.cs" />
|
<Compile Include="Managers\ScriptingManager.cs" />
|
||||||
<Compile Include="Utils\TorchAssemblyResolver.cs" />
|
<Compile Include="Utils\TorchAssemblyResolver.cs" />
|
||||||
|
<Compile Include="Utils\ReflectedManager.cs" />
|
||||||
|
<Compile Include="Session\TorchSessionManager.cs" />
|
||||||
<Compile Include="TorchBase.cs" />
|
<Compile Include="TorchBase.cs" />
|
||||||
<Compile Include="SteamService.cs" />
|
<Compile Include="SteamService.cs" />
|
||||||
<Compile Include="TorchPluginBase.cs" />
|
<Compile Include="TorchPluginBase.cs" />
|
||||||
|
<Compile Include="Session\TorchSession.cs" />
|
||||||
<Compile Include="ViewModels\ModViewModel.cs" />
|
<Compile Include="ViewModels\ModViewModel.cs" />
|
||||||
<Compile Include="Collections\MTObservableCollection.cs" />
|
<Compile Include="Collections\MTObservableCollection.cs" />
|
||||||
<Compile Include="Extensions\MyPlayerCollectionExtensions.cs" />
|
<Compile Include="Extensions\MyPlayerCollectionExtensions.cs" />
|
||||||
|
@@ -19,9 +19,11 @@ using SpaceEngineers.Game;
|
|||||||
using Torch.API;
|
using Torch.API;
|
||||||
using Torch.API.Managers;
|
using Torch.API.Managers;
|
||||||
using Torch.API.ModAPI;
|
using Torch.API.ModAPI;
|
||||||
|
using Torch.API.Session;
|
||||||
using Torch.Commands;
|
using Torch.Commands;
|
||||||
using Torch.Managers;
|
using Torch.Managers;
|
||||||
using Torch.Utils;
|
using Torch.Utils;
|
||||||
|
using Torch.Session;
|
||||||
using VRage.Collections;
|
using VRage.Collections;
|
||||||
using VRage.FileSystem;
|
using VRage.FileSystem;
|
||||||
using VRage.Game.ObjectBuilder;
|
using VRage.Game.ObjectBuilder;
|
||||||
@@ -57,15 +59,24 @@ namespace Torch
|
|||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
public string[] RunArgs { get; set; }
|
public string[] RunArgs { get; set; }
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
|
[Obsolete]
|
||||||
public IPluginManager Plugins { get; protected set; }
|
public IPluginManager Plugins { get; protected set; }
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
|
[Obsolete]
|
||||||
public IMultiplayerManager Multiplayer { get; protected set; }
|
public IMultiplayerManager Multiplayer { get; protected set; }
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
|
[Obsolete]
|
||||||
public EntityManager Entities { get; protected set; }
|
public EntityManager Entities { get; protected set; }
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
|
[Obsolete]
|
||||||
public INetworkManager Network { get; protected set; }
|
public INetworkManager Network { get; protected set; }
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
|
[Obsolete]
|
||||||
public CommandManager Commands { get; protected set; }
|
public CommandManager Commands { get; protected set; }
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
public ITorchSession CurrentSession => Managers?.GetManager<ITorchSessionManager>()?.CurrentSession;
|
||||||
|
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
public event Action SessionLoading;
|
public event Action SessionLoading;
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
@@ -107,6 +118,7 @@ namespace Torch
|
|||||||
Network = new NetworkManager(this);
|
Network = new NetworkManager(this);
|
||||||
Commands = new CommandManager(this);
|
Commands = new CommandManager(this);
|
||||||
|
|
||||||
|
Managers.AddManager(new TorchSessionManager(this));
|
||||||
Managers.AddManager(new FilesystemManager(this));
|
Managers.AddManager(new FilesystemManager(this));
|
||||||
Managers.AddManager(new UpdateManager(this));
|
Managers.AddManager(new UpdateManager(this));
|
||||||
Managers.AddManager(Network);
|
Managers.AddManager(Network);
|
||||||
@@ -116,7 +128,6 @@ namespace Torch
|
|||||||
Managers.AddManager(Entities);
|
Managers.AddManager(Entities);
|
||||||
Managers.AddManager(new ChatManager(this));
|
Managers.AddManager(new ChatManager(this));
|
||||||
|
|
||||||
|
|
||||||
TorchAPI.Instance = this;
|
TorchAPI.Instance = this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user