From 54e3342a5e737001b3161f05579bfddc1dfefb0c Mon Sep 17 00:00:00 2001 From: Steffen Pohle Date: Fri, 27 Oct 2023 19:58:29 +0200 Subject: [PATCH] working on split blocks --- .gitignore | 6 ++- server/railway.cc | 112 +++++++++++++++++++++++++++++++++++----------- server/railway.h | 1 + 3 files changed, 93 insertions(+), 26 deletions(-) diff --git a/.gitignore b/.gitignore index e5638cf..31a3209 100644 --- a/.gitignore +++ b/.gitignore @@ -17,4 +17,8 @@ z21emu/z21emu *.bin track.json track.json.backup.* - +Modelbahn.anjuta +*.track.json +Backup/ +.anjuta_sym_db.db +.anjuta/ diff --git a/server/railway.cc b/server/railway.cc index 40371f8..b571660 100644 --- a/server/railway.cc +++ b/server/railway.cc @@ -480,13 +480,52 @@ void Railways::DebugPrintFindWay(struct s_findway_map *fw) { } +/*************************************************************************** + * GetDestBlock: check if the destination is a split block and return + * the final destination block. + */ +string Railways::GetDestBlock(int locoflags, string blockend) { + int block_f; + string block; + string blockp, blockn; // blockend[pos,neg] name + + blockp = blockend.substr(2, string::npos); + block_f = server->blocks.GetFlags(blockp); + if ((block_f & BLOCK_F_SPLIT) && !(locoflags & LOCO_F_SHORTTRAIN)) { + blockn = server->blocks.GetFlags(blockp); + + // direction and position + if (block_f & BLOCK_F_SPLITPOS) { + blockn = server->blocks.GetSecondBlock(blockp); + } + else { + blockn = blockp; + blockp = server->blocks.GetSecondBlock(blockn); + } + + if (blockend[0] == '+') blockend = "+:" + blockn; + else blockend = "-:" + blockp; + } + else { + block = blockend; + } + + debug (0, "Railway::GetDestBlock Final split:%d blockend:%s" + , (block_f & BLOCK_F_SPLIT) ? 1 : 0 + , block.c_str()); + + return 0; +} + + /**************************************************************************** * FindWay: will be in two phases to decide where to go and how + * - check if endblock is valid on SPLIT and long trains. * - check all possible ways in respect of (out of service blocks) * and the ONLYCARGO/PASSENGER flags * return 0 if no way found */ -int Railways::FindWay(string blockstart, string blockend, string lockedfor, string *next) { +int Railways::FindWay(string org_blockstart, string org_blockend, string lockedfor, string *next) { // direction 0 ... RIGHT and DOWN // direction 1 ... LEFT and UP struct s_findway_data fd_pos; @@ -496,16 +535,27 @@ int Railways::FindWay(string blockstart, string blockend, string lockedfor, stri Railway *rpos, *rnext; std::list fd_list; struct s_findway_map *fd_data = NULL; + string blockstart, blockend; string lockedby; int x ,y; 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()); + debug (0, "Railway::FindWay blockstart:%s blockend:%s lockedfor:%s", org_blockstart.c_str(), org_blockend.c_str(), lockedfor.c_str()); + // // check blocklen - if (blockstart.length() <= 3 || blockend.length() <= 3) return 0; + if (org_blockstart.length() <= 3 || org_blockend.length() <= 3) return 0; + + + // + // setup blockstart and blockend depending on train type + // long trains need to get special attentions on the destination + blockstart = org_blockstart; // no check needed + blockend = GetDestBlock(locoflags, org_blockend); + + // // allocate and clear memory for checked data fd_data = (struct s_findway_map *) malloc (sizeof(struct s_findway_map) * width * height); if (fd_data == NULL) { @@ -514,6 +564,7 @@ int Railways::FindWay(string blockstart, string blockend, string lockedfor, stri } memset (fd_data, 0x0, sizeof(struct s_findway_map) * width*height); + // // find start and endpoint mark on fd_data, also startpoint to fd_list fd_end.x = fd_start.x = -1; @@ -558,7 +609,6 @@ int Railways::FindWay(string blockstart, string blockend, string lockedfor, stri } fd_pos = NextPos(fd_start, Get(fd_start.x, fd_start.y).dir); -// fd_list.push_back(fd_pos); Lock(); @@ -575,13 +625,9 @@ int Railways::FindWay(string blockstart, string blockend, string lockedfor, stri if (iter != fd_list.end()) { fd_pos = *iter; fd_list.pop_front(); - // printf ("get from stack (%d,%d)\n", fd_pos.x, fd_pos.y); } } - // printf ("%s:%d fd_start (%d,%d) enterfrom:%d\n", __FILE__, __LINE__, fd_start.x, fd_start.y, fd_start.enterfrom); - // printf ("%s:%d fd_end (%d,%d) enterfrom:%d\n", __FILE__, __LINE__, fd_end.x, fd_end.y, fd_end.enterfrom); - // printf ("%s:%d fd_pos (%d,%d) enterfrom:%d\n", __FILE__, __LINE__, fd_pos.x, fd_pos.y, fd_pos.enterfrom); if (fd_pos.enterfrom < 0 && fd_pos.enterfrom > 3) { fd_pos.enterfrom = -1; fd_pos.x = -1; @@ -667,11 +713,11 @@ int Railways::FindWay(string blockstart, string blockend, string lockedfor, stri fd_pos.way = ""; } } - // - // if block is off ignore it completly else if (rpos->type == RAILWAY_BLOCK) { int blflags = server->blocks.GetFlags(rpos->name); + // + // check if block is available for entering if ((server->blocks.IsOff(rpos->name) || ((blflags & BLOCK_F_ENDSTATION) && !(locoflags & LOCO_F_CANREVERSE)) || ((blflags & BLOCK_F_SHORT) && !(locoflags & LOCO_F_SHORTTRAIN) && @@ -715,13 +761,12 @@ int Railways::FindWay(string blockstart, string blockend, string lockedfor, stri 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" + // check if way found a block. size_t npos; if ((npos = next->find(",b:")) != string::npos) *next = next->substr(0, next->find(",", npos+1)); @@ -732,6 +777,8 @@ int Railways::FindWay(string blockstart, string blockend, string lockedfor, stri free (fd_data); + debug (0, "Railway::FindWay Result (%s) -> (%s) Found:%d Next:%s", blockstart.c_str(), blockend.c_str(), found, next->c_str()); + return found; }; @@ -768,10 +815,11 @@ int Railways::_NextPosIsValid(string loconame, int locoflags, struct s_findway_d int Railways::_SplitBlockIsFreeAndAllowed(string loconame, int locoflags, string block) { string pblock; string nblock; + Railway *rpos = NULL; int bflags = server->blocks.GetFlags(block); int nblockflags = 0; int pblockflags = 0; - int x1, y1, x2, y2, dx = 0, dy = 0; + int x1, y1, x2, y2, x = 0, y = 0; debug (0, "Railway::_SplitBlockIsFreeAndAllowed loconame:%s flags:%d block:%s", loconame.c_str(), locoflags, block.c_str()); @@ -779,7 +827,7 @@ int Railways::_SplitBlockIsFreeAndAllowed(string loconame, int locoflags, string if ((locoflags & !LOCO_F_SHORTTRAIN) && (bflags & !BLOCK_F_SPLIT)) return 0; // - // read negative the positive block flags + // read negative and positive block flags if (bflags & BLOCK_F_SPLITPOS) { pblockflags = bflags; pblock = block; @@ -806,14 +854,16 @@ int Railways::_SplitBlockIsFreeAndAllowed(string loconame, int locoflags, string 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; -} + x = x1; y = y1; + do { + if ( railways[GetRIdx(x,y)].lockedby[0] != 0) return 0; + if (x1 == x2) y++; // block is going from down to up + else x++; // block is going from left to right + } while (x != x2 || y != y2); + + return 1; +} int Railways::FindRandomWay(string blockstart, string lockedfor, string *next) { // direction 0 ... RIGHT and DOWN @@ -832,7 +882,7 @@ int Railways::FindRandomWay(string blockstart, string lockedfor, string *next) { debug (0, "Railway::FindRandomWay - disabled for now - needs to be rewritten"); return 0; - +/* // check blocklen if (blockstart.length() <= 3) return 0; @@ -1040,10 +1090,16 @@ int Railways::FindRandomWay(string blockstart, string lockedfor, string *next) { free (fd_data); return found; +*/ } - +/* + * try to lock or unlock the way for the loco(lockedby) + * Will also do the check for long trains and split blocks. + */ +#warning check for split blocks and long trains not yet finished. +//FIXME: check for split blocks and long trains not yet finished. int Railways::LockWay (string way, string lockedby, int lockonoff) { int res = 0; size_t pos1, pos2; @@ -1070,9 +1126,12 @@ int Railways::LockWay (string way, string lockedby, int lockonoff) { 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()); + printf ("%s:%d LockWay Way: '%s' Startblock: '%s' Endblock: '%s'\n", __FILE__, __LINE__, way.c_str(), + startblock.c_str(), endblock.c_str()); + // + // find start position + // 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; @@ -1088,6 +1147,9 @@ int Railways::LockWay (string way, string lockedby, int lockonoff) { return 0; } + // + // find end position, this needs to take care of the SPLIT blocks. + // if split BLOCK and LONG train check for the currect end block 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; diff --git a/server/railway.h b/server/railway.h index 1470087..116dd36 100644 --- a/server/railway.h +++ b/server/railway.h @@ -101,6 +101,7 @@ class Railways { 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); + string GetDestBlock(int locoflags, string blockend); public: Railways();