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.
Modelbahn/server/railway.cc

296 lines
5.4 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 name = "";
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);
name = railways[idx].name;
json.AddObject("name", name);
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 name;
Railway r = {
type: RAILWAY_NOTHING,
x: 0,
y: 0,
dir: 0,
altdir: 0,
maxspeed: -1,
flags: 0
};
r.name[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", &name);
strncpy (r.name, name.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;
}
//
// 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;
}
};
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;
};