diff --git a/RMFT2.cpp b/RMFT2.cpp index 8c22b43..2018532 100644 --- a/RMFT2.cpp +++ b/RMFT2.cpp @@ -275,6 +275,7 @@ RMFT2::RMFT2(int progCtr) { forward=true; invert=false; stackDepth=0; + onTurnoutId=0; // Not handling an ONTHROW/ONCLOSE // chain into ring of RMFTs if (loopTask==NULL) { @@ -685,15 +686,28 @@ void RMFT2::kill(const FSH * reason, int operand) { return; } } - void RMFT2::turnoutEvent(VPIN id, bool closed) { + void RMFT2::turnoutEvent(int16_t turnoutId, bool closed) { + + // Check we dont already have a task running this turnout + RMFT2 * task=loopTask; + while(task) { + if (task->onTurnoutId==turnoutId) { + DIAG(F("Recursive ONTHROW/ONCLOSE for Turnout %d"),turnoutId); + return; + } + task=task->next; + if (task==loopTask) break; + } + // Hunt for an ONTHROW/ONCLOSE for this turnout byte huntFor=closed ? OPCODE_ONCLOSE : OPCODE_ONTHROW ; // caution hides class progCounter; for (int progCounter=0;; SKIPOP){ byte opcode=GET_OPCODE; if (opcode==OPCODE_ENDEXRAIL) return; if (opcode!=huntFor) continue; - if (id!=GET_OPERAND(0)) continue; - new RMFT2(progCounter); // new task starts at this instruction + if (turnoutId!=(int16_t)GET_OPERAND(0)) continue; + task=new RMFT2(progCounter); // new task starts at this instruction + task->onTurnoutId=turnoutId; // flag for recursion detector return; } } diff --git a/RMFT2.h b/RMFT2.h index 10c147a..bb205c3 100644 --- a/RMFT2.h +++ b/RMFT2.h @@ -68,7 +68,7 @@ enum OPCODE : byte {OPCODE_THROW,OPCODE_CLOSE, static void readLocoCallback(int16_t cv); static void emitWithrottleRouteList(Print* stream); static void createNewTask(int route, uint16_t cab); - static void turnoutEvent(VPIN id, bool closed); + static void turnoutEvent(int16_t id, bool closed); private: static void ComandFilter(Print * stream, byte & opcode, byte & paramCount, int16_t p[]); static bool parseSlash(Print * stream, byte & paramCount, int16_t p[]) ; @@ -106,10 +106,11 @@ private: unsigned long delayTime; byte taskId; - int loco; + int16_t loco; bool forward; bool invert; int speedo; + int16_t onTurnoutId; byte stackDepth; int callStack[MAX_STACK_DEPTH]; };