working on automatic mode

origin
steffen 5 years ago
parent 62f450ba97
commit 50cef93a49

@ -220,7 +220,13 @@ int Blocks::SetLockedby (string blname, string lockedby, int lock_onoff) {
if(network) network->ChangeListPushToAll(jp.ToString()); if(network) network->ChangeListPushToAll(jp.ToString());
res = 1; res = 1;
} }
else res = 0; else {
debug (0, "Blocks::SetLockedby could not set block '%s' for '%s'. Is used by '%s'.", blname.c_str(),lockedby.c_str(), bl->lockedby);
res = 0;
}
}
else {
debug (0, "Blocks::SetLockedby could not find block '%s'.", blname.c_str());
} }
UnLock(); UnLock();
@ -276,3 +282,20 @@ int Blocks::Clear(string name) {
return 0; return 0;
}; };
void Blocks::ClearLockedby(string name) {
int i;
JSONParse jp;
Lock();
for (i = 0; i < max; i++) {
if (name.compare(blocks[i].lockedby) == 0) {
blocks[i].lockedby[0] = 0;
changed = 1;
jp.AddObject("block",_GetJSON(i));
if(network) network->ChangeListPushToAll(jp.ToString());
}
}
UnLock();
}

@ -57,6 +57,7 @@ class Blocks {
int SetLockedby (string blname, string lockedby, int lock_onoff); int SetLockedby (string blname, string lockedby, int lock_onoff);
string GetLockedby (string blname); string GetLockedby (string blname);
void ClearLockedby(string name);
int Clear(string name); int Clear(string name);
}; };

