private void CheckPosition(DirtyItem item, DirtyItem at, DirtyItem prev) { if (((item.Position - prev.Position) < this._minValue) || ((at.Position - prev.Position) < this._minValue)) { this.AdjustPositions(item); } }
internal void RemoveDirtyItem(DirtyItem item) { if (this.IsDirtyItem(item)) { DirtyItem previousItem = item.PreviousItem; DirtyItem nextItem = item.NextItem; if (previousItem != null) { previousItem.NextItem = nextItem; } else { this._headerDirtyItems = nextItem; } if (nextItem != null) { nextItem.PreviousItem = previousItem; } else { this._tailDirtyItems = previousItem; } item.PreviousItem = null; item.NextItem = null; } }
/// <summary> /// hdt 唐忠宝增加 /// </summary> /// <param name="header"></param> /// <param name="tailItem"></param> /// <param name="addingItem"></param> /// <param name="predencyNode"></param> private static void AddDirtyItem(ref DirtyItem header, ref DirtyItem tailItem, DirtyItem addingItem, CalcNode predencyNode) { if (header == null) { header = tailItem = addingItem; } else { addingItem.PreviousItem = tailItem; tailItem.NextItem = addingItem; tailItem = addingItem; } if (!object.ReferenceEquals(predencyNode, null) && (predencyNode.DirtyItem != null)) { DirtyItem dirtyItem = predencyNode.DirtyItem; if (dirtyItem.DependencyCellTemp == null) { dirtyItem.DependencyCellTemp = new HashSet <CalcNode>(); } if (!dirtyItem.DependencyCellTemp.Contains(tailItem.Node)) { dirtyItem.DependencyCellTemp.Add(tailItem.Node); tailItem.PredencyItemCount++; } } }
private void MoveTo(DirtyItem item, DirtyItem beforeAt) { if (!item.Moved) { item.Moved = true; this._movedItems.Add(item); this.RemoveDirtyItem(item); DirtyItem previousItem = beforeAt.PreviousItem; item.NextItem = beforeAt; item.PreviousItem = previousItem; beforeAt.PreviousItem = item; if (previousItem == null) { this._headerDirtyItems = item; item.Position = beforeAt.Position - 1.0; } else { previousItem.NextItem = item; item.Position = previousItem.Position + ((beforeAt.Position - previousItem.Position) / 2.0); this.CheckPosition(item, beforeAt, previousItem); } this.CheckPredencies(item, beforeAt); } }
/// <summary> /// hdt 唐忠宝增加 /// </summary> /// <param name="ids"></param> /// <param name="autoCalculate"></param> public void Invalidate(IEnumerable <CalcLocalIdentity> ids, bool autoCalculate = true) { if (object.ReferenceEquals(ids, null)) { throw new ArgumentNullException("ids"); } if (!this.Graph.IsEmpty) { CalcEvaluatorContext evaluatorContext = this.Source.GetEvaluatorContext(new CalcCellIdentity(0, 0)); DirtyItem header = null; DirtyItem tailItem = null; foreach (CalcLocalIdentity identity in ids) { this.InvalidateIntersecteds(identity, evaluatorContext, null, ref header, ref tailItem); } foreach (CalcNode node in this.Graph.GetAllVolantedNodes()) { this.InvalidateIntersecteds(node.Id as CalcLocalIdentity, evaluatorContext, node, ref header, ref tailItem); } if (header != null) { this.InvalidateDependencies(ref header, ref tailItem); } if (autoCalculate) { this.Service.Recalculate(0xc350, false); } } }
internal void InsertToDirtyBefore(DirtyItem item, DirtyItem at) { if ((item != null) && !this.IsDirtyItem(item)) { if (at == null) { this.AddDirtyItem(item); } else { DirtyItem previousItem = at.PreviousItem; item.NextItem = at; item.PreviousItem = previousItem; if (previousItem == null) { this._headerDirtyItems = item; item.Position = at.Position - 1.0; } else { previousItem.NextItem = item; item.Position = previousItem.Position + ((at.Position - previousItem.Position) / 2.0); this.CheckPosition(item, at, previousItem); } at.PreviousItem = item; this.CheckPredencies(item, at); this.ClearMovedItemCatch(); } } }
/// <summary> /// hdt 唐忠宝增加 /// </summary> /// <param name="header"></param> /// <param name="tailItem"></param> /// <param name="removingItem"></param> private static void RemoveDirtyItem(ref DirtyItem header, ref DirtyItem tailItem, DirtyItem removingItem) { if (header == removingItem) { header = removingItem.NextItem; } if (tailItem == removingItem) { tailItem = removingItem.PreviousItem; } if (removingItem.PreviousItem != null) { removingItem.PreviousItem.NextItem = removingItem.NextItem; } if (removingItem.NextItem != null) { removingItem.NextItem.PreviousItem = removingItem.PreviousItem; } removingItem.NextItem = removingItem.PreviousItem = null; if (removingItem.DependencyCellTemp != null) { foreach (CalcNode node in removingItem.DependencyCellTemp) { if (node.DirtyItem != null) { node.DirtyItem.PredencyItemCount--; } } } }
private static DirtyItem SerchDependForehand(DirtyItem dependForehand, List <CalcNode> searchingDepends, List <CalcNode> intersectants, List <CalcNode> pendingDependDirtyNode, List <SharedFormulaDirtyItem> sharedDirtyItmes) { if (searchingDepends.Count > 0) { foreach (CalcNode node in searchingDepends) { if (node.IsDirty) { if (dependForehand == null) { dependForehand = node.DirtyItem; } else if (node.DirtyItem.Position < dependForehand.Position) { dependForehand = node.DirtyItem; } } else if (!node._isProcessingDirty && !node._isWattingForProcess) { pendingDependDirtyNode.Add(node); } } } if ((intersectants != null) && (intersectants.Count > 0)) { foreach (CalcNode node2 in intersectants) { if (node2.IsDirty) { if (dependForehand == null) { dependForehand = node2.DirtyItem; } else if (node2.DirtyItem.Position < dependForehand.Position) { dependForehand = node2.DirtyItem; } } } } if (sharedDirtyItmes.Count > 0) { foreach (SharedFormulaDirtyItem item in sharedDirtyItmes) { if (item.Node.IsDirty) { if (dependForehand == null) { dependForehand = item; } else if (item.Position < dependForehand.Position) { dependForehand = item; } } } } return(dependForehand); }
internal bool IsDirtyItem(DirtyItem item) { if (item.PreviousItem == null) { return(item == this._headerDirtyItems); } return(true); }
private void ClearDirtyItem() { DirtyItem item2; for (DirtyItem item = this._headerDirtyItems; item != null; item = item2) { item2 = (item == null) ? null : item.NextItem; item.PreviousItem = null; item.NextItem = null; } this._headerDirtyItems = this._tailDirtyItems = null; }
private void CheckPredencies(DirtyItem item, DirtyItem at) { if (item.HasPredencyItem) { foreach (KeyValuePair <CalcIdentity, DirtyItem> pair in item.PredencyItems) { if (at.Position <= pair.Value.Position) { this.MoveTo(pair.Value, item); } } } }
/// <summary> /// hdt 唐忠宝增加 /// </summary> /// <param name="id"></param> /// <param name="context"></param> /// <param name="node"></param> private void Invalidate(CalcLocalIdentity id, CalcEvaluatorContext context, CalcNode node = null) { DirtyItem header = null; DirtyItem tailItem = null; this.InvalidateIntersecteds(id, context, node, ref header, ref tailItem); foreach (CalcNode node2 in this.Graph.GetAllVolantedNodes()) { this.InvalidateIntersecteds(node2.Id as CalcLocalIdentity, context, node2, ref header, ref tailItem); } if (header != null) { this.InvalidateDependencies(ref header, ref tailItem); } }
internal void AddDirtyItem(DirtyItem item) { if ((item != null) && !this.IsDirtyItem(item)) { if (this._tailDirtyItems != null) { this._tailDirtyItems.NextItem = item; item.Position = this._tailDirtyItems.Position + 1.0; } else { item.Position = (this._headerDirtyItems != null) ? (this._headerDirtyItems.Position - 1.0) : 0.0; this._headerDirtyItems = item; } item.PreviousItem = this._tailDirtyItems; item.NextItem = null; this._tailDirtyItems = item; } }
/// <summary> /// Recalculates this instance. /// </summary> /// <param name="maxCalcCount">The max iterator.</param> /// <param name="forceRecalculateAll">Whether force recalculate all formula in current manager.</param> /// <returns><see langword="true" /> if all dirty nodes have been recalculated, otherwise, <see langword="false" /></returns> public bool Recalculate(int maxCalcCount = 0xc350, bool forceRecalculateAll = false) { if (forceRecalculateAll) { this.ClearDirtyItem(); foreach (CalcCalculationManager manager in this._calcManagers.Values) { if (manager.FormulaCount > 0) { manager.InvalidateAllIdentity(); maxCalcCount += manager.FormulaCount; } } } int num = 0; while ((this._headerDirtyItems != null) && (num < maxCalcCount)) { DirtyItem dirtyItem = this._headerDirtyItems; CalcCalculationManager mgr = this.GetCalculationManager(dirtyItem.Source, null, true); this.EvaluateFormula(mgr, dirtyItem); CalcNode objA = dirtyItem.Node; if (object.ReferenceEquals(objA, null)) { objA = mgr.Graph.GetNode(dirtyItem.Id); } if (!object.ReferenceEquals(objA, null)) { objA.ClearDirty(); if (dirtyItem == this._headerDirtyItems) { this.RemoveDirtyItem(dirtyItem); } } else { this.RemoveDirtyItem(dirtyItem); } num++; } return(num < maxCalcCount); }
internal void DisposeCalculationManager(CalcCalculationManager mgr) { ICalcSource key = mgr.Source; if (key != null) { DirtyItem nextItem; if (this._calcManagers.ContainsKey(key)) { this._calcManagers.Remove(key); } for (DirtyItem item = this._headerDirtyItems; item != null; item = nextItem) { nextItem = item.NextItem; if (item.Source == key) { this.RemoveDirtyItem(item); } } } }
private void AdjustPositions(DirtyItem item) { double position = 0.0; while (!object.ReferenceEquals(item.PreviousItem, null) && ((item.Position - item.PreviousItem.Position) < 0.0001)) { item = item.PreviousItem; } if (object.ReferenceEquals(item, null)) { item = this._headerDirtyItems; position = 0.0; } else { position = item.Position; } while (!object.ReferenceEquals(item, null)) { position++; item.Position = position; item = item.NextItem; } }
internal void MarkAsDirty(CalcService service, bool recalculateAll = false, bool recursiveToIntersectant = true, bool recursiveToDependency = true, bool recursiveToSharedFormula = true) { if (!this.IsDirty && !this._isProcessingDirty) { int num; int num2; int num3; int num4; bool flag; this._isProcessingDirty = true; if ((this.DirtyItem == null) && !this._isTempNode) { CalcLocalIdentity objA = this.Id as CalcLocalIdentity; if (object.ReferenceEquals(objA, null)) { return; } this.DirtyItem = new DirtyItem(service, this.Source, objA, this); } CalcGraph graph = service.GetCalculationManager(this.Source, null, true).Graph; CalcReferenceHelper.Id2Range(this.Source, this.Id, out num, out num2, out num3, out num4, out flag); CalcRangeIdentity id = this.Id as CalcRangeIdentity; List <CalcNode> searchingDepends = new List <CalcNode>(); List <CalcNode> list2 = new List <CalcNode>(); if (recursiveToIntersectant && !object.ReferenceEquals(id, null)) { List <CalcNode> list3 = new List <CalcNode>(); for (int i = 0; i < num3; i++) { for (int j = 0; j < num4; j++) { CalcNode node = graph.GetNode(new CalcCellIdentity(num + i, num2 + j)); if (!object.ReferenceEquals(node, null) && node.IsDirty) { list2.Add(node); } if ((!object.ReferenceEquals(node, null) && !node._isWattingForProcess) && (!node._isProcessingDirty && !node.IsDirty)) { node._isWattingForProcess = true; list3.Add(node); } } } foreach (CalcNode node2 in list3) { node2.MarkAsDirty(service, recalculateAll, false, true, true); node2._isWattingForProcess = false; } } DirtyItem dependForehand = null; List <CalcNode> pendingDependDirtyNode = new List <CalcNode>(); if ((this.Dependents != null) && (this.Dependents.Count > 0)) { searchingDepends.AddRange(this.Dependents.Values); } List <SharedFormulaDirtyItem> sharedDirtyItmes = new List <SharedFormulaDirtyItem>(); if (flag || !recalculateAll) { foreach (CalcNode node3 in graph.GetAllDependentRangeNodes(num, num2, num3, num4)) { if ((node3 != this) && ((recalculateAll || !graph.IsSharedFormula(node3.Id as CalcRangeIdentity)) || ((node3.Dependents != null) && (node3.Dependents.Count != 0)))) { if (!recalculateAll && recursiveToDependency) { ExpandSharedFormulaDependency(service, graph, list2, sharedDirtyItmes, node3, this.Id as CalcLocalIdentity); } else if (recalculateAll) { list2.Add(node3); } } } if (recursiveToSharedFormula && this._isTempNode) { foreach (CalcNode node4 in graph.GetAllDependentSharedNodes(num, num2, num3, num4)) { list2.Add(node4); } } } if (recursiveToIntersectant) { searchingDepends.AddRange(list2); list2.Clear(); } dependForehand = SerchDependForehand(dependForehand, searchingDepends, list2, pendingDependDirtyNode, sharedDirtyItmes); if (recursiveToSharedFormula && !this._isTempNode) { if (dependForehand != null) { service.InsertToDirtyBefore(this.DirtyItem, dependForehand); } else { service.AddDirtyItem(this.DirtyItem); } } if (recursiveToDependency) { foreach (CalcNode node5 in pendingDependDirtyNode) { node5._isWattingForProcess = true; } foreach (CalcNode node6 in pendingDependDirtyNode) { node6.MarkAsDirty(service, recalculateAll, true, true, true); node6._isWattingForProcess = false; } foreach (SharedFormulaDirtyItem item2 in sharedDirtyItmes) { if (!item2.Node.IsDirty) { service.AddDirtyItem(item2); } List <CalcNode> list6 = new List <CalcNode>(); foreach (CalcLocalIdentity identity3 in item2.DirtySubIds2) { if (!item2.DirtySubIds.Contains(identity3)) { item2.DirtySubIds.Add(identity3); CalcNode item = graph.GetNode(identity3); if (item == null) { item = CreateTempNode(this.Source, identity3); } item._isWattingForProcess = true; list6.Add(item); } } foreach (CalcNode node8 in list6) { node8.MarkAsDirty(service, recalculateAll, true, true, false); node8._isWattingForProcess = false; } } } else if (recalculateAll) { foreach (CalcNode node9 in searchingDepends) { this.SetPredencyItem(service, node9); } foreach (CalcNode node10 in list2) { if (IsContains(node10.Id as CalcLocalIdentity, this.Id as CalcLocalIdentity)) { this.SetPredencyItem(service, node10); } } } this._isProcessingDirty = false; } }
/// <summary> /// hdt 唐忠宝增加 /// </summary> /// <param name="header"></param> /// <param name="tailItem"></param> private void InvalidateDependencies(ref DirtyItem header, ref DirtyItem tailItem) { this.GetAllDirtyItems(ref header, ref tailItem); while (header != null) { DirtyItem removingItem = header; bool flag = false; while (removingItem != null) { DirtyItem nextItem = removingItem.NextItem; if (removingItem.PredencyItemCount == 0) { RemoveDirtyItem(ref header, ref tailItem, removingItem); this.Service.AddDirtyItem(removingItem); flag = true; } removingItem = nextItem; } if ((header != null) && !flag) { Queue <DirtyItem> queue = new Queue <DirtyItem>(); queue.Enqueue(header); header.CircleReferenceCount++; DirtyItem item3 = header; while ((queue.Count > 0) || (item3 != null)) { removingItem = queue.Dequeue(); if (removingItem.DependencyCellTemp != null) { foreach (CalcNode node in removingItem.DependencyCellTemp) { node.DirtyItem.CircleReferenceCount++; if (node.DirtyItem.CircleReferenceCount > node.DirtyItem.PredencyItemCount) { RemoveDirtyItem(ref header, ref tailItem, node.DirtyItem); this.Service.AddDirtyItem(node.DirtyItem); flag = true; removingItem = node.DirtyItem; break; } queue.Enqueue(node.DirtyItem); } } if (flag) { item3 = header; while (item3 != null) { item3.CircleReferenceCount = 0; item3 = item3.NextItem; } continue; } if ((queue.Count == 0) && (item3 != null)) { item3 = item3.NextItem; while ((item3 != null) && (item3.CircleReferenceCount != 0)) { item3 = item3.NextItem; } if (item3 == null) { continue; } queue.Enqueue(item3); } } } } }
/// <summary> /// hdt 唐忠宝增加 /// </summary> /// <param name="id"></param> /// <param name="context"></param> /// <param name="node"></param> /// <param name="header"></param> /// <param name="tailItem"></param> private void InvalidateIntersecteds(CalcLocalIdentity id, CalcEvaluatorContext context, CalcNode node, ref DirtyItem header, ref DirtyItem tailItem) { ICalcSource source = this.Source; if (node == null) { node = this.Graph.GetNode(id); } if (!object.ReferenceEquals(node, null)) { if (node.DirtyItem != null) { return; } if (node.DirtyItem == null) { node.DirtyItem = new DirtyItem(this, node); } AddDirtyItem(ref header, ref tailItem, node.DirtyItem, null); } if (id is CalcCellIdentity) { foreach (CalcNode node2 in this.EnumerateIntersectedNodesExcludeSelf(id as CalcCellIdentity)) { if (((node2.Dependents != null) && (node2.Dependents.Count > 0)) && (node2.DirtyItem == null)) { node2.DirtyItem = new DirtyItem(this, node2); AddDirtyItem(ref header, ref tailItem, node2.DirtyItem, node); } } } else { foreach (CalcNode node3 in this.Graph.EnumerateIntersectedNodesExcludeSelf(context, id)) { if (node3.DirtyItem == null) { node3.DirtyItem = new DirtyItem(this, node3); AddDirtyItem(ref header, ref tailItem, node3.DirtyItem, node); } } } }
/// <summary> /// hdt 唐忠宝增加 /// </summary> /// <param name="header"></param> /// <param name="tailItem"></param> private void GetAllDirtyItems(ref DirtyItem header, ref DirtyItem tailItem) { DirtyItem nextItem; DirtyItem removingItem = header; while (removingItem != null) { nextItem = removingItem.NextItem; DirtyItem previousItem = removingItem.PreviousItem; CalcNode objB = removingItem.Node; if (objB.NodeType != NodeType.None) { objB.DirtyItem.DirtyFlag = true; } else { objB.DirtyItem = null; RemoveDirtyItem(ref header, ref tailItem, removingItem); } if ((objB.Dependents == null) || (objB.Dependents.Count == 0)) { removingItem = nextItem; } else { foreach (KeyValuePair <CalcNode, CalcNode> pair in objB.Dependents) { if (((pair.Key.DirtyItem == null) && !object.ReferenceEquals(pair.Key, objB)) && ((pair.Key.Id is CalcCellIdentity) || (pair.Key.Id is CalcExternalCellIdentity))) { this.CreateDirtyItem(pair.Key); AddDirtyItem(ref header, ref tailItem, pair.Key.DirtyItem, objB); CalcLocalIdentity id = pair.Key.Id as CalcLocalIdentity; CalcGraph graph = pair.Key.DirtyItem.Manager.Graph; if (object.ReferenceEquals(id, null)) { id = (pair.Key.Id as CalcExternalIdentity).ConvertToLocal(); } foreach (CalcNode node2 in graph.Manager.EnumerateIntersectedNodesExcludeSelf(id as CalcCellIdentity)) { node2.DirtyItem = new DirtyItem(this, node2); AddDirtyItem(ref header, ref tailItem, node2.DirtyItem, pair.Key); } } } if (nextItem == null) { if ((previousItem == null) && (removingItem != header)) { removingItem = header; } else if ((previousItem != null) && (removingItem != previousItem.NextItem)) { removingItem = previousItem.NextItem; } else { removingItem = null; } continue; } removingItem = nextItem; } } for (removingItem = header; removingItem != null; removingItem = nextItem) { nextItem = removingItem.NextItem; CalcNode node = removingItem.Node; if (removingItem.Node.Dependents != null) { foreach (KeyValuePair <CalcNode, CalcNode> pair2 in removingItem.Node.Dependents) { if ((pair2.Key.DirtyItem != null) && !object.ReferenceEquals(pair2.Key, node)) { if (removingItem.DependencyCellTemp == null) { removingItem.DependencyCellTemp = new HashSet <CalcNode>(); } if (!removingItem.DependencyCellTemp.Contains(pair2.Key)) { removingItem.DependencyCellTemp.Add(pair2.Key); pair2.Key.DirtyItem.PredencyItemCount++; } } } } } }
internal bool EvaluateFormula(CalcCalculationManager mgr, DirtyItem dirtyItem) { CalcLocalIdentity id = dirtyItem.Id as CalcLocalIdentity; if (object.ReferenceEquals(id, null)) { return(false); } CalcExpression objA = mgr.GetExpression(id); if (object.ReferenceEquals(objA, null)) { return(false); } ICalcSource source = mgr.Source; Dictionary <CalcLocalIdentity, CalcExpression> dictionary = new Dictionary <CalcLocalIdentity, CalcExpression>(); if ((id is CalcRangeIdentity) && mgr.Graph.IsSharedFormula(id as CalcRangeIdentity)) { List <CalcLocalIdentity> dirtySubIds = new List <CalcLocalIdentity>(); SharedFormulaDirtyItem item = dirtyItem as SharedFormulaDirtyItem; if ((item != null) && !item.IsFullRangeDirty) { dirtySubIds = (dirtyItem as SharedFormulaDirtyItem).DirtySubIds; } else { dirtySubIds.Add(id); } foreach (CalcLocalIdentity identity3 in dirtySubIds) { int num; int num2; int num3; int num4; bool flag; CalcRangeIdentity identity4 = identity3 as CalcRangeIdentity; CalcReferenceHelper.Id2Range(source, identity3, out num, out num2, out num3, out num4, out flag); for (int i = num; i < (num + num3); i++) { for (int j = num2; j < (num2 + num4); j++) { if ((identity4 != null) && (identity4.IsFullRow || identity4.IsFullColumn)) { new FullBandMappingVisitor(identity4.IsFullRow, identity4.IsFullRow ? i : j).Visit(objA, 0, 0); } CalcCellIdentity identity5 = new CalcCellIdentity(i, j); CalcExpression expression = mgr.GetExpression(identity5); if (((expression != null) && (expression == objA)) && !mgr.Graph.IsIsIntersectantWithArrayFormula(identity5)) { dictionary[identity5] = objA; } } } } } else { dictionary.Add(id, objA); } foreach (KeyValuePair <CalcLocalIdentity, CalcExpression> pair in dictionary) { id = pair.Key; object obj2 = mgr.Evaluator.Evaluate(pair.Value, source.GetEvaluatorContext(id)); while (!(id is CalcRangeIdentity) && ((obj2 is CalcReference) || (obj2 is CalcArray))) { if (obj2 is CalcReference) { obj2 = ExtractValueFromReference(id, obj2); } if (obj2 is CalcArray) { obj2 = (obj2 as CalcArray).GetValue(0); } } source.SetValue(id, obj2); } return(true); }