#include #include "modelbahn.h" #include "block.h" #include #include #include using namespace std; Blocks::Blocks () { changed = 0; blocks = (Block*) malloc(sizeof(Block)*SENSORS_MAX); max = BLOCKS_MAX; last_blockidx = -1; }; Blocks::~Blocks() { free (blocks); blocks = NULL; max = 0; }; int Blocks::Lock() { if (pthread_mutex_lock(&mtx) == 0) return 1; else return 0; } int Blocks::UnLock() { if (pthread_mutex_unlock(&mtx) == 0) return 1; else return 0; } JSONParse Blocks::_GetJSON(Block *bl) { JSONParse json; JSONElement je; json.Clear(); json.AddObject("name", bl->name); json.AddObject("flags", bl->flags); json.AddObject("lockedby", bl->lockedby); json.AddObject("sensor_enter_0", bl->s_enter[0]); json.AddObject("sensor_slow_0", bl->s_slow[0]); json.AddObject("sensor_stop_0", bl->s_stop[0]); json.AddObject("sensor_shortstop_0", bl->s_shortstop[0]); json.AddObject("sensor_enter_1", bl->s_enter[1]); json.AddObject("sensor_slow_1", bl->s_slow[1]); json.AddObject("sensor_stop_1", bl->s_stop[1]); json.AddObject("sensor_shortstop_1", bl->s_shortstop[1]); json.AddObject("secondblock", bl->secondblock); return json; }; JSONParse Blocks::GetJSON(string name) { int i; JSONParse jp; jp.Clear(); Lock(); for (i = 0; i < max; i++) if (blocks[i].name[0] != 0) { if (name.compare(blocks[i].name) == 0) { jp = _GetJSON(i); } } UnLock(); return jp; }; void Blocks::GetJSONAll(JSONParse *json) { int i, cnt; JSONElement je; Lock(); // // write all railway data // create json object array manualy je.type = JSON_T_ARRAY; je.name = "blocks"; for (cnt = 0, i = 0; i < max; i++) if (blocks[i].name[0] != 0) { if (cnt != 0) je.value += ","; // not first element je.value += _GetJSON(i).ToString(); cnt++; } json->AddObject(je); UnLock(); }; Block Blocks::GetBlockFromJSON(JSONParse *j) { Block bl; string s; bl.name[0] = 0; bl.secondblock[0] = 0; bl.flags = 0; bl.lockedby[0] = 0; j->GetValue("name", &s); strncpy (bl.name, s.c_str(), REFERENCENAME_LEN); j->GetValueInt("flags", &bl.flags); // j->GetValue("lockedby", &s); // strncpy (bl.lockedby, s.c_str(), REFERENCENAME_LEN); // // old version input data // s = ""; if (j->GetValue("sensor_pos_1", &s)) { strncpy (bl.s_enter[0], s.c_str(), REFERENCENAME_LEN); strncpy (bl.s_stop[1], s.c_str(), REFERENCENAME_LEN); } s = ""; if (j->GetValue("sensor_center", &s)) { strncpy (bl.s_shortstop[0], s.c_str(), REFERENCENAME_LEN); strncpy (bl.s_shortstop[1], s.c_str(), REFERENCENAME_LEN); } s = ""; if (j->GetValue("sensor_neg_1", &s)) { strncpy (bl.s_enter[1], s.c_str(), REFERENCENAME_LEN); strncpy (bl.s_stop[0], s.c_str(), REFERENCENAME_LEN); } // // new version // s = ""; if (j->GetValue("sensor_enter_0", &s)) strncpy (bl.s_enter[0], s.c_str(), REFERENCENAME_LEN); s = ""; if (j->GetValue("sensor_enter_1", &s)) strncpy (bl.s_enter[1], s.c_str(), REFERENCENAME_LEN); s = ""; if (j->GetValue("sensor_slow_0", &s)) strncpy (bl.s_slow[0], s.c_str(), REFERENCENAME_LEN); s = ""; if (j->GetValue("sensor_slow_1", &s)) strncpy (bl.s_slow[1], s.c_str(), REFERENCENAME_LEN); s = ""; if (j->GetValue("sensor_stop_0", &s)) strncpy (bl.s_stop[0], s.c_str(), REFERENCENAME_LEN); 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; }; int Blocks::Change(Block *bl) { int i; int ifree = -1; Lock(); for (i = 0; i < max; i++) { if (blocks[i].name[0] != 0) { // found element if (strncmp(blocks[i].name, bl->name, REFERENCENAME_LEN) == 0) { ifree = i; break; } } else if (ifree == -1) ifree = i; } // element not found add new element if (ifree != -1 && ifree < max) { blocks[ifree] = *bl; strncpy (blocks[ifree].name, bl->name, REFERENCENAME_LEN); } changed = 1; UnLock(); return 1; }; int Blocks::Delete(string name) { int i; Lock(); for (i = 0; i < max; i++) if (blocks[i].name[0] != 0) { if (name.compare(blocks[i].name) == 0) { blocks[i].name[0] = 0; blocks[i].flags = 0; changed = 1; break; } } UnLock(); return 1; }; // // thread will not be locked.. int Blocks::SetOff(string blname) { Block *bl = NULL; JSONParse jp; Lock(); if ((bl = FindBlock(blname)) != NULL) { changed = 1; bl->flags |= BLOCK_F_OFF; debug (0, "Blocks::SetOff block %s", bl->name); jp.AddObject("block",_GetJSON(bl)); if(network) network->ChangeListPushToAll(jp.ToString()); UnLock(); return 1; } UnLock(); return 1; }; int Blocks::IsOff(string blname) { // return -1 if not found, 0 on no lock, 1 on lock Block *bl = NULL; int res = -1; Lock(); if ((bl = FindBlock(blname)) != NULL) { if (bl->flags & BLOCK_F_OFF) res = 1; else res = 0; } UnLock(); return res; }; int Blocks::SetLockedby (string blname, string lockedby, int lock_onoff) { // return -1 if not found, 0 on no lock, 1 on lock Block *bl = NULL; JSONParse jp; int res = -1; int x, y; debug (0, "Blocks::SetLockedby block:'%s' locked for '%s' locked:%d", blname.c_str(), lockedby.c_str(), lock_onoff); Lock(); if ((bl = FindBlock(blname)) != NULL) { if (lockedby.compare (bl->lockedby) == 0 || bl->lockedby[0] == 0) { if (lock_onoff) strncpy (bl->lockedby, lockedby.c_str(), REFERENCENAME_LEN); else bl->lockedby[0] = 0; jp.AddObject("block",_GetJSON(bl)); if(network) network->ChangeListPushToAll(jp.ToString()); x = -1; y = -1; while (server->railways.FindReference(&x, &y, blname)) { server->railways.SetLockedby(x, y, lockedby, lock_onoff); } res = 1; } 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(); return res; }; string Blocks::GetLockedby (string blname) { Block *bl = NULL; string lb; Lock(); if ((bl = FindBlock(blname)) != NULL) { lb = bl->lockedby; UnLock(); return lb; } UnLock(); return ""; }; 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; if (last_blockidx >= 0 && last_blockidx < max) if (name.compare (blocks[last_blockidx].name) == 0) return &blocks[last_blockidx]; for (last_blockidx = 0; last_blockidx < max; last_blockidx++) { if (name.compare (blocks[last_blockidx].name) == 0) return &blocks[last_blockidx]; } return bl; }; int Blocks::Clear(string name) { Block *bl = NULL; Lock(); if ((bl = FindBlock(name)) != NULL) { changed = 1; bl->flags &= ~BLOCK_F_OFF; printf ("%s:%d clear block %s off", __FILE__, __LINE__, bl->name); UnLock(); return 1; } UnLock(); 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(); }; int Blocks::GetFlags (string blname) { int res = 0; int i; JSONParse jp; Lock(); for (i = 0; i < max; i++) if (blname.compare(blocks[i].name) == 0) { res = blocks[i].flags; } UnLock(); return res; }; /* * return a pointer to the blockdata in case of split blocks also return the second block */ int Blocks::GetBlocksPtr (string blname, Block **b1, Block **b2) { int i; (*b1) = NULL; (*b2) = NULL; for (i = 0; i < max; i++) if (blname.compare(blocks[i].name) == 0) { (*b1) = &blocks[i]; } if ((*b1) == NULL) { debug (0, "Blocks::%s Could not find block: %s", __FUNCTION__, blname.c_str()); return 0; } if ((*b1)->flags & BLOCK_F_SPLIT) { for (i = 0; i < max; i++) if (strcmp ((*b1)->secondblock, blocks[i].name) == 0) { (*b2) = &blocks[i]; } if ((*b2) == NULL) { debug (0, "Blocks::%s Could not find second block: %s", __FUNCTION__, (*b1)->secondblock); return 0; } } return 1; } string Blocks::GetSensorEnter (int direction, string blname, int locoflags) { string res = ""; JSONParse jp; Block *b1 = NULL; Block *b2 = NULL; Lock(); if (!GetBlocksPtr(blname, &b1, &b2)) return res; if (!(locoflags & LOCO_F_SHORTTRAIN) && (b1->flags & BLOCK_F_SPLIT)) { if (direction == 0) { if (b1->flags & BLOCK_F_SPLITPOS) res = b1->s_enter[direction]; else res = b2->s_enter[direction]; } else { if (b1->flags & BLOCK_F_SPLITPOS) res = b2->s_enter[direction]; else res = b1->s_enter[direction]; } } if (res.length() == 0) { res = b1->s_enter[direction]; } UnLock(); return res; }; string Blocks::GetSensorSlow (int direction, string blname, int locoflags) { string res = ""; JSONParse jp; Block *b1 = NULL; Block *b2 = NULL; Lock(); if (!GetBlocksPtr(blname, &b1, &b2)) return res; if (!(locoflags & LOCO_F_SHORTTRAIN) && (b1->flags & BLOCK_F_SPLIT)) { if (direction == 0) { if (b1->flags & BLOCK_F_SPLITPOS) res = b2->s_slow[direction]; else res = b1->s_slow[direction]; } else { if (b1->flags & BLOCK_F_SPLITPOS) res = b1->s_slow[direction]; else res = b2->s_slow[direction]; } } if (res.length() == 0) { res = b1->s_slow[direction]; } if (res.length() == 0) { res = b1->s_enter[direction]; } UnLock(); return res; }; string Blocks::GetSensorStop (int direction, string blname, int locoflags) { string res = ""; JSONParse jp; Block *b1 = NULL; Block *b2 = NULL; Lock(); if (!GetBlocksPtr(blname, &b1, &b2)) return res; if ((locoflags & LOCO_F_SHORTTRAIN) && b1->s_shortstop[direction][0] != 0) res = b1->s_shortstop[direction]; if (!(locoflags & LOCO_F_SHORTTRAIN) && (b1->flags & BLOCK_F_SPLIT)) { if (direction == 0) { if (b1->flags & BLOCK_F_SPLITPOS) res = b2->s_stop[direction]; else res = b1->s_stop[direction]; } else { if (b1->flags & BLOCK_F_SPLITPOS) res = b1->s_stop[direction]; else res = b2->s_stop[direction]; } } if (res.length() == 0) { res = b1->s_stop[direction]; } UnLock(); return res; };