@@ -870,6 +870,14 @@ int Alarm::count=0;
870
870
871
871
} // end Alarm::ringerOff
872
872
873
+
874
+
875
+
876
+
877
+
878
+
879
+
880
+
873
881
//-------------------------------------------------------------------------
874
882
//BOP
875
883
// !IROUTINE: Alarm::isRinging - check if Alarm is ringing
@@ -910,6 +918,123 @@ int Alarm::count=0;
910
918
911
919
} // end Alarm::isRinging
912
920
921
+
922
+ //-------------------------------------------------------------------------
923
+ //BOPI
924
+ // !IROUTINE: Alarm::checkRingingDueToRepeatClockTimeStep - an internal routine
925
+ // that checks if a repeat clock alarm should ring when it does a particular
926
+ // time step
927
+ //
928
+ // !INTERFACE:
929
+ int Alarm ::checkRingingDueToRepeatClockTimeStep (Time & prevTime , Time & currTime , TimeInterval & timeStep , bool & ringingDueToTimeStep ) const {
930
+ //
931
+ // !RETURN VALUE:
932
+ // return code
933
+ //
934
+ // !ARGUMENTS:
935
+ // prevTime - The time before it took the time step
936
+ // currTime - The time now that it look the time step
937
+ // timeStep - The time step that it took to get from prev to curr
938
+ // ringingDuetoTimeStep - should the alarm rign for the specified time step
939
+ //
940
+ // !DESCRIPTION:
941
+ // an internal routine that checks if a repeat clock alarm should ring when it does a particular
942
+ // time step. Note that this doesn't change any state in the alarm, it just checks for ringing.
943
+ //
944
+ //EOPI
945
+ // !REQUIREMENTS: developer's guide for classes
946
+
947
+ #undef ESMC_METHOD
948
+ #define ESMC_METHOD "ESMCI::Alarm::checkRingingDueToRepeatClockTimeStep()"
949
+
950
+ // Initialize return code; assume routine not implemented
951
+ int rc = ESMC_RC_NOT_IMPL ;
952
+
953
+ // Useful
954
+ TimeInterval zeroTimeInterval (0 ,0 ,1 ,0 ,0 ,0 );
955
+ Time repeatTime = clock -> startTime + clock -> repeatDuration ;
956
+
957
+ // Init
958
+ ringingDueToTimeStep = false;
959
+
960
+ // If the timeStep is bigger than the repeatDuration, then alarms are
961
+ // ringing no matter what
962
+ if (timeStep >= clock -> repeatDuration ) {
963
+ ringingDueToTimeStep = true;
964
+ }
965
+
966
+ // If not ringing yet, check for alarms due to ringTime and implied ringTimes
967
+ if (!ringingDueToTimeStep ) {
968
+
969
+ // If no ringInterval, then just check the single ringTime
970
+ if (ringInterval == zeroTimeInterval ) {
971
+ // If currTime is after prevtime, then it needs to be within prevTime to currTime
972
+ if (currTime > prevTime ) {
973
+ if ((ringTime > prevTime ) && (ringTime <= currTime )) {
974
+ ringingDueToTimeStep = true;
975
+ }
976
+ } else if (currTime < prevTime ) { // It needs to be within the wrapped time
977
+ if ((ringTime > prevTime ) && (ringTime < repeatTime )) {
978
+ ringingDueToTimeStep = true;
979
+ } else if ((ringTime >= clock -> startTime ) && (ringTime <= currTime )) {
980
+ ringingDueToTimeStep = true;
981
+ }
982
+ } else { // prevTime == currTime, it has to be right on the currTime
983
+ if (ringTime == currTime ) {
984
+ ringingDueToTimeStep = true;
985
+ }
986
+ }
987
+ } else { // Check for ringing due to ringInterval
988
+
989
+ // Loop checking the set of times implied by the ringInterval
990
+ bool wrapped = false;
991
+ Time tmpRingTime = ringTime ;
992
+ while (true) {
993
+
994
+ // Check for tmpRingTime ringing
995
+ if (currTime > prevTime ) { // If currTime is after prevtime, then it needs to be within prevTime to currTime
996
+ if ((tmpRingTime > prevTime ) && (tmpRingTime <= currTime )) {
997
+ ringingDueToTimeStep = true;
998
+ }
999
+ } else if (currTime < prevTime ) { // It needs to be within the wrapped time
1000
+ if ((tmpRingTime > prevTime ) && (tmpRingTime < repeatTime )) {
1001
+ ringingDueToTimeStep = true;
1002
+ } else if ((tmpRingTime >= clock -> startTime ) && (tmpRingTime <= currTime )) {
1003
+ ringingDueToTimeStep = true;
1004
+ }
1005
+ } else { // prevTime == currTime, it has to be right on the currTime
1006
+ if (tmpRingTime == currTime ) {
1007
+ ringingDueToTimeStep = true;
1008
+ }
1009
+ }
1010
+
1011
+ // Check for being done
1012
+ if (ringingDueToTimeStep ) break ;
1013
+
1014
+ // Advance to the next ringtime
1015
+ tmpRingTime = tmpRingTime + ringInterval ;
1016
+
1017
+ // If we're past repeatTime, then wrap
1018
+ if (tmpRingTime >= repeatTime ) {
1019
+ tmpRingTime = clock -> startTime + (tmpRingTime - repeatTime );
1020
+ wrapped = true;
1021
+ }
1022
+
1023
+ // If we've wrapped and passed the original ringTime, then stop
1024
+ if (wrapped && (tmpRingTime > ringTime )) break ;
1025
+
1026
+ }
1027
+ }
1028
+ }
1029
+
1030
+
1031
+ // Output success
1032
+ rc = ESMF_SUCCESS ;
1033
+ return (rc );
1034
+
1035
+ } // end Alarm::checkRingingDueToRepeatClockTimeStep
1036
+
1037
+
913
1038
//-------------------------------------------------------------------------
914
1039
//BOP
915
1040
// !IROUTINE: Alarm::willRingNext - check if Alarm will ring upon the next clock timestep
@@ -963,10 +1088,30 @@ int Alarm::count=0;
963
1088
Time clockNextTime ;
964
1089
clock -> Clock ::getNextTime (& clockNextTime , timeStep );
965
1090
1091
+
966
1092
// if specified, use passed-in timestep, otherwise use clock's
967
1093
TimeInterval tStep = (timeStep != ESMC_NULL_POINTER ) ?
968
1094
* timeStep : clock -> timeStep ;
969
1095
1096
+
1097
+ // IF a repeat clock, handle that and leave
1098
+ if (clock -> repeat ) {
1099
+ int localrc ;
1100
+ bool willRing = false;
1101
+
1102
+ // Check if the alarm should go off due to the time step that will happen next
1103
+ bool ringingDueToCurrTimeStep = false;
1104
+ localrc = checkRingingDueToRepeatClockTimeStep (clock -> currTime , clockNextTime , tStep , willRing );
1105
+ if (ESMC_LogDefault .MsgFoundError (localrc , ESMCI_ERR_PASSTHRU , ESMC_CONTEXT , rc )) {
1106
+ return false;
1107
+ }
1108
+
1109
+ // Set output and exit
1110
+ if (rc != ESMC_NULL_POINTER ) * rc = ESMF_SUCCESS ;
1111
+ return (willRing );
1112
+ }
1113
+
1114
+
970
1115
// get timestep direction: positive or negative
971
1116
bool positive = tStep .TimeInterval ::absValue () == tStep ? true : false;
972
1117
@@ -1181,9 +1326,10 @@ int Alarm::count=0;
1181
1326
//EOP
1182
1327
// !REQUIREMENTS: TMG4.4, 4.6
1183
1328
1184
- #undef ESMC_METHOD
1185
- #define ESMC_METHOD "ESMCI::Alarm::checkRingTime()"
1186
-
1329
+ #undef ESMC_METHOD
1330
+ #define ESMC_METHOD "ESMCI::Alarm::checkRingTime()"
1331
+ int localrc ;
1332
+
1187
1333
if (this == ESMC_NULL_POINTER ) {
1188
1334
ESMC_LogDefault .MsgFoundError (ESMC_RC_PTR_NULL ,
1189
1335
"; 'this' pointer is NULL." , ESMC_CONTEXT , rc );
@@ -1192,7 +1338,7 @@ int Alarm::count=0;
1192
1338
1193
1339
// default return code
1194
1340
if (rc != ESMC_NULL_POINTER ) * rc = ESMC_RC_NOT_IMPL ;
1195
-
1341
+
1196
1342
// must be associated with a clock
1197
1343
if (clock == ESMC_NULL_POINTER ) {
1198
1344
char logMsg [2 * ESMF_MAXSTR ];
@@ -1231,84 +1377,13 @@ int Alarm::count=0;
1231
1377
// Time at which we repeat
1232
1378
Time repeatTime = clock -> startTime + clock -> repeatDuration ;
1233
1379
1234
- //// See what the ringing state is due to the time step that just happened
1380
+ // Check if the alarm should go off due to the time step that just happened
1235
1381
bool ringingDueToCurrTimeStep = false;
1236
-
1237
- // If the timeStep is bigger than the repeatDuration, then alarms are
1238
- // ringing no matter what
1239
- if (clock -> currAdvanceTimeStep >= clock -> repeatDuration ) {
1240
- ringingDueToCurrTimeStep = true;
1382
+ localrc = checkRingingDueToRepeatClockTimeStep (prevTime , clock -> currTime , clock -> currAdvanceTimeStep , ringingDueToCurrTimeStep );
1383
+ if (ESMC_LogDefault .MsgFoundError (localrc , ESMCI_ERR_PASSTHRU , ESMC_CONTEXT , rc )) {
1384
+ return false;
1241
1385
}
1242
1386
1243
-
1244
- // If not ringing yet, check for alarms due to ringTime and implied ringTimes
1245
- if (!ringingDueToCurrTimeStep ) {
1246
-
1247
- // If no ringInterval, then just check the single ringTime
1248
- if (ringInterval == zeroTimeInterval ) {
1249
- // If currTime is after prevtime, then it needs to be within prevTime to currTime
1250
- if (clock -> currTime > prevTime ) {
1251
- if ((ringTime > prevTime ) && (ringTime <= clock -> currTime )) {
1252
- ringingDueToCurrTimeStep = true;
1253
- }
1254
- } else if (clock -> currTime < prevTime ) { // It needs to be within the wrapped time
1255
- if ((ringTime > prevTime ) && (ringTime < repeatTime )) {
1256
- ringingDueToCurrTimeStep = true;
1257
- } else if ((ringTime >= clock -> startTime ) && (ringTime <= clock -> currTime )) {
1258
- ringingDueToCurrTimeStep = true;
1259
- }
1260
- } else { // prevTime == currTime, it has to be right on the currTime
1261
- if (ringTime == clock -> currTime ) {
1262
- ringingDueToCurrTimeStep = true;
1263
- }
1264
- }
1265
- } else { // Check for ringing due to ringInterval
1266
-
1267
- // Loop checking the set of times implied by the ringInterval
1268
- bool wrapped = false;
1269
- Time tmpRingTime = ringTime ;
1270
- while (true) {
1271
-
1272
- // Check for tmpRingTime ringing
1273
- if (clock -> currTime > prevTime ) { // If currTime is after prevtime, then it needs to be within prevTime to currTime
1274
- if ((tmpRingTime > prevTime ) && (tmpRingTime <= clock -> currTime )) {
1275
- ringingDueToCurrTimeStep = true;
1276
- }
1277
- } else if (clock -> currTime < prevTime ) { // It needs to be within the wrapped time
1278
- if ((tmpRingTime > prevTime ) && (tmpRingTime < repeatTime )) {
1279
- ringingDueToCurrTimeStep = true;
1280
- } else if ((tmpRingTime >= clock -> startTime ) && (tmpRingTime <= clock -> currTime )) {
1281
- ringingDueToCurrTimeStep = true;
1282
- }
1283
- } else { // prevTime == currTime, it has to be right on the currTime
1284
- if (tmpRingTime == clock -> currTime ) {
1285
- ringingDueToCurrTimeStep = true;
1286
- }
1287
- }
1288
-
1289
- // Check for being done
1290
- if (ringingDueToCurrTimeStep ) break ;
1291
-
1292
- // Advance to the next ringtime
1293
- tmpRingTime = tmpRingTime + ringInterval ;
1294
-
1295
- // If we're past repeatTime, then wrap
1296
- if (tmpRingTime >= repeatTime ) {
1297
- tmpRingTime = clock -> startTime + (tmpRingTime - repeatTime );
1298
- wrapped = true;
1299
- }
1300
-
1301
- // If we've wrapped and passed the original ringTime, then stop
1302
- if (wrapped && (tmpRingTime > ringTime )) break ;
1303
-
1304
- }
1305
- }
1306
- }
1307
-
1308
-
1309
-
1310
- //// Check for ringing due to repeatCount??
1311
-
1312
1387
// Turn alarm on and off depending on whether we are on the current time step and whether we were already on
1313
1388
if (ringingDueToCurrTimeStep ) {
1314
1389
0 commit comments