// Token: 0x06000959 RID: 2393 RVA: 0x00020C8C File Offset: 0x0001EE8C public override bool Equals(object value) { if (value is ChildValueLookup) { ChildValueLookup childValueLookup = (ChildValueLookup)value; if (this.LookupType == childValueLookup.LookupType && this.Property == childValueLookup.Property && this.Value == childValueLookup.Value) { if (this.Conditions == null && childValueLookup.Conditions == null) { return(true); } if (this.Conditions == null || childValueLookup.Conditions == null) { return(false); } if (this.Conditions.Length == childValueLookup.Conditions.Length) { for (int i = 0; i < this.Conditions.Length; i++) { if (!this.Conditions[i].TypeSpecificEquals(childValueLookup.Conditions[i])) { return(false); } } return(true); } } } return(false); }
// // All table datastructures read-lock-free/write-lock // UpdateTables writes the datastructures, locks set by callers // // This method // 1. Adds a ChildValueLookup entry to the given ChildRecord. // This is used in value computation. // 2. Optionally adds a ChildPropertyDependent entry to the given // ContainerRecordFromProperty list. This is used to invalidate // container dependents. // 3. Optionally adds a ChildPropertyDependent entry to the given // ResourceDependents list. This is used when invalidating resource // references // internal static void UpdateTables( ref PropertyValue propertyValue, ref FrugalStructList<ChildRecord> childRecordFromChildIndex, ref FrugalStructList<ItemStructMap<TriggerSourceRecord>> triggerSourceRecordFromChildIndex, ref FrugalStructList<ChildPropertyDependent> resourceDependents, ref HybridDictionary dataTriggerRecordFromBinding, HybridDictionary childIndexFromChildName, ref bool hasInstanceValues) { // // Record instructions for Child/Self value computation // // Query for child index (may be 0 if "self") int childIndex = QueryChildIndexFromChildName(propertyValue.ChildName, childIndexFromChildName); if (childIndex == -1) { throw new InvalidOperationException(SR.Get(SRID.NameNotFound, propertyValue.ChildName)); } object value = propertyValue.ValueInternal; bool requiresInstanceStorage = RequiresInstanceStorage(ref value); propertyValue.ValueInternal = value; childRecordFromChildIndex.EnsureIndex(childIndex); ChildRecord childRecord = childRecordFromChildIndex[childIndex]; int mapIndex = childRecord.ValueLookupListFromProperty.EnsureEntry(propertyValue.Property.GlobalIndex); ChildValueLookup valueLookup = new ChildValueLookup(); valueLookup.LookupType = (ValueLookupType)propertyValue.ValueType; // Maps directly to ValueLookupType for applicable values valueLookup.Conditions = propertyValue.Conditions; valueLookup.Property = propertyValue.Property; valueLookup.Value = propertyValue.ValueInternal; childRecord.ValueLookupListFromProperty.Entries[mapIndex].Value.Add(ref valueLookup); // Put back modified struct childRecordFromChildIndex[childIndex] = childRecord; // // Container property invalidation // switch ((ValueLookupType)propertyValue.ValueType) { case ValueLookupType.Simple: { hasInstanceValues |= requiresInstanceStorage; } break; case ValueLookupType.Trigger: case ValueLookupType.PropertyTriggerResource: { if( propertyValue.Conditions != null ) { // Record the current property as a dependent to each on of the // properties in the condition. This is to facilitate the invalidation // of the current property in the event that any one of the properties // in the condition change. This will allow the current property to get // re-evaluated. for (int i = 0; i < propertyValue.Conditions.Length; i++) { int sourceChildIndex = propertyValue.Conditions[i].SourceChildIndex; triggerSourceRecordFromChildIndex.EnsureIndex(sourceChildIndex); ItemStructMap<TriggerSourceRecord> triggerSourceRecordMap = triggerSourceRecordFromChildIndex[sourceChildIndex]; if (propertyValue.Conditions[i].Property == null) { throw new InvalidOperationException(SR.Get(SRID.MissingTriggerProperty)); } int index = triggerSourceRecordMap.EnsureEntry(propertyValue.Conditions[i].Property.GlobalIndex); AddPropertyDependent(childIndex, propertyValue.Property, ref triggerSourceRecordMap.Entries[index].Value.ChildPropertyDependents); // Store the triggerSourceRecordMap back into the list after it has been updated triggerSourceRecordFromChildIndex[sourceChildIndex] = triggerSourceRecordMap; } // If value is a resource reference, add dependent on resource changes if ((ValueLookupType)propertyValue.ValueType == ValueLookupType.PropertyTriggerResource) { AddResourceDependent(childIndex, propertyValue.Property, propertyValue.ValueInternal, ref resourceDependents); } } // values in a Trigger may require per-instance storage if ((ValueLookupType)propertyValue.ValueType != ValueLookupType.PropertyTriggerResource) { hasInstanceValues |= requiresInstanceStorage; } } break; case ValueLookupType.DataTrigger: case ValueLookupType.DataTriggerResource: { if( propertyValue.Conditions != null ) { if (dataTriggerRecordFromBinding == null) { dataTriggerRecordFromBinding = new HybridDictionary(); } // Record container conditional child property dependents for (int i = 0; i < propertyValue.Conditions.Length; i++) { DataTriggerRecord record = (DataTriggerRecord)dataTriggerRecordFromBinding[propertyValue.Conditions[i].Binding]; if (record == null) { record = new DataTriggerRecord(); dataTriggerRecordFromBinding[propertyValue.Conditions[i].Binding] = record; } // Add dependent on trigger AddPropertyDependent(childIndex, propertyValue.Property, ref record.Dependents); } // If value is a resource reference, add dependent on resource changes if ((ValueLookupType)propertyValue.ValueType == ValueLookupType.DataTriggerResource) { AddResourceDependent(childIndex, propertyValue.Property, propertyValue.ValueInternal, ref resourceDependents); } } // values in a DataTrigger may require per-instance storage if ((ValueLookupType)propertyValue.ValueType != ValueLookupType.DataTriggerResource) { hasInstanceValues |= requiresInstanceStorage; } } break; case ValueLookupType.TemplateBinding: { TemplateBindingExtension templateBinding = (TemplateBindingExtension)propertyValue.ValueInternal; DependencyProperty destinationProperty = propertyValue.Property; // Child DependencyProperty sourceProperty = templateBinding.Property; // Container // Record the current property as a dependent to the aliased // property on the container. This is to facilitate the // invalidation of the current property in the event that the // aliased container property changes. This will allow the current // property to get re-evaluated. int sourceChildIndex = 0; // TemplateBinding is always sourced off of the container triggerSourceRecordFromChildIndex.EnsureIndex(sourceChildIndex); ItemStructMap<TriggerSourceRecord> triggerSourceRecordMap = triggerSourceRecordFromChildIndex[sourceChildIndex]; int index = triggerSourceRecordMap.EnsureEntry(sourceProperty.GlobalIndex); AddPropertyDependent(childIndex, destinationProperty, ref triggerSourceRecordMap.Entries[index].Value.ChildPropertyDependents); // Store the triggerSourceRecordMap back into the list after it has been updated triggerSourceRecordFromChildIndex[sourceChildIndex] = triggerSourceRecordMap; } break; case ValueLookupType.Resource: { AddResourceDependent(childIndex, propertyValue.Property, propertyValue.ValueInternal, ref resourceDependents); } break; } }