public NotifyCollectionChangedMonitor(PropertyAccessTree propertyAccessTree, IList <T> input)
        {
            if (input == null)
            {
                throw new ArgumentNullException("input");
            }

            INotifyCollectionChanged inputAsINotifyCollectionChanged = input as INotifyCollectionChanged;

            if (inputAsINotifyCollectionChanged == null)
            {
                throw new ArgumentException("Collections must implement INotifyCollectionChanged to work with CLINQ");
            }

            _input = input;

            this.PropertyAccessTree = propertyAccessTree;

            this.ReferenceCountTracker = new ReferenceCountTracker <T>();

            SetupPropertyChangeSubscription();

            SubscribeToItems(_input);

            WeakNotifyCollectionChangedEventHandler.Register(
                inputAsINotifyCollectionChanged,
                this,
                (me, sender, args) => me.OnCollectionChanged(sender, args));
        }
Ejemplo n.º 2
0
        public PropertyNotifier(PropertyAccessTree tree)
            : base()
        {
            if (tree == null)
            {
                throw new ArgumentNullException("tree");
            }

            PropertyAccessTree = tree;
            EntireTreeSupportINotifyPropertyChanging = PropertyAccessTree.DoesEntireTreeSupportINotifyPropertyChanging;
        }
Ejemplo n.º 3
0
        public static PropertyAccessTree Analyze <T, TResult>(Expression <Func <T, TResult> > expression, Predicate <Type> typeFilter)
        {
            if (!typeFilter(typeof(T)))
            {
                return(null);
            }

            PropertyAccessTree tree = AnalyzeLambda(expression, typeFilter);

            return(tree);
        }
Ejemplo n.º 4
0
            public PropertyAccessTreeSubscriberINotifyPropertyChanging(
                PropertyAccessTree propertyAccessTree,
                Action <TListener, object> subscriberCallback)
            {
                _subscriptions = new List <RootSubscription>();

                _propertyAccessTree = propertyAccessTree;

                for (int i = 0; i < propertyAccessTree.Children.Count; i++)
                {
                    var rootSubscription = new RootSubscription(subscriberCallback, propertyAccessTree.Children[i]);
                    _subscriptions.Add(rootSubscription);
                }
            }
Ejemplo n.º 5
0
        private static PropertyAccessTree AnalyzeLambda(LambdaExpression expression, Predicate <Type> typeFilter)
        {
            PropertyAccessTree tree = new PropertyAccessTree();

            //This is done to ensure that the tree has all the parameters and in the same order.
            for (int i = 0; i < expression.Parameters.Count; i++)
            {
                ParameterExpression parameterExpression = expression.Parameters[0];
                tree.Children.Add(new ParameterNode(parameterExpression.Type, parameterExpression.Name));
            }
            BuildUnoptimizedTree(tree, expression.Body, typeFilter);

            RemoveRedundantNodesFromTree(tree.Children);
            ApplyTypeFilter(tree.Children, typeFilter);

            return(tree);
        }
Ejemplo n.º 6
0
        private static void AddBranch(PropertyAccessTree tree, Stack <PropertyAccessTreeNode> currentNodeBranch)
        {
            if (currentNodeBranch.Count == 0)
            {
                return;
            }

            PropertyAccessTreeNode currentNode = currentNodeBranch.Pop();

            tree.Children.Add(currentNode);

            while (currentNodeBranch.Count != 0)
            {
                PropertyAccessTreeNode nextNode = currentNodeBranch.Pop();
                currentNode.Children.Add(nextNode);
                currentNode = nextNode;
            }
        }
Ejemplo n.º 7
0
        internal void SubscribeToChanges(T subject)
        {
            if (EntireTreeSupportINotifyPropertyChanging)
            {
                if (_PropertyAccessTree == null)
                {
                    _PropertyAccessTree = PropertyAccessTree.CreateCallbackSubscription <PropertyNotifier <T> >(OnItemChanging, OnItemChanged);
                }
                _PropertyAccessTree.SubscribeToChanges(subject, this);
            }
            else
            {
                if (_Subscriptions == null)
                {
                    _Subscriptions = new Dictionary <T, SubscriptionTree>();
                }

                SubscriptionTree tree = PropertyAccessTree.CreateSubscriptionTree(subject);
                tree.PropertyChanged += OnAnyPropertyChangeInSubscriptionTree;
                _Subscriptions.Add(subject, tree);
            }
        }
 internal ReadOnlyAdapterContinuousCollection(IList <TSource> list, PropertyAccessTree propertyAccessTree)
 {
     this.Source = list;
     this.NotifyCollectionChangedMonitor = new NotifyCollectionChangedMonitor <TSource>(propertyAccessTree, list);
 }
