示例#1
0
        public ConnectionInfoManagementViewModel()
        {
            AddNewItemCommand = IsItemEditing.Inverse().ToReactiveCommand();
            AddNewItemCommand.Subscribe(() =>
            {
                SelectedItem.Value = null;
                EditingItem.Value  = new T();
                if (IsGroupSelected?.Value == true)
                {
                    EditingItem.Value.GroupName = SelectedGroup.Value?.Name;
                }
                IsItemEditing.Value = true;
            }).AddTo(Disposable);

            ConnectCommand.Subscribe(async item => await ConfirmConnect(item)).AddTo(Disposable);

            IsItemSelected = SelectedItem.Select(x => x != null).ToReadOnlyReactiveProperty();

            IsNotItemEditing = IsItemEditing.Inverse().ToReadOnlyReactiveProperty();

            SelectedItem.Subscribe(x =>
            {
                EditingItem.Value   = SelectedItem.Value;
                IsItemEditing.Value = false;
            }).AddTo(Disposable);

            StartEditCommand = IsItemSelected
                               .CombineLatest(IsItemEditing.Inverse(), (a, b) => a && b)
                               .ToReactiveCommand();
            StartEditCommand.Subscribe(() =>
            {
                EditingItem.Value   = SelectedItem.Value.CloneDeep();
                IsItemEditing.Value = true;
            }).AddTo(Disposable);

            ReplicateCommand = IsItemSelected
                               .CombineLatest(IsItemEditing.Inverse(), (a, b) => a && b)
                               .ToReactiveCommand();
            ReplicateCommand.Subscribe(() =>
            {
                var replicated      = SelectedItem.Value.CloneDeep();
                replicated.Id       = -1;
                SelectedItem.Value  = null;
                EditingItem.Value   = replicated;
                IsItemEditing.Value = true;
            }).AddTo(Disposable);

            RemoveCommand = IsItemSelected
                            .CombineLatest(IsItemEditing.Inverse(), (a, b) => a && b)
                            .ToAsyncReactiveCommand();
            RemoveCommand.Subscribe(async() =>
            {
                if (await Remove(SelectedItem.Value))
                {
                    Items.Remove(SelectedItem.Value);
                    // Renew Windows JumpList
                    JumpListHelper.RenewJumpList(await MainWindow.DbContext.EnumerateAllConnectionInfos());
                }
            }).AddTo(Disposable);

            DiscardChangesCommand = IsItemEditing.ToReactiveCommand();
            DiscardChangesCommand.Subscribe(() =>
            {
                EditingItem.Value   = SelectedItem.Value ?? new T();
                IsItemEditing.Value = false;
            }).AddTo(Disposable);

            SaveChangesCommand = IsItemEditing.ToReactiveCommand();
            SaveChangesCommand.Subscribe(async() =>
            {
                var selectedItem = SelectedItem.Value;
                var item         = EditingItem.Value;
                try
                {
                    var(result, resultItem) = await Save(item);
                    if (resultItem == null)
                    {
                        return;        // FAILED
                    }
                    item = resultItem; // Replace with the saved item
                    if (result)        // ADDED
                    {
                        Items.Add(item);
                    }
                    else // UPDATED
                    {
                        var oldItem = Items.FirstOrDefault(x => x.Id == item.Id);
                        if (oldItem != null)
                        {
                            var index = Items.IndexOf(oldItem);
                            if (index >= 0)
                            {
                                Items.RemoveAt(index);
                                Items.Insert(index, item);
                            }
                        }
                    }
                    // Renew Windows JumpList
                    JumpListHelper.RenewJumpList(await MainWindow.DbContext.EnumerateAllConnectionInfos());
                }
                catch (OperationCanceledException) // User manually canceled
                {
                    return;
                }
                SelectedItem.Value  = item;
                IsItemEditing.Value = false;
            }).AddTo(Disposable);

            // Connection info filterings
            FilterText
            .Throttle(TimeSpan.FromMilliseconds(500))
            .ObserveOnDispatcher()
            .Subscribe(_ => RefreshCollectionView())
            .AddTo(Disposable);
            SelectedGroup
            .ObserveOnDispatcher()
            .Subscribe(_ => RefreshCollectionView())
            .AddTo(Disposable);

            // If any group is selected or not (except for "All")
            IsGroupSelected = SelectedGroup
                              .Select(x => x?.Name != AllGroupName)
                              .ToReadOnlyReactivePropertySlim()
                              .AddTo(Disposable);

            // Group list extraction on connection info events
            Observable.CombineLatest(
                // When Add, Remove or Update
                Items.CollectionChangedAsObservable()
                .Select(_ => Unit.Default)
                .StartWith(Unit.Default),
                // When GroupName property in each element changed
                Items.ObserveElementPropertyChanged()
                .Where(x => x.EventArgs.PropertyName == nameof(ConnectionInfoBase.GroupName))
                .Select(_ => Unit.Default)
                .StartWith(Unit.Default)
                )
            .Throttle(TimeSpan.FromMilliseconds(500))     // Once 500 ms
            .ObserveOnDispatcher()
            .Subscribe(_ =>
            {
                var selectedGroup = SelectedGroup.Value;
                // Reload group list
                Groups.Clear();
                EnumerateGroups().ToList().ForEach(Groups.Add);
                // Reset selected group
                SelectedGroup.Value = (selectedGroup is null) ? Groups.FirstOrDefault() : selectedGroup;
            })
            .AddTo(Disposable);
        }
