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.
467 lines
11 KiB
467 lines
11 KiB
|
|
|
|
#include "modelbahn.h"
|
|
#include "locomotive.h"
|
|
|
|
|
|
Locomotives::Locomotives () {
|
|
changed = 0;
|
|
locomotives = (Locomotive*) malloc(sizeof(Locomotive)*LOCOMOTIVES_MAX);
|
|
memset(locomotives, 0x0, sizeof(Locomotive)*LOCOMOTIVES_MAX);
|
|
max = SENSORS_MAX;
|
|
};
|
|
|
|
Locomotives::~Locomotives() {
|
|
free (locomotives);
|
|
locomotives = NULL;
|
|
max = 0;
|
|
};
|
|
|
|
|
|
int Locomotives::Lock() {
|
|
if (pthread_mutex_lock(&mtx) == 0) return 1;
|
|
else return 0;
|
|
}
|
|
|
|
|
|
int Locomotives::UnLock() {
|
|
if (pthread_mutex_unlock(&mtx) == 0) return 1;
|
|
else return 0;
|
|
}
|
|
|
|
|
|
JSONParse Locomotives::_GetJSON(int idx) {
|
|
JSONParse json;
|
|
JSONElement je;
|
|
string s = "";
|
|
|
|
json.Clear();
|
|
|
|
s = locomotives[idx].name; json.AddObject("name", s);
|
|
s = locomotives[idx].ifname; json.AddObject("ifname", s);
|
|
s = locomotives[idx].blockdest; json.AddObject("blockdest", s);
|
|
s = locomotives[idx].blocknext; json.AddObject("blocknext", s);
|
|
s = locomotives[idx].blockassign; json.AddObject("blockassign", s);
|
|
s = locomotives[idx].blockprev; json.AddObject("blockprev", s);
|
|
json.AddObject("addr", locomotives[idx].addr);
|
|
json.AddObject("stepcode", locomotives[idx].stepcode);
|
|
json.AddObject("speed", locomotives[idx].speed);
|
|
json.AddObject("func", locomotives[idx].func);
|
|
json.AddObject("flags", locomotives[idx].flags);
|
|
json.AddObject("vmin", locomotives[idx].vmin);
|
|
json.AddObject("vslow", locomotives[idx].vslow);
|
|
json.AddObject("vmid", locomotives[idx].vmid);
|
|
json.AddObject("vfast", locomotives[idx].vfast);
|
|
json.AddObject("vmax", locomotives[idx].vmax);
|
|
|
|
return json;
|
|
};
|
|
|
|
|
|
JSONParse Locomotives::GetJSON(string name) {
|
|
int i;
|
|
JSONParse jp;
|
|
|
|
jp.Clear();
|
|
|
|
Lock();
|
|
for (i = 0; i < max; i++) if (locomotives[i].name[0] != 0) {
|
|
if (name.compare(locomotives[i].name) == 0) {
|
|
jp = _GetJSON(i);
|
|
}
|
|
}
|
|
|
|
UnLock();
|
|
|
|
return jp;
|
|
};
|
|
|
|
|
|
void Locomotives::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 = "locomotives";
|
|
for (cnt = 0, i = 0; i < max; i++)
|
|
if (locomotives[i].name[0] != 0) {
|
|
if (cnt != 0) je.value += ","; // not first element
|
|
je.value += _GetJSON(i).ToString();
|
|
cnt++;
|
|
}
|
|
json->AddObject(je);
|
|
|
|
UnLock();
|
|
};
|
|
|
|
|
|
Locomotive Locomotives::GetLocomotiveFromJSON(JSONParse *j) {
|
|
Locomotive l;
|
|
string s;
|
|
|
|
l.name[0] = 0;
|
|
l.ifname[0] = 0;
|
|
l.addr = 0;
|
|
l.stepcode = 0;
|
|
l.vmin = 0;
|
|
l.vslow = 0;
|
|
l.vmid = 0;
|
|
l.vfast = 0;
|
|
l.vmax = 0;
|
|
l.flags = 0;
|
|
l.speed = 0;
|
|
l.func = 0;
|
|
l.blockassign[0] = 0;
|
|
l.blockdest[0] = 0;
|
|
l.blocknext[0] = 0;
|
|
l.blockprev[0] = 0;
|
|
|
|
j->GetValue("name", &s);
|
|
strncpy (l.name, s.c_str(), REFERENCENAME_LEN);
|
|
j->GetValue("ifname", &s);
|
|
strncpy (l.ifname, s.c_str(), REFERENCENAME_LEN);
|
|
j->GetValue("blockassign", &s);
|
|
strncpy (l.blockassign, s.c_str(), REFERENCENAME_LEN);
|
|
j->GetValue("blockdest", &s);
|
|
strncpy (l.blockdest, s.c_str(), REFERENCENAME_LEN);
|
|
j->GetValue("blockprev", &s);
|
|
strncpy (l.blockprev, s.c_str(), REFERENCENAME_LEN);
|
|
j->GetValue("blocknext", &s);
|
|
strncpy (l.blocknext, s.c_str(), REFERENCENAME_LEN);
|
|
j->GetValueInt("addr", &l.addr);
|
|
j->GetValueInt("stepcode", &l.stepcode);
|
|
j->GetValueInt("speed", &l.speed);
|
|
j->GetValueInt64("func", &l.func);
|
|
j->GetValueInt("flags", &l.flags);
|
|
j->GetValueInt("vmin", &l.vmin);
|
|
j->GetValueInt("vslow", &l.vslow);
|
|
j->GetValueInt("vmid", &l.vmid);
|
|
j->GetValueInt("vfast", &l.vfast);
|
|
j->GetValueInt("vmax", &l.vmax);
|
|
|
|
return l;
|
|
};
|
|
|
|
|
|
int Locomotives::Change(Locomotive *loco) {
|
|
int i;
|
|
int ifree = -1;
|
|
|
|
Lock();
|
|
|
|
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
|
|
|
|
ifree = i;
|
|
break;
|
|
}
|
|
}
|
|
else if (ifree == -1) ifree = i;
|
|
}
|
|
|
|
// element not found add new element
|
|
if (ifree != -1 && ifree < max) {
|
|
locomotives[ifree] = *loco;
|
|
strncpy (locomotives[ifree].name, loco->name, REFERENCENAME_LEN);
|
|
strncpy (locomotives[ifree].ifname, loco->ifname, REFERENCENAME_LEN);
|
|
}
|
|
|
|
changed = 1;
|
|
UnLock();
|
|
|
|
return 1;
|
|
};
|
|
|
|
|
|
int Locomotives::Delete(string name) {
|
|
int i;
|
|
|
|
Lock();
|
|
for (i = 0; i < max; i++) if (locomotives[i].name[0] != 0) {
|
|
if (name.compare(locomotives[i].name) == 0) {
|
|
locomotives[i].name[0] = 0;
|
|
locomotives[i].ifname[0] = 0;
|
|
locomotives[i].addr = 0;
|
|
locomotives[i].stepcode = 0;
|
|
locomotives[i].vmin = 0;
|
|
locomotives[i].vslow = 0;
|
|
locomotives[i].vmid = 0;
|
|
locomotives[i].vfast = 0;
|
|
locomotives[i].vmax = 0;
|
|
locomotives[i].flags = 0;
|
|
changed = 1;
|
|
break;
|
|
}
|
|
}
|
|
|
|
UnLock();
|
|
|
|
return 1;
|
|
};
|
|
|
|
|
|
int Locomotives::SetSpeed(string name, int speed) {
|
|
int i;
|
|
|
|
Lock();
|
|
for (i = 0; i < max; i++) if (locomotives[i].name[0] != 0) {
|
|
if (name.compare(locomotives[i].name) == 0) {
|
|
server->interfaces.SetLocoSpeed(&locomotives[i], speed);
|
|
break;
|
|
}
|
|
}
|
|
|
|
UnLock();
|
|
|
|
return 1;
|
|
};
|
|
|
|
|
|
int Locomotives::SetReverse(string name, int reverse) {
|
|
int i;
|
|
|
|
Lock();
|
|
for (i = 0; i < max; i++) if (locomotives[i].name[0] != 0) {
|
|
if (name.compare(locomotives[i].name) == 0) {
|
|
if (reverse)
|
|
locomotives[i].flags |= LOCO_F_REVERSE;
|
|
else
|
|
locomotives[i].flags &= ~LOCO_F_REVERSE;
|
|
|
|
server->interfaces.SetLocoSpeed(&locomotives[i], locomotives[i].speed);
|
|
break;
|
|
}
|
|
}
|
|
|
|
UnLock();
|
|
|
|
return 1;
|
|
};
|
|
|
|
|
|
int Locomotives::SetFunction(string name, int func, int value) {
|
|
int i;
|
|
|
|
Lock();
|
|
for (i = 0; i < max; i++) if (locomotives[i].name[0] != 0) {
|
|
if (name.compare(locomotives[i].name) == 0) {
|
|
server->interfaces.SetLocoFunction(&locomotives[i], func, value);
|
|
break;
|
|
}
|
|
}
|
|
UnLock();
|
|
|
|
return 1;
|
|
};
|
|
|
|
|
|
int Locomotives::SetDestination (string name, string block, int direction) {
|
|
int i;
|
|
string next;
|
|
|
|
Lock();
|
|
for (i = 0; i < max; i++) if (locomotives[i].name[0] != 0)
|
|
if (name.compare(locomotives[i].name) == 0) {
|
|
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);
|
|
|
|
break;
|
|
}
|
|
UnLock();
|
|
|
|
|
|
printf ("%s:%d %s ************** finish me **************\n", __FILE__, __LINE__, __FUNCTION__);
|
|
return 1;
|
|
}
|
|
|
|
|
|
int Locomotives::SetAssign (string name, string block, int direction) {
|
|
int i, x = -1;
|
|
int y = -1;
|
|
|
|
Lock();
|
|
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 (direction) snprintf (locomotives[i].blockassign, REFERENCENAME_LEN, "-:%s", block.c_str());
|
|
else snprintf (locomotives[i].blockassign, REFERENCENAME_LEN, "+:%s", block.c_str());
|
|
break;
|
|
}
|
|
UnLock();
|
|
|
|
while (server->railways.FindReference(&x, &y, block)) {
|
|
printf ("%s:%d Reference found at %d, %d\n", __FILE__, __LINE__, x, y);
|
|
}
|
|
|
|
printf ("%s:%d %s ************** finish me **************\n", __FILE__, __LINE__, __FUNCTION__);
|
|
return 1;
|
|
}
|
|
|
|
|
|
int Locomotives::Reset(string name) {
|
|
Railway rw;
|
|
int i;
|
|
JSONParse jp;
|
|
|
|
Lock();
|
|
for (i = 0; i < max; i++) if (locomotives[i].name[0] != 0)
|
|
if (name.compare(locomotives[i].name) == 0) {
|
|
debug (0, "Locomotives::Reset (Name:%s)\n", name.c_str());
|
|
locomotives[i].blockassign[0] = 0;
|
|
locomotives[i].blockdest[0] = 0;
|
|
locomotives[i].blockprev[0] = 0;
|
|
locomotives[i].blocknext[0] = 0;
|
|
break;
|
|
}
|
|
|
|
server->railways.ClearLockedby(name);
|
|
UnLock();
|
|
|
|
return 1;
|
|
};
|
|
|
|
int Locomotives::SetMan(string name) {
|
|
int i;
|
|
|
|
Lock();
|
|
for (i = 0; i < max; i++) if (locomotives[i].name[0] != 0)
|
|
if (name.compare(locomotives[i].name) == 0) {
|
|
debug (0, "Locomotives::SetMan (Name:%s)\n", name.c_str());
|
|
locomotives[i].flags &= ~(LOCO_F_AUTO | LOCO_F_AUTOSTOP | LOCO_F_RANDOM);
|
|
break;
|
|
}
|
|
UnLock();
|
|
SetSpeed(name, 0);
|
|
|
|
return 1;
|
|
};
|
|
|
|
int Locomotives::SetAutoMan(string name) {
|
|
int i;
|
|
|
|
Lock();
|
|
for (i = 0; i < max; i++) if (locomotives[i].name[0] != 0)
|
|
if (name.compare(locomotives[i].name) == 0 && (locomotives[i].flags & LOCO_F_AUTO)) {
|
|
debug (0, "Locomotives::SetAutoMan (Name:%s)\n", name.c_str());
|
|
locomotives[i].flags |= LOCO_F_AUTOSTOP;
|
|
locomotives[i].flags &= ~LOCO_F_RANDOM;
|
|
break;
|
|
}
|
|
UnLock();
|
|
|
|
return 1;
|
|
};
|
|
|
|
int Locomotives::SetAuto(string name) {
|
|
int i;
|
|
|
|
Lock();
|
|
for (i = 0; i < max; i++) if (locomotives[i].name[0] != 0)
|
|
if (name.compare(locomotives[i].name) == 0) {
|
|
debug (0, "Locomotives::SetAuto (Name:%s)\n", name.c_str());
|
|
locomotives[i].flags |= LOCO_F_AUTO;
|
|
break;
|
|
}
|
|
UnLock();
|
|
|
|
return 1;
|
|
};
|
|
|
|
int Locomotives::SetAutoRand(string name) {
|
|
int i;
|
|
|
|
Lock();
|
|
for (i = 0; i < max; i++) if (locomotives[i].name[0] != 0)
|
|
if (name.compare(locomotives[i].name) == 0 && (locomotives[i].flags & LOCO_F_AUTO)) {
|
|
debug (0, "Locomotives::SetRandom (Name:%s)\n", name.c_str());
|
|
locomotives[i].flags |= LOCO_F_RANDOM;
|
|
locomotives[i].flags &= ~LOCO_F_AUTOSTOP;
|
|
break;
|
|
}
|
|
UnLock();
|
|
|
|
return 1;
|
|
};
|
|
|
|
|
|
//
|
|
// set values from bus...
|
|
//
|
|
int Locomotives::SetSpeedFromBus(string ifname, int addr, int speed) {
|
|
int i;
|
|
JSONParse jp;
|
|
|
|
|
|
debug (0, "%s:%d SetSpeedFromBus IfName:%s Addr:%d Speed:%d", __FILE__, __LINE__, ifname.c_str(), addr, speed);
|
|
|
|
for (i = 0; i < max; i++) if (locomotives[i].name[0] != 0) {
|
|
if (ifname.compare(locomotives[i].ifname) == 0 && locomotives[i].addr == addr) {
|
|
int maxstep;
|
|
switch(locomotives[i].stepcode) {
|
|
case LOCO_INT_DCC14: maxstep = 14; break;
|
|
case LOCO_INT_DCC28: maxstep = 28; break;
|
|
case LOCO_INT_DCC128: maxstep = 126; break;
|
|
default: maxstep = -1; break;
|
|
}
|
|
|
|
if (speed == 0) locomotives[i].speed = 0;
|
|
if (speed >= (127-((127/maxstep)+1))) locomotives[i].speed = locomotives[i].vmax;
|
|
else {
|
|
locomotives[i].speed = speed * locomotives[i].vmax / 127;
|
|
if (locomotives[i].speed > locomotives[i].vmax) locomotives[i].speed = locomotives[i].vmax;
|
|
}
|
|
|
|
jp.AddObject("locomotive",_GetJSON(i));
|
|
if(network) network->ChangeListPushToAll(jp.ToString());
|
|
|
|
return 1;
|
|
}
|
|
}
|
|
return 0;
|
|
};
|
|
|
|
|
|
int Locomotives::SetFunctionFromBus(string ifname, int addr, int func) {
|
|
int i;
|
|
JSONParse jp;
|
|
|
|
debug (0, "%s:%d SetDirectionFromBus IfName:%s Addr:%d function:%d", __FILE__, __LINE__, ifname.c_str(), addr, func);
|
|
for (i = 0; i < max; i++) if (locomotives[i].name[0] != 0) {
|
|
if (ifname.compare(locomotives[i].ifname) == 0 && locomotives[i].addr == addr) {
|
|
if (func & 32) locomotives[i].flags |= LOCO_F_REVERSE;
|
|
else locomotives[i].flags &= ~LOCO_F_REVERSE;
|
|
|
|
jp.AddObject("locomotive",_GetJSON(i));
|
|
if(network) network->ChangeListPushToAll(jp.ToString());
|
|
|
|
return 1;
|
|
}
|
|
}
|
|
return 0;
|
|
};
|
|
|
|
|
|
string Locomotives::GetName(int idx) {
|
|
string result = "";
|
|
|
|
Lock();
|
|
if (idx <= max && idx >= 0)
|
|
result = locomotives[idx].name;
|
|
UnLock();
|
|
|
|
return result;
|
|
};
|
|
|
|
|