Ejemplo n.º 9
0
        private static void BuildBranches(Expression expression, PropertyAccessTree tree, Stack <PropertyAccessTreeNode> currentNodeBranch, Predicate <Type> typeFilter)
        {
            BinaryExpression binaryExpression = expression as BinaryExpression;

            if (binaryExpression != null)
            {
                BuildBranches(binaryExpression.Left, tree, currentNodeBranch, typeFilter);
                BuildBranches(binaryExpression.Right, tree, currentNodeBranch, typeFilter);
                return;
            }

            UnaryExpression unaryExpression = expression as UnaryExpression;

            if (unaryExpression != null)
            {
                BuildBranches(unaryExpression.Operand, tree, currentNodeBranch, typeFilter);
                return;
            }

            MethodCallExpression methodCallExpression = expression as MethodCallExpression;

            if (methodCallExpression != null)
            {
                foreach (Expression argument in methodCallExpression.Arguments)
                {
                    BuildBranches(argument, tree, currentNodeBranch, typeFilter);
                }
                return;
            }

            ConditionalExpression conditionalExpression = expression as ConditionalExpression;

            if (conditionalExpression != null)
            {
                BuildBranches(conditionalExpression.Test, tree, currentNodeBranch, typeFilter);
                BuildBranches(conditionalExpression.IfTrue, tree, currentNodeBranch, typeFilter);
                BuildBranches(conditionalExpression.IfFalse, tree, currentNodeBranch, typeFilter);
                return;
            }

            InvocationExpression invocationExpression = expression as InvocationExpression;

            if (invocationExpression != null)
            {
                foreach (Expression argument in invocationExpression.Arguments)
                {
                    BuildBranches(argument, tree, currentNodeBranch, typeFilter);
                }
                BuildBranches(invocationExpression.Expression, tree, currentNodeBranch, typeFilter);
                return;
            }

            switch (expression.NodeType)
            {
            case ExpressionType.MemberAccess:
                MemberExpression memberExpression = (MemberExpression)expression;

                PropertyInfo property  = memberExpression.Member as PropertyInfo;
                FieldInfo    fieldInfo = memberExpression.Member as FieldInfo;
                if (property != null)
                {
                    PropertyAccessNode node = new PropertyAccessNode(property);
                    currentNodeBranch.Push(node);

                    BuildBranches(memberExpression.Expression, tree, currentNodeBranch, typeFilter);
                }
                else if (fieldInfo != null)
                {
                    if (typeFilter(fieldInfo.FieldType))
                    {
                        ConstantExpression constantExpression = (ConstantExpression)memberExpression.Expression;
                        if (constantExpression.Value != null)
                        {
                            object       value        = fieldInfo.GetValue(constantExpression.Value);
                            ConstantNode constantNode = new ConstantNode((INotifyPropertyChanged)value);
                            currentNodeBranch.Push(constantNode);
                            AddBranch(tree, currentNodeBranch);
                        }
                    }
                    else
                    {
                        currentNodeBranch.Clear();
                    }
                }
                else
                {
                    BuildBranches(memberExpression.Expression, tree, currentNodeBranch, typeFilter);
                }

                break;

            case ExpressionType.Parameter:
                ParameterExpression parameterExpression = (ParameterExpression)expression;
                ParameterNode       parameterNode       = new ParameterNode(expression.Type, parameterExpression.Name);
                currentNodeBranch.Push(parameterNode);
                AddBranch(tree, currentNodeBranch);
                break;

            case ExpressionType.Constant:
            {
                ConstantExpression constantExpression = (ConstantExpression)expression;
                if (typeFilter(constantExpression.Type) &&
                    constantExpression.Value != null)
                {
                    ConstantNode constantNode = new ConstantNode((INotifyPropertyChanged)constantExpression.Value);
                    currentNodeBranch.Push(constantNode);
                    AddBranch(tree, currentNodeBranch);
                }
                else
                {
                    currentNodeBranch.Clear();
                }
            }
            break;

            case ExpressionType.New:
            {
                NewExpression newExpression = (NewExpression)expression;
                foreach (Expression argument in newExpression.Arguments)
                {
                    BuildBranches(argument, tree, currentNodeBranch, typeFilter);
                }
            }
            break;

            case ExpressionType.MemberInit:
            {
                MemberInitExpression memberInitExpression = (MemberInitExpression)expression;
                BuildBranches(memberInitExpression.NewExpression, tree, currentNodeBranch, typeFilter);
                foreach (var memberBinding in memberInitExpression.Bindings)
                {
                    MemberAssignment assignment = memberBinding as MemberAssignment;
                    if (assignment != null)
                    {
                        BuildBranches(assignment.Expression, tree, currentNodeBranch, typeFilter);
                    }
                }
            }
            break;

            default:
                throw new InvalidProgramException(string.Format("CLINQ does not support expressions of type: {0}", expression.NodeType));
            }
        }
Ejemplo n.º 10
0
        private static void BuildUnoptimizedTree(PropertyAccessTree tree, Expression expression, Predicate <Type> typeFilter)
        {
            var currentNodeBranch = new Stack <PropertyAccessTreeNode>();

            BuildBranches(expression, tree, currentNodeBranch, typeFilter);
        }
Ejemplo n.º 11
0
        public static PropertyAccessTree Analyze <T0, T1, TResult>(Expression <Func <T0, T1, TResult> > expression)
        {
            PropertyAccessTree tree = AnalyzeLambda(expression, DoesTypeImplementINotifyPropertyChanged);

            return(tree);
        }