Пример #1
0
        /// <summary>
        /// インスタンスを生成します。
        /// </summary>
        /// <param name="nextTetrimino">次のテトリミノ</param>
        public NextFieldViewModel(IReadOnlyReactiveProperty <TetriminoKind> nextTetrimino)
        {
            //--- 描画するセルを準備
            this.Cells = new CellViewModel[This.RowCount, This.ColumnCount];
            foreach (var item in this.Cells.WithIndex())
            {
                this.Cells[item.X, item.Y] = new CellViewModel();
            }

            //--- ブロックに関する変更を処理
            nextTetrimino
            .Select(x => Tetrimino.Create(x).Blocks.ToDictionary2(y => y.Position.Row, y => y.Position.Column))
            .Subscribe(x =>
            {
                //--- ViewPort のオフセット調整
                //--- ちゃんと書くのがだいぶ面倒臭くなったから無理やりやる
                var offset = new Position((-6 - x.Count) / 2, 2);

                //--- 適用
                foreach (var item in this.Cells.WithIndex())
                {
                    var color = x.GetValueOrDefault(item.X + offset.Row)
                                ?.GetValueOrDefault(item.Y + offset.Column)
                                ?.Color
                                ?? this.BackgroundColor;
                    item.Element.Color.Value = color;
                }
            });
        }
Пример #2
0
        public CollectibleViewModel(Collectible item, IReadOnlyReactiveProperty <string> searchtText, IList <Tag> tags)
        {
            OriginalTitle = item.Title;

            Tags = item.Tags.Select(t => new TagViewModel(t, this)).ToReactiveCollection();

            TagsCount = Tags.ObserveCountChanged(true).ToReadOnlyReactiveProperty();

            AddRandomTag = new ReactiveCommand(TagsCount.Select(t => t < 2));
            AddRandomTag.Subscribe(_ => Tags.Add(new TagViewModel(tags[Random.Range(0, tags.Count - 1)], this)));

            IsSelected = new ReactiveProperty <bool>();

            Title = searchtText.Select(searchVal =>
            {
                if (string.IsNullOrEmpty(searchVal))
                {
                    return(OriginalTitle);
                }

                try
                {
                    return(Regex.Replace(OriginalTitle, "(" + searchVal
                                         .Replace("[", "\\[")
                                         .Replace("]", "\\]")
                                         .Replace("(", "\\(")
                                         .Replace(")", "\\)") + ")",
                                         "<b>$1</b>", RegexOptions.IgnoreCase));
                }
                catch (Exception e)
                {
                    return(OriginalTitle);
                }
            }).ToReadOnlyReactiveProperty();
        }
Пример #3
0
        public Robot(RobotTemplate template, Game game)
        {
            _template = template;
            _game     = game;

            MemorySize = MemoryUpgrades
                         .Select(upgradesCount => template.InitialMemorySize + upgradesCount * template.MemoryUpgradeSize)
                         .ToReactiveProperty();

            Programs = new ReactiveCollection <Program>();

            ProgramBytes = Programs.ObserveCountChanged(true)
                           .SelectMany(_ => Programs
                                       .Select(x => x.MemorySize)
                                       .CombineLatest()
                                       .Select(y => y.Sum()))
                           .ToReactiveProperty(initialValue: 0);

            TotalUsedBytes = ProgramBytes.CombineLatest(LeakedBytes, ProducedBytes,
                                                        (programs, leaked, produced) => programs + leaked + produced)
                             .ToReactiveProperty();

            FreeSpace = TotalUsedBytes.CombineLatest(MemorySize,
                                                     (used, memory) => memory - used)
                        .ToReactiveProperty();

            Status = Programs.ObserveCountChanged(true).CombineLatest(FreeSpace,
                                                                      (programCount, freeSpace) => freeSpace <= 0 ? RobotStatus.OutOfMemory
                                           : programCount == 0 ? RobotStatus.BootError
                                           : RobotStatus.Ok)
                     .ToReactiveProperty();

            HasSyncProgram = Programs.ObserveCountChanged(true)
                             .Select(_ => Programs.Any(x => x.Template.Type == ProgramType.Sync))
                             .ToReactiveProperty();

            //TODO: stop sync on game over
            Observable.CombineLatest(HasSyncProgram, Status.Select(x => x == RobotStatus.OutOfMemory),
                                     (hasSync, outOfMemory) => hasSync && !outOfMemory)
            .DistinctUntilChanged()
            .Select(shouldSync => shouldSync ? Observable.Interval(TimeSpan.FromSeconds(10)) : Observable.Empty <long>())
            .Switch()
            .Subscribe(_ =>
            {
                _game.GameProgress.DataCollected.Value += ProducedBytes.Value;
                ProducedBytes.Value = 0;
            });
        }
