rocket/sync/device_client.cpp
2010-03-19 17:41:06 +01:00

196 lines
4.2 KiB
C++

#include "device.h"
#include "data.h"
#include "network.h"
using namespace sync;
class ClientDevice : public Device
{
public:
ClientDevice(const std::string &baseName, SOCKET serverSocket, Timer &timer) :
baseName(baseName),
timer(timer),
serverSocket(serverSocket),
serverRow(-1)
{
}
~ClientDevice();
Track &getTrack(const std::string &trackName);
bool update(float row);
private:
std::string getTrackFileName(std::string trackName);
void saveTracks();
const std::string baseName;
sync::Data syncData;
Timer &timer;
int serverRow;
SOCKET serverSocket;
};
ClientDevice::~ClientDevice()
{
}
Track &ClientDevice::getTrack(const std::string &trackName)
{
sync::Data::TrackContainer::iterator iter = syncData.tracks.find(trackName);
if (iter != syncData.tracks.end()) return *syncData.actualTracks[iter->second];
unsigned char cmd = GET_TRACK;
send(serverSocket, (char*)&cmd, 1, 0);
size_t clientIndex = syncData.actualTracks.size();
send(serverSocket, (char*)&clientIndex, sizeof(size_t), 0);
// send request data
size_t name_len = trackName.size();
send(serverSocket, (char*)&name_len, sizeof(size_t), 0);
const char *name_str = trackName.c_str();
send(serverSocket, name_str, int(name_len), 0);
sync::Track *track = new sync::Track();
syncData.actualTracks.push_back(track);
syncData.tracks[trackName] = clientIndex;
return *track;
}
bool ClientDevice::update(float row)
{
bool done = false;
// look for new commands
while (pollRead(serverSocket))
{
unsigned char cmd = 0;
int ret = recv(serverSocket, (char*)&cmd, 1, 0);
if (0 >= ret)
{
done = true;
break;
}
else
{
switch (cmd)
{
case SET_KEY:
{
int track, row;
float value;
char interp;
recv(serverSocket, (char*)&track, sizeof(int), 0);
recv(serverSocket, (char*)&row, sizeof(int), 0);
recv(serverSocket, (char*)&value, sizeof(float), 0);
recv(serverSocket, (char*)&interp, 1, 0);
assert(interp >= 0);
assert(interp < Track::KeyFrame::IT_COUNT);
sync::Track &t = syncData.getTrack(track);
t.setKeyFrame(row,
Track::KeyFrame(
value,
Track::KeyFrame::InterpolationType(interp)
)
);
}
break;
case DELETE_KEY:
{
int track, row;
recv(serverSocket, (char*)&track, sizeof(int), 0);
recv(serverSocket, (char*)&row, sizeof(int), 0);
sync::Track &t = syncData.getTrack(track);
t.deleteKeyFrame(row);
}
break;
case SET_ROW:
{
int row;
recv(serverSocket, (char*)&row, sizeof(int), 0);
timer.setRow(float(row));
}
break;
case PAUSE:
{
char flag;
recv(serverSocket, (char*)&flag, 1, 0);
if (flag == 0) timer.play();
else timer.pause();
}
break;
case SAVE_TRACKS:
saveTracks();
break;
default:
assert(false);
fprintf(stderr, "unknown cmd: %02x\n", cmd);
}
}
}
if (timer.isPlaying())
{
int newServerRow = int(floor(row));
if (serverRow != newServerRow)
{
unsigned char cmd = SET_ROW;
send(serverSocket, (char*)&cmd, 1, 0);
send(serverSocket, (char*)&newServerRow, sizeof(int), 0);
serverRow = newServerRow;
}
}
return !done;
}
std::string ClientDevice::getTrackFileName(std::string trackName)
{
std::string fileName = baseName.c_str();
fileName += "_";
fileName += trackName;
fileName += ".track";
return fileName;
}
void ClientDevice::saveTracks()
{
sync::Data::TrackContainer::iterator iter;
for (iter = syncData.tracks.begin(); iter != syncData.tracks.end(); ++iter)
{
std::string fileName = getTrackFileName(iter->first);
printf("\"%s\"\n", fileName.c_str());
}
}
Device *sync::createDevice(const std::string &baseName, Timer &timer)
{
if (false == initNetwork()) return NULL;
struct hostent *myhost = gethostbyname("localhost");
struct sockaddr_in sain;
sain.sin_family = AF_INET;
sain.sin_port = htons(1338);
sain.sin_addr.s_addr= *( (unsigned long *)(myhost->h_addr_list[0]) );
// connect to server
SOCKET serverSocket = serverConnect(&sain);
if (INVALID_SOCKET == serverSocket) return NULL;
ClientDevice *device = new ClientDevice(baseName, serverSocket, timer);
return device;
}