1
0
mirror of https://github.com/DCC-EX/CommandStation-EX.git synced 2024-12-23 12:51:24 +01:00

Rebuild throttle info getters

UNTESTED... create different methods to obtain throttle info without being withrottle specific.

Also implements turnout description of "*" as hidden.
This commit is contained in:
Asbelos 2022-04-03 11:19:04 +01:00
parent 7c1c6dafa1
commit 4c8b7f8517
4 changed files with 101 additions and 73 deletions

View File

@ -40,7 +40,6 @@
T2. Extend to >64k
*/
#include <Arduino.h>
#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: // </ ROUTES > JMRI withrottle support
if (paramCount>1) return false;
StringFormatter::send(stream,F("</ROUTES "));
emitWithrottleRouteList(stream);
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');
}

View File

@ -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

View File

@ -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"

View File

@ -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;r<RMFT2::rosterNameCount;r++) {
int16_t cabid=GETFLASHW(RMFT2::rosterIdList+r);
StringFormatter::send(stream,F("]\\[%S}|{%d}|{%c"),
RMFT2::getRosterName(cabid),cabid,cabid<128?'S':'L');
}
stream->write('\n'); // end roster
#endif
// set heartbeat to 1 second because we need to sync the metadata
StringFormatter::send(stream,F("*1\n"));
initSent = true;