public void setString(string text) { DispatcherHelpers.RunOnDispatcher(new Action(() => { _clipboard.SetText(text); })); }
public async void getSize(string uriString, IPromise promise) { if (string.IsNullOrEmpty(uriString)) { promise.Reject(ErrorInvalidUri, "Cannot get the size of an image for an empty URI."); return; } using (var reference = _imageCache.Get(uriString)) { try { await reference.LoadedObservable.FirstAsync().ToTask().ConfigureAwait(false); DispatcherHelpers.RunOnDispatcher(() => promise.Resolve(new JObject { { "width", reference.Image.PixelWidth }, { "height", reference.Image.PixelHeight }, })); } catch (ImageFailedException ex) { promise.Reject(ErrorGetSizeFailure, ex.Message); } } }
/// <summary> /// Called before a <see cref="IReactInstance"/> is disposed. /// </summary> public override Task OnReactInstanceDisposeAsync() { DispatcherHelpers.RunOnDispatcher(_uiImplementation.OnDestroy); _eventDispatcher.OnReactInstanceDispose(); // return Task.CompletedTask; return(Net46.Net45.Task.CompletedTask); }
public void prefetchImage(string uriString, int requestId, IPromise promise) { if (string.IsNullOrEmpty(uriString)) { promise.Reject(ErrorInvalidUri, "Cannot prefetch an image for an empty URI."); return; } DispatcherHelpers.RunOnDispatcher(async() => { try { var uri = new Uri(uriString); await _prefetchRequests.AddAndInvokeAsync( requestId, async token => await ImageCache.Instance.PreCacheAsync(uri, true, true, token).ConfigureAwait(false)) .ConfigureAwait(false); promise.Resolve(true); } catch (Exception ex) { promise.Reject(ErrorPrefetchFailure, ex.Message); } }); }
private async Task TearDownReactContextAsync(ReactContext reactContext, CancellationToken token) { RnLog.Info(ReactConstants.RNW, $"ReactInstanceManager: Tearing down React context - entry"); token.ThrowIfCancellationRequested(); DispatcherHelpers.AssertOnDispatcher(); _lifecycleStateMachine.SetContext(null); // Existing root views should be silenced before tearing down the context. // Most of the work is done by the tearing down of the context itself, yet the native root views continue to exist, // so things like "size changes" or touch handling should be stopped immediately. foreach (var rootView in _attachedRootViews) { // Inlining allowed DispatcherHelpers.RunOnDispatcher(rootView.Dispatcher, () => { rootView.RemoveSizeChanged(); rootView.StopTouchHandling(); }, true); } await reactContext.DisposeAsync(); _devSupportManager.OnReactContextDestroyed(reactContext); // TODO: add memory pressure hooks RnLog.Info(ReactConstants.RNW, $"ReactInstanceManager: Tearing down React context - done"); }
/// <summary> /// Adds a root view to the hierarchy. /// </summary> /// <param name="tag">The root view tag.</param> /// <param name="rootView">The root view.</param> /// <param name="themedRootContext">The React context.</param> public void AddRootView( int tag, SizeMonitoringCanvas rootView, ThemedReactContext themedRootContext) { // This is called on layout manager thread // Extract dispatcher var rootViewDispatcher = rootView.Dispatcher; // _dispatcherToOperationQueueInfo contains a mapping of CoreDispatcher to <UIViewOperationQueueInstance, # of ReactRootView instances>. // Operation queue instances are created lazily whenever an "unknown" CoreDispatcher is detected. Each operation queue instance // works together with one dedicated NativeViewHierarchyManager and one ReactChoreographer. // One operation queue is the "main" one: // - is coupled with the CoreApplication.MainView dispatcher // - drives animations in ALL views QueueInstanceInfo queueInfo; if (!_dispatcherToOperationQueueInfo.TryGetValue(rootViewDispatcher, out queueInfo)) { // Queue instance doesn't exist for this dispatcher, we need to create // Find the CoreApplicationView associated to the new CoreDispatcher CoreApplicationView foundView = CoreApplication.Views.First(v => v.Dispatcher == rootViewDispatcher); // Create new ReactChoreographer for this view/dispatcher. It will only be used for its DispatchUICallback services ReactChoreographer reactChoreographer = ReactChoreographer.CreateSecondaryInstance(foundView); queueInfo = new QueueInstanceInfo() { queueInstance = new UIViewOperationQueueInstance( _reactContext, new NativeViewHierarchyManager(_viewManagerRegistry, rootViewDispatcher, OnViewsDropped), reactChoreographer), rootViewCount = 1 }; // Add new tuple to map _dispatcherToOperationQueueInfo.Add(rootViewDispatcher, queueInfo); if (_active) { // Simulate an OnResume from the correct dispatcher thread // (OnResume/OnSuspend/OnDestroy have this thread affinity, all other methods do enqueuings in a thread safe manner) DispatcherHelpers.RunOnDispatcher(rootViewDispatcher, queueInfo.queueInstance.OnResume, true); // inlining allowed } } else { // Queue instance does exist. // Increment the count of root views. This is helpful for the case the count reaches 0 so we can cleanup the queue. queueInfo.rootViewCount++; } // Add tag _reactTagToOperationQueue.Add(tag, queueInfo.queueInstance); // Send forward queueInfo.queueInstance.AddRootView(tag, rootView, themedRootContext); }
public void getString(IPromise promise) { if (promise == null) { throw new ArgumentNullException(nameof(promise)); } DispatcherHelpers.RunOnDispatcher(() => { try { if (_clipboard.ContainsText()) { var text = _clipboard.GetText(); promise.Resolve(text); } else { promise.Resolve(""); } } catch (Exception ex) { promise.Reject(ex); } }); }
private void ShowNewError(string message, IStackFrame[] stack, int errorCookie) { DispatcherHelpers.RunOnDispatcher(() => { if (_redBoxDialog == null) { _redBoxDialog = new RedBoxDialog(HandleReloadJavaScript); } if (_redBoxDialogOpen) { return; } _redBoxDialogOpen = true; _redBoxDialog.ErrorCookie = errorCookie; _redBoxDialog.Message = message; _redBoxDialog.StackTrace = stack; _redBoxDialog.Closed += (_, __) => { _redBoxDialogOpen = false; _dismissRedBoxDialog = null; _redBoxDialog = null; }; var asyncInfo = _redBoxDialog.ShowAsync(); _dismissRedBoxDialog = asyncInfo.Cancel; }); }
private async Task ReloadJavaScriptFromServerAsync(Action dismissProgress, CancellationToken token) { var localFolder = ApplicationData.Current.LocalFolder; var localFile = await localFolder.CreateFileAsync(JSBundleFileName, CreationCollisionOption.ReplaceExisting); using (var stream = await localFile.OpenStreamForWriteAsync()) { try { await _devServerHelper.DownloadBundleFromUrlAsync(_jsAppBundleName, stream, token); dismissProgress(); DispatcherHelpers.RunOnDispatcher(_reactInstanceCommandsHandler.OnJavaScriptBundleLoadedFromServer); } catch (DebugServerException ex) { dismissProgress(); ShowNewNativeError(ex.Message, ex); } catch (Exception ex) { dismissProgress(); ShowNewNativeError( "Unable to download JS bundle. Did you forget to " + "start the development server or connect your device?", ex); } } }
public void showAlert( JObject config, ICallback errorCallback, ICallback actionCallback) { var message = config.Value <string>("message") ?? ""; var title = config.Value <string>("title") ?? ""; var buttons = new List <string>(); if (config.ContainsKey(DialogModuleHelper.KeyButtonPositive)) { buttons.Add(config.Value <string>(DialogModuleHelper.KeyButtonPositive)); } if (config.ContainsKey(DialogModuleHelper.KeyButtonNegative)) { buttons.Add(config.Value <string>(DialogModuleHelper.KeyButtonNegative)); } if (config.ContainsKey(DialogModuleHelper.KeyButtonNeutral)) { buttons.Add(config.Value <string>(DialogModuleHelper.KeyButtonNeutral)); } //Run in UI Thread DispatcherHelpers.RunOnDispatcher(() => { _dialog.showDialog(title, message, buttons, actionCallback); }); }
/// <summary> /// Start the bundle change polling service. /// </summary> /// <param name="onServerContentChanged"> /// Callback for when the bundle content changes. /// </param> /// <returns>A disposable to use to stop polling.</returns> public IDisposable StartPollingOnChangeEndpoint(Action onServerContentChanged) { var disposable = new CancellationDisposable(); var task = ThreadPool.RunAsync(async _ => { var onChangePollingClient = new HttpClient(); onChangePollingClient.DefaultRequestHeaders.Connection.Add("keep-alive"); while (!disposable.IsDisposed) { var onChangeUrl = CreateOnChangeEndpointUrl(DebugServerHost); try { using (var response = await onChangePollingClient.GetAsync(onChangeUrl, disposable.Token)) { if (response.StatusCode == HttpStatusCode.ResetContent) { DispatcherHelpers.RunOnDispatcher(new DispatchedHandler(onServerContentChanged)); } } } catch { await Task.Delay(LongPollFailureDelayMs); } } }); return(disposable); }
public void Show() { DispatcherHelpers.RunOnDispatcher(() => { _popup.SetContent(_box); _popup.Show(); _box.PackEnd(_label); _box.PackEnd(_entry); _box.PackEnd(_button); _box.Show(); _label.Show(); _entry.Show(); _button.Show(); _label.AlignmentX = 0.5; _label.AlignmentY = 0.25; _label.WeightX = 1; _label.WeightY = 1; _entry.AlignmentX = 0.5; _entry.AlignmentY = 0.5; _entry.WeightX = 1; _entry.WeightY = 1; _button.AlignmentX = 0.5; _button.AlignmentY = 0.65; _button.WeightX = 1; _button.WeightY = 1; }); }
/// <summary> /// Detaches a root view from the size monitoring hooks in preparation for the unmount /// </summary> /// <param name="rootView">The root view instance.</param> public void DetachRootView(ReactRootView rootView) { // Called on main dispatcher thread DispatcherHelpers.AssertOnDispatcher(); DispatcherHelpers.RunOnDispatcher(rootView.Dispatcher, () => rootView.RemoveSizeChanged(), true); // allow inlining }
public void fAppend(int refId, string base64String, IPromise promise) { DispatcherHelpers.RunOnDispatcher(() => { Task.Run(() => { try { FileWrapper fileWrapper; if (!files.TryGetValue(refId, out fileWrapper)) { throw new Exception("Invalid refId"); } FileStream fileStream = fileWrapper.fileStream; if (!fileStream.CanWrite) { throw new Exception("File is not writable"); } byte[] content = Convert.FromBase64String(base64String); fileStream.Write(content, 0, content.Length); fileStream.Flush(); promise.Resolve(null); } catch (Exception e) { promise.Reject(ERROR_FATAL, e); } }); }); }
public void filePicker(string[] fileTypes, IPromise promise) { DispatcherHelpers.RunOnDispatcher(async() => { FileOpenPicker openPicker = new FileOpenPicker(); openPicker.ViewMode = PickerViewMode.Thumbnail; openPicker.SuggestedStartLocation = PickerLocationId.PicturesLibrary; foreach (string fileType in fileTypes) { openPicker.FileTypeFilter.Add(fileType); } StorageFile file = await openPicker.PickSingleFileAsync(); if (file != null) { StorageFile localFile = await getStorageFolder().CreateFileAsync(file.FolderRelativeId, CreationCollisionOption.ReplaceExisting); await file.CopyAndReplaceAsync(localFile); var jObject = await getFileInfo(localFile); promise.Resolve(jObject); } else { promise.Reject(ERROR_NO_DATA, "Operation cancelled."); } }); }
public void fRead(int refId, string offset, int limit, IPromise promise) { DispatcherHelpers.RunOnDispatcher(() => { Task.Run(() => { try { FileWrapper fileWrapper; if (!files.TryGetValue(refId, out fileWrapper)) { throw new Exception("Invalid refId"); } FileStream fileStream = fileWrapper.fileStream; if (!fileStream.CanRead) { throw new Exception("File is not readable"); } byte[] buffer = new byte[limit]; fileStream.Seek(Convert.ToInt64(offset), SeekOrigin.Begin); fileStream.Read(buffer, 0, limit); promise.Resolve(Convert.ToBase64String(buffer)); } catch (Exception e) { promise.Reject(ERROR_FATAL, e); } }); }); }
/// <summary> /// Enqueues an operation to remove the root view. /// </summary> /// <param name="rootViewTag">The root view tag.</param> public void EnqueueRemoveRootView(int rootViewTag) { // Called on layout manager thread UIViewOperationQueueInstance queue = GetQueueByTag(rootViewTag); // Send forward queue.EnqueueRemoveRootView(rootViewTag); // Do some maintenance/cleanup if needed. // Find the queue info var pair = _dispatcherToOperationQueueInfo.First(p => p.Value.queueInstance == queue); // Decrement number of root views pair.Value.rootViewCount--; if (queue != MainUIViewOperationQueue) { if (pair.Value.rootViewCount == 0) { // We can remove this queue and then destroy _dispatcherToOperationQueueInfo.Remove(pair.Key); // Simulate an OnDestroy from the correct dispatcher thread // (OnResume/OnSuspend/OnDestroy have this thread affinity, all other methods do enqueuings in a thread safe manner) DispatcherHelpers.RunOnDispatcher(pair.Key, queue.OnDestroy); } } }
public void AddLicense(string license) { DispatcherHelpers.RunOnDispatcher(new Action(() => { EO.WebBrowser.Runtime.AddLicense(license); })); }
public void getSize(string uriString, IPromise promise) { if (string.IsNullOrEmpty(uriString)) { promise.Reject(ErrorInvalidUri, "Cannot get the size of an image for an empty URI."); return; } DispatcherHelpers.RunOnDispatcher(async() => { try { var bitmapImage = await ImageCache.Instance.GetFromCacheAsync(new Uri(uriString), true); promise.Resolve(new JObject { { "width", bitmapImage.PixelWidth }, { "height", bitmapImage.PixelHeight }, }); } catch (Exception ex) { promise.Reject(ErrorGetSizeFailure, ex.Message); } }); }
/// <summary> /// Activate the callback for the given key. /// </summary> /// <param name="callbackKey">The callback key.</param> public void ActivateCallback(string callbackKey) { bool subscribe; lock (_gate) { var isSubscribed = Volatile.Read(ref _isSubscribed); var isSubscribing = Volatile.Read(ref _isSubscribing); subscribe = _isSubscribing = _callbackKeys.Add(callbackKey) && _callbackKeys.Count == 1 && !isSubscribed && !isSubscribing; } if (subscribe) { DispatcherHelpers.RunOnDispatcher( ActivatePriority, () => { lock (_gate) { Subscribe(); _isSubscribing = false; } }); } }
public void Add(DevOptionHandler option) { DispatcherHelpers.RunOnDispatcher(() => { Log.Info(ReactConstants.Tag, "Add item:" + option.Name); _list.Append(defaultClass, option); }); }
/// <summary> /// Called when the host is shutting down. /// </summary> public void OnDestroy() { _active = false; foreach (var pair in _dispatcherToOperationQueueInfo) { // Simulate an OnDestroy from the correct dispatcher thread // (OnResume/OnSuspend/OnDestroy have this thread affinity, all other methods do enqueuings in a thread safe manner) DispatcherHelpers.RunOnDispatcher(pair.Key, pair.Value.queueInstance.OnDestroy, true); // inlining allowed } }
public async void HandleException(Exception exception) { #if WINDOWS_UWP await CoreApplication.MainView.CoreWindow.Dispatcher.RunAsync(CoreDispatcherPriority.High, () => { ExceptionDispatchInfo.Capture(exception).Throw(); }).AsTask().ConfigureAwait(false); #else DispatcherHelpers.RunOnDispatcher(() => ExceptionDispatchInfo.Capture(exception).Throw()); #endif }
public void Show() { DispatcherHelpers.RunOnDispatcher(() => { _popup.Show(); //_conformant.Show(); //_list.Show(); _popup.SetContent(_list); Log.Info(ReactConstants.Tag, "_list.show"); }); }
public void Close() { DispatcherHelpers.RunOnDispatcher(() => { //_list.Hide(); _popup.Hide(); //_conformant.Hide(); _list.Clear(); Closed?.Invoke(this, null); }); }
public void OpenFilePicker() { DispatcherHelpers.RunOnDispatcher(async() => { var file = await PickPDF(); if (file != null) { await LoadFileAsync(file); } }); }
public void Close() { DispatcherHelpers.RunOnDispatcher(() => { if (scrollBox != null) { scrollBox.Hide(); scrollBox.Unrealize(); scrollBox = null; } if (scroller != null) { scroller.Hide(); scroller.Unrealize(); scroller = null; } if (background != null) { background.Hide(); background.Unrealize(); background = null; } if (reloadBtn != null) { reloadBtn.Hide(); reloadBtn.Unrealize(); reloadBtn = null; } if (reloadBg != null) { reloadBg.Hide(); reloadBg.Unrealize(); reloadBg = null; } if (redboxTitle != null) { redboxTitle.Hide(); redboxTitle.Unrealize(); redboxTitle = null; } if (labelList != null) { foreach (var item in labelList) { item.Hide(); item.Unrealize(); } labelList.Clear(); labelList = null; } Closed?.Invoke(this, null); }); }
public void Close() { DispatcherHelpers.RunOnDispatcher(() => { _label.Hide(); _box.Hide(); _entry.Hide(); _button.Hide(); _popup.Hide(); Closed?.Invoke(this, null); }); }
public void getSize(string uriString, IPromise promise) { if (string.IsNullOrEmpty(uriString)) { promise.Reject(ErrorInvalidUri, "Cannot get the size of an image for an empty URI."); return; } DispatcherHelpers.RunOnDispatcher(async() => { try { if (BitmapImageHelpers.IsHttpUri(uriString)) { var bitmapImage = await ImageCache.Instance.GetFromCacheAsync(new Uri(uriString), true); promise.Resolve(new JObject { { "width", bitmapImage.PixelWidth }, { "height", bitmapImage.PixelHeight }, }); } else { var bitmapImage = new BitmapImage(); var loadQuery = bitmapImage.GetStreamLoadObservable() .Where(status => status.LoadStatus == ImageLoadStatus.OnLoadEnd) .FirstAsync() .Replay(1); using (loadQuery.Connect()) { using (var stream = await BitmapImageHelpers.GetStreamAsync(uriString)) { await bitmapImage.SetSourceAsync(stream); } await loadQuery; promise.Resolve(new JObject { { "width", bitmapImage.PixelWidth }, { "height", bitmapImage.PixelHeight }, }); } } } catch (Exception ex) { promise.Reject(ErrorGetSizeFailure, ex.Message); } }); }
public void setString(string text) { DispatcherHelpers.RunOnDispatcher(new Action(() => { try { _clipboard.SetText(text); } catch (Exception) { // Ignored } })); }