You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
507 lines
10 KiB
507 lines
10 KiB
|
|
#include <string>
|
|
#include "modelbahn.h"
|
|
#include "block.h"
|
|
|
|
|
|
#include <list>
|
|
#include <string>
|
|
#include <string.h>
|
|
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, cnt;
|
|
|
|
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;
|
|
cnt = 0;
|
|
while (server->railways.FindReference(&x, &y, blname, (cnt++))) {
|
|
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;
|
|
};
|
|
|