public ManualSolverModel(ProblemSpec problem, Vector shift, ImmutableArray <SegmentModel> segments, int?highlightedSegmentIndex, ImmutableList <int> selectedSegmentIndices, PendingOperationType pendingOperation, ImmutableList <Segment> mirrors)
 {
     Problem  = problem;
     Shift    = shift;
     Segments = segments;
     HighlightedSegmentIndex = highlightedSegmentIndex;
     SelectedSegmentIndices  = selectedSegmentIndices;
     PendingOperation        = pendingOperation;
     this.mirrors            = mirrors;
 }
        private ManualSolverModel CompleteOperation(int index)
        {
            var mirror                     = Segments[index].Segment;
            var selectedSegments           = SelectedSegmentIndices.Select(i => Segments[i]).ToList();
            var reflected                  = selectedSegments.Select(s => s.Reflect(mirror));
            IEnumerable <SegmentModel> res = Segments;

            if (PendingOperation == PendingOperationType.ReflectMove)
            {
                res = res.Where(s => !selectedSegments.Contains(s));
            }
            res = res.Concat(reflected);
            PendingOperation = PendingOperationType.None;
            return(With(res, null, ImmutableList <int> .Empty, PendingOperationType.None, mirrors.Add(mirror)));
        }
        public Task <IOperationResult> AddOperation(string description, PendingOperationType opererationType, Func <Action <IOperationProgress>, Task <IOperationResult> > taskFactory,
                                                    long id, OperationCancelToken token = null)
        {
            var operationState = new OperationState
            {
                Status = OperationStatus.InProgress
            };

            var notification = new OperationStatusChangeNotification
            {
                OperationId = id,
                State       = operationState
            };

            Action <IOperationProgress> action = progress =>
            {
                notification.State.Progress = progress;
                RaiseNotifications(notification);
            };
            var task = taskFactory(action);

            var operationDescription = new PendingOperationDescription
            {
                Description = description,
                TaskType    = opererationType,
                StartTime   = SystemTime.UtcNow
            };

            var pendingOperation = new PendingOperation
            {
                Id          = id,
                Task        = task,
                Description = operationDescription,
                Token       = token,
                State       = operationState
            };

            task.ContinueWith(taskResult =>
            {
                operationDescription.EndTime = SystemTime.UtcNow;
                operationState.Progress      = null;
                if (taskResult.IsCanceled)
                {
                    operationState.Result = null;
                    operationState.Status = OperationStatus.Canceled;
                }
                else if (taskResult.IsFaulted)
                {
                    var innerException = taskResult.Exception.ExtractSingleInnerException();

                    var documentConflictException = innerException as DocumentConflictException;
                    var status            = documentConflictException != null ? 409 : 500;
                    operationState.Result = new OperationExceptionResult(innerException, status);
                    operationState.Status = OperationStatus.Faulted;
                }
                else
                {
                    operationState.Result = taskResult.Result;
                    operationState.Status = OperationStatus.Completed;
                }

                RaiseNotifications(notification);
            });

            _pendingOperations.TryAdd(id, pendingOperation);
            return(task);
        }
 public ManualSolverModel CancelPendingOperation()
 {
     PendingOperation = PendingOperationType.None;
     return(this);
 }
 public ManualSolverModel StartOperation(PendingOperationType operation)
 {
     PendingOperation = operation;
     return(this);
 }
 private ManualSolverModel With(IEnumerable <SegmentModel> segments, int?highlightedSegmentIndex, ImmutableList <int> selectedSegmentIndices, PendingOperationType pendingOperation,
                                ImmutableList <Segment> mirrors)
 {
     return(new ManualSolverModel(Problem, Shift, segments.ToImmutableArray(), highlightedSegmentIndex, selectedSegmentIndices, pendingOperation, mirrors));
 }