|
|
|
@ -700,33 +700,51 @@ int Locomotives::SchedulerNextStep(Locomotive *loc) {
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
//
|
|
|
|
|
// with each call only check one single step of the way, if we have to
|
|
|
|
|
// turn a turnout try to do it and return 0.
|
|
|
|
|
// if everything is set up till the destination (next) block return 1
|
|
|
|
|
// to speed things up: we only prepare ways which we have locked already
|
|
|
|
|
//
|
|
|
|
|
int Locomotives::AutoCheckWaySingleStep(string way, string locname, int *data) {
|
|
|
|
|
int res = 0;
|
|
|
|
|
int Locomotives::AutoCheckWaySingleStep(string way, Locomotive *loc, int *data) {
|
|
|
|
|
size_t pos1;
|
|
|
|
|
size_t curpos;
|
|
|
|
|
size_t blockpos;
|
|
|
|
|
int cnt;
|
|
|
|
|
int state;
|
|
|
|
|
int newdata = 0;
|
|
|
|
|
string turnout;
|
|
|
|
|
string nextblock;
|
|
|
|
|
size_t nextblockpos;
|
|
|
|
|
int blflags = 0;
|
|
|
|
|
int x, y;
|
|
|
|
|
Railway r;
|
|
|
|
|
|
|
|
|
|
if (*data < 0) *data = 0;
|
|
|
|
|
debug (0, "Locomotives::AutoCheckWaySingleStep Prepare for Loco: %s Way:%s data:%d blocknext:%s", loc->name, way.c_str(), *data, loc->blocknext);
|
|
|
|
|
|
|
|
|
|
debug (0, "Locomotives::AutoCheckWaySingleStep Prepare for Loco: %s Way:%s data:%d", locname.c_str(), way.c_str(), *data);
|
|
|
|
|
//
|
|
|
|
|
// find final next block
|
|
|
|
|
// check if it is a split block and a long train
|
|
|
|
|
blflags = server->blocks.GetFlags(loc->blocknext+2);
|
|
|
|
|
nextblock = loc->blocknext+2;
|
|
|
|
|
if (!(loc->flags & LOCO_F_SHORTTRAIN) && (blflags & BLOCK_F_SPLIT)) {
|
|
|
|
|
if ((loc->blocknext[0] == '+' && (blflags & BLOCK_F_SPLITPOS)) ||
|
|
|
|
|
(loc->blocknext[0] == '-' && !(blflags & BLOCK_F_SPLITPOS)) ) {
|
|
|
|
|
nextblock = server->blocks.GetSecondBlock(loc->blocknext+2);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
nextblockpos = way.find(nextblock);
|
|
|
|
|
debug (0, "Locomotives::AutoCheckWaySingleStep nextblock:%s", nextblock.c_str());
|
|
|
|
|
|
|
|
|
|
curpos = 0;
|
|
|
|
|
do {
|
|
|
|
|
//
|
|
|
|
|
// read all ways from the begin with stop at "data"
|
|
|
|
|
curpos = way.find (",t:", curpos+1);
|
|
|
|
|
if (curpos != string::npos && nextblockpos != string::npos && curpos > nextblockpos) break;
|
|
|
|
|
|
|
|
|
|
newdata++;
|
|
|
|
|
if (curpos != string::npos) {
|
|
|
|
|
pos1 = way.find(":", curpos+3);
|
|
|
|
@ -750,23 +768,23 @@ int Locomotives::AutoCheckWaySingleStep(string way, string locname, int *data) {
|
|
|
|
|
while (server->railways.FindReference(&x, &y, turnout, cnt++)) {
|
|
|
|
|
cnt++;
|
|
|
|
|
r = server->railways.RailwayGet(x, y);
|
|
|
|
|
debug (0, "Locomotives::AutoCheckWaySingleStep Loco:%s Turnout:%s LockedBy:%s", locname.c_str(), turnout.c_str(), r.lockedby);
|
|
|
|
|
debug (0, "Locomotives::AutoCheckWaySingleStep Loco:%s Turnout:%s LockedBy:%s", loc->name, turnout.c_str(), r.lockedby);
|
|
|
|
|
|
|
|
|
|
//
|
|
|
|
|
//
|
|
|
|
|
if (locname.compare(r.lockedby) == 0 || r.lockedby[0] == 0) {
|
|
|
|
|
if (strncmp(loc->name, r.lockedby, REFERENCENAME_LEN) == 0 || r.lockedby[0] == 0) {
|
|
|
|
|
if (way[pos1+1] == '0' && state != 0) {
|
|
|
|
|
debug (0, "Locomotives::AutoCheckWaySingleStep Loco:%s Turnout:%s Not Equal -> Set:0", locname.c_str(), turnout.c_str());
|
|
|
|
|
debug (0, "Locomotives::AutoCheckWaySingleStep Loco:%s Turnout:%s Not Equal -> Set:0", loc->name, turnout.c_str());
|
|
|
|
|
server->turnouts.Set(way.substr(curpos+3, pos1-curpos-3), 0);
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
else if (way[pos1+1] == '1' && state != 1) {
|
|
|
|
|
debug (0, "Locomotives::AutoCheckWaySingleStep Loco:%s Turnout:%s Not Equal -> Set:1", locname.c_str(), turnout.c_str());
|
|
|
|
|
debug (0, "Locomotives::AutoCheckWaySingleStep Loco:%s Turnout:%s Not Equal -> Set:1", loc->name, turnout.c_str());
|
|
|
|
|
server->turnouts.Set(way.substr(curpos+3, pos1-curpos-3), 1);
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
else if (newdata > *data) {
|
|
|
|
|
debug (0, "Locomotives::AutoCheckWaySingleStep Loco:%s Turnout:%s Equal Reset:%c", locname.c_str(), turnout.c_str(), way[pos1+1]);
|
|
|
|
|
debug (0, "Locomotives::AutoCheckWaySingleStep Loco:%s Turnout:%s Equal Reset:%c", loc->name, turnout.c_str(), way[pos1+1]);
|
|
|
|
|
if (way[pos1+1] == '0') server->turnouts.Set(way.substr(curpos+3, pos1-curpos-3), 0);
|
|
|
|
|
if (way[pos1+1] == '1') server->turnouts.Set(way.substr(curpos+3, pos1-curpos-3), 1);
|
|
|
|
|
(*data) = newdata;
|
|
|
|
@ -775,15 +793,14 @@ int Locomotives::AutoCheckWaySingleStep(string way, string locname, int *data) {
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
if (cnt == 0) {
|
|
|
|
|
debug (0, "Locomotives::AutoCheckWaySingleStep Loco:%s Turnout:%s Reference not found", locname.c_str(), turnout.c_str());
|
|
|
|
|
debug (0, "Locomotives::AutoCheckWaySingleStep Loco:%s Turnout:%s Reference not found", loc->name, turnout.c_str());
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
} while (curpos != string::npos);
|
|
|
|
|
|
|
|
|
|
if (curpos == string::npos) res = 1;
|
|
|
|
|
|
|
|
|
|
return res;
|
|
|
|
|
if (curpos == string::npos || (nextblockpos != string::npos && curpos > nextblockpos)) return 1;
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@ -883,7 +900,7 @@ int Locomotives::Loco_PrepareWay(Locomotive *loco) {
|
|
|
|
|
block = ((string)(loco->blocknext+2)).substr(0, ((string)(loco->blocknext+2)).find(","));
|
|
|
|
|
|
|
|
|
|
if (loco->auto_timenext.tv_sec == 0 || timer_get(&loco->auto_timenext) > LOCO_TO_TURNOUT) {
|
|
|
|
|
if (AutoCheckWaySingleStep(loco->auto_way, loco->name, &loco->auto_data) == 1) {
|
|
|
|
|
if (AutoCheckWaySingleStep(loco->auto_way, loco, &loco->auto_data) == 1) {
|
|
|
|
|
if ((loco->flags & LOCO_F_CARGO) ||
|
|
|
|
|
(server->blocks.GetFlags(block) & BLOCK_F_SPEEDLIMIT)) return 1;
|
|
|
|
|
else return 2;
|
|
|
|
@ -1045,7 +1062,7 @@ int Locomotives::Loco_BlockEnterNext(Locomotive *loco) {
|
|
|
|
|
s_enter = server->blocks.GetSensorEnter(dir_reverse, block, loco->flags);
|
|
|
|
|
|
|
|
|
|
if (server->sensors.GetActive(s_stop) == 1) {
|
|
|
|
|
if (!AutoCheckWaySingleStep(loco->auto_way, loco->name, &loco->auto_data)) {
|
|
|
|
|
if (!AutoCheckWaySingleStep(loco->auto_way, loco, &loco->auto_data)) {
|
|
|
|
|
//
|
|
|
|
|
// end of block and not finished preparing the way.
|
|
|
|
|
// stop everything
|
|
|
|
@ -1074,7 +1091,7 @@ int Locomotives::Loco_BlockEnterNext(Locomotive *loco) {
|
|
|
|
|
|
|
|
|
|
if (loco->auto_timenext.tv_sec > 0 && timer_get(&loco->auto_timenext) > LOCO_TO_TURNOUT) {
|
|
|
|
|
debug (0, "* Locomotives::Loco_BlockEnterNext prepare way for loco: %s", loco->name);
|
|
|
|
|
if (AutoCheckWaySingleStep(loco->auto_way, loco->name, &loco->auto_data) == 1) {
|
|
|
|
|
if (AutoCheckWaySingleStep(loco->auto_way, loco, &loco->auto_data) == 1) {
|
|
|
|
|
//
|
|
|
|
|
// finished preparing new way, need to stay in ENTERBLOCKNEXT to unlock old way
|
|
|
|
|
debug (0, "* Locomotives::Loco_BlockEnterNext finished preparing way for loco: %s", loco->name);
|
|
|
|
@ -1252,21 +1269,3 @@ int Locomotives::Loop() {
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
int Locomotives::Test(string loco) {
|
|
|
|
|
int res = 0;
|
|
|
|
|
int i;
|
|
|
|
|
int j = 0;
|
|
|
|
|
|
|
|
|
|
printf ("%s:%d LocoTest.\n", __FILE__, __LINE__);
|
|
|
|
|
for (i = 0; i < max; i++) if (locomotives[i].name[0] != 0)
|
|
|
|
|
if (loco.compare(locomotives[i].name) == 0) {
|
|
|
|
|
res = AutoCheckWaySingleStep(locomotives[i].auto_way, loco, &j);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
printf ("%s:%d LocoTest ---> Return %d\n", __FILE__, __LINE__, res);
|
|
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|