/// <summary> /// Adds a new <see cref="Command"/> to the group. /// </summary> /// <remarks> /// The <see cref="Command"/> will be started after all the previously added <see cref="Command">commands</see>. /// <para> /// Note that any requirements thee given <see cref="Command"/> has will be added to the group. For this reason, a /// <see cref="Command">Command's</see> requirements cannot be changed after being added to a group. /// </para> /// <para> /// It is recommended that this method be called in the constructor. /// </para> /// </remarks> /// <param name="command">The <see cref="Command"/> to be added.</param> /// <exception cref="IllegalUseOfCommandException">If the command has been started before or been given to another group.</exception> /// <exception cref="ArgumentNullException">If the given <see cref="Command"/> is null</exception> public void AddSequential(Command command) { lock (m_syncRoot) { Validate("Can not add new command to command group"); if (command == null) throw new ArgumentNullException(nameof(command), "Given null command"); command.SetParent(this); m_commands.Add(new Entry(command, Entry.IN_SEQUENCE)); foreach (var e in command.GetRequirements()) { Requires(e); } } }
/// <summary> /// Adds a new <see cref="Command"/> to the group. /// </summary> /// <remarks> /// The <see cref="Command"/> will be started after all the previously added <see cref="Command">commands</see>. /// <para> /// Instead of waiting for the child to finish, a <see cref="CommandGroup"/> will have it run /// at the same time as the subsequent <see cref="Command">Commands</see>. The child wil run /// either until it finishes, a new child with conflicting requirements is started, or the main /// sequence runs a <see cref="Command"/> with conflicting requirements. In the latter two cases, /// the child will be canceled even if it says it can't be interrupted. /// </para> /// <para> /// Note that any requirements thee given <see cref="Command"/> has will be added to the group. For this reason, a /// <see cref="Command">Command's</see> requirements cannot be changed after being added to a group. /// </para> /// <para> /// It is recommended that this method be called in the constructor. /// </para> /// </remarks> /// <param name="command">The <see cref="Command"/> to be added.</param> /// <exception cref="IllegalUseOfCommandException">If the command has been started before or been given to another group.</exception> /// <exception cref="ArgumentNullException">If the given <see cref="Command"/> is null</exception> public void AddParallel(Command command) { lock (m_syncRoot) { Validate("Can not add new command to command group"); if (command == null) { throw new ArgumentNullException(nameof(command), "Given null command"); } command.SetParent(this); m_commands.Add(new Entry(command, Entry.BRANCH_CHILD)); foreach (Subsystem e in command.GetRequirements()) { Requires(e); } } }
/// <summary> /// Adds a new <see cref="Command"/> to the group. /// </summary> /// <remarks> /// The <see cref="Command"/> will be started after all the previously added <see cref="Command">commands</see>. /// <para> /// Note that any requirements thee given <see cref="Command"/> has will be added to the group. For this reason, a /// <see cref="Command">Command's</see> requirements cannot be changed after being added to a group. /// </para> /// <para> /// It is recommended that this method be called in the constructor. /// </para> /// </remarks> /// <param name="command">The <see cref="Command"/> to be added.</param> /// <exception cref="IllegalUseOfCommandException">If the command has been started before or been given to another group.</exception> /// <exception cref="ArgumentNullException">If the given <see cref="Command"/> is null</exception> public void AddSequential(Command command) { lock (m_syncRoot) { Validate("Can not add new command to command group"); if (command == null) { throw new ArgumentNullException(nameof(command), "Given null command"); } command.SetParent(this); m_commands.Add(new Entry(command, Entry.IN_SEQUENCE)); foreach (var e in command.GetRequirements()) { Requires(e); } } }
/// <summary> /// Adds a new <see cref="Command"/> to the group with a given timeout. /// </summary> /// <remarks> /// The <see cref="Command"/> will be started after all the previously added <see cref="Command">commands</see>. /// <para> /// Once the <see cref="Command"/> is started, it will be run until it finishes or the time expires, whichever is sooner. /// Note that the give <see cref="Command"/> will have no knowledge that it is on a timer. /// </para> /// <para> /// Note that any requirements thee given <see cref="Command"/> has will be added to the group. For this reason, a /// <see cref="Command">Command's</see> requirements cannot be changed after being added to a group. /// </para> /// <para> /// It is recommended that this method be called in the constructor. /// </para> /// </remarks> /// <param name="command">The <see cref="Command"/> to be added.</param> /// <param name="timeout">The timeout (in seconds).</param> /// <exception cref="IllegalUseOfCommandException">If the group has been started before or been given to another group.</exception> /// <exception cref="ArgumentNullException">If the given <see cref="Command"/> is null</exception> /// <exception cref="ArgumentOutOfRangeException">If the given timeout is negative.</exception> public void AddSequential(Command command, double timeout) { lock (m_syncRoot) { Validate("Can not add new command to command group"); if (command == null) { throw new ArgumentNullException(nameof(command), "Given null command"); } if (timeout < 0) { throw new ArgumentOutOfRangeException(nameof(timeout), "Can not be given a negative timeout"); } command.SetParent(this); m_commands.Add(new Entry(command, Entry.IN_SEQUENCE, timeout)); foreach (Subsystem e in command.GetRequirements()) { Requires(e); } } }
/// <summary> /// Adds a new <see cref="Command"/> to the group with the given timeout. /// </summary> /// <remarks> /// The <see cref="Command"/> will be started after all the previously added <see cref="Command">commands</see>. /// /// <para> /// Once the <see cref="Command"/> is started, it will be run until it finishes or the time expires, whichever is sooner. /// Note that the give <see cref="Command"/> will have no knowledge that it is on a timer. /// </para> /// <para> /// Instead of waiting for the child to finish, a <see cref="CommandGroup"/> will have it run /// at the same time as the subsequent <see cref="Command">Commands</see>. The child wil run /// either until it finishes, a new child with conflicting requirements is started, or the main /// sequence runs a <see cref="Command"/> with conflicting requirements. In the latter two cases, /// the child will be canceled even if it says it can't be interrupted. /// </para> /// <para> /// Note that any requirements thee given <see cref="Command"/> has will be added to the group. For this reason, a /// <see cref="Command">Command's</see> requirements cannot be changed after being added to a group. /// </para> /// <para> /// It is recommended that this method be called in the constructor. /// </para> /// </remarks> /// <param name="command">The <see cref="Command"/> to be added.</param> /// <param name="timeout">The timeout (in seconds).</param> /// <exception cref="IllegalUseOfCommandException">If the command has been started before or been given to another group.</exception> /// <exception cref="ArgumentNullException">If the given <see cref="Command"/> is null</exception> /// <exception cref="ArgumentOutOfRangeException">If the given timeout is negative.</exception> public void AddParallel(Command command, double timeout) { lock (m_syncRoot) { Validate("Can not add new command to command group"); if (command == null) throw new ArgumentNullException(nameof(command), "Given null command"); if (timeout < 0) throw new ArgumentOutOfRangeException(nameof(command), "Can not be given a negative timeout"); command.SetParent(this); m_commands.Add(new Entry(command, Entry.BRANCH_CHILD, timeout)); foreach (Subsystem e in command.GetRequirements()) { Requires(e); } } }