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; } }
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); }
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; } } }
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; }