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.
353 lines
6.6 KiB
353 lines
6.6 KiB
|
|
#include "modelbahn.h"
|
|
#include "server.h"
|
|
#include "debug.h"
|
|
|
|
Railways::Railways() {
|
|
debug (0, "* Railways Constructor");
|
|
height = 0;
|
|
width = 0;
|
|
railways = NULL;
|
|
mtx = { 0 };
|
|
mtx = PTHREAD_MUTEX_INITIALIZER;
|
|
changed = 0;
|
|
};
|
|
|
|
|
|
Railways::~Railways() {
|
|
if (railways) free (railways);
|
|
height = 0;
|
|
width = 0;
|
|
};
|
|
|
|
|
|
//
|
|
// thread protection: lock
|
|
int Railways::Lock() {
|
|
if (pthread_mutex_lock(&mtx) == 0) return 1;
|
|
else return 0;
|
|
};
|
|
|
|
|
|
//
|
|
// thread protection: unlock
|
|
int Railways::UnLock() {
|
|
if (pthread_mutex_unlock(&mtx) == 0) return 1;
|
|
else return 0;
|
|
};
|
|
|
|
|
|
|
|
//
|
|
// return index inside the array (clip to boundery)
|
|
int Railways::GetRIdx(int x, int y) {
|
|
int _x, _y;
|
|
|
|
if (x < 0) _x = 0;
|
|
else if (x >= width) _x = width-1;
|
|
else _x = x;
|
|
|
|
if (y < 0) _y = 0;
|
|
else if (y >= height) _y = height-1;
|
|
else _y = y;
|
|
|
|
return (_x + _y * width);
|
|
};
|
|
|
|
|
|
//
|
|
// return JSON strign with the Railway data
|
|
// not thread safe !!!!
|
|
JSONParse Railways::_GetJSONRailway(int x, int y) {
|
|
JSONParse json;
|
|
JSONElement je;
|
|
int idx = GetRIdx(x,y);
|
|
string text = "";
|
|
|
|
json.Clear();
|
|
json.AddObject("x", x);
|
|
json.AddObject("y", y);
|
|
json.AddObject("dir", railways[idx].dir);
|
|
json.AddObject("altdir", railways[idx].altdir);
|
|
json.AddObject("type", railways[idx].type);
|
|
json.AddObject("maxspeed", railways[idx].maxspeed);
|
|
json.AddObject("flags", railways[idx].flags);
|
|
text = railways[idx].lockedby;
|
|
json.AddObject("lockedby", text);
|
|
text = railways[idx].name;
|
|
json.AddObject("name", text);
|
|
|
|
return json;
|
|
};
|
|
|
|
|
|
//
|
|
// return JSON strign with the Railway data
|
|
// thread safe.
|
|
JSONParse Railways::GetJSONRailway(int x, int y) {
|
|
JSONParse json;
|
|
|
|
Lock();
|
|
json = _GetJSONRailway(x, y);
|
|
UnLock();
|
|
|
|
return json;
|
|
};
|
|
|
|
|
|
Railway Railways::GetRailwayFromJSON(JSONParse *j) {
|
|
string text;
|
|
Railway r = {
|
|
type: RAILWAY_NOTHING,
|
|
x: 0,
|
|
y: 0,
|
|
dir: 0,
|
|
altdir: 0,
|
|
maxspeed: -1,
|
|
flags: 0,
|
|
name: { 0 }
|
|
};
|
|
r.name[0] = 0;
|
|
r.lockedby[0] = 0;
|
|
|
|
j->GetValueInt("x", &r.x);
|
|
j->GetValueInt("y", &r.y);
|
|
j->GetValueInt("dir", &r.dir);
|
|
j->GetValueInt("altdir", &r.altdir);
|
|
j->GetValueInt("type", &r.type);
|
|
j->GetValueInt("maxspeed", &r.maxspeed);
|
|
j->GetValueInt("flags", &r.flags);
|
|
j->GetValue("name", &text);
|
|
strncpy (r.name, text.c_str(), REFERENCENAME_LEN);
|
|
j->GetValue("lockedby", &text);
|
|
strncpy (r.lockedby, text.c_str(), REFERENCENAME_LEN);
|
|
|
|
return r;
|
|
};
|
|
|
|
|
|
//
|
|
// return some data about the railway/tracks
|
|
//
|
|
JSONParse Railways::GetJSONTrack() {
|
|
JSONParse json;
|
|
JSONParse jsondata;
|
|
JSONElement je;
|
|
|
|
json.Clear();
|
|
json.AddObject("height", height);
|
|
json.AddObject("width", width);
|
|
|
|
return json;
|
|
};
|
|
|
|
//
|
|
// change railway
|
|
// return 1 on change
|
|
int Railways::Change(Railway *rw) {
|
|
int x, y;
|
|
int result = 1;
|
|
JSONParse json;
|
|
|
|
if (rw == NULL) return 0;
|
|
Lock();
|
|
|
|
if (rw->x < 0 || rw->x >= width) result = 0;
|
|
else if (rw->y < 0 || rw->y >= height) result = 0;
|
|
else if (rw->dir < 0 || rw->dir > 6) result = 0;
|
|
else {
|
|
changed = true;
|
|
result = 1;
|
|
|
|
if (rw->dir == 0) rw->type == RAILWAY_NOTHING;
|
|
|
|
//
|
|
// need to delete?
|
|
if (rw->type == RAILWAY_NOTHING) {
|
|
Railway *r = &railways[GetRIdx(rw->x, rw->y)];
|
|
|
|
r->type = RAILWAY_NOTHING;
|
|
r->dir = 0;
|
|
r->altdir = 0;
|
|
r->flags = 0;
|
|
r->maxspeed = 0;
|
|
r->x = rw->x;
|
|
r->y = rw->y;
|
|
r->name[0] = 0;
|
|
r->lockedby[0] = 0;
|
|
}
|
|
|
|
//
|
|
// add normal railway
|
|
else if (rw->type == RAILWAY_NORMAL) {
|
|
railways[GetRIdx(rw->x, rw->y)] = *rw;
|
|
}
|
|
|
|
//
|
|
// add normal railway
|
|
else if (rw->type < RAILWAY_MAX) {
|
|
railways[GetRIdx(rw->x, rw->y)] = *rw;
|
|
}
|
|
|
|
else {
|
|
debug (DEBUG_INFO, "%s:%d add unknown %d,%d dir(%d) type:%d", __FILE__, __LINE__, rw->x, rw->y, rw->dir, rw->type);
|
|
}
|
|
}
|
|
|
|
UnLock();
|
|
return result;
|
|
};
|
|
|
|
//
|
|
// redefine the size of the track, keep data
|
|
void Railways::SetSize (int neww, int newh) {
|
|
Railway *rarray = railways;
|
|
int ow = width;
|
|
int oh = height;
|
|
int x, y;
|
|
|
|
debug (0, "* Railways::SetSize (%d, %d)", neww, newh);
|
|
|
|
Lock();
|
|
|
|
//
|
|
// old values saved during call up of the function, create new array for the railways data
|
|
railways = NULL;
|
|
_New (neww, newh);
|
|
|
|
//
|
|
// copy old data
|
|
for (x = 0; x < ow && x < width; x++)
|
|
for (y = 0; y < oh && x < height; y++)
|
|
railways[x + y * width] = rarray[x + y * oh];
|
|
free (rarray);
|
|
UnLock();
|
|
};
|
|
|
|
|
|
void Railways::_New (int neww, int newh) {
|
|
int x, y;
|
|
|
|
debug (0, "* Railways New");
|
|
|
|
//
|
|
// clip to minimum and maximum sizes
|
|
if (neww < RAILWAYS_MIN_WIDTH) width = RAILWAYS_MIN_WIDTH;
|
|
else if (neww > RAILWAYS_MAX_WIDTH) width = RAILWAYS_MAX_WIDTH;
|
|
else width = neww;
|
|
if (newh < RAILWAYS_MIN_HEIGHT) width = RAILWAYS_MIN_HEIGHT;
|
|
else if (newh > RAILWAYS_MAX_HEIGHT) width = RAILWAYS_MAX_HEIGHT;
|
|
else height = newh;
|
|
|
|
//
|
|
// if memory is already allocated free it first
|
|
if (railways != NULL) free (railways);
|
|
|
|
//
|
|
// allocate memory and reset memory
|
|
railways = (Railway*) malloc (sizeof (Railway) * width * height);
|
|
for (x = 0; x < width; x++) for (y = 0; y < height; y++) {
|
|
Railway *r = &railways[GetRIdx(x, y)];
|
|
r->type = RAILWAY_NOTHING;
|
|
r->dir = 0;
|
|
r->altdir = 0;
|
|
r->flags = 0;
|
|
r->maxspeed = 0;
|
|
r->x = x;
|
|
r->y = y;
|
|
r->name[0] = 0;
|
|
r->lockedby[0] = 0;
|
|
}
|
|
};
|
|
|
|
void Railways::New (int neww, int newh) {
|
|
Lock();
|
|
_New (neww, newh);
|
|
UnLock();
|
|
};
|
|
|
|
|
|
//
|
|
// append all data to the givin jasonobject
|
|
void Railways::GetJSONAll(JSONParse *json) {
|
|
int x, y;
|
|
|
|
if (json == NULL) return;
|
|
|
|
Lock();
|
|
|
|
json->AddObject("track", GetJSONTrack());
|
|
for (y = 0; y < height; y++)
|
|
for (x = 0; x < width; x++)
|
|
if (railways[GetRIdx(x, y)].type != RAILWAY_NOTHING) {
|
|
json->AddObject("railway", _GetJSONRailway(x, y));
|
|
}
|
|
|
|
UnLock();
|
|
}
|
|
|
|
//
|
|
// get railway element
|
|
// thread safe
|
|
Railway Railways::Get(int x, int y) {
|
|
Railway r;
|
|
|
|
Lock();
|
|
r = railways[GetRIdx(x, y)];
|
|
UnLock();
|
|
|
|
return r;
|
|
};
|
|
|
|
void Railways::ClearLockedby(string name) {
|
|
int x, y;
|
|
JSONParse jp;
|
|
|
|
Lock();
|
|
|
|
for (x = 0; x < width; x++)
|
|
for (y = 0; y < height; y++) {
|
|
if (name.compare(railways[GetRIdx(x,y)].lockedby) == 0) {
|
|
railways[GetRIdx(x,y)].lockedby [0] = 0;
|
|
changed = 1;
|
|
jp.AddObject("railway",_GetJSONRailway(x,y));
|
|
if(network) network->ChangeListPushToAll(jp.ToString());
|
|
}
|
|
}
|
|
|
|
UnLock();
|
|
}
|
|
|
|
|
|
int Railways::FindReference(int *x, int *y, string name) {
|
|
int found = 0;
|
|
if (x == NULL || y == NULL) return 0;
|
|
if (*x < 0 || *y < 0) {
|
|
*x = 0;
|
|
*y = 0;
|
|
}
|
|
|
|
Lock();
|
|
for (; found == 0 && *y < height; (*y)++) {
|
|
if (*x >= width) *x = 0;
|
|
else (*x)++;
|
|
|
|
for (; found == 0 && *x < width; (*x)++) {
|
|
if (strncmp (railways[GetRIdx(*x, *y)].name, name.c_str(), REFERENCENAME_LEN) == 0) {
|
|
found = 1;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
UnLock();
|
|
|
|
if (*x < width && *y < height) return 1;
|
|
else return 0;
|
|
};
|
|
|
|
|
|
int FindWay(string blockstart, string blockend, string lockedfor, string *next) {
|
|
return 0;
|
|
};
|
|
|