diff --git a/server/block.cc b/server/block.cc index e2e6e43..39f3171 100644 --- a/server/block.cc +++ b/server/block.cc @@ -220,7 +220,13 @@ int Blocks::SetLockedby (string blname, string lockedby, int lock_onoff) { if(network) network->ChangeListPushToAll(jp.ToString()); 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(); @@ -276,3 +282,20 @@ int Blocks::Clear(string name) { 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(); +} + diff --git a/server/block.h b/server/block.h index 91b6b0b..cb5e7c6 100644 --- a/server/block.h +++ b/server/block.h @@ -57,6 +57,7 @@ class Blocks { int SetLockedby (string blname, string lockedby, int lock_onoff); string GetLockedby (string blname); + void ClearLockedby(string name); int Clear(string name); }; diff --git a/server/locomotive.cc b/server/locomotive.cc index 4be910d..e92ec1c 100644 --- a/server/locomotive.cc +++ b/server/locomotive.cc @@ -43,6 +43,7 @@ JSONParse Locomotives::_GetJSON(int idx) { s = locomotives[idx].blocknext; json.AddObject("blocknext", s); s = locomotives[idx].blockassign; json.AddObject("blockassign", 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("stepcode", locomotives[idx].stepcode); json.AddObject("speed", locomotives[idx].speed); @@ -120,6 +121,8 @@ Locomotive Locomotives::GetLocomotiveFromJSON(JSONParse *j) { l.blockdest[0] = 0; l.blocknext[0] = 0; l.blockprev[0] = 0; + l.auto_way[0] = 0; + l.auto_onroute = 0; j->GetValue("name", &s); strncpy (l.name, s.c_str(), REFERENCENAME_LEN); @@ -153,12 +156,23 @@ int Locomotives::Change(Locomotive *loco) { int ifree = -1; Lock(); - + printf ("%s:%d Change Locomotive\n", __FILE__, __LINE__); for (i = 0; i < max; i++) { if (locomotives[i].name[0] != 0) { // found element if (strncmp(locomotives[i].name, loco->name, REFERENCENAME_LEN) == 0) { // 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; break; @@ -197,6 +211,8 @@ int Locomotives::Delete(string name) { locomotives[i].vfast = 0; locomotives[i].vmax = 0; locomotives[i].flags = 0; + locomotives[i].auto_way[0] = 0; + locomotives[i].auto_onroute = -1; changed = 1; break; } @@ -265,7 +281,7 @@ int Locomotives::SetFunction(string name, int func, int value) { int Locomotives::SetDestination (string name, string block, int direction) { int i; - string next; + string way; Lock(); 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); if (direction) snprintf (locomotives[i].blockdest, REFERENCENAME_LEN, "-:%s", block.c_str()); else snprintf (locomotives[i].blockdest, REFERENCENAME_LEN, "+:%s", block.c_str()); - - server->railways.FindWay(locomotives[i].blockassign, locomotives[i].blockdest, locomotives[i].name, &next); - + printf ("%s:%d Locomotive '%s' blockdest:%s\n", __FILE__, __LINE__, locomotives[i].name, locomotives[i].blockdest); + 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; } UnLock(); - printf ("%s:%d %s ************** finish me **************\n", __FILE__, __LINE__, __FUNCTION__); 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) 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); + + 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()); else snprintf (locomotives[i].blockassign, REFERENCENAME_LEN, "+:%s", block.c_str()); + + server->blocks.SetLockedby(block, name, 1); + break; } UnLock(); while (server->railways.FindReference(&x, &y, block)) { 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__); @@ -322,12 +357,17 @@ int Locomotives::Reset(string name) { locomotives[i].blockdest[0] = 0; locomotives[i].blockprev[0] = 0; locomotives[i].blocknext[0] = 0; + locomotives[i].auto_way[0] = 0; + locomotives[i].auto_onroute = -1; break; } server->railways.ClearLockedby(name); - UnLock(); + server->blocks.ClearLockedby(name); + jp.AddObject("locomotive",_GetJSON(i)); + if(network) network->ChangeListPushToAll(jp.ToString()); + UnLock(); 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; +}; + diff --git a/server/locomotive.h b/server/locomotive.h index b2bf8b8..bcf8e45 100644 --- a/server/locomotive.h +++ b/server/locomotive.h @@ -13,6 +13,8 @@ #define LOCO_F_RANDOM 0x0200 #define LOCO_F_AUTOSTOP 0x0400 +#define WAYDATA_LEN (16*REFERENCENAME_LEN) + enum { LOCO_INT_UNDEF = 0, LOCO_INT_DCC14, @@ -60,7 +62,8 @@ struct s_Locomotive { char blockprev[REFERENCENAME_LEN]; // prev block (mostly assigned 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; class Locomotives { @@ -98,11 +101,14 @@ class Locomotives { int SetDestination (string name, string block, int direction); int SetAssign (string name, string block, int direction); + int AutoCheckWaySingleStep(string way, string locname); + string GetName(int idx); JSONParse GetJSON(string name); void GetJSONAll(JSONParse *json); Locomotive GetLocomotiveFromJSON(JSONParse *j); + int Test(string loco); }; diff --git a/server/network.h b/server/network.h index ebc4ad5..d538aff 100644 --- a/server/network.h +++ b/server/network.h @@ -65,6 +65,7 @@ private: void SetJSONLocoDest(JSONParse *jp); void SetJSONLocoAssign(JSONParse *jp); void SetJSONLocoReset(JSONParse *jp); + void SetJSONLocoTest(JSONParse *jp); void SetJSONLocoMan(JSONParse *jp); void SetJSONLocoAutoMan(JSONParse *jp); void SetJSONLocoAuto(JSONParse *jp); diff --git a/server/railway.cc b/server/railway.cc index c4bb5f9..5fd8716 100644 --- a/server/railway.cc +++ b/server/railway.cc @@ -40,7 +40,9 @@ 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, 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 (pos.enterfrom == EF_NORTH) { @@ -394,7 +396,6 @@ void Railways::ClearLockedby(string name) { } - int Railways::_FindReference(int *x, int *y, string name) { int found = 0; if (x == NULL || y == NULL) return 0; @@ -485,11 +486,16 @@ void Railways::DebugPrintFindWay(struct s_findway_map *fw) { 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 int Railways::FindWay(string blockstart, string blockend, string lockedfor, string *next) { // direction 0 ... RIGHT and DOWN // direction 1 ... LEFT and UP - struct s_findway_data fd_pos; struct s_findway_data fd_tmp; 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; 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)].score = 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; else fd_end.enterfrom = 1; } + fd_end.way = blockend; fd_data[GetRIdx(fd_end.x, fd_end.y)].e = (1 << fd_end.enterfrom); } else { @@ -561,7 +569,9 @@ int Railways::FindWay(string blockstart, string blockend, string lockedfor, stri 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) { DebugPrintFindWay(fd_data); 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.x = -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) { // 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.x = -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) { // start found @@ -596,6 +610,7 @@ int Railways::FindWay(string blockstart, string blockend, string lockedfor, stri fd_pos.enterfrom = -1; fd_pos.x = -1; fd_pos.y = -1; + fd_pos.way = ""; } else if (fd_data[GetRIdx(fd_pos.x, fd_pos.y)].e & (1 << fd_pos.enterfrom)) { // old entry found @@ -603,6 +618,7 @@ int Railways::FindWay(string blockstart, string blockend, string lockedfor, stri fd_pos.enterfrom = -1; fd_pos.x = -1; fd_pos.y = -1; + fd_pos.way = ""; } else if (fd_pos.enterfrom >= 0) { 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) { fd_pos = NextPos(fd_pos, rpos->dir); 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) { 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); - fd_tmp.parma++; + 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++; 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; 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) { if (fd_pos.x != x || fd_pos.y != 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.y = 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.x = -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.x = -1; fd_pos.y = -1; + fd_pos.way = ""; } else { // lockedby = server->blocks.GetLockedby(rpos->name); - fd_pos = NextPos(fd_pos, rpos->dir); - fd_pos.parma++; + lockedby = server->blocks.GetLockedby(rpos->name); + 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.x = -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); } + 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(); free (fd_data); @@ -681,3 +746,217 @@ int Railways::FindWay(string blockstart, string blockend, string lockedfor, stri 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; +}; + diff --git a/server/railway.h b/server/railway.h index e5a71b4..8e2d73a 100644 --- a/server/railway.h +++ b/server/railway.h @@ -71,7 +71,11 @@ struct s_findway_data { int x; int y; int enterfrom; // enter field from clock view (0 = North, 3 = East... 6 ... 9) + int oldx; + int oldy; + int oldenterfrom; int parma; + string way; }; struct s_findway_map { @@ -123,6 +127,10 @@ class Railways { int FindReference(int *x, int *y, string name); 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); }; diff --git a/server/server.h b/server/server.h index 593084c..300d9af 100644 --- a/server/server.h +++ b/server/server.h @@ -168,6 +168,7 @@ public: int LocomotiveSetAuto(string name) { return locomotives.SetAuto(name); }; int LocomotiveSetAutoMan(string name) { return locomotives.SetAutoMan(name); }; int LocomotiveSetAutoRand(string name) { return locomotives.SetAutoRand(name); }; + int LocomotiveTest(string name) { return locomotives.Test(name); }; ///////////////////////////////////////// // Sensor diff --git a/server/session.cc b/server/session.cc index 0ad2c4a..839140f 100644 --- a/server/session.cc +++ b/server/session.cc @@ -142,6 +142,9 @@ int Session::ProcessData(JSONParse *jin, JSONParse *jout) { else if (command.compare("locomotivereset") == 0) { SetJSONLocoReset(jin); } + else if (command.compare("locomotivetest") == 0) { + SetJSONLocoTest(jin); + } // // 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) { string loco; diff --git a/server/turnout.cc b/server/turnout.cc index 0631670..a640f65 100644 --- a/server/turnout.cc +++ b/server/turnout.cc @@ -189,6 +189,26 @@ int Turnouts::Set(string name, int value) { 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 void Turnouts::SetFromBus(string ifname, int addr, int value) { diff --git a/server/turnout.h b/server/turnout.h index 5eda964..e09404b 100644 --- a/server/turnout.h +++ b/server/turnout.h @@ -45,6 +45,7 @@ class Turnouts { int Change(Turnout *to); int Delete(string name); int Set(string name, int active); + int Get(string name); void Loop(); diff --git a/webinterface/block.js b/webinterface/block.js index 5043c26..651d688 100644 --- a/webinterface/block.js +++ b/webinterface/block.js @@ -33,6 +33,7 @@ function block_Update(blockdata) { blocks.push ({ name: blockdata.name, flags: blockdata.flags, + lockedby: blockdata.lockedby, sensor_pos_1: blockdata.sensor_pos_1, sensor_center: blockdata.sensor_center, sensor_neg_1: blockdata.sensor_neg_1 @@ -358,6 +359,7 @@ function blockdetail_setData(elm) { var sensorLU = document.getElementById("blockdet_sensorLU"); var sensorC = document.getElementById("blockdet_sensorC"); var sensorRD = document.getElementById("blockdet_sensorRD"); + var lockedby = document.getElementById("blockdet_lockedby"); if (elm) { if (name) name.value = elm.name; @@ -369,6 +371,7 @@ function blockdetail_setData(elm) { if (sensorLU) sensorLU.value = elm.sensor_pos_1; if (sensorC) sensorC.value = elm.sensor_center; if (sensorRD) sensorRD.value = elm.sensor_neg_1; + if (lockedby) lockedby.value = elm.lockedby; } }; diff --git a/webinterface/locomotive.js b/webinterface/locomotive.js index e3d3958..4e8a4c7 100644 --- a/webinterface/locomotive.js +++ b/webinterface/locomotive.js @@ -24,17 +24,18 @@ function locomotive_Update(data) { locomotives[i].ifname = data.ifname; locomotives[i].addr = data.addr; 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].vslow = data.vslow; locomotives[i].vmid = data.vmid; locomotives[i].vfast = data.vfast; locomotives[i].vmax = data.vmax; locomotives[i].flags = data.flags; - locomotives[i].blockassign = data.blockassign; - locomotives[i].blockprev = data.blockprev; - locomotives[i].blocknext = data.blocknext; - locomotives[i].blockdest = data.blockdest; + if (data.blockassign) locomotives[i].blockassign = data.blockassign; + if (data.blockprev) locomotives[i].blockprev = data.blockprev; + if (data.blocknext) locomotives[i].blocknext = data.blocknext; + if (data.blockdest) locomotives[i].blockdest = data.blockdest; + if (data.auto_way) locomotives[i].auto_way = data.auto_way; locodetail_setData(locomotives[i]); lococtrl_setData(data); return; @@ -58,7 +59,8 @@ function locomotive_Update(data) { blockassign: data.blockassign, blockdest: data.blockdest, blocknext: data.blocknext, - blockprev: data.blockprev + blockprev: data.blockprev, + auto_way: data.auto_way }); }; @@ -138,8 +140,8 @@ function locodetail_show(loconame) { if (!win) { debug ("loco_showdetail create window"); - win = gWindowCreate("locodetail", "Locomotive", 450, 500, " \ -
\ + win = gWindowCreate("locodetail", "Locomotive", 450, 500, + "
\ Name: \
\ \ @@ -183,7 +185,9 @@ function locodetail_show(loconame) { Destination: \ Next: \ Prev: \ - \ + Auto: \ + \ + \ \

\
\ @@ -205,6 +209,7 @@ function locodetail_show(loconame) { gAddEventListener("locodet_short", 'click', locodetail_cb_short); gAddEventListener("locodet_cargo", 'click', locodetail_cb_cargo); gAddEventListener("locodet_RESET", 'click', locodetail_cb_reset); + gAddEventListener("locodet_TEST", 'click', locodetail_cb_test); // gAddEventListener("locodet_DCC14", '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 @@ -435,6 +449,7 @@ function locodetail_setData(elm) { var loco_blockdest = document.getElementById("locodet_blockdest"); var loco_blocknext = document.getElementById("locodet_blocknext"); var loco_blockprev = document.getElementById("locodet_blockprev"); + var loco_auto_way = document.getElementById("locodet_auto_way"); if (elm) { 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_blocknext) loco_blocknext.value = elm.blocknext; if (loco_blockprev) loco_blockprev.value = elm.blockprev; + if (loco_auto_way) loco_auto_way.value = elm.auto_way; } diff --git a/webinterface/track.js b/webinterface/track.js index c50d27c..4c02c4e 100644 --- a/webinterface/track.js +++ b/webinterface/track.js @@ -295,8 +295,23 @@ function trackDrawBlock(ctx, blockelm) { 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 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; 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'); else if (blockelm.lockedby && blockelm.lockedby != "") ctx.fillStyle = cssVar('--block-fg-locked'); 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(); } }