public WrappedTagBlockEntry GetTopLevelWrapper(TagBlockData block, WrappedTagBlockEntry wrapper) { FlattenedTagBlock flattened; if (_flattenInfo.TryGetValue(block, out flattened)) { return(flattened.GetTopLevelWrapper(wrapper)); } return(null); }
/// <summary> /// Forcibly expands a block and all of its ancestors. /// </summary> /// <param name="block">The block to make visible.</param> public void ForceVisible(TagBlockData block) { FlattenedTagBlock flattened; if (!_flattenInfo.TryGetValue(block, out flattened)) { return; } while (flattened != null && flattened.Expand()) { flattened = flattened.Parent; } }
public void EnumWrappers(TagBlockData block, Action <WrappedTagBlockEntry> wrapperProcessor) { FlattenedTagBlock flattened; if (!_flattenInfo.TryGetValue(block, out flattened)) { return; } foreach (WrappedTagBlockEntry wrapper in flattened.Wrappers) { wrapperProcessor(wrapper); } }
public void VisitTagBlock(TagBlockData field) { var values = new StructureValueCollection(); bool isValid = _cache.MetaArea.ContainsBlockPointer(field.FirstElementAddress, (int)(field.Length * field.ElementSize)); values.SetInteger("entry count", isValid ? (uint)field.Length : 0); uint cont = _cache.PointerExpander.Contract(field.FirstElementAddress); values.SetInteger("pointer", isValid ? cont : 0); SeekToOffset(field.Offset); StructureWriter.WriteStructure(values, _tagBlockLayout, _writer); }
public FlattenedTagBlock(FlattenedTagBlock parent, TagBlockData template, ObservableCollection <MetaField> topLevelFields, FieldChangeTracker tracker, FieldChangeSet changes) { _parent = parent; _template = template; _activeTagBlock = template; _synchronizedTagBlocks.Add(template); if (template.HasChildren) { _lastPage = template.Pages[template.CurrentIndex]; } _topLevelFields = topLevelFields; _tracker = tracker; _changes = changes; }
public void ReadTagBlockChildren(TagBlockData block) { if (!block.HasChildren || block.CurrentIndex < 0) { return; } bool opened = OpenReader(); if (_reader == null) { return; } try { // Calculate the base offset to read from long oldBaseOffset = BaseOffset; long dataOffset = block.FirstElementAddress; if (_type == LoadType.File) { dataOffset = (uint)_cache.MetaArea.PointerToOffset(dataOffset); } BaseOffset = (dataOffset + block.CurrentIndex * block.ElementSize); TagBlockPage page = block.Pages[block.CurrentIndex]; for (int i = 0; i < page.Fields.Length; i++) { ReadField(page.Fields[i] ?? block.Template[i]); } BaseOffset = oldBaseOffset; } finally { if (opened) { CloseReader(); } } }
public void VisitTagBlock(TagBlockData field) { // Don't enter empty blocks TagBlockData oldTagBlock = _currentTagBlock; _currentTagBlock = field; if (FilterString(field, field.Name) && field.Length > 0) { // Forcibly highlight everything inside it _highlightLevel++; _flattener.EnumWrappers(field, TagBlockFlattener_HandleWrapper); _highlightLevel--; } else if (field.Length > 0) { _flattener.EnumWrappers(field, TagBlockFlattener_HandleWrapper); } _currentTagBlock = oldTagBlock; }
public void VisitTagBlock(TagBlockData field) { // Create flatten information for the block and attach event handlers to it var flattened = new FlattenedTagBlock(_flatParent, field, _topLevelFields, _tracker, _changes); AttachToTagBlock(field, flattened); FlattenedTagBlock oldParent = _flatParent; _flatParent = flattened; Flatten(field.Template); field.UpdateWidth(); _flatParent = oldParent; for (int i = 0; i < field.Template.Count; i++) { WrappedTagBlockEntry wrapper = flattened.WrapField(field.Template[i], field.Width, i == field.Template.Count - 1); _index++; _fields.Insert(_index, wrapper); } }
public void LoadPage(TagBlockData block, int index) { _activeTagBlock = block; if (!block.HasChildren) { return; } if (index >= 0 && index < block.Length && block.Pages[index] == _lastPage) { return; } UnloadPage(); if (index < 0 || index >= block.Length) { _lastPage = null; return; } _lastPage = block.Pages[index]; for (int i = 0; i < _lastPage.Fields.Length; i++) { // if _lastPage.Fields[i] is null, then we can just re-use the field from the template MetaField newField; if (_lastPage.Fields[i] != null) { newField = _lastPage.Fields[i]; } else { newField = block.Template[i]; } // HACK: synchronize the opacity newField.Opacity = _loadedFields[i].Opacity; _loadedFields[i] = newField; } }
public override MetaField CloneValue() { var result = new TagBlockData(Name, Offset, FieldAddress, ElementSize, Align, Sort, PluginLine, ToolTip, _metaArea); result._expanded = _expanded; result._width = _width; result._currentIndex = _currentIndex; result._firstElementAddr = _firstElementAddr; foreach (MetaField field in _template) { result._template.Add(field); } foreach (TagBlockPage page in _pages) { result._pages.Add(page.CloneValue()); } if (Cloned != null) { Cloned(this, new TagBlockClonedEventArgs(this, result)); } return(result); }
public void VisitTagBlock(TagBlockData field) { SeekToOffset(field.Offset); StructureValueCollection values = StructureReader.ReadStructure(_reader, _tagBlockLayout); var length = (int)values.GetInteger("entry count"); uint pointer = (uint)values.GetInteger("pointer"); long expanded = _cache.PointerExpander.Expand(pointer); // Make sure the pointer looks valid if (length < 0 || !_cache.MetaArea.ContainsBlockPointer(expanded, (int)(length * field.ElementSize))) { length = 0; pointer = 0; expanded = 0; } if (expanded != field.FirstElementAddress) { field.FirstElementAddress = expanded; } field.Length = length; }
public void WriteTagBlockChildren(TagBlockData field) { if (field.CurrentIndex < 0 || !field.HasChildren) { return; } // Get the base address and convert it to an offset if we're writing to the file long newBaseOffset = field.FirstElementAddress; if (_type == SaveType.File) { newBaseOffset = _cache.MetaArea.PointerToOffset(newBaseOffset); } // Save the old base offset and set the base offset to the block's base long oldBaseOffset = _baseOffset; _baseOffset = newBaseOffset; // Write each page int _oldIndex = field.CurrentIndex; bool _oldPokeTemplates = _pokeTemplateFields; for (int i = 0; i < field.Length; i++) { // If we're saving everything, then change the active page so the values get loaded from the file if (_changes == null && field.CurrentIndex != i) { field.CurrentIndex = i; } // If we're not saving everything, then we can only poke template fields in block // if the current indices all line up if (i != _oldIndex) { _pokeTemplateFields = false; } // Get each field in the page and write it TagBlockPage page = field.Pages[i]; for (int j = 0; j < page.Fields.Length; j++) { MetaField pageField = page.Fields[j]; // The field in the page takes precedence over the field in the block's template if (pageField == null && (_changes == null || _pokeTemplateFields)) { pageField = field.Template[j]; // Get it from the template } if (pageField != null) { WriteField(pageField); } } // Advance to the next chunk _baseOffset += field.ElementSize; _pokeTemplateFields = _oldPokeTemplates; } if (!Equals(field.CurrentIndex, _oldIndex)) { field.CurrentIndex = _oldIndex; } // Restore the old base offset _baseOffset = oldBaseOffset; }
public void VisitTagBlock(TagBlockData field) { AddWidth(field.Width); }
/// <summary> /// Synchronizes the expansion state of a block with the expansion state of this FlattenedTagBlock. /// </summary> /// <param name="other">The TagBlock to synchronize the expansion state of.</param> public void SynchronizeWith(TagBlockData other) { _synchronizedTagBlocks.Add(other); }
private void AttachToTagBlock(TagBlockData field, FlattenedTagBlock flattened) { field.PropertyChanged += TagBlockPropertyChanged; field.Cloned += TagBlockCloned; _flattenInfo[field] = flattened; }
public TagBlockClonedEventArgs(TagBlockData old, TagBlockData clone) { Old = old; Clone = clone; }