another work on the split blocks. long trains wont go into split blocks. Some final checks are still needed

master
Steffen Pohle 2 years ago
parent 0c73a38dc8
commit d4efc193c7

@ -1,3 +1,7 @@
2023-05-01:
- another work on the split blocks. long trains wont go into split blocks. Some final
checks are still needed to implement.
2023-04-02:
- fixed: track infomation is fixed.
- removed unneded debug file

@ -110,6 +110,7 @@ Block Blocks::GetBlockFromJSON(JSONParse *j) {
string s;
bl.name[0] = 0;
bl.secondblock[0] = 0;
bl.flags = 0;
bl.lockedby[0] = 0;
@ -150,6 +151,7 @@ Block Blocks::GetBlockFromJSON(JSONParse *j) {
s = ""; if (j->GetValue("sensor_stop_1", &s)) strncpy (bl.s_stop[1], s.c_str(), REFERENCENAME_LEN);
s = ""; if (j->GetValue("sensor_shortstop_0", &s)) strncpy (bl.s_shortstop[0], s.c_str(), REFERENCENAME_LEN);
s = ""; if (j->GetValue("sensor_shortstop_1", &s)) strncpy (bl.s_shortstop[1], s.c_str(), REFERENCENAME_LEN);
s = ""; if (j->GetValue("secondblock", &s)) strncpy (bl.secondblock, s.c_str(), REFERENCENAME_LEN);
printf ("%s:%d block: %s flags: %d\n", __FILE__, __LINE__, bl.name, bl.flags);
return bl;
@ -298,6 +300,22 @@ string Blocks::GetLockedby (string blname) {
};
string Blocks::GetSecondBlock(string block) {
Block *bl = NULL;
string sb;
Lock();
if ((bl = FindBlock(block)) != NULL) {
sb = bl->secondblock;
UnLock();
return sb;
}
UnLock();
return "";
}
Block* Blocks::FindBlock(string name) {
Block *bl = NULL;

@ -94,6 +94,7 @@ class Blocks {
string GetSensorStop (int direction, string blname);
string GetSensorShortStop (int direction, string blname);
int GetFlags (string blname);
string GetSecondBlock(string block);
int SetLockedby (string blname, string lockedby, int lock_onoff);
string GetLockedby (string blname);

@ -201,11 +201,22 @@ void Interfaces::SetTurnout(Turnout *t, int active, int motoractive) {
LockThread();
debug (0, "%s:%d Interfaces::SetTurnout Name:%s active:%d Output%d", __FILE__, __LINE__, t->name, active, motoractive);
//
// if the interfacename is debug ... simulate a change in the turnout
//
if (strncmp(t->ifname, "DEBUG", REFERENCENAME_LEN) == 0) {
if (active) t->flags |= TURNOUT_F_ACTIVE;
else t->flags &= ~TURNOUT_F_ACTIVE;
server->TurnoutAddrMode(t->ifname, t->addr, active);
}
else {
for (i = 0; i < max; i++) if (interfaces[i] != NULL) {
if (!interfaces[i]->IsConnected()) interfaces[i]->Connect();
if (strncmp(t->ifname, interfaces[i]->name, REFERENCENAME_LEN) == 0)
interfaces[i]->SetTurnout(t, active, motoractive);
}
}
UnLockThread();
};

@ -306,7 +306,7 @@ int Locomotives::SetDestination (string name, string block, int direction) {
debug (0, "Locomotives::SetDestination (Name:%s Block:%s Direction:%d)", name.c_str(), block.c_str(), direction);
blflags = server->blocks.GetFlags(block);
if ((blflags & BLOCK_F_SHORT) && !(locomotives[i].flags & LOCO_F_SHORTTRAIN)) break;
if ((blflags & BLOCK_F_SHORT) && !(locomotives[i].flags & LOCO_F_SHORTTRAIN) && !(blflags & BLOCK_F_SPLIT)) break;
if ((blflags & BLOCK_F_ENDSTATION) && !(locomotives[i].flags & LOCO_F_CANREVERSE)) break;
if ((blflags & BLOCK_F_ONLYCARGO) && !(locomotives[i].flags & LOCO_F_CARGO)) break;
if ((blflags & BLOCK_F_ONLYPASSENGER) && (locomotives[i].flags & LOCO_F_CARGO)) break;

@ -41,7 +41,7 @@ int Railways::UnLock() {
// data must be mutex looked before use
struct s_findway_data Railways::NextPos(struct s_findway_data pos, int dirtype) {
struct s_findway_data np = { x: -1, y: -1, enterfrom: -1, oldx: pos.x, oldy:pos.y,
oldenterfrom: pos.enterfrom, parma: pos.parma,
oldenterfrom: pos.enterfrom,
way: pos.way }; // newpos
if (dirtype == 1) {
@ -501,6 +501,8 @@ int Railways::FindWay(string blockstart, string blockend, string lockedfor, stri
int found = 0;
int locoflags = server->locomotives.GetFlags(lockedfor);
debug (0, "Railway::FindWay blockstart:%s blockend:%s lockedfor:%s", blockstart.c_str(), blockend.c_str(), lockedfor.c_str());
// check blocklen
if (blockstart.length() <= 3 || blockend.length() <= 3) return 0;
@ -517,7 +519,6 @@ int Railways::FindWay(string blockstart, string blockend, string lockedfor, stri
fd_end.x = fd_start.x = -1;
fd_end.y = fd_start.y = -1;
fd_end.enterfrom = fd_start.enterfrom = -1;
fd_end.parma = fd_start.parma = -1;
if (FindReference(&fd_start.x, &fd_start.y, blockstart.substr(2, string::npos))) {
if (Get(fd_start.x, fd_start.y).dir == 1) {
@ -531,7 +532,6 @@ int Railways::FindWay(string blockstart, string blockend, string lockedfor, stri
fd_start.way = "b:" + blockstart;
fd_data[GetRIdx(fd_start.x, fd_start.y)].e = (1 << fd_start.enterfrom);
fd_data[GetRIdx(fd_start.x, fd_start.y)].score = 1;
fd_start.parma = 1;
}
else {
debug (0, "Railway::FindWay could not find startblock (%s).", blockstart.c_str());
@ -617,9 +617,8 @@ int Railways::FindWay(string blockstart, string blockend, string lockedfor, stri
if (rpos->type == RAILWAY_NORMAL || rpos->type == RAILWAY_SENSOR) {
fd_pos = NextPos(fd_pos, rpos->dir);
fd_pos.parma++;
rnext = &railways[GetRIdx(fd_pos.x, fd_pos.y)];
if (rnext->lockedby[0] != 0) {
if (rnext->lockedby[0] != 0 || !_NextPosIsValid(lockedfor, locoflags, &fd_pos)) {
fd_pos.enterfrom = -1;
fd_pos.x = -1;
fd_pos.y = -1;
@ -630,19 +629,23 @@ int Railways::FindWay(string blockstart, string blockend, string lockedfor, stri
else if (rpos->type == RAILWAY_TURNOUT) {
fd_tmp = NextPos(fd_pos, rpos->altdir);
fd_tmp.way += (string)",t:" + (string)rpos->name + (string)":1";
fd_tmp.parma += 10; // 10 bad point for using the turnout
fd_list.push_back(fd_tmp);
fd_pos = NextPos(fd_pos, rpos->dir);
fd_pos.way += (string)",t:" + (string)rpos->name + (string)":0";
fd_pos.parma++;
if (!_NextPosIsValid(lockedfor, locoflags, &fd_pos)) {
fd_pos.enterfrom = -1;
fd_pos.x = -1;
fd_pos.y = -1;
fd_pos.way = "";
}
else fd_pos.way += (string)",t:" + (string)rpos->name + (string)":0";
}
else if (rpos->type == RAILWAY_CONNECTOR) {
int found = 0;
int conector_found = 0;
x = -1;
y = -1;
while (found == 0 && _FindReference(&x, &y, rpos->name) == 1) {
while (conector_found == 0 && _FindReference(&x, &y, rpos->name) == 1) {
if (fd_pos.x != x || fd_pos.y != y) {
fd_pos.oldx = fd_pos.x;
fd_pos.oldy = fd_pos.y;
@ -651,13 +654,13 @@ int Railways::FindWay(string blockstart, string blockend, string lockedfor, stri
fd_pos.y = y;
rpos = &railways[GetRIdx(fd_pos.x, fd_pos.y)];
fd_pos = NextPos(fd_pos, rpos->dir);
fd_pos.parma++;
found = 1;
conector_found = 1;
break;
}
}
if (found == 0) {
if (found == 0 || !_NextPosIsValid(lockedfor, locoflags, &fd_pos)) {
fd_pos.enterfrom = -1;
fd_pos.x = -1;
fd_pos.y = -1;
@ -671,7 +674,8 @@ int Railways::FindWay(string blockstart, string blockend, string lockedfor, stri
if ((server->blocks.IsOff(rpos->name) ||
((blflags & BLOCK_F_ENDSTATION) && !(locoflags & LOCO_F_CANREVERSE)) ||
((blflags & BLOCK_F_SHORT) && !(locoflags & LOCO_F_SHORTTRAIN)) ||
((blflags & BLOCK_F_SHORT) && !(locoflags & LOCO_F_SHORTTRAIN) &&
!_SplitBlockIsFreeAndAllowed(lockedfor, locoflags, rpos->name)) ||
((blflags & BLOCK_F_ONLYCARGO) && !(locoflags & LOCO_F_CARGO)) ||
((blflags & BLOCK_F_ONLYPASSENGER) && (locoflags & LOCO_F_CARGO)))) {
fd_pos.enterfrom = -1;
@ -688,7 +692,12 @@ int Railways::FindWay(string blockstart, string blockend, string lockedfor, stri
else fd_pos.way += (string)",b:-:" + (string)rpos->name;
fd_pos = NextPos(fd_pos, rpos->dir);
fd_pos.parma++;
if (!_NextPosIsValid(lockedfor, locoflags, &fd_pos)) {
fd_pos.enterfrom = -1;
fd_pos.x = -1;
fd_pos.y = -1;
fd_pos.way = "";
}
}
else {
fd_pos.enterfrom = -1;
@ -727,6 +736,85 @@ int Railways::FindWay(string blockstart, string blockend, string lockedfor, stri
};
/*
* check if the position in fwd.x|y is valid for the loco. The check will only done on
* RAILWAY_BLOCK types. It will also check if the block is free.
*/
int Railways::_NextPosIsValid(string loconame, int locoflags, struct s_findway_data *fwd) {
int bflags = -1;
Railway *rpos = NULL;
rpos = &railways[GetRIdx(fwd->x, fwd->y)];
bflags = server->blocks.GetFlags(rpos->name);
if (rpos->type != RAILWAY_BLOCK) return 1;
if (server->blocks.IsOff(rpos->name)) return 0;
if ((bflags & BLOCK_F_ENDSTATION) && !(locoflags & LOCO_F_CANREVERSE)) return 0;
if ((bflags & BLOCK_F_SHORT) && !(locoflags & LOCO_F_SHORTTRAIN) &&
!_SplitBlockIsFreeAndAllowed(loconame, locoflags, rpos->name)) return 0;
if ((bflags & BLOCK_F_ONLYCARGO) && !(locoflags & LOCO_F_CARGO)) return 0;
if ((bflags & BLOCK_F_ONLYPASSENGER) && (locoflags & LOCO_F_CARGO)) return 0;
return 1;
};
/*
* check if this is a split block, and if it can be entered
* all needed elements must be unlocked to return 1.
* if the loco is a short train return 0
*/
int Railways::_SplitBlockIsFreeAndAllowed(string loconame, int locoflags, string block) {
string pblock;
string nblock;
int bflags = server->blocks.GetFlags(block);
int nblockflags = 0;
int pblockflags = 0;
int x1, y1, x2, y2, dx = 0, dy = 0;
debug (0, "Railway::_SplitBlockIsFreeAndAllowed loconame:%s flags:%d block:%s", loconame.c_str(), locoflags, block.c_str());
if (locoflags & LOCO_F_SHORTTRAIN) return 0;
if ((locoflags & !LOCO_F_SHORTTRAIN) && (bflags & !BLOCK_F_SPLIT)) return 0;
//
// read negative the positive block flags
if (bflags & BLOCK_F_SPLITPOS) {
pblockflags = bflags;
pblock = block;
nblock = server->blocks.GetSecondBlock(block);
if (nblock.length() == 0) return 0;
nblockflags = server->blocks.GetFlags(nblock);
}
else {
nblockflags = bflags;
nblock = block;
pblock = server->blocks.GetSecondBlock(block);
if (pblock.length() == 0) return 0;
pblockflags = server->blocks.GetFlags(pblock);
}
//
// check if blockflags are setup right and the blocks are free
if (!(nblockflags & BLOCK_F_SPLIT) && (nblockflags & BLOCK_F_SPLITPOS)) return 0;
if (!(pblockflags & BLOCK_F_SPLIT) && !(pblockflags & BLOCK_F_SPLITPOS)) return 0;
if (server->blocks.GetLockedby(nblock).length() != 0) return 0;
if (server->blocks.GetLockedby(pblock).length() != 0) return 0;
// check the way between the blocks
if (_FindReference(&x1, &y1, pblock) == 0) return 0;
if (_FindReference(&x2, &y2, nblock) == 0) return 0;
debug (0, "Railway::_SplitBlockIsFreeAndAllowed p pos(%d,%d) n pos(%d,%d)", x1, y1, x2, y2);
// if (x1 == x2 )
// do {
//
// } while
//
return 0;
}
int Railways::FindRandomWay(string blockstart, string lockedfor, string *next) {
// direction 0 ... RIGHT and DOWN
// direction 1 ... LEFT and UP
@ -742,7 +830,8 @@ int Railways::FindRandomWay(string blockstart, string lockedfor, string *next) {
int found = 0;
int locoflags = server->locomotives.GetFlags(lockedfor);
debug (0, "Railway::FindRandomWay");
debug (0, "Railway::FindRandomWay - disabled for now - needs to be rewritten");
return 0;
// check blocklen
if (blockstart.length() <= 3) return 0;
@ -760,7 +849,6 @@ int Railways::FindRandomWay(string blockstart, string lockedfor, string *next) {
fd_end.x = fd_start.x = -1;
fd_end.y = fd_start.y = -1;
fd_end.enterfrom = fd_start.enterfrom = -1;
fd_end.parma = fd_start.parma = -1;
if (FindReference(&fd_start.x, &fd_start.y, blockstart.substr(2, string::npos))) {
if (Get(fd_start.x, fd_start.y).dir == 1) {
@ -774,7 +862,6 @@ int Railways::FindRandomWay(string blockstart, string lockedfor, string *next) {
fd_start.way = "b:" + blockstart;
fd_data[GetRIdx(fd_start.x, fd_start.y)].e = (1 << fd_start.enterfrom);
fd_data[GetRIdx(fd_start.x, fd_start.y)].score = 1;
fd_start.parma = 1;
}
else {
debug (0, "Railway::FindRandomWay could not find startblock (%s).", blockstart.c_str());
@ -831,7 +918,6 @@ int Railways::FindRandomWay(string blockstart, string lockedfor, string *next) {
if (rpos->type == RAILWAY_NORMAL || rpos->type == RAILWAY_SENSOR) {
fd_pos = NextPos(fd_pos, rpos->dir);
fd_pos.parma++;
rnext = &railways[GetRIdx(fd_pos.x, fd_pos.y)];
if (rnext->lockedby[0] != 0) {
fd_pos.enterfrom = -1;
@ -846,20 +932,16 @@ int Railways::FindRandomWay(string blockstart, string lockedfor, string *next) {
if ((rand() & 1) == 1) {
fd_tmp = NextPos(fd_pos, rpos->altdir);
fd_tmp.way += (string)",t:" + (string)rpos->name + (string)":1";
fd_tmp.parma += 10; // 10 bad point for using the turnout
fd_list.push_back(fd_tmp);
fd_pos = NextPos(fd_pos, rpos->dir);
fd_pos.way += (string)",t:" + (string)rpos->name + (string)":0";
fd_pos.parma++;
}
else {
fd_tmp = NextPos(fd_pos, rpos->dir);
fd_tmp.way += (string)",t:" + (string)rpos->name + (string)":0";
fd_tmp.parma += 10; // 10 bad point for using the turnout
fd_list.push_back(fd_tmp);
fd_pos = NextPos(fd_pos, rpos->altdir);
fd_pos.way += (string)",t:" + (string)rpos->name + (string)":1";
fd_pos.parma++;
}
}
@ -877,7 +959,6 @@ int Railways::FindRandomWay(string blockstart, string lockedfor, string *next) {
fd_pos.y = y;
rpos = &railways[GetRIdx(fd_pos.x, fd_pos.y)];
fd_pos = NextPos(fd_pos, rpos->dir);
fd_pos.parma++;
found = 1;
break;
}
@ -980,7 +1061,6 @@ int Railways::LockWay (string way, string lockedby, int lockonoff) {
end.x = start.x = -1;
end.y = start.y = -1;
end.enterfrom = start.enterfrom = -1;
end.parma = start.parma = -1;
if ((pos1 = way.find("b:", 0)) == string::npos) return 0;
if ((pos2 = way.find(",", pos1+1)) == string::npos) return 0;
@ -1128,7 +1208,6 @@ int Railways::LockWay (string way, string lockedby, int lockonoff) {
pos.y = y;
r = &railways[GetRIdx(pos.x, pos.y)];
pos = NextPos(pos, r->dir);
pos.parma++;
found = 1;
break;
}

@ -74,7 +74,6 @@ struct s_findway_data {
int oldx;
int oldy;
int oldenterfrom;
int parma;
string way;
};
@ -100,6 +99,8 @@ class Railways {
void _New (int w, int h);
void DebugPrintFindWay(struct s_findway_map *fw);
int _FindReference(int *x, int *y, string name);
int _SplitBlockIsFreeAndAllowed(string loconame, int locoflags, string block);
int _NextPosIsValid(string loconame, int locoflags, struct s_findway_data *fwd);
public:
Railways();

@ -22,14 +22,15 @@ function block_Update(blockdata) {
blocks[i].name = blockdata.name;
blocks[i].flags = blockdata.flags;
blocks[i].lockedby = blockdata.lockedby;
blocks[i].sensor_stop_0 = blockdata.sensor_stop_0,
blocks[i].sensor_shortstop_0 = blockdata.sensor_shortstop_0,
blocks[i].sensor_slow_0 = blockdata.sensor_slow_0,
blocks[i].sensor_enter_0 = blockdata.sensor_enter_0,
blocks[i].sensor_stop_1 = blockdata.sensor_stop_1,
blocks[i].sensor_shortstop_1 = blockdata.sensor_shortstop_1,
blocks[i].sensor_slow_1 = blockdata.sensor_slow_1,
blocks[i].sensor_enter_1 = blockdata.sensor_enter_1,
blocks[i].sensor_stop_0 = blockdata.sensor_stop_0;
blocks[i].sensor_shortstop_0 = blockdata.sensor_shortstop_0;
blocks[i].sensor_slow_0 = blockdata.sensor_slow_0;
blocks[i].sensor_enter_0 = blockdata.sensor_enter_0;
blocks[i].sensor_stop_1 = blockdata.sensor_stop_1;
blocks[i].sensor_shortstop_1 = blockdata.sensor_shortstop_1;
blocks[i].sensor_slow_1 = blockdata.sensor_slow_1;
blocks[i].sensor_enter_1 = blockdata.sensor_enter_1;
blocks[i].secondblock = blockdata.secondblock;
blockdetail_setData(blocks[i]);
return;
}
@ -48,7 +49,8 @@ function block_Update(blockdata) {
sensor_enter_1: blockdata.sensor_enter_1,
sensor_slow_1: blockdata.sensor_slow_1,
sensor_stop_1: blockdata.sensor_stop_1,
sensor_shortstop_1: blockdata.sensor_shortstop_1
sensor_shortstop_1: blockdata.sensor_shortstop_1,
secondblock: blockdata.secondblock
});
};
@ -232,7 +234,9 @@ function blockdetail_show(name, create) {
<td><label><input id=\"blockdet_flagstation\" type=\"checkbox\" value=\"\">Station</label></td> \
<td><label><input id=\"blockdet_flagsplitpos\" type=\"checkbox\" value=\"\">Splitpos</label></td> \
</tr><tr> \
<td></td> \
<td></td><td>second block:</td><td>";
innerHTML += "<input id=\"blockdet_secondblock\" style=\"width: 100\">";
innerHTML += " \
</tr></table> \
\
</td><td></td></tr></table> \
@ -390,6 +394,7 @@ function blockdetail_setData(elm) {
var sensor_stop_1 = document.getElementById("blockdet_sensor_stop_1");
var sensor_shortstop_1 = document.getElementById("blockdet_sensor_shortstop_1");
var lockedby = document.getElementById("blockdet_lockedby");
var secondblock = document.getElementById("blockdet_secondblock");
if (elm) {
if (name) name.value = elm.name;
@ -410,6 +415,7 @@ function blockdetail_setData(elm) {
if (sensor_slow_1) sensor_slow_1.value = elm.sensor_slow_1;
if (sensor_stop_1) sensor_stop_1.value = elm.sensor_stop_1;
if (sensor_shortstop_1) sensor_shortstop_1.value = elm.sensor_shortstop_1;
if (secondblock) secondblock.value = elm.secondblock;
if (lockedby) lockedby.value = elm.lockedby;
}
};
@ -439,6 +445,7 @@ function blockdetail_getData() {
var sensor_slow_1 = document.getElementById("blockdet_sensor_slow_1");
var sensor_stop_1 = document.getElementById("blockdet_sensor_stop_1");
var sensor_shortstop_1 = document.getElementById("blockdet_sensor_shortstop_1");
var secondblock = document.getElementById("blockdet_secondblock");
if (name) res.name = name.value;
@ -478,6 +485,8 @@ function blockdetail_getData() {
if (sensor_stop_1) res.sensor_stop_1 = sensor_stop_1.value;
if (sensor_shortstop_1) res.sensor_shortstop_1 = sensor_shortstop_1.value;
if (secondblock) res.secondblock = secondblock.value;
return res;
};

@ -88,7 +88,6 @@ function sensor_IsActive(name) {
function sensordetail_show(name, create) {
var win = document.getElementById("sensordetail");
@ -323,12 +322,15 @@ function sensorlist_cb_close () {
// ***********************************************************************************************
// ***********************************************************************************************
// sensor contextmenu: show a context menu for the sensor
//
// this is only if the INTERFACE name is set tu DEBUG
// ***********************************************************************************************
// ***********************************************************************************************
function sensor_contextmenu(name) {
let innerhtml = "";
for (var i = 0; i < sensors.length; i++) {
if (name == sensors[i].name) {
if (sensors[i].ifname == "DEBUG") {
innerhtml = "<center>";
innerhtml += "<button id=\"contextbox_On\" type=\"button\">Set On</button><br>";
innerhtml += "<button id=\"contextbox_Off\" type=\"button\">Set Off</button><br>";
@ -339,6 +341,9 @@ function sensor_contextmenu(name) {
gAddEventListener("contextbox_On", 'click', sensor_ctxmenu_On);
gAddEventListener("contextbox_Off", 'click', sensor_ctxmenu_Off);
gAddEventListener("contextbox_Close", 'click', gContextmenuClose);
}
}
}
};

Loading…
Cancel
Save