@@ -1007,6 +1007,7 @@ public abstract class CVCWithFrames : CabViewControl
1007
1007
public bool MouseControl ;
1008
1008
public int Orientation ;
1009
1009
public int Direction ;
1010
+ public bool Reversed { get ; protected set ; } = false ;
1010
1011
1011
1012
public List < double > Values
1012
1013
{
@@ -1022,8 +1023,8 @@ public class CVCDiscrete : CVCWithFrames
1022
1023
public List < int > Positions = new List < int > ( ) ;
1023
1024
1024
1025
private int _ValuesRead ;
1025
- private int numPositions ;
1026
- private bool canFill = true ;
1026
+ private int NumPositions ;
1027
+ private bool CanFill = true ;
1027
1028
1028
1029
public struct NewScreenData
1029
1030
{
@@ -1076,7 +1077,7 @@ public CVCDiscrete(STFReader stf, string basepath, DiscreteStates discreteState)
1076
1077
stf . MustMatch ( "(" ) ;
1077
1078
// If Positions are not filled before by Values
1078
1079
bool shouldFill = ( Positions . Count == 0 ) ;
1079
- numPositions = stf . ReadInt ( null ) ; // Number of Positions
1080
+ NumPositions = stf . ReadInt ( null ) ; // Number of Positions
1080
1081
1081
1082
var minPosition = 0 ;
1082
1083
var positionsRead = 0 ;
@@ -1117,20 +1118,20 @@ public CVCDiscrete(STFReader stf, string basepath, DiscreteStates discreteState)
1117
1118
1118
1119
// Check if eligible for filling
1119
1120
1120
- if ( Positions . Count > 1 && Positions [ 0 ] != 0 ) canFill = false ;
1121
+ if ( Positions . Count > 1 && Positions [ 0 ] != 0 ) CanFill = false ;
1121
1122
else
1122
1123
{
1123
1124
for ( var iPos = 1 ; iPos <= Positions . Count - 1 ; iPos ++ )
1124
1125
{
1125
1126
if ( Positions [ iPos ] > Positions [ iPos - 1 ] ) continue ;
1126
- canFill = false ;
1127
+ CanFill = false ;
1127
1128
break ;
1128
1129
}
1129
1130
}
1130
1131
1131
1132
// This is a protection against GP40 locomotives that erroneously have positions pointing beyond frame count limit.
1132
1133
1133
- if ( Positions . Count > 1 && canFill && Positions . Count < FramesCount && Positions [ Positions . Count - 1 ] >= FramesCount && Positions [ 0 ] == 0 )
1134
+ if ( Positions . Count > 1 && CanFill && Positions . Count < FramesCount && Positions [ Positions . Count - 1 ] >= FramesCount && Positions [ 0 ] == 0 )
1134
1135
{
1135
1136
STFException . TraceInformation ( stf , "Some NumPositions entries refer to non-exisiting frames, trying to renumber" ) ;
1136
1137
Positions [ Positions . Count - 1 ] = FramesCount - 1 ;
@@ -1155,7 +1156,7 @@ public CVCDiscrete(STFReader stf, string basepath, DiscreteStates discreteState)
1155
1156
}
1156
1157
// Avoid later repositioning, put every value to its Position
1157
1158
// But before resize Values if needed
1158
- if ( numValues != numPositions )
1159
+ if ( numValues != NumPositions )
1159
1160
{
1160
1161
while ( Values . Count <= Positions [ _ValuesRead ] )
1161
1162
{
@@ -1214,7 +1215,7 @@ public CVCDiscrete(STFReader stf, string basepath, DiscreteStates discreteState)
1214
1215
1215
1216
// Only shuffle data in following cases
1216
1217
1217
- if ( Values . Count != Positions . Count || ( Values . Count < FramesCount & canFill ) || ( Values . Count > 0 && Values [ 0 ] == Values [ Values . Count - 1 ] && Values [ 0 ] == 0 ) )
1218
+ if ( Values . Count != Positions . Count || ( Values . Count < FramesCount & CanFill ) || ( Values . Count > 0 && Values [ 0 ] == Values [ Values . Count - 1 ] && Values [ 0 ] == 0 ) )
1218
1219
{
1219
1220
1220
1221
// Fixup Positions and Values collections first
@@ -1257,7 +1258,11 @@ public CVCDiscrete(STFReader stf, string basepath, DiscreteStates discreteState)
1257
1258
// Fill empty Values
1258
1259
for ( int i = 0 ; i < ( FramesCount - 1 ) ; i ++ )
1259
1260
Values . Add ( 0 ) ;
1260
- Values [ 0 ] = MinValue ;
1261
+ // Some dummy controls will have only one frame
1262
+ if ( Values . Count > 0 )
1263
+ Values [ 0 ] = MinValue ;
1264
+ else
1265
+ Values . Add ( MinValue ) ;
1261
1266
1262
1267
// Add maximum value to the end
1263
1268
Values . Add ( MaxValue ) ;
@@ -1353,13 +1358,21 @@ public CVCDiscrete(STFReader stf, string basepath, DiscreteStates discreteState)
1353
1358
break ;
1354
1359
}
1355
1360
}
1356
- // catch (Exception error)
1357
- // {
1358
- // if (error is STFException) // Parsing error, so pass it on
1359
- // throw;
1360
- // else // Unexpected error, so provide a hint
1361
- // throw new STFException(stf, "Problem with NumPositions/NumValues/NumFrames/ScaleRange");
1362
- // } // End of Need check the Values collection for validity
1361
+ // catch (Exception error)
1362
+ // {
1363
+ // if (error is STFException) // Parsing error, so pass it on
1364
+ // throw;
1365
+ // else // Unexpected error, so provide a hint
1366
+ // throw new STFException(stf, "Problem with NumPositions/NumValues/NumFrames/ScaleRange");
1367
+ // } // End of Need check the Values collection for validity
1368
+
1369
+ // Ensure resulting set of values has the correct format (sorted least to greatest) and resort
1370
+ // Assume values have been entered in reverse order if final value is less than initial value
1371
+ if ( Values . Count > 0 && Values [ 0 ] > Values [ Values . Count - 1 ] )
1372
+ Reversed = true ;
1373
+ // Force sort values from least to greatest
1374
+ Values . Sort ( ) ;
1375
+
1363
1376
} // End of Constructor
1364
1377
1365
1378
protected void ParseNewScreen ( STFReader stf )
@@ -1407,7 +1420,7 @@ public CVCMultiStateDisplay(STFReader stf, string basepath)
1407
1420
stf . ParseBlock ( new STFReader . TokenProcessor [ ] {
1408
1421
new STFReader . TokenProcessor ( "style" , ( ) => { MSStyles . Add ( ParseNumStyle ( stf ) ) ;
1409
1422
} ) ,
1410
- new STFReader . TokenProcessor ( "switchval" , ( ) => { Values . Add ( stf . ReadFloatBlock ( STFReader . UNITS . None , null ) )
1423
+ new STFReader . TokenProcessor ( "switchval" , ( ) => { Values . Add ( stf . ReadDoubleBlock ( null ) )
1411
1424
; } ) ,
1412
1425
} ) ; } ) ,
1413
1426
} ) ;
@@ -1419,6 +1432,13 @@ public CVCMultiStateDisplay(STFReader stf, string basepath)
1419
1432
new STFReader . TokenProcessor ( "ortsscreenpage" , ( ) => { ParseScreen ( stf ) ; } ) ,
1420
1433
new STFReader . TokenProcessor ( "ortscabviewpoint" , ( ) => { ParseCabViewpoint ( stf ) ; } ) ,
1421
1434
} ) ;
1435
+
1436
+ // Ensure resulting set of values has the correct format (sorted least to greatest) and resort
1437
+ // Assume values have been entered in reverse order if final value is less than initial value
1438
+ if ( Values . Count > 0 && Values [ 0 ] > Values [ Values . Count - 1 ] )
1439
+ Reversed = true ;
1440
+ // Force sort values from least to greatest
1441
+ Values . Sort ( ) ;
1422
1442
}
1423
1443
protected int ParseNumStyle ( STFReader stf )
1424
1444
{
@@ -1457,7 +1477,7 @@ public CVCAnimatedDisplay(STFReader stf, string basepath)
1457
1477
stf . ParseBlock ( new STFReader . TokenProcessor [ ] {
1458
1478
new STFReader . TokenProcessor ( "style" , ( ) => { MSStyles . Add ( ParseNumStyle ( stf ) ) ;
1459
1479
} ) ,
1460
- new STFReader . TokenProcessor ( "switchval" , ( ) => { Values . Add ( stf . ReadFloatBlock ( STFReader . UNITS . None , null ) )
1480
+ new STFReader . TokenProcessor ( "switchval" , ( ) => { Values . Add ( stf . ReadDoubleBlock ( null ) )
1461
1481
; } ) ,
1462
1482
} ) ; } ) ,
1463
1483
} ) ;
@@ -1469,6 +1489,13 @@ public CVCAnimatedDisplay(STFReader stf, string basepath)
1469
1489
new STFReader . TokenProcessor ( "ortsscreenpage" , ( ) => { ParseScreen ( stf ) ; } ) ,
1470
1490
new STFReader . TokenProcessor ( "ortscabviewpoint" , ( ) => { ParseCabViewpoint ( stf ) ; } ) ,
1471
1491
} ) ;
1492
+
1493
+ // Ensure resulting set of values has the correct format (sorted least to greatest) and resort
1494
+ // Assume values have been entered in reverse order if final value is less than initial value
1495
+ if ( Values . Count > 0 && Values [ 0 ] > Values [ Values . Count - 1 ] )
1496
+ Reversed = true ;
1497
+ // Force sort values from least to greatest
1498
+ Values . Sort ( ) ;
1472
1499
}
1473
1500
protected int ParseNumStyle ( STFReader stf )
1474
1501
{
0 commit comments