示例#2
0
    public TournamentRunner()
    {
        SceneLoader instance = SceneLoader.Instance;

        Singleton <PropertyManager> .Instance.AddRootContext(this);

        PFIDsUsed.Add("D1E872B9C9DA0648");
        LoggedInPlayfab = (from id in PersistentSingleton <PlayFabService> .Instance.LoggedOnPlayerId.StartWith(string.Empty)
                           select id != string.Empty).TakeUntilDestroy(instance).ToReadOnlyReactiveProperty();
        TimeTillTournament      = TickerService.MasterTicksSlow.CombineLatest(ServerTimeService.IsSynced, (long tick, bool sync) => (!sync) ? (-1) : GetTimeTillTournament()).TakeUntilDestroy(instance).ToReadOnlyReactiveProperty();
        TimeTillTournamentClock = (from time in TimeTillTournament.DistinctUntilChanged()
                                   select(time <= 0) ? string.Empty : TextUtils.FormatSecondsShortWithDays(time)).TakeUntilDestroy(instance).ToReadOnlyReactiveProperty();
        (from till in TimeTillTournament
         where till == 0
         select till).Subscribe(delegate
        {
            ResetIfDifferentDevice();
        }).AddTo(instance);
        TournamentAccessable  = TimeTillTournament.CombineLatest(PlayerData.Instance.TournamentIdCurrent, TournamentFetched, ConnectivityService.InternetConnectionAvailable, (long time, int id, bool fetched, bool connected) => connected && time == 0 && id < 0 && fetched).TakeUntilDestroy(instance).ToReadOnlyReactiveProperty();
        CurrentlyInTournament = (from id in PlayerData.Instance.TournamentIdCurrent
                                 select id >= 0 && CheckIfSameDevice()).TakeUntilDestroy(instance).ToReadOnlyReactiveProperty();
        (from should in TournamentFetched.CombineLatest(TimeTillTournament, FetchAttempt, LoggedInPlayfab, (bool fetched, long till, int attempt, bool loggedIn) => !fetched && attempt == 0 && till == 0)
         where should
         select should).Subscribe(delegate
        {
            TryToFetchTournament();
        }).AddTo(instance);
        (from timestamp in PlayerData.Instance.TournamentTimeStamp
         where timestamp + 10000000L * (long)PersistentSingleton <GameSettings> .Instance.TournamentDurationSeconds >= ServerTimeService.NowTicks() && ServerTimeService.NowTicks() >= timestamp && CheckIfSameDevice()
         select timestamp).Subscribe(delegate
        {
            TournamentRuns.SetValueAndForceNotify(LoadTournamentRuns());
            TournamentActive.SetValueAndForceNotify(value: true);
        }).AddTo(instance);
        TimeTillTournamentEnd = (from should in TickerService.MasterTicks.CombineLatest(ServerTimeService.IsSynced, PlayerData.Instance.TournamentIdCurrent, (long tick, bool sync, int id) => sync && id >= 0 && CheckIfSameDevice())
                                 where should
                                 select should into _
                                 select GetTimeTillTournamentEnd()).TakeUntilDestroy(instance).ToReadOnlyReactiveProperty();
        TournamentEndClock = (from time in TimeTillTournamentEnd.DistinctUntilChanged()
                              select(time <= 0) ? string.Empty : TextUtils.FormatSecondsShort(time)).TakeUntilDestroy(instance).ToReadOnlyReactiveProperty();
        TournamentEnded = TimeTillTournamentEnd.CombineLatest(PlayerData.Instance.TournamentIdCurrent, (long time, int id) => time < 0 && id >= 0).TakeUntilDestroy(instance).ToReadOnlyReactiveProperty();
        (from ended in TournamentEnded
         where ended
         select ended).Subscribe(delegate
        {
            LoadTournamentEndedValues();
        }).AddTo(instance);
        TournamentWorldReached = (from world in PlayerData.Instance.MainChunk
                                  select world >= 70).TakeUntilDestroy(instance).ToReadOnlyReactiveProperty();
        DisplayNameGiven = (from name in PlayerData.Instance.DisplayName
                            select name != string.Empty).TakeUntilDestroy(instance).ToReadOnlyReactiveProperty();
        TournamentsUnlocked = PlayerData.Instance.LifetimePrestiges.CombineLatest(PlayerData.Instance.LifetimeChunk, (int prest, int chunk) => prest > 0 || chunk >= 45).TakeUntilDestroy(instance).ToReadOnlyReactiveProperty();
        (from unlocked in TournamentsUnlocked.Pairwise()
         where !unlocked.Previous && unlocked.Current
         select unlocked).Subscribe(delegate
        {
            BindingManager.Instance.TournamentUnlockedParent.ShowInfo();
        }).AddTo(instance);
        PlayerData.Instance.Medals.Take(1).Subscribe(delegate
        {
            TryToBuyTrophy(showUnlocking: false);
        }).AddTo(instance);
        PlayerData.Instance.Trophies.Subscribe(delegate(int trophies)
        {
            CalculateTrophiesMultiplier(trophies);
        }).AddTo(instance);
        InternetConnectionAvailable = (from avail in ConnectivityService.InternetConnectionAvailable
                                       select(avail)).TakeUntilDestroy(instance).ToReadOnlyReactiveProperty();
    }
