private static void _distinct_internal <T>(this IOperationController controller, object key,
                                                   Func <T, T, IOperation> generateMergedOperation)
            where T : class, IMergeableOperation
        {
            var operations = controller.Operations.ToList();

            var mergeable = operations
                            .OfType <T>()
                            .Where(x => x.MergeJudge.GetMergeKey() == key)
                            .ToArray();

            var first = mergeable.FirstOrDefault();
            var last  = mergeable.LastOrDefault();

            if (first is null || last is null)
            {
                return;
            }

            var lastIndex = 0;

            foreach (var operation in mergeable)
            {
                lastIndex = operations.IndexOf(operation);
                operations.RemoveAt(lastIndex);
            }

            var newOperation = generateMergedOperation(first, last);

            operations.Insert(lastIndex, newOperation);

            controller.Flush();
            operations.ForEach(x => controller.Push(x));
        }
Ejemplo n.º 2
0
 public static IOperation PushTo(this IOperation _this, IOperationController controller)
 {
     if (_this is IMergeableOperation mergeableOperation)
     {
         _this = mergeableOperation.Merge(controller);
     }
     return(controller.Push(_this));
 }
Ejemplo n.º 3
0
        public static IOperation ExecuteAndCombineTop(this IOperation _this, IOperationController controller)
        {
            if (controller.Operations.Any())
            {
                var prev = controller.Pop();
                _this.RollForward();
                var newOperation = prev.CombineOperations(_this).ToCompositeOperation();
                newOperation.Messaage = _this.Messaage;
                return(controller.Push(newOperation));
            }

            return(controller.Execute(_this));
        }
        public static IDisposable BindPropertyChanged <T>(this IOperationController controller, INotifyPropertyChanged owner, string propertyName, bool autoMerge = true)
        {
            var prevValue         = FastReflection.GetProperty <T>(owner, propertyName);
            var callFromOperation = false;

            owner.PropertyChanged += PropertyChanged;

            return(new Disposer(() => owner.PropertyChanged -= PropertyChanged));

            // local function
            void PropertyChanged(object sender, PropertyChangedEventArgs args)
            {
                if (callFromOperation)
                {
                    return;
                }

                if (args.PropertyName == propertyName)
                {
                    callFromOperation = true;
                    T   newValue  = FastReflection.GetProperty <T>(owner, propertyName);
                    var operation = owner
                                    .GenerateAutoMergeOperation(propertyName, newValue, prevValue, $"{sender.GetHashCode()}.{propertyName}", Operation.DefaultMergeSpan);

                    if (autoMerge)
                    {
                        operation = operation.Merge(controller);
                    }

                    operation
                    .AddPreEvent(() => callFromOperation  = true)
                    .AddPostEvent(() => callFromOperation = false);

                    prevValue = newValue;

                    controller.Push(operation);
                    callFromOperation = false;
                }
            }
        }