public static ChangeSet GenerateChangeSet(Config oldConfig, Config newConfig) { var cs = new ChangeSet(); foreach (var n in oldConfig) { var oldKey = n.Key; if (newConfig.ContainsKey(oldKey)) { var newNode = newConfig[oldKey]; if (n.Value != newNode) { cs.Add(new ConfigChange() { Type = ChangeType.Modified, Key = oldKey, Old = n.Value, New = newNode }); } } else { cs.Add(new ConfigChange() { Type = ChangeType.Removed, Key = oldKey, Old = n.Value, New = null }); } } foreach (var n in newConfig) { var newKey = n.Key; if (!oldConfig.ContainsKey(newKey)) { cs.Add(new ConfigChange() { Type = ChangeType.Added, Key = newKey, Old = null, New = newConfig[newKey] }); } } return cs; }
public IObservable <IChangeSet <T> > Run() { return(Observable.Create <IChangeSet <T> >(observer => { var comparer = EqualityComparer <T> .Default; var latest = default(T); return _source .Where(value => !comparer.Equals(latest, value)) .Select(value => { var changes = new ChangeSet <T>(); if (_useReplacements && latest != null && value != null) { changes.Add(new Change <T>(ListChangeReason.Replace, value, latest, 0)); } else { if (latest != null) { changes.Add(new Change <T>(ListChangeReason.Remove, latest, 0)); } if (value != null) { changes.Add(new Change <T>(ListChangeReason.Add, value, 0)); } } latest = value; return changes; }).SubscribeSafe(observer); })); }
private void DataGrid_SelectionChanged(object sender, SelectionChangedEventArgs e) { var changeSet = new ChangeSet <ObservablesListItem>(); changeSet.Add(new Change <ObservablesListItem>(ListChangeReason.RemoveRange, e.RemovedItems.Cast <ObservablesListItem>())); changeSet.Add(new Change <ObservablesListItem>(ListChangeReason.AddRange, e.AddedItems.Cast <ObservablesListItem>())); (DataContext as ObservablesListViewModel)?.OnSelectedItemsChanged(changeSet); }
/// <inheritdoc /> public override bool AddTileEntity(ITileEntity tileEntity) { if (Extent.AddTileEntity(tileEntity)) { _changeSet.Add(new TileEntityAddition(tileEntity)); return(true); } return(false); }
public void Undo_Files() { using (var changeSet = new ChangeSet(1)) { var oldTile = new Tile { WallId = 1 }; changeSet.Add(new TileUpdate(Vector.Zero, oldTile, new Tile())); changeSet.Add(new TileUpdate(Vector.Zero, oldTile, new Tile())); var extent = Mock.Of <Extent>(e => e.SetTile(Vector.Zero, oldTile)); Assert.That(changeSet.Undo(extent), Is.EqualTo(2)); Mock.Get(extent).Verify(e => e.SetTile(Vector.Zero, oldTile), Times.Exactly(2)); } }
public Thread CreateThread(User poster, string title, string body, PostLayer desiredLayer, DateTime date, int?forcedPostId) { PostLayer actualLayer = poster.getActualLayer(this, desiredLayer); AbstractChange threadInsert = new InsertChange( Thread.TableSpec.instance, new Dictionary <string, AbstractFieldValue> { { Thread.TableSpec.FIELD_BOARDID, new ScalarFieldValue(this.id.ToString()) }, { Thread.TableSpec.FIELD_ISANNOUNCEMENT, new ScalarFieldValue("0") }, { Thread.TableSpec.FIELD_ISLOCKED, new ScalarFieldValue("0") }, { Thread.TableSpec.FIELD_TITLE, new ScalarFieldValue(title) }, { Thread.TableSpec.FIELD_TOPICSTARTERID, new ScalarFieldValue(poster.id.ToString()) }, { Thread.TableSpec.FIELD_TOTALPOSTS, new ScalarFieldValue("0") }, { Thread.TableSpec.FIELD_TOTALVIEWS, new ScalarFieldValue("0") }, { Thread.TableSpec.FIELD_FIRSTPOSTID, new ScalarFieldValue(null) }, { Thread.TableSpec.FIELD_LASTPOSTID, new ScalarFieldValue(null) }, { Thread.TableSpec.FIELD_LASTPOSTDATE, new ScalarFieldValue(date.ToUTCString()) }, } ); using (ChangeSet threadInsertSet = new ChangeSet(), dataInsertSet = new ChangeSet()) { Config.Transactional(transaction => { threadInsertSet.Add(threadInsert); threadInsertSet.Apply(transaction); foreach (AbstractChange change in Thread.getNewPostChanges(this, threadInsert.getId().Value, null, poster, actualLayer, title, body, date, forcedPostId).Value) { dataInsertSet.Add(change); } dataInsertSet.Apply(transaction); }); } return(Thread.LoadById(threadInsert.getId().Value)); }
/// <summary> /// Adds one or more entries to the address map for the specified segment. /// </summary> private static void AddAddressEntries(DisasmProject proj, SegmentMapEntry ent, int bufOffset, ChangeSet cs) { int addr = ent.Address; int segRem = ent.Segment.Length; while (true) { // Generate an ORG directive. int origAddr = proj.AddrMap.Get(bufOffset); UndoableChange uc = UndoableChange.CreateAddressChange(bufOffset, origAddr, addr); cs.Add(uc); // Compare amount of space in this bank to amount left in segment. int bankRem = 0x00010000 - (addr & 0xffff); if (bankRem > segRem) { // All done, bail. break; } // Advance to start of next bank. addr += bankRem; Debug.Assert((addr & 0x0000ffff) == 0); bufOffset += bankRem; segRem -= bankRem; Debug.WriteLine("Adding additional ORG at " + addr); } }
private void AddHeaderComment(DisasmProject proj, ChangeSet cs) { // Add header comment. StringBuilder sb = new StringBuilder(); sb.AppendLine(string.Format(Res.Strings.DEFAULT_HEADER_COMMENT_FMT, App.ProgramVersion)); sb.AppendLine(); foreach (SegmentMapEntry ent in mSegmentMap) { if (ent == null) { continue; } string segCmt = string.Format(Res.Strings.OMF_SEG_HDR_COMMENT_FMT, ent.Segment.SegNum, ent.Segment.Kind, ent.Segment.SegName, mFormatter.FormatAddress(ent.Address, true), ent.Segment.Length); sb.AppendLine(segCmt); } UndoableChange uc = UndoableChange.CreateLongCommentChange( LineListGen.Line.HEADER_COMMENT_OFFSET, null, new MultiLineComment(sb.ToString())); cs.Add(uc); }
public void Add_NullChange_ThrowsArgumentNullException() { using (var changeSet = new ChangeSet()) { // ReSharper disable once AssignNullToNotNullAttribute Assert.That(() => changeSet.Add(null), Throws.ArgumentNullException); } }
private ItemCreated(ChangeSet owner, Item item, int index, string name) { Owner = owner; _name = name; Item = item; AtIndex = index; owner.Add(this); UpdateDelta(); }
private ItemMoved(ChangeSet owner, Item item, int index1, int index2, string name) { Owner = owner; _name = name; Item = item; Index1 = index1; Index2 = index2; owner.Add(this); UpdateDelta(); }
public void AddOrUpdate(TObject item) { TKey key = _keySelector.GetKey(item); var previous = _cache.Lookup(key); _queue.Add(previous.HasValue ? new Change <TObject, TKey>(ChangeReason.Update, key, item, previous) : new Change <TObject, TKey>(ChangeReason.Add, key, item)); _cache.AddOrUpdate(item, key); }
private ItemLinked(ChangeSet owner, Relation relation, Item parent, Item child, int parentIndex, int childIndex, string name) { Owner = owner; _name = name; _child = child; _parent = parent; _relation = relation; _childIndex = parentIndex; _parentIndex = parentIndex; owner.Add(this); }
public void Redo() { using (var changeSet = new ChangeSet()) { var newTile = new Tile { WallId = 1 }; changeSet.Add(new TileUpdate(Vector.Zero, new Tile(), newTile)); var extent = Mock.Of <Extent>(e => e.SetTile(Vector.Zero, newTile)); Assert.That(changeSet.Redo(extent), Is.EqualTo(1)); Mock.Get(extent).Verify(e => e.SetTile(Vector.Zero, newTile), Times.Once); } }
private ItemChildMoved(ChangeSet owner, Relation relation, Item key, Item item, int index1, int index2, string name) { Owner = owner; _name = name; Key = key; Item = item; Relation = relation; Index1 = index1; Index2 = index2; owner.Add(this); UpdateDelta(); }
/*public async Task BulkDelete() { * await BulkDelete("SELECT c._self FROM c"); * }*/ public T Add <T>(T entity) where T : HasId { ChangeSet.Add(entity); return(entity); }
public ValueListNodeInputViewModel() { MaxConnections = Int32.MaxValue; ConnectionValidator = pending => new ConnectionValidationResult( pending.Output is ValueNodeOutputViewModel <T> || pending.Output is ValueNodeOutputViewModel <IObservableList <T> >, null ); var valuesFromSingles = Connections.Connect(c => c.Output is ValueNodeOutputViewModel <T>) .Transform(c => ((ValueNodeOutputViewModel <T>)c.Output)) //Note: this line used to be //.AutoRefresh(output => output.CurrentValue) //which ignored changes where CurrentValue didn't change. //This caused problems when the value object isn't replaced, but one of its properties changes. .AutoRefreshOnObservable(output => output.Value) .Transform(output => output.CurrentValue, true) .Filter(v => v != null) .Select((IChangeSet <T> changes) => { if (changes.TotalChanges == changes.Replaced + changes.Refreshes) { bool allRefresh = true; var newChanges = new ChangeSet <T>(); foreach (var change in changes) { if (change.Reason == ListChangeReason.Replace) { if (change.Type == ChangeType.Item) { if (change.Item.Previous != change.Item.Current) { allRefresh = false; break; } newChanges.Add(new Change <T>(ListChangeReason.Refresh, change.Item.Current, change.Item.Previous, change.Item.CurrentIndex, change.Item.PreviousIndex)); } else { throw new Exception("Does this ever occur?"); } } else { newChanges.Add(change); } } if (allRefresh) { return(newChanges); } } return(changes); }); var valuesFromLists = Connections.Connect(c => c.Output is ValueNodeOutputViewModel <IObservableList <T> >) // Grab list of values from output, using switch to handle when the list object is replaced .Transform(c => ((ValueNodeOutputViewModel <IObservableList <T> >)c.Output).Value.Switch()) // Materialize this changeset stream into a list (needed to make sure the next step is done dynamically) .AsObservableList() // Take the union of all values from all lists. This is done dynamically, so adding/removing new lists works as expected. .Or(); Values = valuesFromSingles.Or(valuesFromLists).AsObservableList(); }
/// <summary> /// Edits the data file, essentially putting the jump table entries into the /// "loaded" state. /// </summary> /// <remarks> /// We don't use ent.Segment.Relocs, as that is expected to be empty. /// </remarks> private bool RelocJumpTable(SegmentMapEntry ent, byte[] data, int bufOffset, ChangeSet cs) { const int ENTRY_LEN = 14; if (ent.Segment.Relocs.Count != 0) { Debug.WriteLine("WEIRD: jump table has reloc data?"); } byte[] srcData = ent.Segment.GetConstData(); Array.Copy(srcData, 0, data, bufOffset, srcData.Length); // For no documented reason, jump tables start with 8 zero bytes. for (int i = 0; i < 8; i++) { if (data[bufOffset + i] != 0) { Debug.WriteLine("JumpTab: missing 8-byte header"); return(false); } } TypedRangeSet newSet = new TypedRangeSet(); TypedRangeSet undoSet = new TypedRangeSet(); for (int i = 8; i + 4 <= ent.Segment.Length; i += ENTRY_LEN) { //int userId = RawData.GetWord(data, bufOffset + i, 2, false); int fileNum = RawData.GetWord(data, bufOffset + i + 2, 2, false); if (fileNum == 0) { // A zero file number indicates end of table. Debug.WriteLine("JumpTab: found fileNum=0 at offset " + i + ", len=" + ent.Segment.Length); break; } else if (fileNum != 1) { // External file, ignore entry. Debug.WriteLine("JumpTab: ignoring entry with FileNum=" + fileNum); continue; } else if (i + ENTRY_LEN > ent.Segment.Length) { // Make sure the rest fits. Debug.WriteLine("JumpTab: overran buffer"); return(false); } // Note: segment might end right after FileNum, so don't try to read further // until we've confirmed that FileNum != 0. int segNum = RawData.GetWord(data, bufOffset + i + 4, 2, false); int segOff = RawData.GetWord(data, bufOffset + i + 6, 4, false); if (segNum < 0 || segNum >= mSegmentMap.Count || mSegmentMap[segNum] == null) { Debug.WriteLine("JumpTab: invalid SegNum=" + segNum); return(false); } if (data[bufOffset + i + 10] != 0x22) { Debug.WriteLine("JumpTab: did not find expected JSL at off=" + i); return(false); } int addr = mSegmentMap[segNum].Address + segOff; int jmlOffset = bufOffset + i + 10; data[jmlOffset] = 0x5c; // JML data[jmlOffset + 1] = (byte)addr; data[jmlOffset + 2] = (byte)(addr >> 8); data[jmlOffset + 3] = (byte)(addr >> 16); //Debug.WriteLine("JumpTab: off=" + i + " -> " + // mFormatter.FormatAddress(addr, true)); // It seems to be fairly common for jump table entries to not be referenced // from the program, which can leave whole dynamic segments unreferenced. Set // a code start tag on the JML instruction. undoSet.Add(jmlOffset, (int)CodeAnalysis.AnalyzerTag.None); newSet.Add(jmlOffset, (int)CodeAnalysis.AnalyzerTag.Code); } UndoableChange uc = UndoableChange.CreateAnalyzerTagChange(undoSet, newSet); cs.Add(uc); return(true); }
private bool GenerateDataAndProject() { // Sum up the segment lengths to get the total project size. int totalLen = 0; foreach (SegmentMapEntry ent in mSegmentMap) { if (ent == null) { continue; } totalLen += ent.Segment.Length; } Debug.WriteLine("Total length of loaded binary is " + totalLen); byte[] data = new byte[totalLen]; // Create the project object. DisasmProject proj = new DisasmProject(); proj.Initialize(data.Length); // Try to get the Apple IIgs system definition. This is fragile, because it // relies on the name in the JSON file, but it's optional. (If the default CPU // type stops being 65816, we should be sure to set that here.) try { // TODO(maybe): encapsulate this somewhere else string sysDefsPath = RuntimeDataAccess.GetPathName("SystemDefs.json"); SystemDefSet sds = SystemDefSet.ReadFile(sysDefsPath); SystemDef sd = sds.FindEntryByName(IIGS_SYSTEM_DEF); if (sd != null) { proj.ApplySystemDef(sd); } else { Debug.WriteLine("Unable to find Apple IIgs system definition"); } } catch (Exception) { // never mind Debug.WriteLine("Failed to apply Apple IIgs system definition"); } ChangeSet cs = new ChangeSet(mSegmentMap.Count * 2); AddHeaderComment(proj, cs); UndoableChange uc; // Load the segments, and add entries to the project. int bufOffset = 0; foreach (SegmentMapEntry ent in mSegmentMap) { if (ent == null) { continue; } if (ent.Segment.Kind == OmfSegment.SegmentKind.JumpTable) { if (!RelocJumpTable(ent, data, bufOffset, cs)) { // Could treat this as non-fatal, but it really ought to work. Debug.WriteLine("Jump Table reloc failed"); return(false); } } else { // Perform relocation. if (!RelocSegment(ent, data, bufOffset)) { return(false); } } // Add one or more address entries. (Normally one, but data segments // can straddle multiple pages.) AddAddressEntries(proj, ent, bufOffset, cs); if ((mFlags & Flags.AddNotes) != 0) { // Add a comment identifying the segment and its attributes. string segCmt = string.Format(Res.Strings.OMF_SEG_COMMENT_FMT, ent.Segment.SegNum, ent.Segment.Kind, ent.Segment.Attrs, ent.Segment.SegName); uc = UndoableChange.CreateLongCommentChange(bufOffset, null, new MultiLineComment(segCmt)); cs.Add(uc); // Add a note identifying the segment. string segNote = string.Format(Res.Strings.OMF_SEG_NOTE_FMT, ent.Segment.SegNum, mFormatter.FormatAddress(ent.Address, true), ent.Segment.SegName); uc = UndoableChange.CreateNoteChange(bufOffset, null, new MultiLineComment(segNote)); cs.Add(uc); } bufOffset += ent.Segment.Length; } proj.PrepForNew(data, "new_proj"); foreach (KeyValuePair <int, DisasmProject.RelocData> kvp in mRelocData) { proj.RelocList.Add(kvp.Key, kvp.Value); } // Enable "use reloc" in the analysis parameters. ProjectProperties newProps = new ProjectProperties(proj.ProjectProps); newProps.AnalysisParams.UseRelocData = true; uc = UndoableChange.CreateProjectPropertiesChange(proj.ProjectProps, newProps); cs.Add(uc); // TODO(someday): by default we apply a code start tag to offset 0 of the first // segment. The placement should take the segment's ENTRY into account. Debug.WriteLine("Applying " + cs.Count + " changes"); proj.ApplyChanges(cs, false, out _); mLoadedData = data; mNewProject = proj; return(true); }
public void Add(TEntity entity) { Validate(entity); _changeSet.Add(entity, EntityState.Added); }