From 4c8b7f851754c5a648fabe0bd1d58ff7a62aa286 Mon Sep 17 00:00:00 2001 From: Asbelos Date: Sun, 3 Apr 2022 11:19:04 +0100 Subject: [PATCH] Rebuild throttle info getters UNTESTED... create different methods to obtain throttle info without being withrottle specific. Also implements turnout description of "*" as hidden. --- EXRAIL2.cpp | 20 ++--------- EXRAIL2.h | 19 ++++++----- EXRAILMacros.h | 93 ++++++++++++++++++++++++++++++-------------------- WiThrottle.cpp | 42 +++++++++++++++++------ 4 files changed, 101 insertions(+), 73 deletions(-) diff --git a/EXRAIL2.cpp b/EXRAIL2.cpp index 3c7af23..1a4f536 100644 --- a/EXRAIL2.cpp +++ b/EXRAIL2.cpp @@ -40,7 +40,6 @@ T2. Extend to >64k */ - #include #include "EXRAIL2.h" #include "DCC.h" @@ -347,13 +346,6 @@ bool RMFT2::parseSlash(Print * stream, byte & paramCount, int16_t p[]) { } return true; - case HASH_KEYWORD_ROUTES: // JMRI withrottle support - if (paramCount>1) return false; - StringFormatter::send(stream,F("")); - return true; - default: break; } @@ -408,11 +400,7 @@ bool RMFT2::parseSlash(Print * stream, byte & paramCount, int16_t p[]) { // Automations are given a state to set the button to "handoff" which implies // handing over the loco to the automation. // Routes are given "Set" buttons and do not cause the loco to be handed over. -void RMFT2::emitWithrottleRouteList(Print* stream) { - StringFormatter::send(stream,F("PRT]\\[Routes}|{Route]\\[Set}|{2]\\[Handoff}|{4\nPRL")); - emitWithrottleDescriptions(stream); - StringFormatter::send(stream,F("\n")); -} + RMFT2::RMFT2(int progCtr) { @@ -1037,8 +1025,4 @@ void RMFT2::printMessage2(const FSH * msg) { DIAG(F("EXRAIL(%d) %S"),loco,msg); } -// This is called by emitRouteDescriptions to emit a withrottle description for a route or autoomation. -void RMFT2::emitRouteDescription(Print * stream, char type, int id, const FSH * description) { - StringFormatter::send(stream,F("]\\[%c%d}|{%S}|{%c"), - type,id,description, type=='R'?'2':'4'); -} + diff --git a/EXRAIL2.h b/EXRAIL2.h index 6cc0243..97e0d98 100644 --- a/EXRAIL2.h +++ b/EXRAIL2.h @@ -87,17 +87,21 @@ class LookList { RMFT2(int route, uint16_t cab); ~RMFT2(); static void readLocoCallback(int16_t cv); - static void emitWithrottleRouteList(Print* stream); static void createNewTask(int route, uint16_t cab); static void turnoutEvent(int16_t id, bool closed); static void activateEvent(int16_t addr, bool active); - static void emitTurnoutDescription(Print* stream,int16_t id); - static const byte rosterNameCount; - static void emitWithrottleRoster(Print * stream); - static const FSH * getRosterFunctions(int16_t cabid); static const int16_t SERVO_SIGNAL_FLAG=0x4000; static const int16_t ACTIVE_HIGH_SIGNAL_FLAG=0x2000; - + + // Throttle Info Access functions built by exrail macros + static const byte rosterNameCount; + static const int16_t FLASH routeIdList[]; + static const int16_t FLASH rosterIdList[]; + static const FSH * getRouteDescription(int16_t id); + static const FSH * getTurnoutDescription(int16_t id); + static const FSH * getRosterName(int16_t id); + static const FSH * getRosterFunctions(int16_t id); + private: static void ComandFilter(Print * stream, byte & opcode, byte & paramCount, int16_t p[]); static bool parseSlash(Print * stream, byte & paramCount, int16_t p[]) ; @@ -106,8 +110,6 @@ private: static bool getFlag(VPIN id,byte mask); static int16_t progtrackLocoId; static void doSignal(VPIN id,bool red, bool amber, bool green); - static void emitRouteDescription(Print * stream, char type, int id, const FSH * description); - static void emitWithrottleDescriptions(Print * stream); static RMFT2 * loopTask; static RMFT2 * pausingTask; @@ -132,6 +134,7 @@ private: static LookList * onActivateLookup; static LookList * onDeactivateLookup; + // Local variables - exist for each instance/task RMFT2 *next; // loop chain int progCounter; // Byte offset of next route opcode in ROUTES table diff --git a/EXRAILMacros.h b/EXRAILMacros.h index e0b078c..60fd557 100644 --- a/EXRAILMacros.h +++ b/EXRAILMacros.h @@ -49,24 +49,38 @@ // CAUTION: The macros below are multiple passed over myAutomation.h +#define O_DESC(id, desc) case id: return ("" desc)[0]?F("" desc):NULL; + // Pass 1 Implements aliases #include "EXRAIL2MacroReset.h" #undef ALIAS #define ALIAS(name,value...) const int name= 1##value##0 ==10 ? -__COUNTER__ : value##0/10; #include "myAutomation.h" -// Pass 2 convert descriptions to withrottle format emitter function +// Pass 2 create throttle route list #include "EXRAIL2MacroReset.h" #undef ROUTE -#define ROUTE(id, description) emitRouteDescription(stream,'R',id,F(description)); +#define ROUTE(id, description) id, #undef AUTOMATION -#define AUTOMATION(id, description) emitRouteDescription(stream,'A',id,F(description)); -void RMFT2::emitWithrottleDescriptions(Print * stream) { - (void)stream; +#define AUTOMATION(id, description) -id, +const int16_t FLASH RMFT2::routeIdList[]= { #include "myAutomation.h" + 0}; + +// Pass 3 Create route descriptions: +#undef ROUTE +#define ROUTE(id, description) case id: return F(description); +#undef AUTOMATION +#define AUTOMATION(id, description) case id: return F(description); +const FSH * RMFT2::getRouteDescription(int16_t id) { + switch(id) { + #include "myAutomation.h" + default: break; + } + return NULL; } -// Pass 3... Create Text sending functions +// Pass 4... Create Text sending functions #include "EXRAIL2MacroReset.h" const int StringMacroTracker1=__COUNTER__; #undef BROADCAST @@ -96,58 +110,63 @@ void RMFT2::printMessage(uint16_t id) { } -// Pass 4: Turnout descriptions (optional) +// Pass 5: Turnout descriptions (optional) #include "EXRAIL2MacroReset.h" #undef TURNOUT -#define TURNOUT(id,addr,subaddr,description...) case id: desc=F("" description); break; +#define TURNOUT(id,addr,subaddr,description...) O_DESC(id,description) #undef PIN_TURNOUT -#define PIN_TURNOUT(id,pin,description...) case id: desc=F("" description); break; +#define PIN_TURNOUT(id,pin,description...) O_DESC(id,description) #undef SERVO_TURNOUT -#define SERVO_TURNOUT(id,pin,activeAngle,inactiveAngle,profile,description...) case id: desc=F("" description); break; +#define SERVO_TURNOUT(id,pin,activeAngle,inactiveAngle,profile,description...) O_DESC(id,description) #undef VIRTUAL_TURNOUT -#define VIRTUAL_TURNOUT(id,description...) case id: desc=F("" description); break; +#define VIRTUAL_TURNOUT(id,description...) O_DESC(id,description) -void RMFT2::emitTurnoutDescription(Print* stream,int16_t turnoutid) { - const FSH * desc=F(""); +const FSH * RMFT2::getTurnoutDescription(int16_t turnoutid) { switch (turnoutid) { #include "myAutomation.h" - default: break; + default:break; } - if (GETFLASH(desc)=='\0') desc=F("%d"); - StringFormatter::send(stream,desc,turnoutid); + return NULL; } -// Pass 5: Roster names (count) +// Pass 6: Roster IDs (count) #include "EXRAIL2MacroReset.h" #undef ROSTER #define ROSTER(cabid,name,funcmap...) +1 - const byte RMFT2::rosterNameCount=0 - #include "myAutomation.h" - ; - -// Pass 6: Roster names emitter + #include "myAutomation.h" + ; + +// Pass 6: Roster IDs #include "EXRAIL2MacroReset.h" #undef ROSTER -#define ROSTER(cabid,name,funcmap...) StringFormatter::send(stream,(FSH *)format,F(name),cabid,cabid<128?'S':'L'); -void RMFT2::emitWithrottleRoster(Print * stream) { - static const char format[] FLASH ="]\\[%S}|{%d}|{%c"; - (void)format; - StringFormatter::send(stream,F("RL%d"), rosterNameCount); - #include "myAutomation.h" - stream->write('\n'); -} +#define ROSTER(cabid,name,funcmap...) cabid, +const int16_t FLASH RMFT2::rosterIdList[]={ + #include "myAutomation.h" + 0}; -// Pass 7: functions getter +// Pass 7: Roster names getter #include "EXRAIL2MacroReset.h" #undef ROSTER -#define ROSTER(cabid,name,funcmap...) case cabid: return F("" funcmap); -const FSH * RMFT2::getRosterFunctions(int16_t cabid) { - switch(cabid) { +#define ROSTER(cabid,name,funcmap...) case cabid: return F(name); +const FSH * RMFT2::getRosterName(int16_t id) { + switch(id) { #include "myAutomation.h" - default: return NULL; - } -} + default: return NULL; + } + return NULL; +} + +// Pass to get roster functions +#undef ROSTER +#define ROSTER(cabid,name,funcmap...) O_DESC(cabid,funcmap) +const FSH * RMFT2::getRosterFunctions(int16_t id) { + switch(id) { + #include "myAutomation.h" + default: break; + } + return NULL; +} // Pass 8 Signal definitions #include "EXRAIL2MacroReset.h" diff --git a/WiThrottle.cpp b/WiThrottle.cpp index d91745c..72ee75a 100644 --- a/WiThrottle.cpp +++ b/WiThrottle.cpp @@ -120,13 +120,15 @@ void WiThrottle::parse(RingStream * stream, byte * cmdx) { StringFormatter::send(stream,F("PTL")); for(Turnout *tt=Turnout::first();tt!=NULL;tt=tt->next()){ int id=tt->getId(); - StringFormatter::send(stream,F("]\\[%d}|{"), id); -#ifdef EXRAIL_ACTIVE - RMFT2::emitTurnoutDescription(stream,id); -#else - StringFormatter::send(stream,F("%d"), id); -#endif - StringFormatter::send(stream,F("}|{%c"), Turnout::isClosed(id)?'2':'4'); + const FSH * tdesc=NULL; + #ifdef EXRAIL_ACTIVE + tdesc=RMFT2::getTurnoutDescription(id); + #endif + char tchar=Turnout::isClosed(id)?'2':'4'; + if (tdesc==NULL) // turnout with no description + StringFormatter::send(stream,F("]\\[%d}|{T%d}|{T%c"), id,id,tchar); + else if (GETFLASH(tdesc)!='*') // ignore hidden turnouts + StringFormatter::send(stream,F("]\\[%d}|{%S}|{%c"), id,tdesc,tchar); } StringFormatter::send(stream,F("\n")); turnoutListHash = Turnout::turnoutlistHash; // keep a copy of hash for later comparison @@ -136,7 +138,17 @@ void WiThrottle::parse(RingStream * stream, byte * cmdx) { // Send EX-RAIL routes list if not already sent (but not at same time as turnouts above) exRailSent=true; #ifdef EXRAIL_ACTIVE - RMFT2::emitWithrottleRouteList(stream); + StringFormatter::send(stream,F("PRT]\\[Routes}|{Route]\\[Set}|{2]\\[Handoff}|{4\nPRL")); + for (int ix=0;;ix+=2) { + int16_t id=GETFLASHW(RMFT2::routeIdList+ix); + if (id==0) break; + bool isRoute=id<0; + if (isRoute) id=-id; + const FSH * desc=RMFT2::getRouteDescription(id); + StringFormatter::send(stream,F("]\\[%c%d}|{%S}|{%c"), + isRoute?'R':'A',id,desc, isRoute?'2':'4'); + } + StringFormatter::send(stream,F("\n")); #endif // allow heartbeat to slow down once all metadata sent StringFormatter::send(stream,F("*%d\n"),HEARTBEAT_SECONDS); @@ -205,9 +217,19 @@ void WiThrottle::parse(RingStream * stream, byte * cmdx) { StringFormatter::send(stream,F("HtDCC-EX v%S, %S, %S, %S\n"), F(VERSION), F(ARDUINO_TYPE), DCC::getMotorShieldName(), F(GITHUB_SHA)); StringFormatter::send(stream,F("PTT]\\[Turnouts}|{Turnout]\\[THROW}|{2]\\[CLOSE}|{4\n")); StringFormatter::send(stream,F("PPA%x\n"),DCCWaveform::mainTrack.getPowerMode()==POWERMODE::ON); + + // Send the roster #ifdef EXRAIL_ACTIVE - RMFT2::emitWithrottleRoster(stream); -#endif + StringFormatter::send(stream,F("RL%d"), RMFT2::rosterNameCount); + for (int16_t r=0;rwrite('\n'); // end roster +#endif + + // set heartbeat to 1 second because we need to sync the metadata StringFormatter::send(stream,F("*1\n")); initSent = true;