Beispiel #1
0
        private static Car ParseCarNode(XElement parent)
        {
            Car car;

            if ((bool)parent.Element("IsMotorCar"))
            {
                car = new MotorCar();
            }
            else
            {
                car = new TrailerCar();
            }

            car.Mass   = (double)parent.Element("Mass");
            car.Length = (double)parent.Element("Length");
            car.Width  = (double)parent.Element("Width");
            car.Height = (double)parent.Element("Height");
            car.CenterOfGravityHeight = (double)parent.Element("CenterOfGravityHeight");
            car.DefinedAxles          = (bool)parent.Element("DefinedAxles");
            car.FrontAxle             = (double)parent.Element("FrontAxle");
            car.RearAxle = (double)parent.Element("RearAxle");

            car.FrontBogie = ParseBogieNode(parent.Element("FrontBogie"));
            car.RearBogie  = ParseBogieNode(parent.Element("RearBogie"));

            car.ExposedFrontalArea   = (double)parent.Element("ExposedFrontalArea");
            car.UnexposedFrontalArea = (double)parent.Element("UnexposedFrontalArea");

            car.Performance = ParsePerformanceNode(parent.Element("Performance"));
            car.Delay       = ParseDelayNode(parent.Element("Delay"));
            car.Move        = ParseMoveNode(parent.Element("Move"));
            car.Brake       = ParseBrakeNode(parent.Element("Brake"));
            car.Pressure    = ParsePressureNode(parent.Element("Pressure"));

            MotorCar motorCar = car as MotorCar;

            if (motorCar != null)
            {
                motorCar.Acceleration = ParseAccelerationNode(parent.Element("Acceleration"));
                motorCar.Motor        = ParseMotorNode(parent.Element("Motor"));
            }

            car.Reversed    = (bool)parent.Element("Reversed");
            car.Object      = (string)parent.Element("Object");
            car.LoadingSway = (bool)parent.Element("LoadingSway");

            return(car);
        }
Beispiel #2
0
        internal MotorCarViewModel(MotorCar car, Train train) : base(car)
        {
            Acceleration = car
                           .ObserveProperty(x => x.Acceleration)
                           .Do(_ => Acceleration?.Value.Dispose())
                           .Select(x => new AccelerationViewModel(x, train, car))
                           .ToReadOnlyReactivePropertySlim()
                           .AddTo(disposable);

            Motor = car
                    .ObserveProperty(x => x.Motor)
                    .Do(_ => Motor?.Value.Dispose())
                    .Select(x => new MotorViewModel(x))
                    .ToReadOnlyReactivePropertySlim()
                    .AddTo(disposable);
        }
Beispiel #3
0
        private static void WriteCarNode(XElement parent, Car car)
        {
            XElement carNode = new XElement("Car");

            parent.Add(carNode);

            carNode.Add(
                new XElement("IsMotorCar", car is MotorCar),
                new XElement("Mass", car.Mass),
                new XElement("Length", car.Length),
                new XElement("Width", car.Width),
                new XElement("Height", car.Height),
                new XElement("CenterOfGravityHeight", car.CenterOfGravityHeight),
                new XElement("DefinedAxles", car.DefinedAxles),
                new XElement("FrontAxle", car.FrontAxle),
                new XElement("RearAxle", car.RearAxle)
                );

            WriteBogieNode(carNode, "FrontBogie", car.FrontBogie);
            WriteBogieNode(carNode, "RearBogie", car.RearBogie);

            carNode.Add(new XElement("ExposedFrontalArea", car.ExposedFrontalArea));
            carNode.Add(new XElement("UnexposedFrontalArea", car.UnexposedFrontalArea));

            WritePerformanceNode(carNode, car.Performance);
            WriteDelayNode(carNode, car.Delay);
            WriteMoveNode(carNode, car.Move);
            WriteBrakeNode(carNode, car.Brake);
            WritePressureNode(carNode, car.Pressure);

            MotorCar motorCar = car as MotorCar;

            if (motorCar != null)
            {
                WriteAccelerationNode(carNode, motorCar.Acceleration);
                WriteMotorNode(carNode, motorCar.Motor);
            }

            carNode.Add(
                new XElement("Reversed", car.Reversed),
                new XElement("Object", car.Object),
                new XElement("LoadingSway", car.LoadingSway)
                );
        }
