示例#1
0
        private void OnResourceDeleting(object sender, ResourceIndexEventArgs e)
        {
            if (_resList == null || e.Index < 0)
            {
                return;
            }

            lock ( _events )
            {
                ResourceListEvent ev = new ResourceListEvent(_resList, EventType.Remove, e.Resource.Id, e.Index);
                _events.Add(ev);
                _needMerge = true;
            }
        }
示例#2
0
        public ResourceListEvent GetNextEvent()
        {
            if (_processingLevel == 0)
            {
                throw new InvalidOperationException("You need to call BeginProcessEvents() before calling GetNextEvent()");
            }

            while (_events.Count > 0)
            {
                ResourceListEvent ev = (ResourceListEvent)_events [0];
                _events.RemoveAt(0);
                if (ev.ResourceList == _resList)
                {
                    return(ev);
                }
            }

            return(null);
        }
示例#3
0
        private void OnResourceChanged(object sender, ResourcePropIndexEventArgs e)
        {
            IResourceList resList = _resList;

            if (resList == null || e.Index < 0)
            {
                return;
            }

            lock ( resList )
            {
                lock ( _events )
                {
                    if (_resList == null)
                    {
                        return;
                    }
                    ResourceListEvent ev = new ResourceListEvent(_resList, EventType.Change, e.Resource.Id, e.Index, e.ChangeSet);
                    _events.Add(ev);
                    _needMerge = true;
                }
            }
        }
示例#4
0
        private void DoMergeEvents()
        {
            if (!_mergeEvents)
            {
                return;
            }

            // C0 A1 A2 A3 R1

            for (int i = _events.Count - 1; i >= 0; i--)
            {
                //             i
                // C0 A1 A2 A3 R1

                ResourceListEvent ev = (ResourceListEvent)_events [i];
                if (ev.ResourceList != _resList)
                {
                    _events.RemoveAt(i);
                    continue;
                }

                if (ev.EventType == EventType.Remove)
                {
                    bool discardRemove = false;

                    // Remove eats all previous events with the same resource, up to and including the Add

                    //          j  i
                    // C0 A1 A2 A3 R1

                    for (int j = i - 1; j >= 0; j--)
                    {
                        ResourceListEvent ev2 = (ResourceListEvent)_events [j];
                        if (ev2.ResourceID == ev.ResourceID)
                        {
                            //    j        i
                            // C0 A1 A2 A3 R1

                            _events.RemoveAt(j);

                            //    j        i
                            // C0 A2 A3 R1

                            i--;

                            //    j     i
                            // C0 A2 A3 R1

                            if (ev2.EventType == EventType.Add)
                            {
                                // adjust the index of events following the removed Add
                                discardRemove = true;

                                //    jk     i
                                // C0 A2 A3 R1

                                int maxAdjustIndex = ev2.Index;

                                for (int k = j; k <= i; k++)
                                {
                                    ResourceListEvent ev3 = (ResourceListEvent)_events [k];
                                    if (ev3.EventType == EventType.Remove && ev3.Index < maxAdjustIndex)
                                    {
                                        maxAdjustIndex--;
                                        if (maxAdjustIndex < 0)
                                        {
                                            throw new ApplicationException("ResourceList event queue internal error: negative maxAdjustIndex");
                                        }
                                    }
                                    else if (ev3.Index > maxAdjustIndex)
                                    {
                                        if (ev3.Index <= 0)
                                        {
                                            throw new ApplicationException("ResourceList event queue internal error: negative index on" + ev.ToString());
                                        }
                                        ev3.SetIndex(ev3.Index - 1);
                                    }
                                }
                                //    j     ik
                                // C0 A1 A2 R1
                                break;
                            }
                        }
                    }
                    if (discardRemove)
                    {
                        Debug.Assert(_events [i] == ev);
                        _events.RemoveAt(i);
                        continue;
                    }
                    //    j     ik
                    // C0 A1 A2
                }
                else if (ev.EventType == EventType.Change)
                {
                    bool discardChange = false;
                    for (int j = i - 1; j >= 0; j--)
                    {
                        ResourceListEvent ev2 = (ResourceListEvent)_events [j];
                        if (ev2.ResourceID == ev.ResourceID)
                        {
                            if (ev2.EventType == EventType.Change)
                            {
                                ev2.SetChangeSet(ev.ChangeSet.Merge(ev2.ChangeSet));
                            }
                            discardChange = true;
                            break;
                        }
                    }
                    if (discardChange)
                    {
                        Debug.Assert(_events [i] == ev);
                        _events.RemoveAt(i);
                        continue;
                    }
                }

                if (ev.EventType != EventType.Remove)
                {
                    int index = _resList.IndexOf(ev.ResourceID);
                    if (index < 0)
                    {
                        throw new InvalidOperationException("ResourceListEventQueue internal error: resource " +
                                                            ev.ResourceID + " not found in list (event" + ev.ToString() + ")");
                    }
                    ev.SetListIndex(index);
                }
            }

            _needMerge = false;
        }