Пример #4
0
        /// <summary>
        /// コンストラクタ。
        /// </summary>
        /// <param name="canModify">
        /// 再生や音声保存に関わる設定値の変更可否状態値。
        /// </param>
        /// <param name="items">アイテムコレクション。</param>
        public TalkTextReplaceItemsViewModel(
            IReadOnlyReactiveProperty <bool> canModify,
            IReadOnlyReactiveProperty <TalkTextReplaceItemCollection> items)
            : base(canModify, items)
        {
            // 選択中アイテムインデックス
            this.SelectedIndex =
                new ReactiveProperty <int>((items.Value.Count > 0) ? 0 : -1)
                .AddTo(this.CompositeDisposable);

            // アイテム追加コマンド
            this.AddCommand =
                this.MakeCommand(
                    () =>
            {
                this.Items.Value.Add(new TalkTextReplaceItem());
                this.SelectedIndex.Value = this.Items.Value.Count - 1;
            },
                    canModify);

            // プリセットアイテム追加コマンド
            this.AddPresetCommand =
                this.MakeCommand <TalkTextReplacePreset>(
                    this.ExecuteAddPresetCommand,
                    canModify);

            // コレクションまたは選択中インデックスの変更通知
            var itemsNotifier =
                Observable
                .CombineLatest(
                    items,
                    items
                    .Select(i => i.CollectionChangedAsObservable())
                    .Switch()
                    .ToUnit()
                    .Merge(Observable.Return(Unit.Default)),
                    this.SelectedIndex,
                    (i, _, index) => new { count = i.Count, index })
                .DistinctUntilChanged();

            // コレクションが空でなくなったらアイテム選択
            Observable
            .Zip(itemsNotifier, itemsNotifier.Skip(1))
            .Where(v => v[0].count <= 0 && v[1].count > 0 && v[1].index < 0)
            .Subscribe(_ => this.SelectedIndex.Value = 0)
            .AddTo(this.CompositeDisposable);

            // アイテム削除コマンド
            this.RemoveCommand =
                this.MakeCommand(
                    this.ExecuteRemoveCommand,
                    canModify,
                    itemsNotifier
                    .Select(n => n.index >= 0 && n.index < n.count)
                    .DistinctUntilChanged());

            // アイテムクリアコマンド
            this.ClearCommand =
                this.MakeCommand(
                    this.Items.Value.Clear,
                    canModify,
                    itemsNotifier.Select(n => n.count > 0).DistinctUntilChanged());

            // アイテム上移動コマンド
            this.UpCommand =
                this.MakeCommand(
                    () =>
                    this.Items.Value.Move(
                        this.SelectedIndex.Value,
                        this.SelectedIndex.Value - 1),
                    canModify,
                    itemsNotifier
                    .Select(n => n.index > 0 && n.index < n.count)
                    .DistinctUntilChanged());

            // アイテム下移動コマンド
            this.DownCommand =
                this.MakeCommand(
                    () =>
                    this.Items.Value.Move(
                        this.SelectedIndex.Value,
                        this.SelectedIndex.Value + 1),
                    canModify,
                    itemsNotifier
                    .Select(n => n.index >= 0 && n.index + 1 < n.count)
                    .DistinctUntilChanged());
        }