@ -43,6 +43,7 @@ JSONParse Locomotives::_GetJSON(int idx) {
s = locomotives[idx].blocknext; json.AddObject("blocknext", s); s = locomotives[idx].blocknext; json.AddObject("blocknext", s);
s = locomotives[idx].blockassign; json.AddObject("blockassign", s); s = locomotives[idx].blockassign; json.AddObject("blockassign", s);
s = locomotives[idx].blockprev; json.AddObject("blockprev", s); s = locomotives[idx].blockprev; json.AddObject("blockprev", s);
s = locomotives[idx].auto_way; json.AddObject("auto_way", s);
json.AddObject("addr", locomotives[idx].addr); json.AddObject("addr", locomotives[idx].addr);
json.AddObject("stepcode", locomotives[idx].stepcode); json.AddObject("stepcode", locomotives[idx].stepcode);
json.AddObject("speed", locomotives[idx].speed); json.AddObject("speed", locomotives[idx].speed);
@ -120,6 +121,8 @@ Locomotive Locomotives::GetLocomotiveFromJSON(JSONParse *j) {
l.blockdest[0] = 0; l.blockdest[0] = 0;
l.blocknext[0] = 0; l.blocknext[0] = 0;
l.blockprev[0] = 0; l.blockprev[0] = 0;
l.auto_way[0] = 0;
l.auto_onroute = 0;
j->GetValue("name", &s); j->GetValue("name", &s);
strncpy (l.name, s.c_str(), REFERENCENAME_LEN); strncpy (l.name, s.c_str(), REFERENCENAME_LEN);
@ -153,12 +156,23 @@ int Locomotives::Change(Locomotive *loco) {
int ifree = -1; int ifree = -1;
Lock(); Lock();
printf ("%s:%d Change Locomotive\n", __FILE__, __LINE__);
for (i = 0; i < max; i++) { for (i = 0; i < max; i++) {
if (locomotives[i].name[0] != 0) { if (locomotives[i].name[0] != 0) {
// found element // found element
if (strncmp(locomotives[i].name, loco->name, REFERENCENAME_LEN) == 0) { if (strncmp(locomotives[i].name, loco->name, REFERENCENAME_LEN) == 0) {
// copy block data // copy block data
strncpy (locomotives[i].ifname, loco->name, REFERENCENAME_LEN);
locomotives[i].addr = loco->addr;
locomotives[i].stepcode = loco->stepcode;
locomotives[i].vmin = loco->vmin;
locomotives[i].vslow = loco->vslow;
locomotives[i].vmid = loco->vmid;
locomotives[i].vfast = loco->vfast;
locomotives[i].vmax = loco->vmax;
locomotives[i].flags = loco->flags;
// locomotives[i].speed = 0;
// locomotives[i].func = 0;
ifree = i; ifree = i;
break; break;
@ -197,6 +211,8 @@ int Locomotives::Delete(string name) {
locomotives[i].vfast = 0; locomotives[i].vfast = 0;
locomotives[i].vmax = 0; locomotives[i].vmax = 0;
locomotives[i].flags = 0; locomotives[i].flags = 0;
locomotives[i].auto_way[0] = 0;
locomotives[i].auto_onroute = -1;
changed = 1; changed = 1;
break; break;
} }
@ -265,7 +281,7 @@ int Locomotives::SetFunction(string name, int func, int value) {
int Locomotives::SetDestination (string name, string block, int direction) { int Locomotives::SetDestination (string name, string block, int direction) {
int i; int i;
string next; string way;
Lock(); Lock();
for (i = 0; i < max; i++) if (locomotives[i].name[0] != 0) for (i = 0; i < max; i++) if (locomotives[i].name[0] != 0)
@ -273,14 +289,21 @@ int Locomotives::SetDestination (string name, string block, int direction) {
debug (0, "Locomotives::SetDestination (Name:%s Block:%s Direction:%d)\n", name.c_str(), block.c_str(), direction); debug (0, "Locomotives::SetDestination (Name:%s Block:%s Direction:%d)\n", name.c_str(), block.c_str(), direction);
if (direction) snprintf (locomotives[i].blockdest, REFERENCENAME_LEN, "-:%s", block.c_str()); if (direction) snprintf (locomotives[i].blockdest, REFERENCENAME_LEN, "-:%s", block.c_str());
else snprintf (locomotives[i].blockdest, REFERENCENAME_LEN, "+:%s", block.c_str()); else snprintf (locomotives[i].blockdest, REFERENCENAME_LEN, "+:%s", block.c_str());
printf ("%s:%d Locomotive '%s' blockdest:%s\n", __FILE__, __LINE__, locomotives[i].name, locomotives[i].blockdest);
server->railways.FindWay(locomotives[i].blockassign, locomotives[i].blockdest, locomotives[i].name, &next); if (server->railways.FindWay(locomotives[i].blockassign, locomotives[i].blockdest, locomotives[i].name, &way)) {
size_t pos;
if ((pos = way.find(",b:", 1)) != string::npos) {
strncpy (locomotives[i].blocknext, way.substr(pos+3,string::npos).c_str(), REFERENCENAME_LEN);
strncpy (locomotives[i].auto_way, way.c_str(), WAYDATA_LEN);
server->railways.LockWay(way, locomotives[i].name);
}
}
printf ("%s:%d Locomotive '%s' blockdest:%s\n", __FILE__, __LINE__, locomotives[i].name, locomotives[i].blockdest);
break; break;
} }
UnLock(); UnLock();
printf ("%s:%d %s ************** finish me **************\n", __FILE__, __LINE__, __FUNCTION__); printf ("%s:%d %s ************** finish me **************\n", __FILE__, __LINE__, __FUNCTION__);
return 1; return 1;
} }
@ -294,14 +317,26 @@ int Locomotives::SetAssign (string name, string block, int direction) {
for (i = 0; i < max; i++) if (locomotives[i].name[0] != 0) for (i = 0; i < max; i++) if (locomotives[i].name[0] != 0)
if (name.compare(locomotives[i].name) == 0) { if (name.compare(locomotives[i].name) == 0) {
debug (0, "Locomotives::SetAssign (Name:%s Block:%s Direction:%d)\n", name.c_str(), block.c_str(), direction); debug (0, "Locomotives::SetAssign (Name:%s Block:%s Direction:%d)\n", name.c_str(), block.c_str(), direction);
if (locomotives[i].blockassign[0] != 0) // still locked unlock
server->blocks.SetLockedby(locomotives[i].blockassign, name, 0);
if (direction) snprintf (locomotives[i].blockassign, REFERENCENAME_LEN, "-:%s", block.c_str()); if (direction) snprintf (locomotives[i].blockassign, REFERENCENAME_LEN, "-:%s", block.c_str());
else snprintf (locomotives[i].blockassign, REFERENCENAME_LEN, "+:%s", block.c_str()); else snprintf (locomotives[i].blockassign, REFERENCENAME_LEN, "+:%s", block.c_str());
server->blocks.SetLockedby(block, name, 1);
break; break;
} }
UnLock(); UnLock();
while (server->railways.FindReference(&x, &y, block)) { while (server->railways.FindReference(&x, &y, block)) {
printf ("%s:%d Reference found at %d, %d\n", __FILE__, __LINE__, x, y); printf ("%s:%d Reference found at %d, %d\n", __FILE__, __LINE__, x, y);
string bl = server->blocks.GetLockedby(block);
if(bl.length() == 0 || bl.compare(name) == 0) {
server->blocks.SetLockedby(block, name, 1);
server->railways.SetLockedby(x, y, name, 1);
}
} }
printf ("%s:%d %s ************** finish me **************\n", __FILE__, __LINE__, __FUNCTION__); printf ("%s:%d %s ************** finish me **************\n", __FILE__, __LINE__, __FUNCTION__);
@ -322,12 +357,17 @@ int Locomotives::Reset(string name) {
locomotives[i].blockdest[0] = 0; locomotives[i].blockdest[0] = 0;
locomotives[i].blockprev[0] = 0; locomotives[i].blockprev[0] = 0;
locomotives[i].blocknext[0] = 0; locomotives[i].blocknext[0] = 0;
locomotives[i].auto_way[0] = 0;
locomotives[i].auto_onroute = -1;
break; break;
} }
server->railways.ClearLockedby(name); server->railways.ClearLockedby(name);
UnLock(); server->blocks.ClearLockedby(name);
jp.AddObject("locomotive",_GetJSON(i));
if(network) network->ChangeListPushToAll(jp.ToString());
UnLock();
return 1; return 1;
}; };
@ -464,3 +504,65 @@ string Locomotives::GetName(int idx) {
}; };
//
// 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 block return 1
//
int Locomotives::AutoCheckWaySingleStep(string way, string locname) {
int res = 0;
size_t pos1, pos2;
size_t curpos;
int val, state;
curpos = 0;
do {
curpos = way.find (",t:", curpos+1);
if (curpos != string::npos) {
pos1 = way.find(":", curpos+3);
if (pos1 == string::npos) {
debug (0, "%s:%d turnout without value? '%s'", __FILE__, __LINE__, way.c_str());
return 0;
}
state = server->turnouts.Get(way.substr(curpos+3, pos1-curpos-3));
if (state == -1) {
debug (0, "%s:%d turnout not found '%s'", __FILE__, __LINE__, way.substr(curpos+3, pos1-curpos-3).c_str());
return 0;
}
if (way[pos1+1] == '0' && state != 0) {
server->TurnoutSet(way.substr(curpos+3, pos1-curpos-3), 0);
break;
}
else if (way[pos1+1] == '1' && state != 1) {
server->TurnoutSet(way.substr(curpos+3, pos1-curpos-3), 1);
break;
}
printf ("%s:%d Checked:%s\n", __FILE__, __LINE__, way.substr(curpos+3, pos1-curpos-3).c_str());
}
} while (curpos != string::npos);
if (curpos == string::npos) res = 1;
return res;
}
int Locomotives::Test(string loco) {
int res = 0;
int i;
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);
}
printf ("%s:%d LocoTest ---> Return %d\n", __FILE__, __LINE__, res);
return 0;
};

@ -13,6 +13,8 @@
#define LOCO_F_RANDOM 0x0200 #define LOCO_F_RANDOM 0x0200
#define LOCO_F_AUTOSTOP 0x0400 #define LOCO_F_AUTOSTOP 0x0400
#define WAYDATA_LEN (16*REFERENCENAME_LEN)
enum { enum {
LOCO_INT_UNDEF = 0, LOCO_INT_UNDEF = 0,
LOCO_INT_DCC14, LOCO_INT_DCC14,
@ -60,7 +62,8 @@ struct s_Locomotive {
char blockprev[REFERENCENAME_LEN]; // prev block (mostly assigned block char blockprev[REFERENCENAME_LEN]; // prev block (mostly assigned block
char blockdest[REFERENCENAME_LEN]; // destination block char blockdest[REFERENCENAME_LEN]; // destination block
int auto_onroute; // LOCO_OR_.... char auto_way[WAYDATA_LEN]; // route to way "b:+blockname,t:name:0,t:name:1,b:-blockname"
int auto_onroute; // LOCO_OR_....
} typedef Locomotive; } typedef Locomotive;
class Locomotives { class Locomotives {
@ -98,11 +101,14 @@ class Locomotives {
int SetDestination (string name, string block, int direction); int SetDestination (string name, string block, int direction);
int SetAssign (string name, string block, int direction); int SetAssign (string name, string block, int direction);
int AutoCheckWaySingleStep(string way, string locname);
string GetName(int idx); string GetName(int idx);
JSONParse GetJSON(string name); JSONParse GetJSON(string name);
void GetJSONAll(JSONParse *json); void GetJSONAll(JSONParse *json);
Locomotive GetLocomotiveFromJSON(JSONParse *j); Locomotive GetLocomotiveFromJSON(JSONParse *j);
int Test(string loco);
}; };

@ -65,6 +65,7 @@ private:
void SetJSONLocoDest(JSONParse *jp); void SetJSONLocoDest(JSONParse *jp);
void SetJSONLocoAssign(JSONParse *jp); void SetJSONLocoAssign(JSONParse *jp);
void SetJSONLocoReset(JSONParse *jp); void SetJSONLocoReset(JSONParse *jp);
void SetJSONLocoTest(JSONParse *jp);
void SetJSONLocoMan(JSONParse *jp); void SetJSONLocoMan(JSONParse *jp);
void SetJSONLocoAutoMan(JSONParse *jp); void SetJSONLocoAutoMan(JSONParse *jp);
void SetJSONLocoAuto(JSONParse *jp); void SetJSONLocoAuto(JSONParse *jp);

@ -40,7 +40,9 @@ int Railways::UnLock() {
// //
// data must be mutex looked before use // data must be mutex looked before use
struct s_findway_data Railways::NextPos(struct s_findway_data pos, int dirtype) { struct s_findway_data Railways::NextPos(struct s_findway_data pos, int dirtype) {
struct s_findway_data np = { x: -1, y: -1, enterfrom: -1, parma: pos.parma }; // newpos struct s_findway_data np = { x: -1, y: -1, enterfrom: -1, oldx: pos.x, oldy:pos.y,
oldenterfrom: pos.enterfrom, parma: pos.parma,
way: pos.way }; // newpos
if (dirtype == 1) { if (dirtype == 1) {
if (pos.enterfrom == EF_NORTH) { if (pos.enterfrom == EF_NORTH) {
@ -394,7 +396,6 @@ void Railways::ClearLockedby(string name) {
} }
int Railways::_FindReference(int *x, int *y, string name) { int Railways::_FindReference(int *x, int *y, string name) {
int found = 0; int found = 0;
if (x == NULL || y == NULL) return 0; if (x == NULL || y == NULL) return 0;
@ -485,11 +486,16 @@ void Railways::DebugPrintFindWay(struct s_findway_map *fw) {
printf ("Debug Finished\n"); printf ("Debug Finished\n");
} }
/////////////////////////////////////////////////////////////////////
//
// FindWay: will be in two phases to decide where to go and how
// 1. check all possible ways in respect of (out of service blocks)
// 2.
// return 0 if no way found // return 0 if no way found
int Railways::FindWay(string blockstart, string blockend, string lockedfor, string *next) { int Railways::FindWay(string blockstart, string blockend, string lockedfor, string *next) {
// direction 0 ... RIGHT and DOWN // direction 0 ... RIGHT and DOWN
// direction 1 ... LEFT and UP // direction 1 ... LEFT and UP
struct s_findway_data fd_pos; struct s_findway_data fd_pos;
struct s_findway_data fd_tmp; struct s_findway_data fd_tmp;
struct s_findway_data fd_start; struct s_findway_data fd_start;
@ -528,6 +534,7 @@ int Railways::FindWay(string blockstart, string blockend, string lockedfor, stri
if (blockstart[0] == '+') fd_start.enterfrom = 3; if (blockstart[0] == '+') fd_start.enterfrom = 3;
else fd_start.enterfrom = 1; else fd_start.enterfrom = 1;
} }
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)].e = (1 << fd_start.enterfrom);
fd_data[GetRIdx(fd_start.x, fd_start.y)].score = 1; fd_data[GetRIdx(fd_start.x, fd_start.y)].score = 1;
fd_start.parma = 1; fd_start.parma = 1;
@ -547,6 +554,7 @@ int Railways::FindWay(string blockstart, string blockend, string lockedfor, stri
if (blockend[0] == '+') fd_end.enterfrom = 3; if (blockend[0] == '+') fd_end.enterfrom = 3;
else fd_end.enterfrom = 1; else fd_end.enterfrom = 1;
} }
fd_end.way = blockend;
fd_data[GetRIdx(fd_end.x, fd_end.y)].e = (1 << fd_end.enterfrom); fd_data[GetRIdx(fd_end.x, fd_end.y)].e = (1 << fd_end.enterfrom);
} }
else { else {
@ -561,7 +569,9 @@ int Railways::FindWay(string blockstart, string blockend, string lockedfor, stri
Lock(); Lock();
// //
// loop through the map; if found next needs to be filled in // loop through the map to find all possible ways to the destination
// this will be done in respect of lockedby blocks and ways.
//
while ((fd_list.size() > 0 || fd_pos.enterfrom >= 0) && found == 0) { while ((fd_list.size() > 0 || fd_pos.enterfrom >= 0) && found == 0) {
DebugPrintFindWay(fd_data); DebugPrintFindWay(fd_data);
if (fd_pos.enterfrom < 0) { if (fd_pos.enterfrom < 0) {
@ -582,13 +592,17 @@ int Railways::FindWay(string blockstart, string blockend, string lockedfor, stri
fd_pos.enterfrom = -1; fd_pos.enterfrom = -1;
fd_pos.x = -1; fd_pos.x = -1;
fd_pos.y = -1; fd_pos.y = -1;
fd_pos.way = "";
} }
else if (fd_pos.enterfrom >= 0 && fd_end.x == fd_pos.x && fd_pos.y == fd_end.y && fd_pos.enterfrom == fd_end.enterfrom) { else if (fd_pos.enterfrom >= 0 && fd_end.x == fd_pos.x && fd_pos.y == fd_end.y && fd_pos.enterfrom == fd_end.enterfrom) {
// destination found // destination found
printf ("%s:%d destination found fd_pos (%d,%d) fd_end (%d,%d)\n", __FILE__, __LINE__, fd_pos.x, fd_pos.y, fd_end.x, fd_end.y); printf ("%s:%d destination found fd_pos (%d,%d) fd_end (%d,%d) next:%s\n", __FILE__, __LINE__, fd_pos.x, fd_pos.y, fd_end.x, fd_end.y, fd_pos.way.c_str());
found = 1;
*next = fd_pos.way + ",b:" + blockend;
fd_pos.enterfrom = -1; fd_pos.enterfrom = -1;
fd_pos.x = -1; fd_pos.x = -1;
fd_pos.y = -1; fd_pos.y = -1;
fd_pos.way = "";
} }
else if (fd_pos.enterfrom >= 0 && fd_start.x == fd_pos.x && fd_start.y == fd_pos.y && fd_start.enterfrom == fd_pos.enterfrom) { else if (fd_pos.enterfrom >= 0 && fd_start.x == fd_pos.x && fd_start.y == fd_pos.y && fd_start.enterfrom == fd_pos.enterfrom) {
// start found // start found
@ -596,6 +610,7 @@ int Railways::FindWay(string blockstart, string blockend, string lockedfor, stri
fd_pos.enterfrom = -1; fd_pos.enterfrom = -1;
fd_pos.x = -1; fd_pos.x = -1;
fd_pos.y = -1; fd_pos.y = -1;
fd_pos.way = "";
} }
else if (fd_data[GetRIdx(fd_pos.x, fd_pos.y)].e & (1 << fd_pos.enterfrom)) { else if (fd_data[GetRIdx(fd_pos.x, fd_pos.y)].e & (1 << fd_pos.enterfrom)) {
// old entry found // old entry found
@ -603,6 +618,7 @@ int Railways::FindWay(string blockstart, string blockend, string lockedfor, stri
fd_pos.enterfrom = -1; fd_pos.enterfrom = -1;
fd_pos.x = -1; fd_pos.x = -1;
fd_pos.y = -1; fd_pos.y = -1;
fd_pos.way = "";
} }
else if (fd_pos.enterfrom >= 0) { else if (fd_pos.enterfrom >= 0) {
rpos = &railways[GetRIdx(fd_pos.x, fd_pos.y)]; rpos = &railways[GetRIdx(fd_pos.x, fd_pos.y)];
@ -611,14 +627,24 @@ int Railways::FindWay(string blockstart, string blockend, string lockedfor, stri
if (rpos->type == RAILWAY_NORMAL || rpos->type == RAILWAY_SENSOR) { if (rpos->type == RAILWAY_NORMAL || rpos->type == RAILWAY_SENSOR) {
fd_pos = NextPos(fd_pos, rpos->dir); fd_pos = NextPos(fd_pos, rpos->dir);
fd_pos.parma++; fd_pos.parma++;
rnext = &railways[GetRIdx(fd_pos.x, fd_pos.y)];
if (rnext->lockedby[0] != 0) {
printf ("%s:%d railway is locked by %s\n", __FILE__, __LINE__, rnext->lockedby);
fd_pos.enterfrom = -1;
fd_pos.x = -1;
fd_pos.y = -1;
fd_pos.way = "";
}
} }
else if (rpos->type == RAILWAY_TURNOUT) { else if (rpos->type == RAILWAY_TURNOUT) {
fd_tmp = NextPos(fd_pos, rpos->altdir); fd_tmp = NextPos(fd_pos, rpos->altdir);
fd_tmp.way += (string)",t:" + (string)rpos->name + (string)":1";
printf ("%s:%d turnout dir:%d altdir:%d fd_pos (%d,%d -> %d) fd_tmp (%d,%d -> %d)\n", __FILE__, __LINE__, rpos->dir, rpos->altdir, fd_pos.x, fd_pos.y, fd_pos.enterfrom, fd_tmp.x, fd_tmp.y, fd_tmp.enterfrom); printf ("%s:%d turnout dir:%d altdir:%d fd_pos (%d,%d -> %d) fd_tmp (%d,%d -> %d)\n", __FILE__, __LINE__, rpos->dir, rpos->altdir, fd_pos.x, fd_pos.y, fd_pos.enterfrom, fd_tmp.x, fd_tmp.y, fd_tmp.enterfrom);
fd_tmp.parma++; fd_tmp.parma += 10; // 10 bad point for using the turnout
fd_list.push_back(fd_tmp); fd_list.push_back(fd_tmp);
fd_pos = NextPos(fd_pos, rpos->dir); fd_pos = NextPos(fd_pos, rpos->dir);
fd_pos.way += (string)",t:" + (string)rpos->name + (string)":0";
fd_pos.parma++; fd_pos.parma++;
printf ("%s:%d turnout fd_newpos (%d,%d -> %d)\n", __FILE__, __LINE__, fd_pos.x, fd_pos.y, fd_pos.enterfrom); printf ("%s:%d turnout fd_newpos (%d,%d -> %d)\n", __FILE__, __LINE__, fd_pos.x, fd_pos.y, fd_pos.enterfrom);
} }
@ -627,10 +653,14 @@ int Railways::FindWay(string blockstart, string blockend, string lockedfor, stri
int found = 0; int found = 0;
printf ("%s:%d connector found Reference:'%s'\n", __FILE__, __LINE__, rpos->name); printf ("%s:%d connector found Reference:'%s'\n", __FILE__, __LINE__, rpos->name);
x = -1;
y = -1;
while (found == 0 && _FindReference(&x, &y, rpos->name) == 1) { while (found == 0 && _FindReference(&x, &y, rpos->name) == 1) {
if (fd_pos.x != x || fd_pos.y != y) { if (fd_pos.x != x || fd_pos.y != y) {
printf ("%s:%d found %d,%d\n", __FILE__, __LINE__, x, y); printf ("%s:%d found %d,%d\n", __FILE__, __LINE__, x, y);
fd_pos.oldx = fd_pos.x;
fd_pos.oldy = fd_pos.y;
fd_pos.oldenterfrom = fd_pos.enterfrom;
fd_pos.x = x; fd_pos.x = x;
fd_pos.y = y; fd_pos.y = y;
rpos = &railways[GetRIdx(fd_pos.x, fd_pos.y)]; rpos = &railways[GetRIdx(fd_pos.x, fd_pos.y)];
@ -645,6 +675,7 @@ int Railways::FindWay(string blockstart, string blockend, string lockedfor, stri
fd_pos.enterfrom = -1; fd_pos.enterfrom = -1;
fd_pos.x = -1; fd_pos.x = -1;
fd_pos.y = -1; fd_pos.y = -1;
fd_pos.way = "";
} }
} }
// //
@ -656,11 +687,26 @@ int Railways::FindWay(string blockstart, string blockend, string lockedfor, stri
fd_pos.enterfrom = -1; fd_pos.enterfrom = -1;
fd_pos.x = -1; fd_pos.x = -1;
fd_pos.y = -1; fd_pos.y = -1;
fd_pos.way = "";
} }
else { else {
// lockedby = server->blocks.GetLockedby(rpos->name); // lockedby = server->blocks.GetLockedby(rpos->name);
fd_pos = NextPos(fd_pos, rpos->dir); lockedby = server->blocks.GetLockedby(rpos->name);
fd_pos.parma++; if (lockedby.length() == 0) {
if (fd_pos.enterfrom == 0 || fd_pos.enterfrom == 3)
fd_pos.way += (string)",b:+:" + (string)rpos->name;
else fd_pos.way += (string)",b:-:" + (string)rpos->name;
fd_pos = NextPos(fd_pos, rpos->dir);
fd_pos.parma++;
}
else {
printf ("%s:%d block is locked by %s\n", __FILE__, __LINE__, lockedby.c_str());
fd_pos.enterfrom = -1;
fd_pos.x = -1;
fd_pos.y = -1;
fd_pos.way = "";
}
} }
} }
@ -669,11 +715,30 @@ int Railways::FindWay(string blockstart, string blockend, string lockedfor, stri
fd_pos.enterfrom = -1; fd_pos.enterfrom = -1;
fd_pos.x = -1; fd_pos.x = -1;
fd_pos.y = -1; fd_pos.y = -1;
fd_pos.way = "";
} }
} }
printf ("%s:%d fd_pos (%d,%d) enterfrom:%d\n\n", __FILE__, __LINE__, fd_pos.x, fd_pos.y, fd_pos.enterfrom); printf ("%s:%d fd_pos (%d,%d) enterfrom:%d\n\n", __FILE__, __LINE__, fd_pos.x, fd_pos.y, fd_pos.enterfrom);
} }
if (found == 0) *next = ""; if (found == 0) *next = "";
else {
//
// next = "b:+blockname,t:name:0,t:name:1,b:-blockname"
printf ("Temp Next: %s\n", next->c_str());
int i;
i = 0;
size_t npos;
if ((npos = next->find(",b:")) != string::npos) {
*next = next->substr(0, next->find(",", npos+1));
printf ("%s:%d next: '%s' found\n", __FILE__, __LINE__, next->c_str());
}
else {
// nothing found?
printf ("%s:%d next: '%s' but no next block?\n", __FILE__, __LINE__, next->c_str());
*next = "";
}
}
UnLock(); UnLock();
free (fd_data); free (fd_data);
@ -681,3 +746,217 @@ int Railways::FindWay(string blockstart, string blockend, string lockedfor, stri
return found; return found;
}; };
int Railways::LockWay (string way, string lockedby, int lockonoff) {
int res = 0;
size_t pos1, pos2;
size_t curwaypos;
struct s_findway_data start;
struct s_findway_data end;
struct s_findway_data pos;
string startblock, endblock;
Railway *r;
int finished = 0;
JSONParse jp;
debug (0, "* LockWay Way:'%s' for '%s'", way.c_str(), lockedby.c_str());
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;
startblock = way.substr (pos1+2, pos2-pos1-2);
if ((pos1 = way.find(",b:", 0)) == string::npos) return 0;
if ((pos2 = way.find(",", pos1+1)) == string::npos) endblock = way.substr (pos1+3, pos2);
else endblock = way.substr (pos1+3, pos2-pos1-3);
// printf ("%s:%d LockWay Way: '%s' Startblock: '%s' Endblock: '%s'\n", __FILE__, __LINE__, way.c_str(),
// startblock.c_str(), endblock.c_str());
if (FindReference(&start.x, &start.y, startblock.substr(2,string::npos))) {
if (Get(start.x, start.y).dir == 1) {
if (startblock[0] == '+') start.enterfrom = 0;
else start.enterfrom = 2;
}
else {
if (startblock[0] == '+') start.enterfrom = 3;
else start.enterfrom = 1;
}
}
else {
debug (0, "Railway::LockWay could not find start (%s).", startblock.c_str());
return 0;
}
if (FindReference(&end.x, &end.y, endblock.substr(2,string::npos))) {
if (Get(end.x, end.y).dir == 1) {
if (endblock[0] == '+') end.enterfrom = 0;
else end.enterfrom = 2;
}
else {
if (endblock[0] == '+') end.enterfrom = 3;
else end.enterfrom = 1;
}
}
else {
debug (0, "Railway::FindWay could not find end (%s).", endblock.c_str());
return 0;
}
printf ("%s:%d LockWay Way:'%s' start [%d,%d -> %d] to [%d,%d -> %d]\n", __FILE__, __LINE__, way.c_str(),
start.x, start.y, start.enterfrom, end.x, end.y, end.enterfrom);
//
// lock way depending on Way
Lock();
pos.x = start.x;
pos.y = start.y;
pos.enterfrom = start.enterfrom;
curwaypos = 0; // position in string // find first turnout
curwaypos = way.find(",t:", curwaypos);
if (curwaypos != string::npos) curwaypos++;
finished = 0;
do {
r = &railways[GetRIdx(pos.x, pos.y)];
printf ("LockWay Position [%d,%d] Name:%s LockedBy:'%s'\n", pos.x, pos.y, r->name, r->lockedby);
// check if railway is free or locked by me
if (r->lockedby[0] != 0 && lockedby.compare(r->lockedby) != 0) {
debug (0, "LockWay: Railway currently locked by '%s'.", r->lockedby);
UnLock();
return 0;
}
// do lock start and endpoint... unlock only start
if (pos.x == end.x && pos.y == end.y && r->type == RAILWAY_BLOCK) {
if (lockonoff == 1) {
server->blocks.SetLockedby(r->name, lockedby, 1);
strncpy (r->lockedby, lockedby.c_str(), REFERENCENAME_LEN);
jp.Clear();
jp.AddObject("railway",_GetJSONRailway(pos.x, pos.y));
if(network) network->ChangeListPushToAll(jp.ToString());
}
}
else if (pos.x != start.x && pos.y != start.y && r->type == RAILWAY_BLOCK) {
server->blocks.SetLockedby(r->name, lockedby, lockonoff);
if (lockonoff) strncpy (r->lockedby, lockedby.c_str(), REFERENCENAME_LEN);
else r->lockedby[0] = 0;
jp.Clear();
jp.AddObject("railway",_GetJSONRailway(pos.x, pos.y));
if(network) network->ChangeListPushToAll(jp.ToString());
}
else {
if (lockonoff) strncpy (r->lockedby, lockedby.c_str(), REFERENCENAME_LEN);
else r->lockedby[0] = 0;
jp.Clear();
jp.AddObject("railway",_GetJSONRailway(pos.x, pos.y));
if(network) network->ChangeListPushToAll(jp.ToString());
}
if ((pos.x == end.x && pos.y == end.y) || pos.x < 0 || pos.y < 0 || pos.x >= width || pos.y >= height) {
finished = 1;
break;
}
// go to next position
if (r->type == RAILWAY_TURNOUT) {
if (curwaypos == string::npos) { // we should have a turnout
debug (0, "LockWay turnout '%s' not on Way '%s'", r->name, way.c_str());
UnLock();
return 0;
}
pos1 = way.find(":", curwaypos+2);
if (pos1 == string::npos) {
debug (0, "LockWay turnout could not find parameter 'active'" );
UnLock();
return 0;
}
if (way.substr(curwaypos+2, pos1-curwaypos-2).compare(r->name) != 0) {
debug (0, "LockWay turnout '%s' not on Way '%s' we should on '%s'", r->name, way.c_str(), way.substr(curwaypos+2, pos1-curwaypos-2).c_str());
UnLock();
return 0;
}
if (way[pos1+1] == '0') pos = NextPos(pos, r->dir);
else pos = NextPos(pos, r->altdir);
// next turnout?
curwaypos = way.find(",t:", curwaypos);
if (curwaypos != string::npos) curwaypos++;
}
else if (r->type == RAILWAY_CONNECTOR) {
int found = 0;
int x, y;
printf ("%s:%d connector found Reference:'%s'\n", __FILE__, __LINE__, r->name);
x = -1;
y = -1;
while (found == 0 && _FindReference(&x, &y, r->name) == 1) {
if (pos.x != x || pos.y != y) {
printf ("%s:%d found %d,%d\n", __FILE__, __LINE__, x, y);
pos.oldx = pos.x;
pos.oldy = pos.y;
pos.oldenterfrom = pos.enterfrom;
pos.x = x;
pos.y = y;
r = &railways[GetRIdx(pos.x, pos.y)];
pos = NextPos(pos, r->dir);
pos.parma++;
found = 1;
break;
}
}
if (found == 0) {
debug (0, "LockWay connector '%s' did not find second end.", r->name );
UnLock();
return 0;
}
}
else if (r->type == RAILWAY_BLOCK || r->type == RAILWAY_SENSOR || r->type == RAILWAY_NORMAL) {
pos = NextPos(pos, r->dir);
}
} while (finished == 0);
if (pos.x == end.x && pos.y == end.y) res = 1;
UnLock();
return res;
};
int Railways::SetLockedby (int x, int y, string name, int locked) {
int res = 1;
Railway *r;
JSONParse jp;
if (x < 0 || y < 0 || x >= width || y >= height) return 0;
Lock();
r = &railways[GetRIdx(x,y)];
if (r->lockedby[0] != 0)
if (name.compare(r->lockedby) != 0) res = 0;
if (res) {
if (locked) strncpy (r->lockedby, name.c_str(), REFERENCENAME_LEN);
else r->lockedby[0] = 0;
if (railways[GetRIdx(x, y)].type != RAILWAY_NOTHING) {
jp.AddObject("railway", _GetJSONRailway(x, y));
if(network) network->ChangeListPushToAll(jp.ToString());
}
}
UnLock();
return res;
};

@ -71,7 +71,11 @@ struct s_findway_data {
int x; int x;
int y; int y;
int enterfrom; // enter field from clock view (0 = North, 3 = East... 6 ... 9) int enterfrom; // enter field from clock view (0 = North, 3 = East... 6 ... 9)
int oldx;
int oldy;
int oldenterfrom;
int parma; int parma;
string way;
}; };
struct s_findway_map { struct s_findway_map {
@ -123,6 +127,10 @@ class Railways {
int FindReference(int *x, int *y, string name); int FindReference(int *x, int *y, string name);
int FindWay(string blockstart, string blockend, string lockedfor, string *next); int FindWay(string blockstart, string blockend, string lockedfor, string *next);
int LockWay (string way, string lockedby, int lockonoff);
int LockWay (string way, string lockedby) { return LockWay(way, lockedby, 1); };
int UnLockWay (string way, string lockedby) { return LockWay(way, lockedby, 0); };
int SetLockedby (int x, int y, string name, int locked);
struct s_findway_data NextPos(struct s_findway_data pos, int dirtype); struct s_findway_data NextPos(struct s_findway_data pos, int dirtype);
}; };

@ -168,6 +168,7 @@ public:
int LocomotiveSetAuto(string name) { return locomotives.SetAuto(name); }; int LocomotiveSetAuto(string name) { return locomotives.SetAuto(name); };
int LocomotiveSetAutoMan(string name) { return locomotives.SetAutoMan(name); }; int LocomotiveSetAutoMan(string name) { return locomotives.SetAutoMan(name); };
int LocomotiveSetAutoRand(string name) { return locomotives.SetAutoRand(name); }; int LocomotiveSetAutoRand(string name) { return locomotives.SetAutoRand(name); };
int LocomotiveTest(string name) { return locomotives.Test(name); };
///////////////////////////////////////// /////////////////////////////////////////
// Sensor // Sensor

@ -142,6 +142,9 @@ int Session::ProcessData(JSONParse *jin, JSONParse *jout) {
else if (command.compare("locomotivereset") == 0) { else if (command.compare("locomotivereset") == 0) {
SetJSONLocoReset(jin); SetJSONLocoReset(jin);
} }
else if (command.compare("locomotivetest") == 0) {
SetJSONLocoTest(jin);
}
// //
// poweron / poweroff / save and resetdata // poweron / poweroff / save and resetdata
// //
@ -510,6 +513,20 @@ void Session::SetJSONLocoAssign(JSONParse *jp) {
}; };
void Session::SetJSONLocoTest(JSONParse *jp) {
string loco;
JSONParse jout;
jp->GetValue("locomotive", &loco);
server->LockThread();
server->LocomotiveTest(loco);
jout.Clear();
jout.AddObject("locomotive", server->LocomotiveGetJSON(loco));
if (network) network->ChangeListPushToAll(jout.ToString());
server->UnLockThread();
};
void Session::SetJSONLocoReset(JSONParse *jp) { void Session::SetJSONLocoReset(JSONParse *jp) {
string loco; string loco;

@ -189,6 +189,26 @@ int Turnouts::Set(string name, int value) {
return 1; return 1;
}; };
// return -1 not found, 0 inactive 1 active
int Turnouts::Get(string name) {
int i;
int res = -1;
//
Lock();
for (i = 0; i < max; i++) if (turnouts[i].name[0] != 0) {
if (name.compare(turnouts[i].name) == 0) {
if (turnouts[i].flags & TURNOUT_F_TURNOUT) res = 1;
else res = 0;
break;
}
}
UnLock();
return res;
}
// //
// got some data from bus // got some data from bus
void Turnouts::SetFromBus(string ifname, int addr, int value) { void Turnouts::SetFromBus(string ifname, int addr, int value) {

@ -45,6 +45,7 @@ class Turnouts {
int Change(Turnout *to); int Change(Turnout *to);
int Delete(string name); int Delete(string name);
int Set(string name, int active); int Set(string name, int active);
int Get(string name);
void Loop(); void Loop();

@ -33,6 +33,7 @@ function block_Update(blockdata) {
blocks.push ({ blocks.push ({
name: blockdata.name, name: blockdata.name,
flags: blockdata.flags, flags: blockdata.flags,
lockedby: blockdata.lockedby,
sensor_pos_1: blockdata.sensor_pos_1, sensor_pos_1: blockdata.sensor_pos_1,
sensor_center: blockdata.sensor_center, sensor_center: blockdata.sensor_center,
sensor_neg_1: blockdata.sensor_neg_1 sensor_neg_1: blockdata.sensor_neg_1
@ -358,6 +359,7 @@ function blockdetail_setData(elm) {
var sensorLU = document.getElementById("blockdet_sensorLU"); var sensorLU = document.getElementById("blockdet_sensorLU");
var sensorC = document.getElementById("blockdet_sensorC"); var sensorC = document.getElementById("blockdet_sensorC");
var sensorRD = document.getElementById("blockdet_sensorRD"); var sensorRD = document.getElementById("blockdet_sensorRD");
var lockedby = document.getElementById("blockdet_lockedby");
if (elm) { if (elm) {
if (name) name.value = elm.name; if (name) name.value = elm.name;
@ -369,6 +371,7 @@ function blockdetail_setData(elm) {
if (sensorLU) sensorLU.value = elm.sensor_pos_1; if (sensorLU) sensorLU.value = elm.sensor_pos_1;
if (sensorC) sensorC.value = elm.sensor_center; if (sensorC) sensorC.value = elm.sensor_center;
if (sensorRD) sensorRD.value = elm.sensor_neg_1; if (sensorRD) sensorRD.value = elm.sensor_neg_1;
if (lockedby) lockedby.value = elm.lockedby;
} }
}; };

@ -24,17 +24,18 @@ function locomotive_Update(data) {
locomotives[i].ifname = data.ifname; locomotives[i].ifname = data.ifname;
locomotives[i].addr = data.addr; locomotives[i].addr = data.addr;
locomotives[i].stepcode = data.stepcode; locomotives[i].stepcode = data.stepcode;
locomotives[i].speed = data.speed; if (data.speed) locomotives[i].speed = data.speed;
locomotives[i].vmin = data.vmin; locomotives[i].vmin = data.vmin;
locomotives[i].vslow = data.vslow; locomotives[i].vslow = data.vslow;
locomotives[i].vmid = data.vmid; locomotives[i].vmid = data.vmid;
locomotives[i].vfast = data.vfast; locomotives[i].vfast = data.vfast;
locomotives[i].vmax = data.vmax; locomotives[i].vmax = data.vmax;
locomotives[i].flags = data.flags; locomotives[i].flags = data.flags;
locomotives[i].blockassign = data.blockassign; if (data.blockassign) locomotives[i].blockassign = data.blockassign;
locomotives[i].blockprev = data.blockprev; if (data.blockprev) locomotives[i].blockprev = data.blockprev;
locomotives[i].blocknext = data.blocknext; if (data.blocknext) locomotives[i].blocknext = data.blocknext;
locomotives[i].blockdest = data.blockdest; if (data.blockdest) locomotives[i].blockdest = data.blockdest;
if (data.auto_way) locomotives[i].auto_way = data.auto_way;
locodetail_setData(locomotives[i]); locodetail_setData(locomotives[i]);
lococtrl_setData(data); lococtrl_setData(data);
return; return;
@ -58,7 +59,8 @@ function locomotive_Update(data) {
blockassign: data.blockassign, blockassign: data.blockassign,
blockdest: data.blockdest, blockdest: data.blockdest,
blocknext: data.blocknext, blocknext: data.blocknext,
blockprev: data.blockprev blockprev: data.blockprev,
auto_way: data.auto_way
}); });
}; };
@ -138,8 +140,8 @@ function locodetail_show(loconame) {
if (!win) { if (!win) {
debug ("loco_showdetail create window"); debug ("loco_showdetail create window");
win = gWindowCreate("locodetail", "Locomotive", 450, 500, " \ win = gWindowCreate("locodetail", "Locomotive", 450, 500,
<div style=\"float: left\"> \ "<div style=\"float: left\"> \
Name: <input id=\"locodet_name\" style=\"width: 100\"> \ Name: <input id=\"locodet_name\" style=\"width: 100\"> \
</div> <div style=\"float: right\"> \ </div> <div style=\"float: right\"> \
<button id=\"locodet_PREV\">&lt</button> \ <button id=\"locodet_PREV\">&lt</button> \
@ -183,7 +185,9 @@ function locodetail_show(loconame) {
<tr><td>Destination:</td><td><input id=\"locodet_blockdest\" style=\"width: 50\" disabled></td></tr> \ <tr><td>Destination:</td><td><input id=\"locodet_blockdest\" style=\"width: 50\" disabled></td></tr> \
<tr><td>Next:</td><td><input id=\"locodet_blocknext\" style=\"width: 50\" disabled></td></tr> \ <tr><td>Next:</td><td><input id=\"locodet_blocknext\" style=\"width: 50\" disabled></td></tr> \
<tr><td>Prev:</td><td><input id=\"locodet_blockprev\" style=\"width: 50\" disabled></td></tr> \ <tr><td>Prev:</td><td><input id=\"locodet_blockprev\" style=\"width: 50\" disabled></td></tr> \
</table><button id=\"locodet_RESET\" type=\"button\">Reset</button></fileset>\ <tr><td>Auto:</td><td><input id=\"locodet_auto_way\" style=\"width: 50\" disabled></td></tr> \
</table><button id=\"locodet_RESET\" type=\"button\">Reset</button> \
<button id=\"locodet_TEST\" type=\"button\">Test</button></fileset>\
\ \
</td></tr></table></div> <hr>\ </td></tr></table></div> <hr>\
<div align=right> \ <div align=right> \
@ -205,6 +209,7 @@ function locodetail_show(loconame) {
gAddEventListener("locodet_short", 'click', locodetail_cb_short); gAddEventListener("locodet_short", 'click', locodetail_cb_short);
gAddEventListener("locodet_cargo", 'click', locodetail_cb_cargo); gAddEventListener("locodet_cargo", 'click', locodetail_cb_cargo);
gAddEventListener("locodet_RESET", 'click', locodetail_cb_reset); gAddEventListener("locodet_RESET", 'click', locodetail_cb_reset);
gAddEventListener("locodet_TEST", 'click', locodetail_cb_test);
// gAddEventListener("locodet_DCC14", 'click', locodetail_cb_stepcode); // gAddEventListener("locodet_DCC14", 'click', locodetail_cb_stepcode);
// gAddEventListener("locodet_DCC28", 'click', locodetail_cb_stepcode); // gAddEventListener("locodet_DCC28", 'click', locodetail_cb_stepcode);
@ -274,6 +279,15 @@ function locodetail_cb_reset (element) {
}; };
function locodetail_cb_test (element) {
var loco = document.getElementById("locodet_name");
if (loco.value) {
var request = { command: "locomotivetest", locomotive: loco.value };
serverinout (request, serverinout_defaultCallback);
}
};
// //
// canreverse selected, setup flags // canreverse selected, setup flags
@ -435,6 +449,7 @@ function locodetail_setData(elm) {
var loco_blockdest = document.getElementById("locodet_blockdest"); var loco_blockdest = document.getElementById("locodet_blockdest");
var loco_blocknext = document.getElementById("locodet_blocknext"); var loco_blocknext = document.getElementById("locodet_blocknext");
var loco_blockprev = document.getElementById("locodet_blockprev"); var loco_blockprev = document.getElementById("locodet_blockprev");
var loco_auto_way = document.getElementById("locodet_auto_way");
if (elm) { if (elm) {
if (loco_name) loco_name.value = elm.name; if (loco_name) loco_name.value = elm.name;
@ -475,6 +490,7 @@ function locodetail_setData(elm) {
if (loco_blockdest) loco_blockdest.value = elm.blockdest; if (loco_blockdest) loco_blockdest.value = elm.blockdest;
if (loco_blocknext) loco_blocknext.value = elm.blocknext; if (loco_blocknext) loco_blocknext.value = elm.blocknext;
if (loco_blockprev) loco_blockprev.value = elm.blockprev; if (loco_blockprev) loco_blockprev.value = elm.blockprev;
if (loco_auto_way) loco_auto_way.value = elm.auto_way;
} }

@ -295,8 +295,23 @@ function trackDrawBlock(ctx, blockelm) {
if (block && Number(block.flags) & BLOCK_F_OFF) ctx.fillStyle = cssVar('--block-fg-closed'); if (block && Number(block.flags) & BLOCK_F_OFF) ctx.fillStyle = cssVar('--block-fg-closed');
else if (blockelm.lockedby && blockelm.lockedby != "") ctx.fillStyle = cssVar('--block-fg-locked'); else if (blockelm.lockedby && blockelm.lockedby != "") ctx.fillStyle = cssVar('--block-fg-locked');
else ctx.fillStyle = cssVar('--block-fg'); else ctx.fillStyle = cssVar('--block-fg');
ctx.fillText(blockelm.name, x1, y1);
} else { let li;
text = blockelm.name;
for (li = 0; li < locomotives.length; li++)
if (locomotives[li].name == blockelm.lockedby) {
if (locomotives[li].blockassign.substring(2,2+blockelm.lockedby.length) == blockelm.name) {
if (locomotives[li].blockassign.substring(0,1) == "-") text = "<= "+blockelm.lockedby;
else text = blockelm.lockedby + " =>";
}
else {
text = blockelm.lockedby;
}
}
ctx.fillText(text, x1, y1);
} else {
x1 = (0.5 + blockelm.x) * track.scale + 5; x1 = (0.5 + blockelm.x) * track.scale + 5;
y1 = (0.5 + blockelm.y) * track.scale; y1 = (0.5 + blockelm.y) * track.scale;
@ -308,7 +323,20 @@ function trackDrawBlock(ctx, blockelm) {
if (block && Number(block.flags) & BLOCK_F_OFF) ctx.fillStyle = cssVar('--block-fg-closed'); if (block && Number(block.flags) & BLOCK_F_OFF) ctx.fillStyle = cssVar('--block-fg-closed');
else if (blockelm.lockedby && blockelm.lockedby != "") ctx.fillStyle = cssVar('--block-fg-locked'); else if (blockelm.lockedby && blockelm.lockedby != "") ctx.fillStyle = cssVar('--block-fg-locked');
else ctx.fillStyle = cssVar('--block-fg'); else ctx.fillStyle = cssVar('--block-fg');
ctx.fillText(blockelm.name, 0, 0);
let li;
text = blockelm.name;
for (li = 0; li < locomotives.length; li++)
if (locomotives[li].name == blockelm.lockedby) {
if (locomotives[li].blockassign.substring(2,2+blockelm.lockedby.length) == blockelm.name) {
if (locomotives[li].blockassign.substring(0,1) == "-") text = blockelm.lockedby + " =>";
else text = "<= " + blockelm.lockedby;
}
else text = blockelm.lockedby;
}
ctx.fillText(text, 0, 0);
ctx.restore(); ctx.restore();
} }
} }

Loading…
Cancel
Save