Skip to content

Commit 9eecb9c

Browse files
committed
RANDOM_CALL, RANDOM_FOLLOW
1 parent 6c26235 commit 9eecb9c

File tree

6 files changed

+99
-2
lines changed

6 files changed

+99
-2
lines changed

EXRAIL2.cpp

Lines changed: 27 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -969,7 +969,33 @@ void RMFT2::loop2() {
969969
progCounter=routeLookup->find(operand);
970970
if (progCounter<0) kill(F("CALL unknown"),operand);
971971
return;
972-
972+
973+
974+
case OPCODE_RANDOM_FOLLOW:
975+
// operand is number to choose from
976+
{
977+
auto newroute=getOperand(1+(millis()%operand));
978+
progCounter=routeLookup->find(newroute);
979+
if (progCounter<0) kill(F("RANDOM_FOLLOW unknown"), newroute);
980+
}
981+
return;
982+
983+
case OPCODE_RANDOM_CALL:
984+
// operand is number to choose from
985+
if (stackDepth==MAX_STACK_DEPTH) {
986+
kill(F("CALL stack"), stackDepth);
987+
return;
988+
}
989+
{
990+
auto newroute=getOperand(1+(millis()%operand));
991+
992+
// return position is after the RANDOM_CALL + all its operands
993+
callStack[stackDepth++]=progCounter+3*(operand+1);
994+
progCounter=routeLookup->find(newroute);
995+
if (progCounter<0) kill(F("CALL unknown"),newroute);
996+
}
997+
return;
998+
973999
case OPCODE_RETURN:
9741000
if (stackDepth==0) {
9751001
kill(F("RETURN stack"));

EXRAIL2.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,7 @@ enum OPCODE : byte {OPCODE_THROW,OPCODE_CLOSE,OPCODE_TOGGLE_TURNOUT,
8888
OPCODE_WAIT_WHILE_RED,
8989
OPCODE_SAVE_SPEED,OPCODE_RESTORE_SPEED,
9090
OPCODE_XSAVE_SPEED,OPCODE_XRESTORE_SPEED,
91+
OPCODE_RANDOM_CALL,OPCODE_RANDOM_FOLLOW,
9192

9293
// OPcodes below this point are skip-nesting IF operations
9394
// placed here so that they may be skipped as a group

EXRAIL2MacroReset.h

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -154,6 +154,8 @@
154154
#undef POM
155155
#undef POWEROFF
156156
#undef POWERON
157+
#undef RANDOM_CALL
158+
#undef RANDOM_FOLLOW
157159
#undef READ_LOCO
158160
#undef RED
159161
#undef RESERVE
@@ -1070,6 +1072,23 @@
10701072
* @brief Powers ON all tracks
10711073
*/
10721074
#define POWERON
1075+
/**
1076+
* @def RANDOM_CALL(sequence_id...)
1077+
* @brief CALL to another sequence randomly chosen from list
1078+
* @see CALL
1079+
* @param sequence_id.. list of SEQUENCE that may be called, each must terminate or RETURN
1080+
*
1081+
*/
1082+
#define RANDOM_CALL(sequence_id...)
1083+
1084+
/**
1085+
* @def RANDOM_FOLLOW(sequence_id...)
1086+
* @brief jump to another sequence randomly chosen from list
1087+
* @see FOLLOW
1088+
* @param sequence_id.. list of SEQUENCE that may be followed
1089+
*/
1090+
#define RANDOM_FOLLOW(sequence_id...)
1091+
10731092
/**
10741093
* @def READ_LOCO
10751094
* @brief Reads loco Id from prog track and sets currenmt task loco id.

EXRAILAsserts.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -99,6 +99,14 @@ constexpr bool unsafePin(const int16_t value, const int16_t pos=0 ) {
9999
#define CALL(id) static_assert(seqCount(id)>0,"Sequence not found");
100100
#undef FOLLOW
101101
#define FOLLOW(id) static_assert(seqCount(id)>0,"Sequence not found");
102+
103+
// random call and follow will generate CALL macros here which
104+
// will check for invalid sequences
105+
#define RANDOM_CALL(...) \
106+
ZCRIP(FOR_EACH_NARG(__VA_ARGS__))(__VA_ARGS__)
107+
#define RANDOM_FOLLOW(...) \
108+
ZCRIP(FOR_EACH_NARG(__VA_ARGS__))(__VA_ARGS__)
109+
102110
#undef START
103111
#define START(id) static_assert(seqCount(id)>0,"Sequence not found");
104112
#undef START_SHARED

EXRAILMacros.h

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,27 @@
8080
// NEOPIXEL RG generator for NEOPIXEL_SIGNAL
8181
#define NeoRGB(red,green,blue) (((uint32_t)(red & 0xff)<<16) | ((uint32_t)(green & 0xff)<<8) | (uint32_t)(blue & 0xff))
8282

83+
// Collection of macros to assist variadic exrail macros
84+
// in particular RANDOMCALL and RANDOMFOLLOW
85+
// Count the number of arguments
86+
#define FOR_EACH_NARG(...) FOR_EACH_NARG_HELPER(__VA_ARGS__,8,7, 6,5,4, 3, 2, 1, 0)
87+
#define FOR_EACH_NARG_HELPER(_1, _2, _3, _4, _5, _6, _7, _8, N, ...) N
88+
// Force proper expansion (extra indirection to resolve `##`)
89+
#define _CONCAT_(a, b) a##b
90+
#define _EXPAND_(a) a
91+
92+
#define ZC0()
93+
#define ZC1(_1) CALL(_1)
94+
#define ZC2(_1,_2) CALL(_1) CALL(_2)
95+
#define ZC3(_1,_2,_3) CALL(_1) CALL(_2) CALL(_3)
96+
#define ZC4(_1,_2,_3,_4) CALL(_1) CALL(_2) CALL(_3) CALL(_4)
97+
#define ZC5(_1,_2,_3,_4,_5) CALL(_1) CALL(_2) CALL(_3) CALL(_4) CALL(_5)
98+
#define ZC6(_1,_2,_3,_4,_5,_6) CALL(_1) CALL(_2) CALL(_3) CALL(_4) CALL(_5) CALL(_6)
99+
#define ZC7(_1,_2,_3,_4,_5,_6,_7) CALL(_1) CALL(_2) CALL(_3) CALL(_4) CALL(_5) CALL(_6) CALL(_7)
100+
#define ZC8(_1,_2,_3,_4,_5,_6,_7,_8) CALL(_1) CALL(_2) CALL(_3) CALL(_4) CALL(_5) CALL(_6) CALL(_7) CALL(_8)
101+
#define ZCRIP(count) _EXPAND_(_CONCAT_(ZC,count))
102+
103+
83104
// Pass 1 Implements aliases
84105
#include "EXRAIL2MacroReset.h"
85106
#undef ALIAS
@@ -596,6 +617,12 @@ int RMFT2::onLCCLookup[RMFT2::countLCCLookup];
596617
#define POWERON OPCODE_POWERON,0,0,
597618
#define PRINT(msg) OPCODE_PRINT,V(__COUNTER__ - StringMacroTracker2),
598619
#define PARSE(msg) PRINT(msg)
620+
#define RANDOM_CALL(...) \
621+
OPCODE_RANDOM_CALL,V(FOR_EACH_NARG(__VA_ARGS__)), \
622+
ZCRIP(FOR_EACH_NARG(__VA_ARGS__))(__VA_ARGS__)
623+
#define RANDOM_FOLLOW(...) \
624+
OPCODE_RANDOM_FOLLOW,V(FOR_EACH_NARG(__VA_ARGS__)), \
625+
ZCRIP(FOR_EACH_NARG(__VA_ARGS__))(__VA_ARGS__)
599626
#define READ_LOCO OPCODE_READ_LOCO1,0,0,OPCODE_READ_LOCO2,0,0,
600627
#define RED(signal_id) OPCODE_RED,V(signal_id),
601628
#define RESERVE(blockid) OPCODE_RESERVE,V(blockid),

EXRAILTest.h

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -96,4 +96,20 @@ ROUTE(7000, "Route state tests")
9696
XRESTORE_SPEED(4)
9797
PRINT("7401 Speed 4 restored")
9898
DONE
99-
99+
100+
SEQUENCE(7500)
101+
PRINT("7500 Testing RANDOM_CALL and RANDOM_FOLLOW")
102+
RANDOM_CALL(7501, 7502, 7503,9191)
103+
PRINT("7500 Returned from RANDOM_CALL")
104+
RANDOM_FOLLOW(7511, 7512, 7513)
105+
PRINT("7500 ERROR Returned from RANDOM_FOLLOW")
106+
DONE
107+
108+
SEQUENCE(7501) PRINT("7501 RANDOM_CALL") RETURN
109+
SEQUENCE(7502) PRINT("7502 RANDOM_CALL") RETURN
110+
SEQUENCE(7503) PRINT("7503 RANDOM_CALL") RETURN
111+
112+
SEQUENCE(7511) PRINT("7511 RANDOM_FOLLOW") DONE
113+
SEQUENCE(7512) PRINT("7512 RANDOM_FOLLOW") DONE
114+
SEQUENCE(7513) PRINT("7513 RANDOM_FOLLOW") DONE
115+

0 commit comments

Comments
 (0)