示例#1
0
 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);
 }
示例#4
0
        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");
        }
示例#6
0
        /// <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);
                }
            }
        }
示例#10
0
        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);
            });
        }
示例#11
0
        /// <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);
        }
示例#12
0
        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
        }
示例#14
0
        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);
                    }
                });
            });
        }
示例#15
0
        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.");
                }
            });
        }
示例#16
0
        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);
     }));
 }
示例#19
0
        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);
                }
            });
        }
示例#20
0
        /// <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);
     });
 }
示例#22
0
 /// <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);
     });
 }
示例#26
0
 public void OpenFilePicker()
 {
     DispatcherHelpers.RunOnDispatcher(async() =>
     {
         var file = await PickPDF();
         if (file != null)
         {
             await LoadFileAsync(file);
         }
     });
 }
示例#27
0
 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);
     });
 }
示例#28
0
 public void Close()
 {
     DispatcherHelpers.RunOnDispatcher(() =>
     {
         _label.Hide();
         _box.Hide();
         _entry.Hide();
         _button.Hide();
         _popup.Hide();
         Closed?.Invoke(this, null);
     });
 }
示例#29
0
        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
         }
     }));
 }