示例#3
0
    public BossBattleRunner()
    {
        Singleton <PropertyManager> .Instance.AddRootContext(this);

        SceneLoader instance = SceneLoader.Instance;

        BossMaxDuration = (from duration in Singleton <CumulativeBonusRunner> .Instance.BonusMult[7]
                           select PersistentSingleton <GameSettings> .Instance.BossDurationSeconds + duration.ToInt()).TakeUntilDestroy(instance).ToReadOnlyReactiveProperty();
        UniRx.IObservable <long> left2 = (from dead in (from health in BossCurrentHP
                                                        select health <= BigDouble.ZERO).DistinctUntilChanged()
                                          select(!dead) ? TickerService.MasterTicks : Observable.Never <long>()).Switch();
        (from tuple in left2.CombineLatest(BossBattlePaused, (long ticks, bool paused) => new
        {
            ticks,
            paused
        })
         where !tuple.paused
         select tuple).Subscribe(tuple =>
        {
            if (ElapsedTime.Value < 864000000000L)
            {
                ElapsedTime.Value += tuple.ticks;
            }
        }).AddTo(instance);
        BattleSecondsLeft = (from left in ElapsedTime.CombineLatest(BossMaxDuration, (long elapsed, int dur) => dur - (int)(elapsed / 10000000))
                             select Mathf.Max(0, left)).TakeUntilDestroy(instance).ToReactiveProperty();
        BattleSecondsLeftNormalized = (from secs in BattleSecondsLeft
                                       select(float) secs / (float)BossMaxDuration.Value).ToReadOnlyReactiveProperty();
        UniRx.IObservable <bool> source = from secs in BattleSecondsLeft.Skip(1)
                                          select secs <= 0 into ranOut
                                          where ranOut
                                          select ranOut;

        UniRx.IObservable <bool> observable = from killed in (from health in BossCurrentHP
                                                              select health <= BigDouble.ZERO).DistinctUntilChanged()
                                              where killed
                                              select killed;

        observable.Subscribe(delegate
        {
            PlayerData.Instance.BossFailedLastTime.Value = false;
            PersistentSingleton <MainSaver> .Instance.PleaseSave("boss_killed_chunk_" + Singleton <WorldRunner> .Instance.CurrentChunk.Value.Index + "_prestige_" + PlayerData.Instance.LifetimePrestiges.Value);
        }).AddTo(instance);
        (from order in Singleton <PrestigeRunner> .Instance.PrestigeTriggered
         select order == PrestigeOrder.PrestigeStart).Subscribe(delegate
        {
            if (BossBattleActive.Value)
            {
                ElapsedTime.Value = 85536000000000L;
            }
            PlayerData.Instance.BossFailedLastTime.Value = false;
        }).AddTo(instance);
        (from seq in Singleton <WorldRunner> .Instance.MapSequence
         where seq
         select seq).Subscribe(delegate
        {
            PlayerData.Instance.BossFailedLastTime.Value = false;
        }).AddTo(instance);
        UniRx.IObservable <bool> observable2 = (from pair in Singleton <ChunkRunner> .Instance.AllBlockAmount.Pairwise()
                                                select pair.Current == 1 && pair.Previous > 1).CombineLatest(Singleton <ChunkRunner> .Instance.BossBlock, (bool cleared, BossBlockController boss) => cleared && boss != null).StartWith(value: false);
        (from activated in observable2
         where activated
         select activated).Subscribe(delegate
        {
            StartCountdown();
        }).AddTo(instance);
        BossBattleActive = (from secs in BattleSecondsLeft
                            select secs > 0).CombineLatest(observable2, (bool time, bool block) => time && block).DistinctUntilChanged().TakeUntilDestroy(instance)
                           .ToReadOnlyReactiveProperty();
        BossLevelActive = (from boss in Singleton <ChunkRunner> .Instance.BossBlock
                           select boss != null).TakeUntilDestroy(instance).ToReadOnlyReactiveProperty();
        (from pair in BossLevelActive.Pairwise()
         select pair.Current&& !pair.Previous into start
         where start
         select start).Subscribe(delegate
        {
            StartBossLevel();
        }).AddTo(instance);
        BossPreludeActive       = BossLevelActive.CombineLatest(Singleton <ChunkRunner> .Instance.AllBlockAmount, (bool level, int blocks) => level && blocks > 1).TakeUntilDestroy(instance).ToReadOnlyReactiveProperty();
        BossFailedActive        = BossLevelActive.CombineLatest(BossPreludeActive, BossBattleActive, (bool level, bool prelude, bool battle) => level && !prelude && !battle).TakeUntilDestroy(instance).ToReadOnlyReactiveProperty();
        TryBossAvailable        = PlayerData.Instance.BossFailedLastTime.CombineLatest(BossLevelActive, (bool failed, bool active) => failed && !active).TakeUntilDestroy(instance).ToReadOnlyReactiveProperty();
        BossBattlePending       = TryBossAvailable.CombineLatest(BossLevelActive, (bool avail, bool level) => avail || level).TakeUntilDestroy(instance).ToReadOnlyReactiveProperty();
        BossSuccessNotification = (from _ in observable
                                   select Observable.Merge(new UniRx.IObservable <bool>[2]
        {
            Observable.Return <bool>(value: true),
            Observable.Return <bool>(value: false).Delay(TimeSpan.FromSeconds(10.0))
        })).Switch().TakeUntilDestroy(instance).ToReadOnlyReactiveProperty();
        BossFailedNotification = (from _ in source
                                  select Observable.Merge(new UniRx.IObservable <bool>[2]
        {
            Observable.Return <bool>(value: true),
            Observable.Return <bool>(value: false).Delay(TimeSpan.FromSeconds(10.0))
        })).Switch().TakeUntilDestroy(instance).ToReadOnlyReactiveProperty();
        BossBattleResult = (from _ in source
                            select false).Merge(observable).StartWith(value: false).ToSequentialReadOnlyReactiveProperty();
        BossFullHP = (from chunk in Singleton <WorldRunner> .Instance.CurrentChunk
                      select ChunkRunner.IsLastChunkForNode(chunk.Index)).Select(delegate(bool last)
        {
            BiomeConfig value = Singleton <WorldRunner> .Instance.CurrentBiomeConfig.Value;
            return((!last) ? value.MiniBossHP : value.BossHP);
        }).CombineLatest(Singleton <DrJellyRunner> .Instance.DrJellyBattle, (BigDouble hp, bool dr) => (!dr) ? hp : (hp * PersistentSingleton <GameSettings> .Instance.DrJellyHpMult)).TakeUntilDestroy(instance)
                     .ToReadOnlyReactiveProperty();
        BossHealthNormalized = (from hp in BossFullHP
                                select(!(hp > new BigDouble(1.0))) ? new BigDouble(1.0) : hp).CombineLatest(BossCurrentHP, (BigDouble full, BigDouble current) => (current / full).ToFloat()).TakeUntilDestroy(instance).ToReadOnlyReactiveProperty();
        (from result in BossBattleResult.Skip(1)
         where !result
         select result).Subscribe(delegate
        {
            AudioController.Instance.QueueEvent(new AudioEvent("BossSequenceFailed", AUDIOEVENTACTION.Play));
        }).AddTo(instance);
        (from result in BossBattleResult.Skip(1)
         where result
         select result).Subscribe(delegate
        {
            PlayerData.Instance.RetryLevelNumber.Value = 0;
        }).AddTo(instance);
        if (PersistentSingleton <GameAnalytics> .Instance != null)
        {
            BossBattleResult.Subscribe(delegate(bool result)
            {
                PersistentSingleton <GameAnalytics> .Instance.BossBattleResult.Value = result;
            }).AddTo(instance);
        }
    }
