private void onExecutionEnd(object sender, EventArgs e)
        {
            var executor = sender as IProgramExecutor;

            lock (runningExecutorsMutex)
            {
                RunningExecutors.Remove(executor);
            }

            ProgramExecutionCompleted?.Invoke(this, new ProgramExecutionServiceProgramEventArgs(executor.Program));
        }
        public IProgramExecutor Execute(IProgram program, IRobot robot)
        {
            if (CanExecute(program, robot) == false)
            {
                throw new RobotsException("Robot is already running a program!");
            }

            IProgramExecutor executor = ExecutorFactory.Create(program, robot);

            lock (runningExecutorsMutex)
            {
                RunningExecutors.Add(executor);
            }

            executor.ProgramExecutionEnd += onExecutionEnd;

            executor.Start();
            ProgramExecutionStarted?.Invoke(this, new ProgramExecutionServiceProgramEventArgs(program));
            return(executor);
        }
 public bool IsProgramRunning(IProgram program)
 {
     return(RunningExecutors.Any(e => e.Program == program));
 }
 public bool CanExecute(IProgram program, IRobot robot)
 {
     return(RunningExecutors.Any(e => e.Robot == robot) == false);
 }