Merge pull request #156 from ey6es/master

Style fixes to chat code, and moved packet reading to main thread to fix synchronization issues.
This commit is contained in:
Philip Rosedale 2013-04-26 16:34:41 -07:00
commit 1804357eab
8 changed files with 75 additions and 70 deletions

View file

@ -674,7 +674,7 @@ void Avatar::render(bool lookingInMirror) {
glTranslatef(width * 0.5, 0, 0); glTranslatef(width * 0.5, 0, 0);
glDisable(GL_LIGHTING); glDisable(GL_LIGHTING);
if (_keyState == NoKeyDown) { if (_keyState == NO_KEY_DOWN) {
drawtext(0, 0, chatMessageScale, 180, 1.0, 0, _chatMessage.c_str(), 0, 1, 0); drawtext(0, 0, chatMessageScale, 180, 1.0, 0, _chatMessage.c_str(), 0, 1, 0);
} else { } else {

View file

@ -15,8 +15,8 @@ using namespace std;
const int MAX_CONTENT_LENGTH = 140; const int MAX_CONTENT_LENGTH = 140;
void ChatEntry::clear () { void ChatEntry::clear () {
contents.clear(); _contents.clear();
cursorPos = 0; _cursorPos = 0;
} }
bool ChatEntry::key(unsigned char k) { bool ChatEntry::key(unsigned char k) {
@ -25,22 +25,22 @@ bool ChatEntry::key(unsigned char k) {
return false; return false;
case '\b': case '\b':
if (cursorPos != 0) { if (_cursorPos != 0) {
contents.erase(cursorPos - 1, 1); _contents.erase(_cursorPos - 1, 1);
cursorPos--; _cursorPos--;
} }
return true; return true;
case 127: // delete case 127: // delete
if (cursorPos < contents.size()) { if (_cursorPos < _contents.size()) {
contents.erase(cursorPos, 1); _contents.erase(_cursorPos, 1);
} }
return true; return true;
default: default:
if (contents.size() != MAX_CONTENT_LENGTH) { if (_contents.size() != MAX_CONTENT_LENGTH) {
contents.insert(cursorPos, 1, k); _contents.insert(_cursorPos, 1, k);
cursorPos++; _cursorPos++;
} }
return true; return true;
} }
@ -49,24 +49,24 @@ bool ChatEntry::key(unsigned char k) {
void ChatEntry::specialKey(unsigned char k) { void ChatEntry::specialKey(unsigned char k) {
switch (k) { switch (k) {
case GLUT_KEY_LEFT: case GLUT_KEY_LEFT:
if (cursorPos != 0) { if (_cursorPos != 0) {
cursorPos--; _cursorPos--;
} }
break; break;
case GLUT_KEY_RIGHT: case GLUT_KEY_RIGHT:
if (cursorPos != contents.size()) { if (_cursorPos != _contents.size()) {
cursorPos++; _cursorPos++;
} }
break; break;
} }
} }
void ChatEntry::render(int screenWidth, int screenHeight) { void ChatEntry::render(int screenWidth, int screenHeight) {
drawtext(20, screenHeight - 150, 0.10, 0, 1.0, 0, contents.c_str(), 1, 1, 1); drawtext(20, screenHeight - 150, 0.10, 0, 1.0, 0, _contents.c_str(), 1, 1, 1);
float width = 0; float width = 0;
for (string::iterator it = contents.begin(), end = it + cursorPos; it != end; it++) { for (string::iterator it = _contents.begin(), end = it + _cursorPos; it != end; it++) {
width += glutStrokeWidth(GLUT_STROKE_ROMAN, *it)*0.10; width += glutStrokeWidth(GLUT_STROKE_ROMAN, *it)*0.10;
} }
glDisable(GL_LINE_SMOOTH); glDisable(GL_LINE_SMOOTH);

View file

@ -14,7 +14,7 @@
class ChatEntry { class ChatEntry {
public: public:
const std::string& getContents () const { return contents; } const std::string& getContents () const { return _contents; }
void clear (); void clear ();
@ -25,9 +25,8 @@ public:
private: private:
std::string contents; std::string _contents;
int _cursorPos;
int cursorPos;
}; };
#endif /* defined(__interface__ChatEntry__) */ #endif /* defined(__interface__ChatEntry__) */

View file

@ -39,8 +39,6 @@
#include <ifaddrs.h> #include <ifaddrs.h>
#endif #endif
#include <pthread.h>
#include <glm/glm.hpp> #include <glm/glm.hpp>
#include <glm/gtc/matrix_transform.hpp> #include <glm/gtc/matrix_transform.hpp>
#include <glm/gtc/type_ptr.hpp> #include <glm/gtc/type_ptr.hpp>
@ -87,10 +85,7 @@ using namespace std;
void reshape(int width, int height); // will be defined below void reshape(int width, int height); // will be defined below
void loadViewFrustum(ViewFrustum& viewFrustum); // will be defined below void loadViewFrustum(ViewFrustum& viewFrustum); // will be defined below
unsigned char incomingPacket[MAX_PACKET_SIZE];
pthread_t networkReceiveThread;
bool stopNetworkReceiveThread = false;
int packetCount = 0; int packetCount = 0;
int packetsPerSecond = 0; int packetsPerSecond = 0;
int bytesPerSecond = 0; int bytesPerSecond = 0;
@ -420,8 +415,6 @@ void terminate () {
#ifndef _WIN32 #ifndef _WIN32
audio.terminate(); audio.terminate();
#endif #endif
stopNetworkReceiveThread = true;
pthread_join(networkReceiveThread, NULL);
exit(EXIT_SUCCESS); exit(EXIT_SUCCESS);
} }
@ -1378,7 +1371,7 @@ void specialkey(int k, int x, int y)
void keyUp(unsigned char k, int x, int y) { void keyUp(unsigned char k, int x, int y) {
if (::chatEntryOn) { if (::chatEntryOn) {
myAvatar.setKeyState(AvatarData::NoKeyDown); myAvatar.setKeyState(NO_KEY_DOWN);
return; return;
} }
@ -1396,7 +1389,7 @@ void key(unsigned char k, int x, int y)
if (::chatEntryOn) { if (::chatEntryOn) {
if (chatEntry.key(k)) { if (chatEntry.key(k)) {
myAvatar.setKeyState(k == '\b' || k == 127 ? // backspace or delete myAvatar.setKeyState(k == '\b' || k == 127 ? // backspace or delete
AvatarData::DeleteKeyDown : AvatarData::InsertKeyDown); DELETE_KEY_DOWN : INSERT_KEY_DOWN);
myAvatar.setChatMessage(string(chatEntry.getContents().size(), 'X')); myAvatar.setChatMessage(string(chatEntry.getContents().size(), 'X'));
} else { } else {
@ -1475,47 +1468,40 @@ void key(unsigned char k, int x, int y)
if (k == '\r') { if (k == '\r') {
::chatEntryOn = true; ::chatEntryOn = true;
myAvatar.setKeyState(AvatarData::NoKeyDown); myAvatar.setKeyState(NO_KEY_DOWN);
myAvatar.setChatMessage(string()); myAvatar.setChatMessage(string());
} }
} }
// Receive packets from other agents/servers and decide what to do with them! // Receive packets from other agents/servers and decide what to do with them!
void *networkReceive(void *args) void networkReceive()
{ {
sockaddr senderAddress; sockaddr senderAddress;
ssize_t bytesReceived; ssize_t bytesReceived;
unsigned char *incomingPacket = new unsigned char[MAX_PACKET_SIZE];
while (!stopNetworkReceiveThread) { while (AgentList::getInstance()->getAgentSocket().receive(&senderAddress, incomingPacket, &bytesReceived)) {
if (AgentList::getInstance()->getAgentSocket().receive(&senderAddress, incomingPacket, &bytesReceived)) { packetCount++;
packetCount++; bytesCount += bytesReceived;
bytesCount += bytesReceived;
switch (incomingPacket[0]) {
switch (incomingPacket[0]) { case PACKET_HEADER_TRANSMITTER_DATA:
case PACKET_HEADER_TRANSMITTER_DATA: myAvatar.processTransmitterData(incomingPacket, bytesReceived);
myAvatar.processTransmitterData(incomingPacket, bytesReceived); break;
break; case PACKET_HEADER_VOXEL_DATA:
case PACKET_HEADER_VOXEL_DATA: case PACKET_HEADER_Z_COMMAND:
case PACKET_HEADER_Z_COMMAND: case PACKET_HEADER_ERASE_VOXEL:
case PACKET_HEADER_ERASE_VOXEL: voxels.parseData(incomingPacket, bytesReceived);
voxels.parseData(incomingPacket, bytesReceived); break;
break; case PACKET_HEADER_BULK_AVATAR_DATA:
case PACKET_HEADER_BULK_AVATAR_DATA: AgentList::getInstance()->processBulkAgentData(&senderAddress,
AgentList::getInstance()->processBulkAgentData(&senderAddress, incomingPacket,
incomingPacket, bytesReceived);
bytesReceived); break;
break; default:
default: AgentList::getInstance()->processAgentData(&senderAddress, incomingPacket, bytesReceived);
AgentList::getInstance()->processAgentData(&senderAddress, incomingPacket, bytesReceived); break;
break;
}
} }
} }
delete[] incomingPacket;
pthread_exit(0);
return NULL;
} }
void idle(void) { void idle(void) {
@ -1548,6 +1534,9 @@ void idle(void) {
// Sample hardware, update view frustum if needed, Lsend avatar data to mixer/agents // Sample hardware, update view frustum if needed, Lsend avatar data to mixer/agents
// //
updateAvatar(deltaTime); updateAvatar(deltaTime);
// read incoming packets from network
networkReceive();
//loop through all the other avatars and simulate them... //loop through all the other avatars and simulate them...
AgentList* agentList = AgentList::getInstance(); AgentList* agentList = AgentList::getInstance();
@ -1691,6 +1680,7 @@ int main(int argc, const char * argv[])
listenPort = atoi(portStr); listenPort = atoi(portStr);
} }
AgentList::createInstance(AGENT_TYPE_AVATAR, listenPort); AgentList::createInstance(AGENT_TYPE_AVATAR, listenPort);
AgentList::getInstance()->getAgentSocket().setBlocking(false);
gettimeofday(&applicationStartupTime, NULL); gettimeofday(&applicationStartupTime, NULL);
const char* domainIP = getCmdOption(argc, argv, "--domain"); const char* domainIP = getCmdOption(argc, argv, "--domain");
@ -1773,10 +1763,6 @@ int main(int argc, const char * argv[])
printLog("Local Voxel File loaded.\n"); printLog("Local Voxel File loaded.\n");
} }
// create thread for receipt of data via UDP
pthread_create(&networkReceiveThread, NULL, networkReceive, NULL);
printLog("Network receive thread created.\n");
glutTimerFunc(1000, Timer, 0); glutTimerFunc(1000, Timer, 0);
glutMainLoop(); glutMainLoop();

View file

@ -51,7 +51,7 @@ AvatarData::AvatarData() :
_cameraAspectRatio(0.0f), _cameraAspectRatio(0.0f),
_cameraNearClip(0.0f), _cameraNearClip(0.0f),
_cameraFarClip(0.0f), _cameraFarClip(0.0f),
_keyState(NoKeyDown) { _keyState(NO_KEY_DOWN) {
} }

View file

@ -15,6 +15,13 @@
#include <AgentData.h> #include <AgentData.h>
enum KeyState
{
NO_KEY_DOWN,
INSERT_KEY_DOWN,
DELETE_KEY_DOWN
};
class AvatarData : public AgentData { class AvatarData : public AgentData {
public: public:
AvatarData(); AvatarData();
@ -76,8 +83,6 @@ public:
void setCameraNearClip(float nearClip) { _cameraNearClip = nearClip; } void setCameraNearClip(float nearClip) { _cameraNearClip = nearClip; }
void setCameraFarClip(float farClip) { _cameraFarClip = farClip; } void setCameraFarClip(float farClip) { _cameraFarClip = farClip; }
enum KeyState { NoKeyDown, InsertKeyDown, DeleteKeyDown };
// key state // key state
void setKeyState(KeyState s) { _keyState = s; } void setKeyState(KeyState s) { _keyState = s; }
KeyState keyState() const { return _keyState; } KeyState keyState() const { return _keyState; }
@ -118,7 +123,7 @@ protected:
float _cameraNearClip; float _cameraNearClip;
float _cameraFarClip; float _cameraFarClip;
// key state (nothing, down, up, backspace) // key state
KeyState _keyState; KeyState _keyState;
// chat message // chat message

View file

@ -119,7 +119,7 @@ unsigned short loadBufferWithSocketInfo(char *addressBuffer, sockaddr *socket) {
} }
} }
UDPSocket::UDPSocket(int listeningPort) { UDPSocket::UDPSocket(int listeningPort) : blocking(true) {
init(); init();
// create the socket // create the socket
handle = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP); handle = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
@ -191,6 +191,18 @@ bool UDPSocket::init() {
return true; return true;
} }
void UDPSocket::setBlocking(bool blocking) {
this->blocking = blocking;
#ifdef _WIN32
u_long mode = blocking ? 0 : 1;
ioctlsocket(handle, FIONBIO, &mode);
#else
int flags = fcntl(handle, F_GETFL, 0);
fcntl(handle, F_SETFL, blocking ? (flags & ~O_NONBLOCK) : (flags | O_NONBLOCK));
#endif
}
// Receive data on this socket with retrieving address of sender // Receive data on this socket with retrieving address of sender
bool UDPSocket::receive(void *receivedData, ssize_t *receivedBytes) { bool UDPSocket::receive(void *receivedData, ssize_t *receivedBytes) {

View file

@ -23,12 +23,15 @@ class UDPSocket {
UDPSocket(int listening_port); UDPSocket(int listening_port);
~UDPSocket(); ~UDPSocket();
bool init(); bool init();
void setBlocking(bool blocking);
bool isBlocking() { return blocking; }
int send(sockaddr *destAddress, const void *data, size_t byteLength); int send(sockaddr *destAddress, const void *data, size_t byteLength);
int send(char *destAddress, int destPort, const void *data, size_t byteLength); int send(char *destAddress, int destPort, const void *data, size_t byteLength);
bool receive(void *receivedData, ssize_t *receivedBytes); bool receive(void *receivedData, ssize_t *receivedBytes);
bool receive(sockaddr *recvAddress, void *receivedData, ssize_t *receivedBytes); bool receive(sockaddr *recvAddress, void *receivedData, ssize_t *receivedBytes);
private: private:
int handle; int handle;
bool blocking;
}; };
bool socketMatch(sockaddr *first, sockaddr *second); bool socketMatch(sockaddr *first, sockaddr *second);