private void DeviceRemoved(object sender, RPlotDeviceEventArgs e) { _shell.DispatchOnUIThread(() => { RemoveAll(e.Device.DeviceId); }); UnsubscribeDeviceEvents(e.Device); }
private void DeviceLocatorModeChanged(object sender, RPlotDeviceEventArgs e) { _shell.DispatchOnUIThread(() => { LocatorMode = e.Device.LocatorMode; LocatorModeChanged?.Invoke(this, EventArgs.Empty); }); }
private int Search(IList <IRPackageViewModel> packages, string searchString, CancellationToken cancellationToken) { if (string.IsNullOrEmpty(searchString)) { _coreShell.DispatchOnUIThread(() => ApplySearch(packages, cancellationToken)); return(packages.Count); } var filteredPackages = new List <IRPackageViewModel>(); foreach (var package in packages) { if (cancellationToken.IsCancellationRequested) { return(filteredPackages.Count); } if (package.Name.StartsWithIgnoreCase(searchString)) { filteredPackages.Add(package); } } _coreShell.DispatchOnUIThread(() => ApplySearch(filteredPackages, cancellationToken)); return(filteredPackages.Count); }
private void ViewModel_LocatorModeChanged(object sender, EventArgs e) { _shell.DispatchOnUIThread(() => { UpdateCaption(); UpdateStatus(); }); }
private void SessionOnAfterRequest(object sender, RAfterRequestEventArgs e) { if (_evaluatorRequest.Count == 0 && e.AddToHistory && e.IsVisible) { _coreShell.DispatchOnUIThread(() => { if (CurrentWindow == null || CurrentWindow.IsResetting) { return; } ((IInteractiveWindow2)CurrentWindow).AddToHistory(e.Request.TrimEnd()); History.AddToHistory(e.Request); }); } }
private void ConnectionStateChanged(object sender, ConnectionEventArgs e) { _shell.DispatchOnUIThread(() => { IsConnected = e.State; UpdateConnections(); }); }
public ConnectionManager(IStatusBar statusBar, IRSessionProvider sessionProvider, IRSettings settings, IRInteractiveWorkflow interactiveWorkflow) { _statusBar = statusBar; _sessionProvider = sessionProvider; _brokerConnector = interactiveWorkflow.BrokerConnector; _settings = settings; _shell = interactiveWorkflow.Shell; _statusBarViewModel = new ConnectionStatusBarViewModel(this, interactiveWorkflow.Shell); _disposableBag = DisposableBag.Create <ConnectionManager>() .Add(_statusBarViewModel) .Add(() => _brokerConnector.BrokerChanged -= BrokerChanged) .Add(() => interactiveWorkflow.RSession.Connected -= RSessionOnConnected) .Add(() => interactiveWorkflow.RSession.Disconnected -= RSessionOnDisconnected); _brokerConnector.BrokerChanged += BrokerChanged; // TODO: Temporary solution - need to separate RHost errors and network connection issues interactiveWorkflow.RSession.Connected += RSessionOnConnected; interactiveWorkflow.RSession.Disconnected += RSessionOnDisconnected; _shell.DispatchOnUIThread(() => _disposableBag.Add(_statusBar.AddItem(new ConnectionStatusBar { DataContext = _statusBarViewModel }))); // Get initial values var connections = GetConnectionsFromSettings(); _connections = new ConcurrentDictionary <Uri, IConnection>(connections); UpdateRecentConnections(); SwitchBrokerToLastConnection(); }
private void ConnectionStateChanged(object sender, ConnectionEventArgs e) { _shell.DispatchOnUIThread(() => { IsConnected = e.State; IsRemote = e.Connection?.IsRemote ?? false; SelectedConnection = e.Connection?.Name; }); }
private void LastActiveTextViewChanged(object sender, ActiveTextViewChangedEventArgs e) { if (ActiveWindow == null) { return; } if (ActiveWindow.TextView.Equals(e.Old) && !ActiveWindow.TextView.Equals(e.New)) { _replLostFocus = true; _coreShell.DispatchOnUIThread(CheckPossibleBreakModeFocusChange); } if (ActiveWindow.TextView.Equals(e.New)) { _coreShell.DispatchOnUIThread(Operations.PositionCaretAtPrompt); } }
public Task <string> ReadUserInput(string prompt, int maximumLength, CancellationToken ct) { _coreShell.DispatchOnUIThread(() => _interactiveWindow.Write(prompt)); return(Task.Run(() => { using (var reader = _interactiveWindow.ReadStandardInput()) { return reader != null ? Task.FromResult(reader.ReadToEnd()) : Task.FromResult("\n"); } }, ct)); }
private void ConnectionStateChanged(object sender, ConnectionEventArgs e) { _shell.DispatchOnUIThread(() => { IsConnected = e.State; foreach (var item in _items) { item.IsConnected = e.State && item.IsActive; } }); }
private void SaveActiveConnectionToSettings() { _shell.DispatchOnUIThread(() => _settings.LastActiveConnection = ActiveConnection == null ? null : new ConnectionInfo { Name = ActiveConnection.Name, Path = ActiveConnection.Path, RCommandLineArguments = ActiveConnection.RCommandLineArguments }); }
private void SessionOnBeforeRequest(object sender, RRequestEventArgs e) { _coreShell.DispatchOnUIThread(() => { if (CurrentWindow == null || CurrentWindow.IsRunning) { return; } var projectionBuffer = CurrentWindow.TextView.TextBuffer as IProjectionBuffer; if (projectionBuffer == null) { return; } var spanCount = projectionBuffer.CurrentSnapshot.SpanCount; projectionBuffer.ReplaceSpans(spanCount - 2, 1, new List <object> { GetPrompt() }, EditOptions.None, new object()); }); }
/// <summary> /// Fetches help on the function from R asynchronously. /// When function data is obtained, parsed and the function /// index is updated, method invokes <see cref="infoReadyCallback"/> /// callback passing the specified parameter. Callback method can now /// fetch function information from the index. /// </summary> private async Task <string> GetFunctionInfoFromEngineAsync(string functionName, string packageName, Action <object, string> infoReadyCallback = null, object parameter = null) { packageName = packageName ?? await _host.GetFunctionPackageNameAsync(functionName); if (string.IsNullOrEmpty(packageName)) { // Even if nothing is found, still notify the callback if (infoReadyCallback != null) { _coreShell.DispatchOnUIThread(() => { infoReadyCallback(null, null); }); } return(packageName); } if (infoReadyCallback == null) { // regular async call var rdData = await _functionRdDataProvider.GetFunctionRdDataAsync(functionName, packageName); if (!string.IsNullOrEmpty(rdData)) { // If package is found update data in the index UpdateIndex(functionName, packageName, rdData); } return(packageName); } _functionRdDataProvider.GetFunctionRdDataAsync(functionName, packageName, rdData => { if (!string.IsNullOrEmpty(packageName) && !string.IsNullOrEmpty(rdData)) { // If package is found update data in the index UpdateIndex(functionName, packageName, rdData); } _coreShell.DispatchOnUIThread(() => infoReadyCallback(parameter, packageName)); }); return(packageName); }
public bool ProcessMessage(string message) { // Note: DispatchOnUIThread is expensive, and can saturate the message pump when there's a lot of output, // making UI non-responsive. So avoid using it unless we need it - and we only need it for FlushOutput, // and we only need it to handle CR. if (message.Length > 1 && message[0] == '\r' && message[1] != '\n') { _coreShell.DispatchOnUIThread(() => { // Make sure output buffer is up to date _interactiveWindow.FlushOutput(); // If message starts with CR we remember current output buffer // length so we can continue writing lines into the same spot. // See txtProgressBar in R. // Store the message and the initial position. All subsequent // messages that start with CR will be written into the same place. if (_messagePos != null) { ProcessReplacement(); } // Locate last end of line var snapshot = _interactiveWindow.OutputBuffer.CurrentSnapshot; var line = snapshot.GetLineFromPosition(snapshot.Length); var text = message.Substring(1); _messagePos = new MessagePos() { Text = text, Position = line.Start, PlaceholderLength = text.Length + 8 // buffer for, say, '| 100%' }; // It is important that replacement matches original text length // since interactive window creates fixed colorized spans for errors // and replacement of text by a text with a different length // causes odd changes in color - word may appear partially in // black and partially in red. // Replacement placeholder so we can receive 'buffer changed' event // Placeholder is whitespace that is as long as original message plus // few more space to account for example, for 0% - 100% when CR is used // to display ASCII progress. var placeholder = new string(' ', _messagePos.PlaceholderLength); _interactiveWindow.Write(placeholder); _interactiveWindow.FlushOutput(); // Must flush so we do get 'buffer changed' immediately. }); return(true); } return(false); }
/// <summary> /// Fetches help on the function from R asynchronously. /// When function data is obtained, parsed and the function /// index is updated, method invokes <see cref="infoReadyCallback"/> /// callback passing the specified parameter. Callback method can now /// fetch function information from the index. /// </summary> private void GetFunctionInfoFromEngineAsync(string functionName, string packageName, Action <object> infoReadyCallback = null, object parameter = null) { _functionRdDataProvider.GetFunctionRdDataAsync(functionName, packageName, rdData => { UpdateIndex(functionName, rdData); if (infoReadyCallback != null) { _coreShell.DispatchOnUIThread(() => { infoReadyCallback(parameter); }); } }); }
private async Task EnsureAvailablePackagesLoadedAsync() { var availablePackagesLoaded = await _availableLock.WaitAsync(); try { if (!availablePackagesLoaded) { await LoadAvailablePackagesAsync(); } } catch (RPackageManagerException ex) { _coreShell.DispatchOnUIThread(() => AddErrorMessage(ex.Message)); } finally { _availableLock.Release(); } }
private void OnHostLoadChanged(object sender, HostLoadChangedEventArgs e) { _shell.DispatchOnUIThread(() => { CpuLoad = e.HostLoad.CpuLoad; MemoryLoad = e.HostLoad.MemoryLoad; NetworkLoad = e.HostLoad.NetworkLoad; Tooltip = string.Format(CultureInfo.InvariantCulture, Resources.HostLoad_Tooltip, (int)Math.Round(100 * CpuLoad), (int)Math.Round(100 * MemoryLoad), (int)Math.Round(100 * NetworkLoad)); }); }
public Task <LocatorResult> StartLocatorModeAsync(Guid deviceId, CancellationToken cancellationToken) { var device = FindDevice(deviceId); device.LocatorMode = true; _locatorTcs = new TaskCompletionSource <LocatorResult>(); _locatorCancelTokenRegistration = cancellationToken.Register(() => CancelLocatorMode(device)); _shell.DispatchOnUIThread(() => { var visualComponent = GetVisualComponentForDevice(deviceId); visualComponent?.Container.Show(focus: false, immediate: true); }); return(_locatorTcs.Task); }
private void Refresh(IRPlot plot) { _shell.DispatchOnUIThread(() => { if (plot != null) { PlotImage = plot.Image; ShowWatermark = false; ShowError = plot.Image == null; } else { PlotImage = null; ShowWatermark = true; ShowError = false; } DeviceNameChanged?.Invoke(this, EventArgs.Empty); PlotChanged?.Invoke(this, EventArgs.Empty); }); }
private void FileWatcherError(object sender, EventArgs args) { _fileWatcher.Error -= FileWatcherError; _coreShell.DispatchOnUIThread(() => { foreach (var iVsProjectLazy in _cpsIVsProjects) { IVsProject iVsProject; try { iVsProject = iVsProjectLazy.Value; } catch (Exception) { continue; } if (iVsProject.AsUnconfiguredProject() != _unconfiguredProject) { continue; } var solution = VsAppShell.Current.GetGlobalService <IVsSolution>(typeof(SVsSolution)); solution.CloseSolutionElement((uint)__VSSLNCLOSEOPTIONS.SLNCLOSEOPT_UnloadProject, (IVsHierarchy)iVsProject, 0); return; } }); }
private void OnBrokerChanged(object sender, BrokerStateChangedEventArgs e) { _shell.DispatchOnUIThread(() => UpdateWindowTitle(e.IsConnected)); }
/// <summary> /// Main asyncronous task body /// </summary> void ProcessTextChanges(TextChange changeToProcess, bool async, Func <bool> isCancelledCallback) { lock (_disposeLock) { if (_editorTree == null || _disposed || isCancelledCallback()) { return; } EditorTreeChangeCollection treeChanges = null; // Cache id since it can change if task is canceled long taskId = TaskId; try { AstRoot rootNode; // We only need read lock since changes will be applied // from the main thread if (async) { rootNode = _editorTree.AcquireReadLock(_treeUserId); } else { rootNode = _editorTree.GetAstRootUnsafe(); } treeChanges = new EditorTreeChangeCollection(changeToProcess.Version, changeToProcess.FullParseRequired); TextChangeProcessor changeProcessor = new TextChangeProcessor(_editorTree, rootNode, isCancelledCallback); bool fullParseRequired = changeToProcess.FullParseRequired; if (fullParseRequired) { changeProcessor.FullParse(treeChanges, changeToProcess.NewTextProvider); } else { changeProcessor.ProcessChange(changeToProcess, treeChanges); } } finally { if (async && _editorTree != null) { _editorTree.ReleaseReadLock(_treeUserId); } } // Lock should be released at this point since actual application // of tree changes is going to be happen from the main thread. if (!isCancelledCallback() && treeChanges != null) { // Queue results for the main thread application. This must be done before // signaling that the task is complete since if EnsureProcessingComplete // is waiting it will want to apply changes itself rather than wait for // the DispatchOnUIThread to go though and hence it will need all changes // stored and ready for application. _backgroundParsingResults.Enqueue(treeChanges); } // Signal task complete now so if main thread is waiting // it can proceed and appy the changes immediately. SignalTaskComplete(taskId); if (_backgroundParsingResults.Count > 0) { _uiThreadTransitionRequestTime = DateTime.UtcNow; // It is OK to post results while main thread might be working // on them since if if it does, by the time posted request comes // queue will already be empty. if (async) { // Post request to apply tree changes to the main thread. // This must NOT block or else task will never enter 'RanToCompletion' state. _shell.DispatchOnUIThread(ApplyBackgroundProcessingResults); } else { // When processing is synchronous, apply changes and fire events right away. ApplyBackgroundProcessingResults(); } } } }
private void SaveActiveConnectionToSettings() { _shell.DispatchOnUIThread(() => _settings.LastActiveConnection = ActiveConnection == null ? null : new ConnectionInfo(ActiveConnection)); }
public void Write(string text) { _coreShell.DispatchOnUIThread(() => _workflowLazy.Value.ActiveWindow?.InteractiveWindow?.WriteErrorLine(text)); }