Beispiel #4
0
        internal void ChangeCarClass(int carIndex)
        {
            MotorCar   motorCar   = Train.Cars[carIndex] as MotorCar;
            TrailerCar trailerCar = Train.Cars[carIndex] as TrailerCar;

            if (motorCar != null)
            {
                Train.Cars[carIndex] = new TrailerCar(motorCar);
            }

            if (trailerCar != null)
            {
                Train.Cars[carIndex] = new MotorCar(trailerCar);

                Train.ApplyPowerNotchesToCar();
            }

            Item.Children[1].Children[carIndex].Tag = Train.Cars[carIndex];
            OnPropertyChanged(new PropertyChangedEventArgs(nameof(SelectedItem)));
        }
Beispiel #5
0
    static void Main()
    {
        MotorCar car1 = MotorCar.DesignFromComponents("Bumpy", new MotorCar.Wheels(MotorCar.Wheels.Shape.Square, 4), new MotorCar.WindScreen(false));
        MotorCar car2 = MotorCar.DesignFromComponents("Wobbly", new MotorCar.Wheels(MotorCar.Wheels.Shape.Round, 2), new MotorCar.WindScreen(false));
        MotorCar car3 = MotorCar.DesignFromComponents("Batty", new MotorCar.Wheels(MotorCar.Wheels.Shape.Round, 4), new MotorCar.WindScreen(true));
        MotorCar car4 = MotorCar.DesignFromComponents("Spiffing", new MotorCar.Wheels(MotorCar.Wheels.Shape.Round, 4), new MotorCar.WindScreen(false));

        Console.WriteLine("Expert opinion on " + car1.Name() + " : \n  " + car1.WillItWork());
        Console.WriteLine("Expert opinion on " + car2.Name() + " : \n  " + car2.WillItWork());
        Console.WriteLine("Expert opinion on " + car3.Name() + " : \n  " + car3.WillItWork());
        Console.WriteLine("Expert opinion on " + car4.Name() + " : \n  " + car4.WillItWork());

        int count   = MotorCar.DesignOpinion.AceDesignCount;
        int total   = MotorCar.DesignOpinion.TotalDesignCount;
        int percent = MotorCar.DesignOpinion.PercentScore();

        Console.WriteLine("Overall opinion rating on car design is " + count + "/" + total + " = " + percent + "%");

        Console.WriteLine("Single square wheel thoughts: " + new MotorCar.Wheels(MotorCar.Wheels.Shape.Square, 1).Opinion().reason);
    }
Beispiel #6
0
        static void Main(string[] args)
        {
            MotorCar motorCar = new MotorCar(new Chassis(4, 102, 10.1),
                                             new Engine(1200, 1600, 5454),
                                             new Transmission("B", "Russia", 5), "Audi");

            Truck truck = new Truck(new Chassis(4, 102, 10.1),
                                    new Engine(1200, 10, 5454),
                                    new Transmission("A", "Russia", 5),
                                    5000);
            Bus bus = new Bus(new Chassis(4, 102, 10.1),
                              new Engine(1200, 1600, 5454),
                              new Transmission("A", "Russia", 5), 25);
            Autopark autopark = new Autopark();

            autopark.AddAuto(motorCar);
            autopark.AddAuto(motorCar);
            autopark.AddAuto(truck);
            autopark.AddAuto(bus);

            autopark.PrintInfoCarsSpaceOfEngineMoreThan1500();
            autopark.PrintInfoAboutEngineForAllBusesAndTrucks();
            autopark.PrintInfoAboutCarsWithIdetnicalTypeTransmission();
        }
