public void LoadBlame(GitRevision revision, [CanBeNull] IReadOnlyList <ObjectId> children, string fileName, RevisionGridControl revGrid, Control controlToMask, Encoding encoding, int?initialLine = null, bool force = false) { var objectId = revision.ObjectId; // refresh only when something changed if (!force && objectId == _blameId && fileName == _fileName && revGrid == _revGrid && encoding == _encoding) { return; } controlToMask?.Mask(); var scrollPos = BlameFile.ScrollPos; var line = _clickedBlameLine != null && _clickedBlameLine.Commit.ObjectId == objectId ? _clickedBlameLine.OriginLineNumber : initialLine ?? 0; _revGrid = revGrid; _fileName = fileName; _encoding = encoding; _blameLoader.LoadAsync(() => _blame = Module.Blame(fileName, objectId.ToString(), encoding), () => ProcessBlame(revision, children, controlToMask, line, scrollPos)); }
private void LoadBranches() { string from = _NO_TRANSLATE_From.Text; Cursor = Cursors.AppStarting; _branchListLoader.LoadAsync(() => Module.GetRemoteServerRefs(from, false, true), UpdateBranches); }
private void ViewPullRequestsForm_Load(object sender, EventArgs e) { _fileStatusList.SelectedIndexChanged += _fileStatusList_SelectedIndexChanged; _discussionWB.DocumentCompleted += _discussionWB_DocumentCompleted; _isFirstLoad = true; this.Mask(); _loader.LoadAsync( () => { var t = _gitHoster.GetHostedRemotesForModule().ToList(); foreach (var el in t) { el.GetHostedRepository(); // We do this now because we want to do it in the async part. } return(t); }, hostedRemotes => { _hostedRemotes = hostedRemotes; _selectHostedRepoCB.Items.Clear(); foreach (var hostedRepo in _hostedRemotes) { _selectHostedRepoCB.Items.Add(hostedRepo); } SelectHostedRepositoryForCurrentRemote(); this.UnMask(); }); }
public DashboardItem(Repository repository) : this() { if (repository == null) { return; } Bitmap icon = GetRepositoryIcon(repository); if (AppSettings.DashboardShowCurrentBranch) { _branchNameLoader = new AsyncLoader(); _branchNameLoader.LoadAsync(() => { if (!GitModule.IsBareRepository(repository.Path)) { return(GitModule.GetSelectedBranchFast(repository.Path)); } return(string.Empty); }, UpdateBranchName); } Initialize(icon, repository.Path, repository.Title, repository.Description); }
private void CreatePullRequestForm_Load(object sender, EventArgs e) { _createBtn.Enabled = false; _yourBranchesCB.Text = _strLoading.Text; _hostedRemotes = _repoHost.GetHostedRemotesForModule(Module); this.Mask(); _remoteLoader.LoadAsync( () => _hostedRemotes.Where(r => !r.IsOwnedByMe).ToArray(), foreignHostedRemotes => { if (foreignHostedRemotes.Length == 0) { MessageBox.Show(this, _strFailedToCreatePullRequest.Text + Environment.NewLine + _strPleaseCloneGitHubRep.Text, "", MessageBoxButtons.OK, MessageBoxIcon.Error); Close(); return; } this.UnMask(); _currentBranch = Module.IsValidGitWorkingDir() ? Module.GetSelectedBranch() : ""; LoadRemotes(foreignHostedRemotes); LoadMyBranches(); }); }
private void LoadBranchesAsync() { var selectedBranch = UICommands.GitModule.GetSelectedBranch(); ExistingBranches = Module.GetRefs(false); comboBoxBranches.Text = Strings.GetLoadingData(); ThreadHelper.JoinableTaskFactory.RunAsync(async() => { await _branchesLoader.LoadAsync( () => ExistingBranches.Where(r => r.Name != selectedBranch).ToList(), list => { comboBoxBranches.Text = string.Empty; comboBoxBranches.DataSource = list; comboBoxBranches.DisplayMember = nameof(IGitRef.LocalName); }); await this.SwitchToMainThreadAsync(); if (comboBoxBranches.Items.Count == 0) { radioButtonCreateNewBranch.Checked = true; radioButtonCheckoutExistingBranch.Enabled = false; } else { radioButtonCheckoutExistingBranch.Checked = true; } ValidateWorktreeOptions(); }); }
public void LoadAsyncClearsPreviousContents() { IEnumerable <int> originalItems = new[] { 1, 2, 3 }; IEnumerable <int> loadedItems = new[] { 4, 5, 6 }; var loadFunc = Substitute.For <Func <CancellationToken, Task <IEnumerable <int> > > >(); loadFunc.Invoke(Arg.Any <CancellationToken>()).Returns(Task.FromResult(originalItems), Task.FromResult(loadedItems)); var loader = new AsyncLoader <int>(seqFactory: Seq.ListBased, loadDataAsync: loadFunc); loader.LoadAsync(); // initial load loader.Should().BeEquivalentTo(originalItems); // sanity check loader.LoadAsync(); // --- Perform --- loader.Should().BeEquivalentTo(loadedItems); }
public void CanLoadEmptyList() { var loader = new AsyncLoader <string>( seqFactory: Seq.ListBased, loadDataAsync: token => Task.FromResult(Enumerable.Empty <string>())); loader.LoadAsync(); Assert.That(loader.ToList(), Is.Empty); }
public async Task Using_load_or_cancel_after_dispose_throws() { var loader = new AsyncLoader(); // Safe to dispose multiple times loader.Dispose(); loader.Dispose(); loader.Dispose(); // Any use after dispose should throw await AssertEx.ThrowsAsync <ObjectDisposedException>(() => loader.LoadAsync(() => { }, () => { })); await AssertEx.ThrowsAsync <ObjectDisposedException>(() => loader.LoadAsync(() => 1, i => { })); await AssertEx.ThrowsAsync <ObjectDisposedException>(() => loader.LoadAsync(_ => { }, () => { })); await AssertEx.ThrowsAsync <ObjectDisposedException>(() => loader.LoadAsync(_ => 1, i => { })); Assert.Throws <ObjectDisposedException>(() => loader.Cancel()); }
private Task LoadTagsAsync() { comboBoxTags.Text = Strings.LoadingData; return(_tagsLoader.LoadAsync( () => Module.GetTagRefs(GitModule.GetTagRefsSortOrder.ByCommitDateDescending).ToList(), list => { comboBoxTags.Text = string.Empty; comboBoxTags.DataSource = list; comboBoxTags.DisplayMember = nameof(IGitRef.LocalName); SetSelectedRevisionByFocusedControl(); })); }
private Task LoadBranchesAsync() { comboBoxBranches.Text = Strings.LoadingData; return(_branchesLoader.LoadAsync( () => Module.GetRefs(false).ToList(), list => { comboBoxBranches.Text = string.Empty; comboBoxBranches.DataSource = list; comboBoxBranches.DisplayMember = nameof(IGitRef.LocalName); SetSelectedRevisionByFocusedControl(); })); }
public async Task CanUpdateNonEmptyLoaderWithEmptyChanges() { IEnumerable <int> initialItems = new[] { 1, 2, 3 }; var loader = new AsyncLoader <int>( seqFactory: Seq.ListBased, loadDataAsync: _ => Task.FromResult(initialItems), fetchUpdatesAsync: (_, __) => Task.FromResult(Enumerable.Empty <ItemChange <int> >())); await loader.LoadAsync(); // load initial data await loader.UpdateAsync(); // --- Perform --- loader.ShouldAllBeEquivalentTo(initialItems); }
private void FilePattern_TextChanged(object sender, EventArgs e) { _ignoredFilesLoader.Cancel(); if (_NO_TRANSLATE_Preview.Enabled) { _ignoredFilesLoader.Delay = TimeSpan.FromMilliseconds(300); _NO_TRANSLATE_filesWillBeIgnored.Text = _updateStatusString.Text; _NO_TRANSLATE_Preview.DataSource = new List <string> { _updateStatusString.Text }; _NO_TRANSLATE_Preview.Enabled = false; } _ignoredFilesLoader.LoadAsync(() => Module.GetIgnoredFiles(GetCurrentPatterns()), UpdatePreviewPanel); }
private void InitializeSoft() { GitStash gitStash = Stashes.SelectedItem as GitStash; Stashed.SetDiffs(); Loading.Visible = true; Stashes.Enabled = false; refreshToolStripButton.Enabled = false; toolStripButton_customMessage.Enabled = false; if (gitStash == _currentWorkingDirStashItem) { toolStripButton_customMessage.Enabled = true; _asyncLoader.LoadAsync(() => Module.GetAllChangedFiles(), LoadGitItemStatuses); Clear.Enabled = false; // disallow Drop (of current working directory) Apply.Enabled = false; // disallow Apply (of current working directory) } else if (gitStash != null) { _asyncLoader.LoadAsync(() => Module.GetStashDiffFiles(gitStash.Name), LoadGitItemStatuses); Clear.Enabled = true; // allow Drop Apply.Enabled = true; // allow Apply } }
public void CanEnumerateLoadedItems() { var loadedItems = new[] { 1, 2, 3 }; var loader = new AsyncLoader <int>( seqFactory: Seq.ListBased, loadDataAsync: t => Task.FromResult(loadedItems.AsEnumerable())); IEnumerable <int> values = loader; loader.LoadAsync(); // --- Perform --- Assert.That(loader, Is.EqualTo(loadedItems)); }
private void LoadBranchesAsync() { comboBoxBranches.Text = Strings.GetLoadingData(); ThreadHelper.JoinableTaskFactory.RunAsync(() => { return(_branchesLoader.LoadAsync( () => Module.GetRefs(false).ToList(), list => { comboBoxBranches.Text = string.Empty; comboBoxBranches.DataSource = list; comboBoxBranches.DisplayMember = nameof(IGitRef.LocalName); SetSelectedRevisionByFocusedControl(); })); }); }
private void LoadTagsAsync() { comboBoxTags.Text = Strings.GetLoadingData(); ThreadHelper.JoinableTaskFactory.RunAsync(() => { return(_tagsLoader.LoadAsync( () => Module.GetTagRefs(GitModule.GetTagRefsSortOrder.ByCommitDateDescending).ToList(), list => { comboBoxTags.Text = string.Empty; GitRefsToDataSource(comboBoxTags, list); comboBoxTags.DisplayMember = "LocalName"; SetSelectedRevisionByFocusedControl(); })); }); }
public async Task UpdateAsyncCanRemoveSingleItemFromLoader() { IEnumerable <int> originalItems = new int[] { 1 }; IEnumerable <ItemChange <int> > changes = new ItemChange <int>[] { new ItemChange <int>(ChangeType.Removed, 1) }; var loader = new AsyncLoader <int>( Seq.ListBased, loadDataAsync: tok => Task.FromResult(originalItems), fetchUpdatesAsync: (items, tok) => Task.FromResult(changes)); await loader.LoadAsync(); loader.Should().NotBeEmpty(); // sanity check await loader.UpdateAsync(); // --- Perform --- loader.Should().BeEmpty(); }
public async Task UpdateAsyncDoesNotAddOrRemoveItemsForUpdateItemChange() { IEnumerable <int> originalItems = new int[] { 1 }; IEnumerable <ItemChange <int> > changes = new ItemChange <int>[] { new ItemChange <int>(ChangeType.Updated, 1) }; var loader = new AsyncLoader <int>( Seq.ListBased, loadDataAsync: tok => Task.FromResult(originalItems), fetchUpdatesAsync: (items, tok) => Task.FromResult(changes)); await loader.LoadAsync(); loader.Should().Equal(new[] { 1 }); // sanity check await loader.UpdateAsync(); // --- Perform --- loader.Should().Equal(new[] { 1 }); }
private void LoadFileHistory() { FileChanges.Visible = true; _asyncLoader.LoadAsync(() => BuildFilter(FileName), (filter) => { if (filter == null) { return; } FileChanges.FixedRevisionFilter = filter.RevisionFilter; FileChanges.FixedPathFilter = filter.PathFilter; FileChanges.FiltredFileName = FileName; FileChanges.AllowGraphWithFilter = true; FileChanges.Load(); }); }
private void LoadBranches(string branchType) { cbManageType.Enabled = false; cbBranches.DataSource = new List <string> { _loading.Text }; if (!Branches.ContainsKey(branchType)) { _task.LoadAsync(() => GetBranches(branchType), branches => { Branches.Add(branchType, branches); DisplayBranchData(); }); } else { DisplayBranchData(); } }
public async Task LoadAsyncPreservesItemsAddedDuringLoad() { IEnumerable <int> itemsToLoad = new[] { 2, 3, 4 }; var loadTask = new TaskCompletionSource <IEnumerable <int> >(); var loader = new AsyncLoader <int>(seqFactory: Seq.ListBased, loadDataAsync: tok => loadTask.Task); // --- Perform --- var loadComplete = loader.LoadAsync(); // Will get stuck, waiting for loadTask to complete loader.Conj(1); loader.Should().BeEquivalentTo(new[] { 1 }); // sanity check loadTask.SetResult(itemsToLoad); // complete loading await loadComplete; // wait for LoadAsync to finish loader.Should().BeEquivalentTo(new[] { 1, 2, 3, 4 }); }
public void LoadAsyncDoesNotNotifyOfClearIfEmptyBeforeCall() { IEnumerable <int> loadedItems = new[] { 1 }; var loader = new AsyncLoader <int>( Seq.ListBased, loadDataAsync: tok => Task.FromResult(loadedItems), eventContext: new RunInlineSynchronizationContext()); var listener = Substitute.For <CollectionChangedHandler <int> >(); loader.CollectionChanged += listener; loader.LoadAsync(); // --- Perform --- listener.Received(1).Invoke(loader, Arg.Any <IntChangesAlias>()); }
public async Task UpdateAsyncRetainsOrder() { IEnumerable <int> originalItems = new int[] { 1, 2, 3 }; IEnumerable <ItemChange <int> > changes = new ItemChange <int>[] { new ItemChange <int>(ChangeType.Updated, 2), new ItemChange <int>(ChangeType.Added, 4) }; var loader = new AsyncLoader <int>( Seq.ListBased, loadDataAsync: tok => Task.FromResult(originalItems), fetchUpdatesAsync: (items, tok) => Task.FromResult(changes)); await loader.LoadAsync(); // load original items await loader.UpdateAsync(); // --- Perform --- loader.Should().Equal(new[] { 1, 2, 3, 4 }); }
private void FormCreateWorktree_Load(object sender, EventArgs e) { _initialDirectoryPath = GetWorktreeDirectory(); LoadBranchesAsync(); string GetWorktreeDirectory() { return(UICommands.GitModule.WorkingDir.TrimEnd('\\', '/')); } void LoadBranchesAsync() { var selectedBranch = UICommands.GitModule.GetSelectedBranch(); ExistingBranches = Module.GetRefs(false); comboBoxBranches.Text = Strings.LoadingData; ThreadHelper.JoinableTaskFactory.RunAsync(async() => { await _branchesLoader.LoadAsync( () => ExistingBranches.Where(r => r.Name != selectedBranch).ToList(), list => { comboBoxBranches.Text = string.Empty; comboBoxBranches.DataSource = list; comboBoxBranches.DisplayMember = nameof(IGitRef.LocalName); }); await this.SwitchToMainThreadAsync(); if (comboBoxBranches.Items.Count == 0) { radioButtonCreateNewBranch.Checked = true; radioButtonCheckoutExistingBranch.Enabled = false; } else { radioButtonCheckoutExistingBranch.Checked = true; } ValidateWorktreeOptions(); }); } }
public void Load_performed_on_thread_pool_and_result_handled_via_callers_context() { ThreadHelper.JoinableTaskFactory.Run(async() => { var callerThread = Thread.CurrentThread; Thread loadThread = null; Thread continuationThread = null; Assert.False(callerThread.IsThreadPoolThread); using var loader = new AsyncLoader(); await loader.LoadAsync( () => loadThread = Thread.CurrentThread, () => continuationThread = Thread.CurrentThread); Assert.True(loadThread.IsThreadPoolThread); Assert.AreNotSame(loadThread, callerThread); Assert.AreNotSame(loadThread, continuationThread); }); }
public async Task CollectionChangedHandlerInvokedForTakeAsync() { IEnumerable <int> loadedInts = new[] { 35 }; var loader = new AsyncLoader <int>( Seq.ListBased, loadDataAsync: tok => Task.FromResult(loadedInts), eventContext: new RunInlineSynchronizationContext()); await loader.LoadAsync(); // load initial items var listener = Substitute.For <CollectionChangedHandler <int> >(); loader.CollectionChanged += listener; await loader.TakeAsync(CancellationToken.None); // --- Perform --- listener.Received().Invoke(loader, Fluent.Match <IntChangesAlias>(changes => changes.Should().ContainSingle().Which.ShouldBeEquivalentTo(new ItemChange <int>(ChangeType.Removed, 35)))); }
public void CollectionChangedHandlerInvokedForLoadOfInts() { var loadedItems = new[] { 1, 2, 3 }; var loader = new AsyncLoader <int>( seqFactory: Seq.ListBased, loadDataAsync: t => Task.FromResult(loadedItems.AsEnumerable()), eventContext: new RunInlineSynchronizationContext()); var listener = Substitute.For <CollectionChangedHandler <int> >(); loader.CollectionChanged += listener; loader.LoadAsync(); // --- Perform --- var expectedChanges = loadedItems.Select(i => new ItemChange <int>(ChangeType.Added, i)); listener.Received().Invoke(loader, Fluent.Match <IntChangesAlias>(coll => coll.Should().BeEquivalentTo(expectedChanges))); }
private void LoadFileHistory() { FileChanges.Visible = true; if (string.IsNullOrEmpty(FileName)) { return; } _asyncLoader.LoadAsync( () => BuildFilter(FileName), filter => { var(revisionFilter, pathFilter) = BuildFilter(FileName); FileChanges.FixedRevisionFilter = revisionFilter; FileChanges.FixedPathFilter = pathFilter; FileChanges.FiltredFileName = FileName; FileChanges.AllowGraphWithFilter = true; FileChanges.Load(); }); }
private void LoadFileHistory() { FileChanges.Visible = true; if (string.IsNullOrEmpty(FileName)) { return; } _asyncLoader.LoadAsync( () => BuildFilter(), filter => { FileChanges.SetFilters(filter); FileChanges.Load(); }); return; (string revision, string path) BuildFilter() { var fileName = FileName; // Replace windows path separator to Linux path separator. // This is needed to keep the file history working when started from file tree in // browse dialog. fileName = fileName.ToPosixPath(); // we will need this later to look up proper casing for the file var fullFilePath = _fullPathResolver.Resolve(fileName); // The section below contains native windows (kernel32) calls // and breaks on Linux. Only use it on Windows. Casing is only // a Windows problem anyway. if (EnvUtils.RunningOnWindows() && File.Exists(fullFilePath)) { // grab the 8.3 file path var shortPath = new StringBuilder(4096); NativeMethods.GetShortPathName(fullFilePath, shortPath, shortPath.Capacity); // use 8.3 file path to get properly cased full file path var longPath = new StringBuilder(4096); NativeMethods.GetLongPathName(shortPath.ToString(), longPath, longPath.Capacity); // remove the working directory and now we have a properly cased file name. fileName = longPath.ToString().Substring(Module.WorkingDir.Length).ToPosixPath(); } if (fileName.StartsWith(Module.WorkingDir, StringComparison.InvariantCultureIgnoreCase)) { fileName = fileName.Substring(Module.WorkingDir.Length); } FileName = fileName; var res = (revision : (string)null, path : $" \"{fileName}\""); if (AppSettings.FollowRenamesInFileHistory && !Directory.Exists(fullFilePath)) { // git log --follow is not working as expected (see http://kerneltrap.org/mailarchive/git/2009/1/30/4856404/thread) // // But we can take a more complicated path to get reasonable results: // 1. use git log --follow to get all previous filenames of the file we are interested in // 2. use git log "list of files names" to get the history graph // // note: This implementation is quite a quick hack (by someone who does not speak C# fluently). // var args = new GitArgumentBuilder("log") { "--format=\"%n\"", "--name-only", "--format", GitCommandHelpers.FindRenamesAndCopiesOpts(), "--", fileName.Quote() }; var listOfFileNames = new StringBuilder(fileName.Quote()); // keep a set of the file names already seen var setOfFileNames = new HashSet <string> { fileName }; var lines = Module.GetGitOutputLines(args, GitModule.LosslessEncoding); foreach (var line in lines.Select(GitModule.ReEncodeFileNameFromLossless)) { if (!string.IsNullOrEmpty(line) && setOfFileNames.Add(line)) { listOfFileNames.Append(" \""); listOfFileNames.Append(line); listOfFileNames.Append('\"'); } } // here we need --name-only to get the previous filenames in the revision graph res.path = listOfFileNames.ToString(); res.revision += " --name-only --parents" + GitCommandHelpers.FindRenamesAndCopiesOpts(); } else if (AppSettings.FollowRenamesInFileHistory) { // history of a directory // --parents doesn't work with --follow enabled, but needed to graph a filtered log res.revision = " " + GitCommandHelpers.FindRenamesOpt() + " --follow --parents"; } else { // rename following disabled res.revision = " --parents"; } if (AppSettings.FullHistoryInFileHistory) { res.revision = string.Concat(" --full-history --simplify-merges ", res.revision); } return(res); } }