示例#4
0
        // FIXME: VMでやることじゃない
        public AxisStandardViewModel(
            INativeWindowManager nativeWindowManager,
            IScreenManager screenManager,
            IAudioManager audioManager,
            IVersionRepository versionRepository,
            ISettingService settingService)
        {
            settings              = settingService.Instance();
            Vertical              = BindSettings(settings.Vertical, nameof(settings.Vertical));
            Horizontal            = BindSettings(settings.Horizontal, nameof(settings.Horizontal));
            WindowFittingStandard = BindSettings(settings.WindowFittingStandard, nameof(settings.WindowFittingStandard));
            MuteCondition         = BindSettings(settings.MuteCondition, nameof(settings.MuteCondition));
            TargetApplicationName = BindSettings(settings.TargetApplicationName, nameof(TargetApplicationName));
            LatestVersion         = new ReactiveProperty <string>("");

            UseCurrentVerticalUserSetting   = BindSettings(settings.UseCurrentVerticalUserSetting, nameof(settings.UseCurrentVerticalUserSetting), ReactivePropertyMode.RaiseLatestValueOnSubscribe);
            UseCurrentHorizontalUserSetting = BindSettings(settings.UseCurrentHorizontalUserSetting, nameof(settings.UseCurrentHorizontalUserSetting), ReactivePropertyMode.RaiseLatestValueOnSubscribe);
            UserDefinedVerticalWindowRect   = BindSettings(settings.UserDefinedVerticalWindowRect, nameof(settings.UserDefinedVerticalWindowRect));
            UserDefinedHorizontalWindowRect = BindSettings(settings.UserDefinedHorizontalWindowRect, nameof(settings.UserDefinedHorizontalWindowRect));
            IsMostTop      = BindSettings(settings.IsMostTop, nameof(settings.IsMostTop));
            IsRemoveBorder = BindSettings(settings.IsRemoveBorder, nameof(settings.IsRemoveBorder));

            // FIXME: PollingじゃなくてGlobalHookとかでやりたい
            targetWindowHandle = Observable.Interval(TimeSpan.FromSeconds(5))
                                 .CombineLatest(TargetApplicationName)
                                 .Select(x => nativeWindowManager.GetWindowHandle(x.Second))
                                 .Distinct()
                                 .ToReadOnlyReactiveProperty();

            // FIXME: TargetApplicationNameが変わってもThreadが変わって動かなくなるわ…
            Disposable.Add(TargetApplicationName.Subscribe(x => nativeWindowManager.SetHook(x)));
            Disposable.Add(targetWindowHandle.Subscribe(x => nativeWindowManager.SetTargetProcessHandler(x)));

            var observableBorderChanged = Observable.FromEventPattern(nativeWindowManager, nameof(nativeWindowManager.OnBorderChanged)).StartWith(new object[] { null });
            var observableOnMoveChanged = Observable.FromEventPattern(nativeWindowManager, nameof(nativeWindowManager.OnMoveOrSizeChanged)).Throttle(TimeSpan.FromMilliseconds(200)).StartWith(new object[] { null });

            var windowRect = targetWindowHandle
                             .CombineLatest(
                observableOnMoveChanged,
                observableBorderChanged.Delay(TimeSpan.FromMilliseconds(500))
                )
                             .Select(x =>
            {
                if (x.First == IntPtr.Zero)
                {
                    return(WindowRect.Empty, WindowRect.Empty);
                }
                var windowClientRectPair = nativeWindowManager.GetWindowRect(x.First);
                var(r, _) = windowClientRectPair;
                if (r.IsEmpty)
                {
                    return(WindowRect.Empty, WindowRect.Empty);
                }
                return(windowClientRectPair);
            });

            Disposable.Add(UseCurrentHorizontalUserSetting.Subscribe(x =>
            {
                if (!x)
                {
                    return;
                }
                var handle = targetWindowHandle.Value;
                if (handle == IntPtr.Zero)
                {
                    return;
                }
                var(r, _) = nativeWindowManager.GetWindowRect(handle);
                if (r.IsEmpty)
                {
                    UserDefinedHorizontalWindowRect.Value = WindowRect.Empty;
                    return;
                }
                UserDefinedHorizontalWindowRect.Value = r;
                return;
            }));

            Disposable.Add(UseCurrentVerticalUserSetting.Subscribe(x =>
            {
                if (!x)
                {
                    return;
                }
                var handle = targetWindowHandle.Value;
                if (handle == IntPtr.Zero)
                {
                    return;
                }
                var(r, _) = nativeWindowManager.GetWindowRect(handle);
                if (r.IsEmpty)
                {
                    UserDefinedVerticalWindowRect.Value = WindowRect.Empty;
                    return;
                }
                UserDefinedVerticalWindowRect.Value = r;
                return;
            }));

            Disposable.Add(targetWindowHandle.CombineLatest(
                               MuteCondition,
                               Observable.CombineLatest(
                                   Observable.FromEventPattern <bool>(nativeWindowManager, nameof(nativeWindowManager.OnForeground))
                                   .Select(x => x.EventArgs.ToDefaultableBooleanLike()).StartWith(DefaultableBooleanLike.Default),
                                   Observable.FromEventPattern <bool>(nativeWindowManager, nameof(nativeWindowManager.OnMinimized))
                                   .Select(x => x.EventArgs.ToDefaultableBooleanLike()).StartWith(DefaultableBooleanLike.Default)
                                   )
                               .DistinctUntilChanged()
                               .Select(x =>
            {
                var maybeForeground = x[0];
                var maybeMinimized  = x[1];
                return((maybeForeground, maybeMinimized) switch
                {
                    (DefaultableBooleanLike.Default, DefaultableBooleanLike.Default) => ApplicationState.Foreground,
                    (DefaultableBooleanLike.Default, DefaultableBooleanLike.True) => ApplicationState.Minimized,
                    (DefaultableBooleanLike.Default, DefaultableBooleanLike.False) => ApplicationState.Background,
                    (DefaultableBooleanLike.True, DefaultableBooleanLike.Default) => ApplicationState.Foreground,
                    (DefaultableBooleanLike.True, DefaultableBooleanLike.True) => ApplicationState.Minimized,
                    (DefaultableBooleanLike.True, DefaultableBooleanLike.False) => ApplicationState.Foreground,
                    (DefaultableBooleanLike.False, DefaultableBooleanLike.Default) => ApplicationState.Background,
                    (DefaultableBooleanLike.False, DefaultableBooleanLike.True) => ApplicationState.Minimized,
                    (DefaultableBooleanLike.False, DefaultableBooleanLike.False) => ApplicationState.Background
                });
            })