1 using System; 2 using System.Reactive.Linq; 3 using Reactive.Bindings; 4 using Reactive.Bindings.Extensions; 5 using TrainEditor2.Models.Trains; 6 using TrainManager.Handles; 7 8 namespace TrainEditor2.ViewModels.Trains 9 { 10 internal class HandleViewModel : BaseViewModel 11 { 12 internal ReactiveProperty<HandleType> HandleType 13 { 14 get; 15 } 16 17 internal ReactiveProperty<int> PowerNotches 18 { 19 get; 20 } 21 22 internal ReactiveProperty<int> BrakeNotches 23 { 24 get; 25 } 26 27 internal ReactiveProperty<int> PowerNotchReduceSteps 28 { 29 get; 30 } 31 32 internal ReactiveProperty<EbHandleBehaviour> HandleBehaviour 33 { 34 get; 35 } 36 37 internal ReactiveProperty<LocoBrakeType> LocoBrake 38 { 39 get; 40 } 41 42 internal ReactiveProperty<int> LocoBrakeNotches 43 { 44 get; 45 } 46 47 internal ReactiveProperty<int> DriverPowerNotches 48 { 49 get; 50 } 51 52 internal ReactiveProperty<int> DriverBrakeNotches 53 { 54 get; 55 } 56 HandleViewModel(Handle handle, Train train)57 internal HandleViewModel(Handle handle, Train train) 58 { 59 HandleType = handle 60 .ToReactivePropertyAsSynchronized(x => x.HandleType) 61 .AddTo(disposable); 62 63 PowerNotches = handle 64 .ToReactivePropertyAsSynchronized(x => x.PowerNotches, ignoreValidationErrorValue: true) 65 .AddTo(disposable); 66 67 PowerNotches.Subscribe(_ => train.ApplyPowerNotchesToCar()).AddTo(disposable); 68 69 BrakeNotches = handle 70 .ToReactivePropertyAsSynchronized(x => x.BrakeNotches, ignoreValidationErrorValue: true) 71 .SetValidateNotifyError(x => 72 { 73 if (x == 0 && train.Device.HoldBrake) 74 { 75 return "BrakeNotches must be at least 1 if HoldBrake is set."; 76 } 77 78 return null; 79 }) 80 .AddTo(disposable); 81 82 BrakeNotches.Subscribe(_ => train.ApplyBrakeNotchesToCar()).AddTo(disposable); 83 84 PowerNotchReduceSteps = handle 85 .ToReactivePropertyAsSynchronized(x => x.PowerNotchReduceSteps) 86 .AddTo(disposable); 87 88 HandleBehaviour = handle 89 .ToReactivePropertyAsSynchronized(x => x.HandleBehaviour) 90 .AddTo(disposable); 91 92 LocoBrake = handle 93 .ToReactivePropertyAsSynchronized(x => x.LocoBrake) 94 .AddTo(disposable); 95 96 LocoBrakeNotches = handle 97 .ToReactivePropertyAsSynchronized(x => x.LocoBrakeNotches) 98 .AddTo(disposable); 99 100 LocoBrakeNotches.Subscribe(_ => train.ApplyLocoBrakeNotchesToCar()).AddTo(disposable); 101 102 DriverPowerNotches = handle 103 .ToReactivePropertyAsSynchronized(x => x.DriverPowerNotches, ignoreValidationErrorValue: true) 104 .AddTo(disposable); 105 106 DriverBrakeNotches = handle 107 .ToReactivePropertyAsSynchronized(x => x.DriverBrakeNotches, ignoreValidationErrorValue: true) 108 .AddTo(disposable); 109 110 PowerNotches 111 .SetValidateNotifyError(x => 112 { 113 if (x < DriverPowerNotches.Value) 114 { 115 return "DriverPowerNotches must be less than or equal to PowerNotches."; 116 } 117 118 return null; 119 }) 120 .Subscribe(_ => DriverPowerNotches.ForceValidate()) 121 .AddTo(disposable); 122 123 PowerNotches 124 .ObserveHasErrors 125 .ToReadOnlyReactivePropertySlim(mode: ReactivePropertyMode.DistinctUntilChanged) 126 .Where(x => !x) 127 .Subscribe(_ => PowerNotches.ForceNotify()) 128 .AddTo(disposable); 129 130 BrakeNotches 131 .SetValidateNotifyError(x => 132 { 133 if (x < DriverBrakeNotches.Value) 134 { 135 return "DriverBrakeNotches must be less than or equal to BrakeNotches."; 136 } 137 138 return null; 139 }) 140 .Subscribe(_ => DriverBrakeNotches.ForceValidate()) 141 .AddTo(disposable); 142 143 BrakeNotches 144 .ObserveHasErrors 145 .ToReadOnlyReactivePropertySlim(mode: ReactivePropertyMode.DistinctUntilChanged) 146 .Where(x => !x) 147 .Subscribe(_ => BrakeNotches.ForceNotify()) 148 .AddTo(disposable); 149 150 DriverPowerNotches 151 .SetValidateNotifyError(x => 152 { 153 if (x > PowerNotches.Value) 154 { 155 return "DriverPowerNotches must be less than or equal to PowerNotches."; 156 } 157 158 return null; 159 }) 160 .Subscribe(_ => PowerNotches.ForceValidate()) 161 .AddTo(disposable); 162 163 DriverPowerNotches 164 .ObserveHasErrors 165 .ToReadOnlyReactivePropertySlim(mode: ReactivePropertyMode.DistinctUntilChanged) 166 .Where(x => !x) 167 .Subscribe(_ => DriverPowerNotches.ForceNotify()) 168 .AddTo(disposable); 169 170 DriverBrakeNotches 171 .SetValidateNotifyError(x => 172 { 173 if (x > BrakeNotches.Value) 174 { 175 return "DriverBrakeNotches must be less than or equal to BrakeNotches."; 176 } 177 178 return null; 179 }) 180 .Subscribe(_ => BrakeNotches.ForceValidate()) 181 .AddTo(disposable); 182 183 DriverBrakeNotches 184 .ObserveHasErrors 185 .ToReadOnlyReactivePropertySlim(mode: ReactivePropertyMode.DistinctUntilChanged) 186 .Where(x => !x) 187 .Subscribe(_ => DriverBrakeNotches.ForceNotify()) 188 .AddTo(disposable); 189 } 190 } 191 } 192