Beispiel #7
0
        internal TrainViewModel(Train train, App app)
        {
            Handle = train
                     .ObserveProperty(x => x.Handle)
                     .Do(_ => Handle?.Value.Dispose())
                     .Select(x => new HandleViewModel(x, train))
                     .ToReadOnlyReactivePropertySlim()
                     .AddTo(disposable);

            Device = train
                     .ObserveProperty(x => x.Device)
                     .Do(_ => Device?.Value.Dispose())
                     .Select(x => new DeviceViewModel(x, train.Handle))
                     .ToReadOnlyReactivePropertySlim()
                     .AddTo(disposable);

            Cab = train
                  .ObserveProperty(x => x.Cab)
                  .Do(_ => Cab?.Value.Dispose())
                  .Select(x => new CabViewModel(x))
                  .ToReadOnlyReactivePropertySlim()
                  .AddTo(disposable);

            Cars = train.Cars
                   .ToReadOnlyReactiveCollection(x =>
            {
                MotorCar motorCar     = x as MotorCar;
                TrailerCar trailerCar = x as TrailerCar;

                CarViewModel viewModel = null;

                if (motorCar != null)
                {
                    viewModel = new MotorCarViewModel(motorCar, train);
                }

                if (trailerCar != null)
                {
                    viewModel = new TrailerCarViewModel(trailerCar);
                }

                return(viewModel);
            })
                   .AddTo(disposable);

            Couplers = train.Couplers
                       .ToReadOnlyReactiveCollection(x => new CouplerViewModel(x))
                       .AddTo(disposable);

            SelectedCar = app
                          .ObserveProperty(x => x.SelectedItem)
                          .Where(x => x != null)
                          .Select(x => Cars.FirstOrDefault(y => y.Model == x.Tag))
                          .ToReadOnlyReactivePropertySlim()
                          .AddTo(disposable);

            SelectedCoupler = app
                              .ObserveProperty(x => x.SelectedItem)
                              .Where(x => x != null)
                              .Select(x => Couplers.FirstOrDefault(y => y.Model == x.Tag))
                              .ToReadOnlyReactivePropertySlim()
                              .AddTo(disposable);
        }
