diff --git a/Torch.API/Session/ITorchSession.cs b/Torch.API/Session/ITorchSession.cs
new file mode 100644
index 0000000..710c9dd
--- /dev/null
+++ b/Torch.API/Session/ITorchSession.cs
@@ -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
+{
+ ///
+ /// Represents the Torch code working with a single game session
+ ///
+ public interface ITorchSession
+ {
+ ///
+ /// The Torch instance this session is bound to
+ ///
+ ITorchBase Torch { get; }
+
+ ///
+ /// The Space Engineers game session this session is bound to.
+ ///
+ MySession KeenSession { get; }
+
+ ///
+ IDependencyManager Managers { get; }
+ }
+}
diff --git a/Torch.API/Session/ITorchSessionManager.cs b/Torch.API/Session/ITorchSessionManager.cs
new file mode 100644
index 0000000..78ccfaf
--- /dev/null
+++ b/Torch.API/Session/ITorchSessionManager.cs
@@ -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
+{
+ ///
+ /// Creates a manager for the given session if applicable.
+ ///
+ ///
+ /// This is for creating managers that will live inside the session, not the manager that controls sesssions.
+ ///
+ /// The session to construct a bound manager for
+ /// The manager that will live in the session, or null if none.
+ public delegate IManager SessionManagerFactory(ITorchSession session);
+
+ ///
+ /// Manages the creation and destruction of instances for each created by Space Engineers.
+ ///
+ public interface ITorchSessionManager : IManager
+ {
+ ///
+ /// The currently running session
+ ///
+ ITorchSession CurrentSession { get; }
+
+ ///
+ /// Adds the given factory as a supplier for session based managers
+ ///
+ /// Session based manager supplier
+ /// true if added, false if already present
+ /// If the factory is null
+ bool AddFactory(SessionManagerFactory factory);
+
+ ///
+ /// Remove the given factory from the suppliers for session based managers
+ ///
+ /// Session based manager supplier
+ /// true if removed, false if not present
+ /// If the factory is null
+ bool RemoveFactory(SessionManagerFactory factory);
+ }
+}
diff --git a/Torch.API/Torch.API.csproj b/Torch.API/Torch.API.csproj
index c8f60f1..2195b2d 100644
--- a/Torch.API/Torch.API.csproj
+++ b/Torch.API/Torch.API.csproj
@@ -175,6 +175,7 @@
+
diff --git a/Torch/Session/TorchSession.cs b/Torch/Session/TorchSession.cs
new file mode 100644
index 0000000..6ec4a2d
--- /dev/null
+++ b/Torch/Session/TorchSession.cs
@@ -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();
+
+ ///
+ /// The Torch instance this session is bound to
+ ///
+ public ITorchBase Torch { get; }
+
+ ///
+ /// The Space Engineers game session this session is bound to.
+ ///
+ public MySession KeenSession { get; }
+
+ ///
+ 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();
+ }
+ }
+}
diff --git a/Torch/Session/TorchSessionManager.cs b/Torch/Session/TorchSessionManager.cs
new file mode 100644
index 0000000..e55afe3
--- /dev/null
+++ b/Torch/Session/TorchSessionManager.cs
@@ -0,0 +1,79 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using Sandbox.Game.World;
+using Torch.API;
+using Torch.API.Managers;
+using Torch.API.Session;
+using Torch.Managers;
+using Torch.Session;
+
+namespace Torch.Session
+{
+
+ ///
+ /// Manages the creation and destruction of instances for each created by Space Engineers.
+ ///
+ public class TorchSessionManager : Manager, ITorchSessionManager
+ {
+ ///
+ public ITorchSession CurrentSession { get; private set; }
+
+ private readonly HashSet _factories = new HashSet();
+
+ public TorchSessionManager(ITorchBase torchInstance) : base(torchInstance)
+ {
+ }
+
+ ///
+ public bool AddFactory(SessionManagerFactory factory)
+ {
+ if (factory == null)
+ throw new ArgumentNullException(nameof(factory), "Factory must be non-null");
+ return _factories.Add(factory);
+ }
+
+ ///
+ public bool RemoveFactory(SessionManagerFactory factory)
+ {
+ if (factory == null)
+ throw new ArgumentNullException(nameof(factory), "Factory must be non-null");
+ return _factories.Remove(factory);
+ }
+
+ private void SessionLoaded()
+ {
+ (CurrentSession as TorchSession)?.Detach();
+ CurrentSession = new TorchSession(Torch, MySession.Static);
+ foreach (SessionManagerFactory factory in _factories)
+ {
+ IManager manager = factory(CurrentSession);
+ if (manager != null)
+ CurrentSession.Managers.AddManager(manager);
+ }
+ (CurrentSession as TorchSession)?.Attach();
+ }
+
+ private void SessionUnloaded()
+ {
+ (CurrentSession as TorchSession)?.Detach();
+ CurrentSession = null;
+ }
+
+ ///
+ public override void Attach()
+ {
+ MySession.AfterLoading += SessionLoaded;
+ MySession.OnUnloaded += SessionUnloaded;
+ }
+
+ ///
+ public override void Detach()
+ {
+ MySession.AfterLoading -= SessionLoaded;
+ MySession.OnUnloaded -= SessionUnloaded;
+ }
+ }
+}
diff --git a/Torch/Torch.csproj b/Torch/Torch.csproj
index 92974e5..518e8f6 100644
--- a/Torch/Torch.csproj
+++ b/Torch/Torch.csproj
@@ -151,7 +151,7 @@
-
+
@@ -180,9 +180,11 @@
+
+