/// <summary>
    /// Data binding method.
    /// </summary>
    /// <typeparam name="TView">View type</typeparam>
    /// <typeparam name="TProperty">Property type</typeparam>
    /// <param name="self">View</param>
    /// <param name="propertySelector">Target property selector</param>
    /// <param name="source">Source property</param>
    /// <param name="updateSourceTrigger">Update source trigger</param>
    /// <returns>Data binding token</returns>
    public static IDisposable SetBinding <TView, TProperty>(
        this TView self,
        Expression <Func <TView, TProperty> > propertySelector,
        IReactiveProperty <TProperty> source, Func <TView, IObservable <Unit> > updateSourceTrigger = null)
        where TView : View
    {
        var d = new CompositeDisposable();

        var isUpdating = false;
        var setter     = AccessorCache <TView> .LookupSet(propertySelector, out var propertyName);

        source
        .Where(_ => !isUpdating)
        .Subscribe(x => setter(self, x))
        .AddTo(d);
        if (updateSourceTrigger != null)
        {
            var getter = AccessorCache <TView> .LookupGet(propertySelector, out propertyName);

            updateSourceTrigger(self).Subscribe(_ =>
            {
                isUpdating = true;
                try
                {
                    source.Value = getter(self);
                }
                finally
                {
                    isUpdating = false;
                }
            }).AddTo(d);
        }

        return(d);
    }
Exemplo n.º 2
0
        public static IDisposable BindTwoWayTo <TSource, TTarget>(this IReactiveProperty <TSource> This, IReactiveProperty <TTarget> target)
        {
            if (This == null || target == null)
            {
                return(Disposable.Empty);
            }

            bool isUpdating = false;

            return(new CompositeDisposable(
                       This
                       .Where(_ => !isUpdating)
                       .Subscribe(x =>
            {
                isUpdating = true;
                target.Value = (TTarget)(object)x;
                isUpdating = false;
            }),
                       target
                       .Where(_ => !isUpdating)
                       .Subscribe(x =>
            {
                isUpdating = true;
                This.Value = (TSource)(object)x;
                isUpdating = false;
            })));
        }
        protected override void Awake()
        {
            base.Awake();

            Debug.Log($"DialogueConversationController: Loaded {m_Sprites.Length} sprite(s).");

            // When a text phase event is processed from the dialogue system and it didn't have choices, this will post
            // a delayed dialogue continuation to make it look like the other person was typing. Posts the length
            // of the output for the purposes of making an appropriate delay.
            var lastChoice = -1;
            CompositeDisposable subscriptions = null;

            m_ChatBoxController.choices
            .Subscribe(choice => { lastChoice = choice.index; })
            .AddTo(this);

            profile
            .Where(item => item != null)
            .Subscribe(item =>
            {
                m_DatingProfileView.data = item;
                m_ConversationController.conversantName = profile.Value.name;
            })
            .AddTo(this);

            selectedDialogue
            .StartWith((DialogueItem)null)
            .Pairwise()
            .Subscribe(dialogues =>
            {
                var oldDialogue = dialogues.Previous;
                var newDialogue = dialogues.Current;
                if (oldDialogue == newDialogue || newDialogue == null)
                {
                    return;
                }

                subscriptions?.Dispose();
                subscriptions = ResumeStory(newDialogue, oldDialogue);

                AnalyticsEvent.Custom("chat_with", new Dictionary <string, object>()
                {
                    { "on_profile", profile.Value?.name }
                });
                var eventHitBuilder1 = new EventHitBuilder()
                                       .SetEventCategory("conversation")
                                       .SetEventAction("chat_with")
                                       .SetEventLabel(profile.Value?.name);
                GoogleAnalyticsV4.getInstance().LogEvent(eventHitBuilder1);
            })
            .AddTo(this);
        }
        public FFmpegDownloadViewModel(FFmpegSettings FFmpegSettings,
                                       FFmpegDownloadModel DownloadModel,
                                       IFFmpegViewsProvider FFmpegViewsProvider,
                                       IMessageProvider MessageProvider)
        {
            this.FFmpegSettings = FFmpegSettings;
            _downloadModel      = DownloadModel;
            _messageProvider    = MessageProvider;

            StartCommand = _downloaderProgress
                           .Select(M => M.State)
                           .Select(M => M == FFmpegDownloaderState.Ready)
                           .ToReactiveCommand()
                           .WithSubscribe(async() =>
            {
                var progress = new Progress <FFmpegDownloaderProgress>(M => _downloaderProgress.Value = M);

                _downloadTask = DownloadModel.Start(progress, _cancellationTokenSource.Token);

                var result = await _downloadTask;

                AfterDownload?.Invoke(result);
            });

            CanCancel = _downloaderProgress
                        .Select(M => M.State)
                        .Select(M => M == FFmpegDownloaderState.Downloading)
                        .ToReadOnlyReactivePropertySlim();

            SelectFolderCommand = _downloaderProgress
                                  .Select(M => M.State)
                                  .Select(M => M == FFmpegDownloaderState.Ready)
                                  .ToReactiveCommand()
                                  .WithSubscribe(FFmpegViewsProvider.PickFolder);

            OpenFolderCommand = new ReactiveCommand()
                                .WithSubscribe(() =>
            {
                var path = FFmpegSettings.GetFolderPath();

                if (Directory.Exists(path))
                {
                    Process.Start(path);
                }
            });

            Status = _downloaderProgress
                     .Select(M =>
            {
                switch (M.State)
                {
                case FFmpegDownloaderState.Error:
                    return(M.ErrorMessage);

                case FFmpegDownloaderState.Downloading:
                    return($"{FFmpegDownloaderState.Downloading} ({M.DownloadProgress}%)");

                default:
                    return(M.State.ToString());
                }
            })
                     .ToReadOnlyReactivePropertySlim();

            Progress = _downloaderProgress
                       .Where(M => M.State == FFmpegDownloaderState.Downloading)
                       .Select(M => M.DownloadProgress)
                       .ToReadOnlyReactivePropertySlim();

            Progress.Subscribe(M => ProgressChanged?.Invoke(M));

            InProgress = _downloaderProgress
                         .Select(M => M.State)
                         .Select(M => M == FFmpegDownloaderState.Downloading || M == FFmpegDownloaderState.Extracting)
                         .ToReadOnlyReactivePropertySlim();

            IsDone = _downloaderProgress
                     .Select(M => M.State)
                     .Select(M => M == FFmpegDownloaderState.Done || M == FFmpegDownloaderState.Cancelled || M == FFmpegDownloaderState.Error)
                     .ToReadOnlyReactivePropertySlim();
        }