Beispiel #8
0
        internal static void Write(string fileName, Train train)
        {
            StringBuilder builder = new StringBuilder();
            CultureInfo   culture = CultureInfo.InvariantCulture;
            const int     n       = 15;

            MotorCar   firstMotorCar   = train.Cars.OfType <MotorCar>().First();
            TrailerCar firstTrailerCar = train.Cars.OfType <TrailerCar>().FirstOrDefault();

            builder.AppendLine("OPENBVE" + currentVersion);

            builder.AppendLine("#ACCELERATION");

            for (int i = firstMotorCar.Acceleration.Entries.Count - 1; i >= train.Handle.PowerNotches; i--)
            {
                firstMotorCar.Acceleration.Entries.RemoveAt(i);
            }

            foreach (Acceleration.Entry entry in firstMotorCar.Acceleration.Entries)
            {
                builder.Append(entry.A0.ToString(culture) + ",");
                builder.Append(entry.A1.ToString(culture) + ",");
                builder.Append(entry.V1.ToString(culture) + ",");
                builder.Append(entry.V2.ToString(culture) + ",");
                builder.AppendLine(entry.E.ToString(culture));
            }

            builder.AppendLine("#PERFORMANCE");
            builder.AppendLine($"{firstMotorCar.Performance.Deceleration.ToString(culture).PadRight(n, ' ')}; Deceleration");
            builder.AppendLine($"{firstMotorCar.Performance.CoefficientOfStaticFriction.ToString(culture).PadRight(n, ' ')}; CoefficientOfStaticFriction");
            builder.AppendLine($"{"0".PadRight(n, ' ')}; Reserved (not used)");
            builder.AppendLine($"{firstMotorCar.Performance.CoefficientOfRollingResistance.ToString(culture).PadRight(n, ' ')}; CoefficientOfRollingResistance");
            builder.AppendLine($"{firstMotorCar.Performance.AerodynamicDragCoefficient.ToString(culture).PadRight(n, ' ')}; AerodynamicDragCoefficient");

            builder.AppendLine("#DELAY");
            builder.AppendLine($"{string.Join(",", firstMotorCar.Delay.DelayPower.Select(d => d.Up.ToString(culture))).PadRight(n, ' ')}; DelayPowerUp");
            builder.AppendLine($"{string.Join(",", firstMotorCar.Delay.DelayPower.Select(d => d.Down.ToString(culture))).PadRight(n, ' ')}; DelayPowerDown");
            builder.AppendLine($"{string.Join(",", firstMotorCar.Delay.DelayBrake.Select(d => d.Up.ToString(culture))).PadRight(n, ' ')}; DelayBrakeUp");
            builder.AppendLine($"{string.Join(",", firstMotorCar.Delay.DelayBrake.Select(d => d.Down.ToString(culture))).PadRight(n, ' ')}; DelayBrakeDown");
            builder.AppendLine($"{string.Join(",", firstMotorCar.Delay.DelayLocoBrake.Select(d => d.Up.ToString(culture))).PadRight(n, ' ')}; DelayLocoBrakeUp (1.5.3.4+)");
            builder.AppendLine($"{string.Join(",", firstMotorCar.Delay.DelayLocoBrake.Select(d => d.Down.ToString(culture))).PadRight(n, ' ')}; DelayLocoBrakeDown (1.5.3.4+)");

            builder.AppendLine("#MOVE");
            builder.AppendLine($"{firstMotorCar.Move.JerkPowerUp.ToString(culture).PadRight(n, ' ')}; JerkPowerUp");
            builder.AppendLine($"{firstMotorCar.Move.JerkPowerDown.ToString(culture).PadRight(n, ' ')}; JerkPowerDown");
            builder.AppendLine($"{firstMotorCar.Move.JerkBrakeUp.ToString(culture).PadRight(n, ' ')}; JerkBrakeUp");
            builder.AppendLine($"{firstMotorCar.Move.JerkBrakeDown.ToString(culture).PadRight(n, ' ')}; JerkBrakeDown");
            builder.AppendLine($"{firstMotorCar.Move.BrakeCylinderUp.ToString(culture).PadRight(n, ' ')}; BrakeCylinderUp");
            builder.AppendLine($"{firstMotorCar.Move.BrakeCylinderDown.ToString(culture).PadRight(n, ' ')}; BrakeCylinderDown");

            builder.AppendLine("#BRAKE");
            builder.AppendLine($"{((int)firstMotorCar.Brake.BrakeType).ToString(culture).PadRight(n, ' ')}; BrakeType");
            builder.AppendLine($"{((int)firstMotorCar.Brake.BrakeControlSystem).ToString(culture).PadRight(n, ' ')}; BrakeControlSystem");
            builder.AppendLine($"{firstMotorCar.Brake.BrakeControlSpeed.ToString(culture).PadRight(n, ' ')}; BrakeControlSpeed");
            builder.AppendLine($"{((int)firstMotorCar.Brake.LocoBrakeType).ToString(culture).PadRight(n, ' ')}; LocoBrakeType (1.5.3.4+)");

            builder.AppendLine("#PRESSURE");
            builder.AppendLine($"{firstMotorCar.Pressure.BrakeCylinderServiceMaximumPressure.ToString(culture).PadRight(n, ' ')}; BrakeCylinderServiceMaximumPressure");
            builder.AppendLine($"{firstMotorCar.Pressure.BrakeCylinderEmergencyMaximumPressure.ToString(culture).PadRight(n, ' ')}; BrakeCylinderEmergencyMaximumPressure");
            builder.AppendLine($"{firstMotorCar.Pressure.MainReservoirMinimumPressure.ToString(culture).PadRight(n, ' ')}; MainReservoirMinimumPressure");
            builder.AppendLine($"{firstMotorCar.Pressure.MainReservoirMaximumPressure.ToString(culture).PadRight(n, ' ')}; MainReservoirMaximumPressure");
            builder.AppendLine($"{firstMotorCar.Pressure.BrakePipeNormalPressure.ToString(culture).PadRight(n, ' ')}; BrakePipeNormalPressure");

            builder.AppendLine("#HANDLE");
            builder.AppendLine($"{((int)train.Handle.HandleType).ToString(culture).PadRight(n, ' ')}; HandleType");
            builder.AppendLine($"{train.Handle.PowerNotches.ToString(culture).PadRight(n, ' ')}; PowerNotches");
            builder.AppendLine($"{train.Handle.BrakeNotches.ToString(culture).PadRight(n, ' ')}; BrakeNotches");
            builder.AppendLine($"{train.Handle.PowerNotchReduceSteps.ToString(culture).PadRight(n, ' ')}; PowerNotchReduceSteps");
            builder.AppendLine($"{((int)train.Handle.HandleBehaviour).ToString(culture).PadRight(n, ' ')}; EbHandleBehaviour (1.5.3.3+)");
            builder.AppendLine($"{train.Handle.LocoBrakeNotches.ToString(culture).PadRight(n, ' ')}; LocoBrakeNotches (1.5.3.4+)");
            builder.AppendLine($"{((int)train.Handle.LocoBrake).ToString(culture).PadRight(n, ' ')}; LocoBrakeType (1.5.3.4+)");
            builder.AppendLine($"{train.Handle.DriverPowerNotches.ToString(culture).PadRight(n, ' ')}; DriverPowerNotches (1.5.3.11+)");
            builder.AppendLine($"{train.Handle.DriverBrakeNotches.ToString(culture).PadRight(n, ' ')}; DriverBrakeNotches (1.5.3.11+)");

            builder.AppendLine("#CAB");
            builder.AppendLine($"{train.Cab.PositionX.ToString(culture).PadRight(n, ' ')}; X");
            builder.AppendLine($"{train.Cab.PositionY.ToString(culture).PadRight(n, ' ')}; Y");
            builder.AppendLine($"{train.Cab.PositionZ.ToString(culture).PadRight(n, ' ')}; Z");
            builder.AppendLine($"{train.Cab.DriverCar.ToString(culture).PadRight(n, ' ')}; DriverCar");

            builder.AppendLine("#CAR");
            builder.AppendLine($"{firstMotorCar.Mass.ToString(culture).PadRight(n, ' ')}; MotorCarMass");
            builder.AppendLine($"{train.Cars.Count(c => c is MotorCar).ToString(culture).PadRight(n, ' ')}; NumberOfMotorCars");
            builder.AppendLine($"{(firstTrailerCar ?? new TrailerCar()).Mass.ToString(culture).PadRight(n, ' ')}; TrailerCarMass");
            builder.AppendLine($"{train.Cars.Count(c => c is TrailerCar).ToString(culture).PadRight(n, ' ')}; NumberOfTrailerCars");
            builder.AppendLine($"{firstMotorCar.Length.ToString(culture).PadRight(n, ' ')}; LengthOfACar");
            builder.AppendLine($"{(train.Cars.First() is MotorCar ? "1" : "0").PadRight(n, ' ')}; FrontCarIsAMotorCar");
            builder.AppendLine($"{firstMotorCar.Width.ToString(culture).PadRight(n, ' ')}; WidthOfACar");
            builder.AppendLine($"{firstMotorCar.Height.ToString(culture).PadRight(n, ' ')}; HeightOfACar");
            builder.AppendLine($"{firstMotorCar.CenterOfGravityHeight.ToString(culture).PadRight(n, ' ')}; CenterOfGravityHeight");
            builder.AppendLine($"{firstMotorCar.ExposedFrontalArea.ToString(culture).PadRight(n, ' ')}; ExposedFrontalArea");
            builder.AppendLine($"{firstMotorCar.UnexposedFrontalArea.ToString(culture).PadRight(n, ' ')}; UnexposedFrontalArea");

            builder.AppendLine("#DEVICE");
            builder.AppendLine($"{((int)train.Device.Ats).ToString(culture).PadRight(n, ' ')}; Ats");
            builder.AppendLine($"{((int)train.Device.Atc).ToString(culture).PadRight(n, ' ')}; Atc");
            builder.AppendLine($"{(train.Device.Eb ? "1" : "0").PadRight(n, ' ')}; Eb");
            builder.AppendLine($"{(train.Device.ConstSpeed ? "1" : "0").PadRight(n, ' ')}; ConstSpeed");
            builder.AppendLine($"{(train.Device.HoldBrake ? "1" : "0").PadRight(n, ' ')}; HoldBrake");
            builder.AppendLine($"{((int)train.Device.ReAdhesionDevice).ToString(culture).PadRight(n, ' ')}; ReAdhesionDevice");
            builder.AppendLine($"{train.Device.LoadCompensatingDevice.ToString(culture).PadRight(n, ' ')}; Reserved (not used)");
            builder.AppendLine($"{((int)train.Device.PassAlarm).ToString(culture).PadRight(n, ' ')}; PassAlarm");
            builder.AppendLine($"{((int)train.Device.DoorOpenMode).ToString(culture).PadRight(n, ' ')}; DoorOpenMode");
            builder.AppendLine($"{((int)train.Device.DoorCloseMode).ToString(culture).PadRight(n, ' ')}; DoorCloseMode");
            builder.AppendLine($"{train.Device.DoorWidth.ToString(culture).PadRight(n, ' ')}; DoorWidth");
            builder.AppendLine($"{train.Device.DoorMaxTolerance.ToString(culture).PadRight(n, ' ')}; DoorMaxTolerance");

            for (int i = 0; i < 4; i++)
            {
                BVEMotorSoundTableEntry[] entries = new BVEMotorSoundTableEntry[0];

                switch (i)
                {
                case 0:
                    builder.AppendLine("#MOTOR_P1");
                    entries = Motor.Track.TrackToEntries(firstMotorCar.Motor.Tracks[(int)Motor.TrackInfo.Power1]);
                    break;

                case 1:
                    builder.AppendLine("#MOTOR_P2");
                    entries = Motor.Track.TrackToEntries(firstMotorCar.Motor.Tracks[(int)Motor.TrackInfo.Power2]);
                    break;

                case 2:
                    builder.AppendLine("#MOTOR_B1");
                    entries = Motor.Track.TrackToEntries(firstMotorCar.Motor.Tracks[(int)Motor.TrackInfo.Brake1]);
                    break;

                case 3:
                    builder.AppendLine("#MOTOR_B2");
                    entries = Motor.Track.TrackToEntries(firstMotorCar.Motor.Tracks[(int)Motor.TrackInfo.Brake2]);
                    break;
                }

                int k;

                for (k = entries.Length - 1; k >= 0; k--)
                {
                    if (entries[k].SoundIndex >= 0)
                    {
                        break;
                    }
                }

                k = Math.Min(k + 2, entries.Length);
                Array.Resize(ref entries, k);

                for (int j = 0; j < entries.Length; j++)
                {
                    builder.Append(entries[j].SoundIndex.ToString(culture) + ",");
                    builder.Append(entries[j].Pitch.ToString(culture) + ",");
                    builder.AppendLine(entries[j].Gain.ToString(culture));
                }
            }

            File.WriteAllText(fileName, builder.ToString(), new UTF8Encoding(true));
        }
        internal AccelerationViewModel(Acceleration acceleration, Train train, MotorCar car)
        {
            CultureInfo culture = CultureInfo.InvariantCulture;

            Entries = acceleration.Entries
                      .ToReadOnlyReactiveCollection(x => new EntryViewModel(x))
                      .AddTo(disposable);

            SelectedEntryIndex = acceleration
                                 .ToReactivePropertyAsSynchronized(
                x => x.SelectedEntryIndex,
                ignoreValidationErrorValue: true
                )
                                 .SetValidateNotifyError(x => x < 0 ? string.Empty : null)
                                 .AddTo(disposable);

            SelectedEntry = SelectedEntryIndex
                            .Select(x => x < 0 ? null : Entries[x])
                            .ToReadOnlyReactivePropertySlim()
                            .AddTo(disposable);

            MinVelocity = acceleration
                          .ToReactivePropertyAsSynchronized(
                x => x.MinVelocity,
                x => x.ToString(culture),
                x => double.Parse(x, NumberStyles.Float, culture),
                ignoreValidationErrorValue: true
                )
                          .AddTo(disposable);

            MaxVelocity = acceleration
                          .ToReactivePropertyAsSynchronized(
                x => x.MaxVelocity,
                x => x.ToString(culture),
                x => double.Parse(x, NumberStyles.Float, culture),
                ignoreValidationErrorValue: true
                )
                          .AddTo(disposable);

            MinAcceleration = acceleration
                              .ToReactivePropertyAsSynchronized(
                x => x.MinAcceleration,
                x => x.ToString(culture),
                x => double.Parse(x, NumberStyles.Float, culture),
                ignoreValidationErrorValue: true
                )
                              .AddTo(disposable);

            MaxAcceleration = acceleration
                              .ToReactivePropertyAsSynchronized(
                x => x.MaxAcceleration,
                x => x.ToString(culture),
                x => double.Parse(x, NumberStyles.Float, culture),
                ignoreValidationErrorValue: true
                )
                              .AddTo(disposable);

            NowVelocity = acceleration
                          .ObserveProperty(x => x.NowVelocity)
                          .Select(x => $"{x} km/h")
                          .ToReadOnlyReactivePropertySlim()
                          .AddTo(disposable);

            NowAcceleration = acceleration
                              .ObserveProperty(x => x.NowAcceleration)
                              .Select(x => $"{x} km/h/s")
                              .ToReadOnlyReactivePropertySlim()
                              .AddTo(disposable);

            Resistance = acceleration
                         .ToReactivePropertyAsSynchronized(x => x.Resistance)
                         .AddTo(disposable);

            ImageWidth = acceleration
                         .ToReactivePropertyAsSynchronized(
                x => x.ImageWidth,
                ignoreValidationErrorValue: true
                )
                         .SetValidateNotifyError(x => x <= 0 ? string.Empty : null)
                         .AddTo(disposable);

            ImageHeight = acceleration
                          .ToReactivePropertyAsSynchronized(
                x => x.ImageHeight,
                ignoreValidationErrorValue: true
                )
                          .SetValidateNotifyError(x => x <= 0 ? string.Empty : null)
                          .AddTo(disposable);

            Image = acceleration
                    .ObserveProperty(x => x.Image)
                    .ToReadOnlyReactivePropertySlim()
                    .AddTo(disposable);

            new[]
            {
                acceleration
                .PropertyChangedAsObservable()
                .Where(x => x.PropertyName != nameof(acceleration.NowVelocity) &&
                       x.PropertyName != nameof(acceleration.NowAcceleration) &&
                       x.PropertyName != nameof(acceleration.Image)
                       )
                .OfType <object>(),
                acceleration.Entries.ObserveElementPropertyChanged().OfType <object>()
            }
            .Merge()
            .ToReadOnlyReactivePropertySlim()
            .Subscribe(_ => train.DrawAccelerationImage(car))
            .AddTo(disposable);

            ZoomIn = new ReactiveCommand();
            ZoomIn.Subscribe(acceleration.ZoomIn).AddTo(disposable);

            ZoomOut = new ReactiveCommand();
            ZoomOut.Subscribe(acceleration.ZoomOut).AddTo(disposable);

            Reset = new ReactiveCommand();
            Reset.Subscribe(acceleration.Reset).AddTo(disposable);

            MoveLeft = new ReactiveCommand();
            MoveLeft.Subscribe(acceleration.MoveLeft).AddTo(disposable);

            MoveRight = new ReactiveCommand();
            MoveRight.Subscribe(acceleration.MoveRight).AddTo(disposable);

            MoveBottom = new ReactiveCommand();
            MoveBottom.Subscribe(acceleration.MoveBottom).AddTo(disposable);

            MoveTop = new ReactiveCommand();
            MoveTop.Subscribe(acceleration.MoveTop).AddTo(disposable);

            MouseMove = new ReactiveCommand <InputEventModel.EventArgs>();
            MouseMove.Subscribe(acceleration.MouseMove).AddTo(disposable);

            MinVelocity
            .SetValidateNotifyError(x =>
            {
                double min;
                string message;

                if (Utilities.TryParse(x, NumberRange.NonNegative, out min, out message))
                {
                    double max;

                    if (Utilities.TryParse(MaxVelocity.Value, NumberRange.NonNegative, out max) && min >= max)
                    {
                        message = "MinはMax未満でなければなりません。";
                    }
                }

                return(message);
            })
            .Subscribe(_ => MaxVelocity.ForceValidate())
            .AddTo(disposable);

            MinVelocity.ObserveHasErrors
            .ToReadOnlyReactivePropertySlim(mode: ReactivePropertyMode.DistinctUntilChanged)
            .Where(x => !x)
            .Subscribe(_ => MinVelocity.ForceNotify())
            .AddTo(disposable);

            MaxVelocity
            .SetValidateNotifyError(x =>
            {
                double max;
                string message;

                if (Utilities.TryParse(x, NumberRange.NonNegative, out max, out message))
                {
                    double min;

                    if (Utilities.TryParse(MinVelocity.Value, NumberRange.NonNegative, out min) && max <= min)
                    {
                        message = "MinはMax未満でなければなりません。";
                    }
                }

                return(message);
            })
            .Subscribe(_ => MinVelocity.ForceValidate())
            .AddTo(disposable);

            MaxVelocity.ObserveHasErrors
            .ToReadOnlyReactivePropertySlim(mode: ReactivePropertyMode.DistinctUntilChanged)
            .Where(x => !x)
            .Subscribe(_ => MaxVelocity.ForceNotify())
            .AddTo(disposable);

            MinAcceleration
            .SetValidateNotifyError(x =>
            {
                double min;
                string message;

                if (Utilities.TryParse(x, NumberRange.NonNegative, out min, out message))
                {
                    double max;

                    if (Utilities.TryParse(MaxAcceleration.Value, NumberRange.NonNegative, out max) && min >= max)
                    {
                        message = "MinはMax未満でなければなりません。";
                    }
                }

                return(message);
            })
            .Subscribe(_ => MaxAcceleration.ForceValidate())
            .AddTo(disposable);

            MinAcceleration.ObserveHasErrors
            .ToReadOnlyReactivePropertySlim(mode: ReactivePropertyMode.DistinctUntilChanged)
            .Where(x => !x)
            .Subscribe(_ => MinAcceleration.ForceNotify())
            .AddTo(disposable);

            MaxAcceleration
            .SetValidateNotifyError(x =>
            {
                double max;
                string message;

                if (Utilities.TryParse(x, NumberRange.NonNegative, out max, out message))
                {
                    double min;

                    if (Utilities.TryParse(MinAcceleration.Value, NumberRange.NonNegative, out min) && max <= min)
                    {
                        message = "MinはMax未満でなければなりません。";
                    }
                }

                return(message);
            })
            .Subscribe(_ => MinAcceleration.ForceValidate())
            .AddTo(disposable);

            MaxAcceleration.ObserveHasErrors
            .ToReadOnlyReactivePropertySlim(mode: ReactivePropertyMode.DistinctUntilChanged)
            .Where(x => !x)
            .Subscribe(_ => MaxAcceleration.ForceNotify())
            .AddTo(disposable);
        }