diff --git a/src/Moryx.ControlSystem/Processes/ProcessHolderExtensions.cs b/src/Moryx.ControlSystem/Processes/ProcessHolderExtensions.cs index abd8d03..bc65de3 100644 --- a/src/Moryx.ControlSystem/Processes/ProcessHolderExtensions.cs +++ b/src/Moryx.ControlSystem/Processes/ProcessHolderExtensions.cs @@ -18,6 +18,12 @@ public static class ProcessHolderExtensions public static TPosition GetPositionByIdentifier(this IProcessHolderGroup group, string identifier) where TPosition : IProcessHolderPosition => GetPosition(group.Positions, t => t.Identifier == identifier); + /// + /// Get the position by its + /// + public static IProcessHolderPosition GetPositionByIdentifier(this IProcessHolderGroup group, string identifier) + => GetPosition(group.Positions, t => t.Identifier == identifier); + /// /// Get the position by its /// @@ -30,6 +36,12 @@ public static TPosition GetPositionByIdentifier(this IEnumerable(this IProcessHolderGroup group, Session session) where TPosition : IProcessHolderPosition => GetPosition(group.Positions, t => t.Session?.Id == session.Id); + /// + /// Get the position by its + /// + public static IProcessHolderPosition GetPositionBySession(this IProcessHolderGroup group, Session session) + => GetPosition(group.Positions, t => t.Session?.Id == session.Id); + /// /// Get the position by its /// @@ -42,6 +54,12 @@ public static TPosition GetPositionBySession(this IEnumerable(this IProcessHolderGroup group, long processId) where TPosition : IProcessHolderPosition => GetPosition(group.Positions, t => t.Process?.Id == processId); + /// + /// Get the position by its + /// + public static IProcessHolderPosition GetPositionByProcessId(this IProcessHolderGroup group, long processId) + => GetPosition(group.Positions, t => t.Process?.Id == processId); + /// /// Get the position by its /// @@ -54,12 +72,40 @@ public static TPosition GetPositionByProcessId(this IEnumerable(this IProcessHolderGroup group, long activityId) where TPosition : IProcessHolderPosition => GetPosition(group.Positions, t => (t.Session as ActivityStart)?.Activity.Id == activityId); + /// + /// Get the position by id of the running activity + /// + public static IProcessHolderPosition GetPositionByActivityId(this IProcessHolderGroup group, long activityId) + => GetPosition(group.Positions, t => (t.Session as ActivityStart)?.Activity.Id == activityId); + /// /// Get the position by id of the running activity /// public static TPosition GetPositionByActivityId(this IEnumerable positions, long activityId) where TPosition : IProcessHolderPosition => GetPosition(positions, t => (t.Session as ActivityStart)?.Activity.Id == activityId); + /// + /// Tries to get an empty from the + /// + /// The group to search + /// When this method returns, contains the first empty + /// , if any is found; otherwise null + /// + /// true if an empty was found; otherwise, false. + /// + public static bool TryGetEmptyPosition(this IProcessHolderGroup group, out IProcessHolderPosition position) + { + foreach (var possible in group.Positions) + { + if (!possible.IsEmpty()) + continue; + position = possible; + return true; + } + position = default; + return false; + } + private static TPosition GetPosition(IEnumerable positions, Func filter) where TPosition : IProcessHolderPosition => positions.SingleOrDefault(filter); @@ -92,6 +138,30 @@ public static IEnumerable Attach(this ProcessHolderPosition position) public static IEnumerable Attach(this IEnumerable positions) => positions.SelectMany(p => p.Attach()); + /// + /// Get or create sessions for all that have a process. + /// This is usually used when attaching to the control system. + /// + public static IEnumerable Attach(this IProcessHolderGroup group) + { + var sessions = new List(); + foreach(var position in group.Positions) + { + if (position.Session is not null) + { + sessions.Add(position.Session); + continue; + } + + if (position.Process is null) + continue; + + if (position is ProcessHolderPosition php) + sessions.Add(php.StartSession()); + } + return sessions; + } + /// /// Get a session if has one. Otherwise returns an empty enumerable. /// This is usually used when detaching from the control system. @@ -105,6 +175,12 @@ public static IEnumerable Detach(this ProcessHolderPosition position) public static IEnumerable Detach(this IEnumerable positions) => positions.Where(p => p.Session != null).Select(p => p.Session); + /// + /// Create sessions for all positions on the , that have a process + /// + public static IEnumerable Detach(this IProcessHolderGroup group) + => group.Positions.Where(p => p.Session != null).Select(p => p.Session); + #endregion #region Mounting @@ -115,6 +191,12 @@ public static IEnumerable Detach(this IEnumerable position.Mount(new MountInformation(process, null)); + /// + /// Assign a to this position + /// + public static void Mount(this IProcessHolderPosition position, Session session) + => position.Mount(new MountInformation(null, session)); + /// /// Assign and to this position /// @@ -123,7 +205,26 @@ public static void Mount(this IProcessHolderPosition position, IProcess process, #endregion - #region Has + #region Status Checks + + /// + /// Checks if the has no empty + /// + public static bool IsFull(this IProcessHolderGroup group) + => group.Positions.All(position => !position.IsEmpty()); + + /// + /// Checks if the has no filled + /// + public static bool IsEmpty(this IProcessHolderGroup group) + => group.Positions.All(position => position.IsEmpty()); + + /// + /// True if the has neither a nor a + /// ; false otherwise. + /// + public static bool IsEmpty(this IProcessHolderPosition position) + => position.Process is null && position.Session is null; /// /// Checks if the group holds a process with a finished activity having the matching result @@ -144,5 +245,33 @@ public static bool HasFinishedActivity(this IProcessHolderPosition holderPositio /// public static TTracing Tracing(this IProcessHolderPosition position) where TTracing : Tracing, new() => (position.Session as ActivityStart)?.Activity?.TransformTracing(); + + /// + /// Updates and by resetting the + /// and remounting the . For s + /// a direct update of the session and process is done on the object. + /// + /// The position to update + /// The updated session on the position + /// Thrown if the given does not match + /// the session on the + public static void Update(this IProcessHolderPosition position, Session session) + { + if (position.Session.Id != session.Id) + throw new InvalidOperationException($"Tried to update the {nameof(Session)} on an " + + $"{nameof(IProcessHolderPosition)} with a different session. Make sure to " + + $"{nameof(IProcessHolderPosition.Reset)} the {nameof(IProcessHolderPosition)} before " + + $"assigning a new {nameof(Session)}"); + + if (position is ProcessHolderPosition explicitPosition) + { + explicitPosition.Session = session; + explicitPosition.AssignProcess(session.Process); + return; + } + + position.Reset(); + position.Mount(session.Process, session); + } } } \ No newline at end of file