[Orxonox-commit 666] r3198 - in trunk/src: core network network/packet network/synchronisable orxonox/gamestates util
scheusso at orxonox.net
scheusso at orxonox.net
Sat Jun 20 16:27:39 CEST 2009
Author: scheusso
Date: 2009-06-20 16:27:38 +0200 (Sat, 20 Jun 2009)
New Revision: 3198
Modified:
trunk/src/core/ConfigFileManager.cc
trunk/src/core/ConsoleCommandCompilation.cc
trunk/src/core/Language.cc
trunk/src/core/LuaBind.cc
trunk/src/network/Client.cc
trunk/src/network/ClientConnection.cc
trunk/src/network/ClientInformation.h
trunk/src/network/ConnectionManager.cc
trunk/src/network/ConnectionManager.h
trunk/src/network/GamestateManager.cc
trunk/src/network/Server.cc
trunk/src/network/TrafficControl.cc
trunk/src/network/packet/Acknowledgement.cc
trunk/src/network/packet/Gamestate.cc
trunk/src/network/packet/Gamestate.h
trunk/src/network/synchronisable/Synchronisable.cc
trunk/src/orxonox/gamestates/GSDedicated.cc
trunk/src/orxonox/gamestates/GSDedicated.h
trunk/src/util/OutputBuffer.cc
trunk/src/util/SignalHandler.cc
Log:
merged netp4 back to trunk
Modified: trunk/src/core/ConfigFileManager.cc
===================================================================
--- trunk/src/core/ConfigFileManager.cc 2009-06-20 13:26:42 UTC (rev 3197)
+++ trunk/src/core/ConfigFileManager.cc 2009-06-20 14:27:38 UTC (rev 3198)
@@ -39,7 +39,6 @@
namespace orxonox
{
- const int CONFIG_FILE_MAX_LINELENGHT = 1024;
const char* const DEFAULT_CONFIG_FILE = "default.ini";
ConfigFileManager* ConfigFileManager::singletonRef_s = 0;
@@ -243,17 +242,13 @@
file.open(filepath.string().c_str(), std::fstream::in);
if (file.is_open())
{
-
- char linearray[CONFIG_FILE_MAX_LINELENGHT];
-
ConfigFileSection* newsection = 0;
while (file.good() && !file.eof())
{
- file.getline(linearray, CONFIG_FILE_MAX_LINELENGHT);
+ std::string line;
+ std::getline(file, line);
- std::string line = std::string(linearray);
-
std::string temp = getStripped(line);
if (!isEmpty(temp) && !isComment(temp))
{
Modified: trunk/src/core/ConsoleCommandCompilation.cc
===================================================================
--- trunk/src/core/ConsoleCommandCompilation.cc 2009-06-20 13:26:42 UTC (rev 3197)
+++ trunk/src/core/ConsoleCommandCompilation.cc 2009-06-20 14:27:38 UTC (rev 3198)
@@ -72,10 +72,10 @@
executingFiles.insert(filename);
// Iterate through the file and put the lines into the CommandExecutor
- char line[1024];
while (file.good() && !file.eof())
{
- file.getline(line, 1024);
+ std::string line;
+ std::getline(file, line);
CommandExecutor::execute(line);
}
@@ -143,10 +143,10 @@
}
std::string output = "";
- char line[1024];
while (file.good() && !file.eof())
{
- file.getline(line, 1024);
+ std::string line;
+ std::getline(file, line);
output += line;
output += "\n";
}
Modified: trunk/src/core/Language.cc
===================================================================
--- trunk/src/core/Language.cc 2009-06-20 13:26:42 UTC (rev 3197)
+++ trunk/src/core/Language.cc 2009-06-20 14:27:38 UTC (rev 3198)
@@ -223,13 +223,11 @@
return;
}
- char line[1024];
-
// Iterate through the file and create the LanguageEntries
while (file.good() && !file.eof())
{
- file.getline(line, 1024);
- std::string lineString = std::string(line);
+ std::string lineString;
+ std::getline(file, lineString);
// Check if the line is empty
if ((lineString != "") && (lineString.size() > 0))
@@ -271,13 +269,11 @@
return;
}
- char line[1024];
-
// Iterate through the file and create the LanguageEntries
while (file.good() && !file.eof())
{
- file.getline(line, 1024);
- std::string lineString = std::string(line);
+ std::string lineString;
+ std::getline(file, lineString);
// Check if the line is empty
if ((lineString != "") && (lineString.size() > 0))
Modified: trunk/src/core/LuaBind.cc
===================================================================
--- trunk/src/core/LuaBind.cc 2009-06-20 13:26:42 UTC (rev 3197)
+++ trunk/src/core/LuaBind.cc 2009-06-20 14:27:38 UTC (rev 3198)
@@ -94,12 +94,12 @@
// some error msg
}
- char line[1024*32];
std::string levelString = "";
while (file.good() && !file.eof())
{
- file.getline(line, 1024*32);
+ std::string line;
+ std::getline(file, line);
levelString += line;
levelString += "\n";
}
Modified: trunk/src/network/Client.cc
===================================================================
--- trunk/src/network/Client.cc 2009-06-20 13:26:42 UTC (rev 3197)
+++ trunk/src/network/Client.cc 2009-06-20 14:27:38 UTC (rev 3198)
@@ -168,6 +168,7 @@
// note: packet commits suicide here except for the GameState. That is then deleted by a GamestateHandler
bool b = packet->process();
assert(b);
+ delete event;
}
if(gamestate.processGamestates())
{
Modified: trunk/src/network/ClientConnection.cc
===================================================================
--- trunk/src/network/ClientConnection.cc 2009-06-20 13:26:42 UTC (rev 3197)
+++ trunk/src/network/ClientConnection.cc 2009-06-20 14:27:38 UTC (rev 3198)
@@ -168,8 +168,8 @@
// we should never reach this point
// assert(0);
printf("ClientConnection: ENet returned with an error!\n");
- quit_=true;
- break;
+// quit_=true;
+ continue;
// add some error handling here ========================
}
lock.unlock();
@@ -196,12 +196,18 @@
break;
}
}
+ delete event;
// now disconnect
if(!disconnectConnection())
+ {
+ printf("could not disconnect properly\n");
// if disconnecting failed destroy conn.
boost::recursive_mutex::scoped_lock lock(enet_mutex_g);
enet_peer_reset(server);
+ }
+ else
+ printf("properly disconnected\n");
return;
}
@@ -220,6 +226,7 @@
enet_packet_destroy(event.packet);
break;
case ENET_EVENT_TYPE_DISCONNECT:
+ printf("received disconnect confirmation from server");
return true;
}
}
Modified: trunk/src/network/ClientInformation.h
===================================================================
--- trunk/src/network/ClientInformation.h 2009-06-20 13:26:42 UTC (rev 3197)
+++ trunk/src/network/ClientInformation.h 2009-06-20 14:27:38 UTC (rev 3198)
@@ -90,7 +90,6 @@
bool setSynched(bool s);
bool getSynched();
-
private:
static ClientInformation *head_;
Modified: trunk/src/network/ConnectionManager.cc
===================================================================
--- trunk/src/network/ConnectionManager.cc 2009-06-20 13:26:42 UTC (rev 3197)
+++ trunk/src/network/ConnectionManager.cc 2009-06-20 14:27:38 UTC (rev 3198)
@@ -131,6 +131,7 @@
bool ConnectionManager::quitListener() {
quit_=true;
receiverThread_->join();
+ delete receiverThread_;
return true;
}
@@ -205,8 +206,8 @@
if(enet_host_service(server, event, NETWORK_WAIT_TIMEOUT)<0){
// we should never reach this point
printf("ConnectionManager: ENet returned with an error\n");
- quit_=true;
- printf("waaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaahhhhhhhhhhhhhhhh\n");
+// quit_=true;
+// printf("waaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaahhhhhhhhhhhhhhhh\n");
continue;
// add some error handling here ========================
}
@@ -217,13 +218,14 @@
case ENET_EVENT_TYPE_CONNECT:
// printf("====================================================================");
case ENET_EVENT_TYPE_DISCONNECT:
+// printf("====================================================================");
case ENET_EVENT_TYPE_RECEIVE:
- processData(event);
- event = new ENetEvent;
+ processData(event);
+ event = new ENetEvent;
break;
case ENET_EVENT_TYPE_NONE:
//receiverThread_->yield();
- msleep(10);
+ msleep(1);
break;
}
// usleep(100);
Modified: trunk/src/network/ConnectionManager.h
===================================================================
--- trunk/src/network/ConnectionManager.h 2009-06-20 13:26:42 UTC (rev 3197)
+++ trunk/src/network/ConnectionManager.h 2009-06-20 14:27:38 UTC (rev 3198)
@@ -54,7 +54,7 @@
{
const int NETWORK_PORT = 55556;
const int NETWORK_MAX_CONNECTIONS = 50;
- const int NETWORK_WAIT_TIMEOUT = 10;
+ const int NETWORK_WAIT_TIMEOUT = 1;
const int NETWORK_DEFAULT_CHANNEL = 0;
struct _NetworkExport ClientList{
Modified: trunk/src/network/GamestateManager.cc
===================================================================
--- trunk/src/network/GamestateManager.cc 2009-06-20 13:26:42 UTC (rev 3197)
+++ trunk/src/network/GamestateManager.cc 2009-06-20 14:27:38 UTC (rev 3198)
@@ -62,6 +62,10 @@
GamestateManager::~GamestateManager()
{
+ if( this->reference )
+ delete this->reference;
+ for( std::map<unsigned int, packet::Gamestate*>::iterator it = gamestateQueue.begin(); it != gamestateQueue.end(); it++ )
+ delete (*it).second;
delete trafficControl_;
}
@@ -132,7 +136,10 @@
if(client){
// COUT(3) << "diffing" << std::endl;
// packet::Gamestate* gs1 = gs;
- gs = gs->diff(client);
+ packet::Gamestate *diffed = gs->diff(client);
+ //packet::Gamestate *gs2 = diffed->undiff(gs);
+// assert(*gs == *gs2);
+ gs = diffed;
// packet::Gamestate* gs2 = gs->undiff(client);
// gs = new packet::Gamestate(*gs);
// assert(*gs1==*gs2);
Modified: trunk/src/network/Server.cc
===================================================================
--- trunk/src/network/Server.cc 2009-06-20 13:26:42 UTC (rev 3197)
+++ trunk/src/network/Server.cc 2009-06-20 14:27:38 UTC (rev 3198)
@@ -127,6 +127,15 @@
* This function closes the server
*/
void Server::close() {
+ ClientInformation *temp = ClientInformation::getBegin();
+ ClientInformation *temp2;
+ // disconnect all connected clients
+ while( temp )
+ {
+ temp2 = temp;
+ temp = temp->next();
+ disconnectClient( temp2 );
+ }
connection->quitListener();
return;
}
@@ -197,7 +206,7 @@
assert(event->type != ENET_EVENT_TYPE_NONE);
switch( event->type ) {
case ENET_EVENT_TYPE_CONNECT:
- COUT(3) << "processing event_Type_connect" << std::endl;
+ COUT(4) << "processing event_Type_connect" << std::endl;
addClient(event);
break;
case ENET_EVENT_TYPE_DISCONNECT:
@@ -303,6 +312,7 @@
temp=temp->next();
// gs gets automatically deleted by enet callback
}
+ delete del;
return true;
}
@@ -380,16 +390,9 @@
ClientInformation *client = ClientInformation::findClient(&event->peer->address);
if(!client)
return false;
- gamestates_->removeClient(client);
-
-// inform all the listeners
- ObjectList<ClientConnectionListener>::iterator listener = ObjectList<ClientConnectionListener>::begin();
- while(listener){
- listener->clientDisconnected(client->getID());
- listener++;
- }
-
- return ClientInformation::removeClient(event->peer);
+ else
+ disconnectClient( client );
+ return true;
}
void Server::disconnectClient(int clientID){
@@ -397,9 +400,17 @@
if(client)
disconnectClient(client);
}
+
void Server::disconnectClient( ClientInformation *client){
connection->disconnectClient(client);
gamestates_->removeClient(client);
+// inform all the listeners
+ ObjectList<ClientConnectionListener>::iterator listener = ObjectList<ClientConnectionListener>::begin();
+ while(listener){
+ listener->clientDisconnected(client->getID());
+ ++listener;
+ }
+ delete client; //remove client from list
}
bool Server::chat(const std::string& message){
Modified: trunk/src/network/TrafficControl.cc
===================================================================
--- trunk/src/network/TrafficControl.cc 2009-06-20 13:26:42 UTC (rev 3197)
+++ trunk/src/network/TrafficControl.cc 2009-06-20 14:27:38 UTC (rev 3198)
@@ -136,6 +136,8 @@
void TrafficControl::ack(unsigned int clientID, unsigned int gamestateID)
{
+ if ( !this->bActive_ )
+ return;
std::list<obj>::iterator itvec; // iterator to iterate through the acked objects
//assertions to make sure the maps already exist
@@ -188,7 +190,7 @@
*/
void TrafficControl::updateClientListTemp(std::list<obj>& list)
{
- clientListTemp_[currentClientID][currentGamestateID] = std::list<obj>(list);
+ clientListTemp_[currentClientID][currentGamestateID] = list;
}
/**
@@ -226,34 +228,34 @@
void TrafficControl::evaluateList(unsigned int clientID, std::list<obj>& list)
{
- //now the sorting
+ if( bActive_ )
+ {
+ //now the sorting
- //compare listToProcess vs clientListPerm
- //if listToProcess contains new Objects, add them to clientListPerm
- std::list<obj>::iterator itvec;
+ //compare listToProcess vs clientListPerm
+ //if listToProcess contains new Objects, add them to clientListPerm
+ std::list<obj>::iterator itvec;
- std::map<unsigned int, objInfo >& objectListPerm = clientListPerm_[clientID];
+ std::map<unsigned int, objInfo >& objectListPerm = clientListPerm_[clientID];
- for( itvec=list.begin(); itvec != list.end(); itvec++)
- {
- if ( objectListPerm.find( (*itvec).objID) != objectListPerm.end() )
+ for( itvec=list.begin(); itvec != list.end(); itvec++)
{
+ if ( objectListPerm.find( (*itvec).objID) != objectListPerm.end() )
+ {
// we already have the object in our map
//obj bleibt in liste und permanente prio wird berechnet
- objectListPerm[(*itvec).objID].objDiffGS = currentGamestateID - objectListPerm[(*itvec).objID].objCurGS;
- continue;//check next objId
- }
- else
- {
+ objectListPerm[(*itvec).objID].objDiffGS = currentGamestateID - objectListPerm[(*itvec).objID].objCurGS;
+ continue;//check next objId
+ }
+ else
+ {
// insert the object into clientListPerm
- insertinClientListPerm(clientID,*itvec);
- continue;//check next objId
+ insertinClientListPerm(clientID,*itvec);
+ continue;//check next objId
+ }
}
- }
- //end compare listToProcess vs clientListPerm
-
- if( bActive_ )
- {
+ //end compare listToProcess vs clientListPerm
+
//sort copied list according to priorities
// use boost bind here because we need to pass a memberfunction to stl sort
// sort( list.begin(), list.end(), boost::bind(&TrafficControl::prioritySort, this, clientID, _1, _2) );
@@ -274,10 +276,11 @@
//now sort again after objDataOffset
// sort(list.begin(), list.end(), boost::bind(&TrafficControl::dataSort, this, _1, _2) );
list.sort( boost::bind(&TrafficControl::dataSort, this, _1, _2) );
+
+ //diese Funktion updateClientList muss noch gemacht werden
+ updateClientListTemp(list);
+ //end of sorting
}
- //diese Funktion updateClientList muss noch gemacht werden
- updateClientListTemp(list);
- //end of sorting
}
void TrafficControl::printList(std::list<obj>& list, unsigned int clientID)
Modified: trunk/src/network/packet/Acknowledgement.cc
===================================================================
--- trunk/src/network/packet/Acknowledgement.cc 2009-06-20 13:26:42 UTC (rev 3197)
+++ trunk/src/network/packet/Acknowledgement.cc 2009-06-20 14:27:38 UTC (rev 3198)
@@ -63,7 +63,7 @@
}
bool Acknowledgement::process(){
-COUT(6) << "processing ACK with ID: " << getAckID() << endl;
+ COUT(5) << "processing ACK with ID: " << getAckID() << endl;
bool b = GamestateHandler::ackGamestate(getAckID(), clientID_);
delete this;
return b;
Modified: trunk/src/network/packet/Gamestate.cc
===================================================================
--- trunk/src/network/packet/Gamestate.cc 2009-06-20 13:26:42 UTC (rev 3197)
+++ trunk/src/network/packet/Gamestate.cc 2009-06-20 14:27:38 UTC (rev 3198)
@@ -78,6 +78,8 @@
Gamestate::~Gamestate()
{
+ if( header_ )
+ delete header_;
}
bool Gamestate::collectData(int id, uint8_t mode)
@@ -97,6 +99,7 @@
}
// create the header object
+ assert( header_ == 0 );
header_ = new GamestateHeader(data_);
//start collect data synchronisable by synchronisable
@@ -136,6 +139,7 @@
//start write gamestate header
header_->setDataSize( currentsize );
header_->setID( id );
+ header_->setBaseID( GAMESTATEID_INITIAL );
header_->setDiffed( false );
header_->setComplete( true );
header_->setCompressed( false );
@@ -206,7 +210,6 @@
}
}
#endif
-
return true;
}
@@ -319,7 +322,7 @@
return true;
}
-Gamestate *Gamestate::diff(Gamestate *base)
+/*Gamestate *Gamestate::diff(Gamestate *base)
{
assert(data_);
assert(!header_->isCompressed());
@@ -354,8 +357,73 @@
g->flags_=flags_;
g->packetDirection_ = packetDirection_;
return g;
+}*/
+
+Gamestate *Gamestate::diff(Gamestate *base)
+{
+ assert(this && base); assert(data_ && base->data_);
+ assert(!header_->isCompressed() && !base->header_->isCompressed());
+ assert(!header_->isDiffed());
+
+ uint8_t *basep = GAMESTATE_START(base->data_);
+ uint8_t *gs = GAMESTATE_START(this->data_);
+ uint32_t dest_length = header_->getDataSize();
+
+ if(dest_length==0)
+ return NULL;
+
+ uint8_t *ndata = new uint8_t[dest_length*sizeof(uint8_t)+GamestateHeader::getSize()];
+ uint8_t *dest = GAMESTATE_START(ndata);
+
+ rawDiff( dest, gs, basep, header_->getDataSize(), base->header_->getDataSize() );
+#ifndef NDEBUG
+ uint8_t *dest2 = new uint8_t[dest_length];
+ rawDiff( dest2, dest, basep, header_->getDataSize(), base->header_->getDataSize() );
+ assert( memcmp( dest2, gs, dest_length) == 0 );
+#endif
+
+ Gamestate *g = new Gamestate(ndata, getClientID());
+ assert(g->header_);
+ *(g->header_) = *header_;
+ g->header_->setDiffed( true );
+ g->header_->setBaseID( base->getID() );
+ g->flags_=flags_;
+ g->packetDirection_ = packetDirection_;
+ assert(g->isDiffed());
+ assert(!g->isCompressed());
+ return g;
}
+Gamestate *Gamestate::undiff(Gamestate *base)
+{
+ assert(this && base); assert(data_ && base->data_);
+ assert(!header_->isCompressed() && !base->header_->isCompressed());
+ assert(header_->isDiffed());
+
+ uint8_t *basep = GAMESTATE_START(base->data_);
+ uint8_t *gs = GAMESTATE_START(this->data_);
+ uint32_t dest_length = header_->getDataSize();
+
+ if(dest_length==0)
+ return NULL;
+
+ uint8_t *ndata = new uint8_t[dest_length*sizeof(uint8_t)+GamestateHeader::getSize()];
+ uint8_t *dest = ndata + GamestateHeader::getSize();
+
+ rawDiff( dest, gs, basep, header_->getDataSize(), base->header_->getDataSize() );
+
+ Gamestate *g = new Gamestate(ndata, getClientID());
+ assert(g->header_);
+ *(g->header_) = *header_;
+ g->header_->setDiffed( false );
+ g->flags_=flags_;
+ g->packetDirection_ = packetDirection_;
+ assert(!g->isDiffed());
+ assert(!g->isCompressed());
+ return g;
+}
+
+
// Gamestate *Gamestate::diff(Gamestate *base)
// {
// assert(data_);
@@ -408,6 +476,33 @@
// return g;
// }
+
+void Gamestate::rawDiff( uint8_t* newdata, uint8_t* data, uint8_t* basedata, uint32_t datalength, uint32_t baselength)
+{
+ uint64_t* gd = (uint64_t*)data;
+ uint64_t* bd = (uint64_t*)basedata;
+ uint64_t* nd = (uint64_t*)newdata;
+
+ unsigned int i;
+ for( i=0; i<datalength/8; i++ )
+ {
+ if( i<baselength/8 )
+ *(nd+i) = *(gd+i) ^ *(bd+i); // xor the data
+ else
+ *(nd+i) = *(gd+i); // just copy over the data
+ }
+ unsigned int j;
+ // now process the rest (when datalength isn't a multiple of 4)
+ for( j = 8*(datalength/8); j<datalength; j++ )
+ {
+ if( j<baselength )
+ *(newdata+j) = *(data+j) ^ *(basedata+j); // xor
+ else
+ *(newdata+j) = *(data+j); // just copy
+ }
+ assert(j==datalength);
+}
+
Gamestate* Gamestate::doSelection(unsigned int clientID, unsigned int targetSize){
assert(data_);
std::list<obj>::iterator it;
@@ -477,7 +572,7 @@
}
-Gamestate *Gamestate::undiff(Gamestate *base)
+/*Gamestate *Gamestate::undiff(Gamestate *base)
{
assert(this && base);assert(data_);
assert(header_->isDiffed());
@@ -513,9 +608,8 @@
assert(!g->isDiffed());
assert(!g->isCompressed());
return g;
-}
+}*/
-
uint32_t Gamestate::calcGamestateSize(int32_t id, uint8_t mode)
{
uint32_t size=0;
Modified: trunk/src/network/packet/Gamestate.h
===================================================================
--- trunk/src/network/packet/Gamestate.h 2009-06-20 13:26:42 UTC (rev 3197)
+++ trunk/src/network/packet/Gamestate.h 2009-06-20 14:27:38 UTC (rev 3198)
@@ -123,6 +123,7 @@
// Packet functions
private:
+ void rawDiff( uint8_t* newdata, uint8_t* data, uint8_t* basedata, uint32_t datalength, uint32_t baselength);
virtual uint32_t getSize() const;
virtual inline bool process();
Modified: trunk/src/network/synchronisable/Synchronisable.cc
===================================================================
--- trunk/src/network/synchronisable/Synchronisable.cc 2009-06-20 13:26:42 UTC (rev 3197)
+++ trunk/src/network/synchronisable/Synchronisable.cc 2009-06-20 14:27:38 UTC (rev 3198)
@@ -97,10 +97,14 @@
Synchronisable::~Synchronisable(){
// delete callback function objects
if(!Identifier::isCreatingHierarchy()){
+ // remove object from the static objectMap
+ if (this->objectMode_ != 0x0 && (Host::running() && Host::isServer()))
+ deletedObjects_.push(objectID);
+ // delete all Synchronisable Variables from syncList ( which are also in stringList )
for(std::vector<SynchronisableVariableBase*>::iterator it = syncList.begin(); it!=syncList.end(); it++)
delete (*it);
- if (this->objectMode_ != 0x0 && (Host::running() && Host::isServer()))
- deletedObjects_.push(objectID);
+ syncList.clear();
+ stringList.clear();
}
std::map<uint32_t, Synchronisable*>::iterator it;
it = objectMap_.find(objectID);
@@ -173,6 +177,8 @@
no->classID=header.getClassID();
COUT(4) << "fabricate objectID: " << no->objectID << " classID: " << no->classID << std::endl;
// update data and create object/entity...
+ assert( Synchronisable::objectMap_.find(header.getObjectID()) == Synchronisable::objectMap_.end() );
+ Synchronisable::objectMap_[header.getObjectID()] = no;
bool b = no->updateData(mem, mode, true);
assert(b);
if (b)
@@ -212,13 +218,14 @@
if (it1 != objectMap_.end())
return it1->second;
- ObjectList<Synchronisable>::iterator it;
- for(it = ObjectList<Synchronisable>::begin(); it; ++it){
- if( it->getObjectID()==objectID ){
- objectMap_[objectID] = *it;
- return *it;
- }
- }
+// ObjectList<Synchronisable>::iterator it;
+// for(it = ObjectList<Synchronisable>::begin(); it; ++it){
+// if( it->getObjectID()==objectID ){
+// objectMap_[objectID] = *it;
+// return *it;
+// }
+// }
+ // if the objects not in the map it should'nt exist at all anymore
return NULL;
}
Modified: trunk/src/orxonox/gamestates/GSDedicated.cc
===================================================================
--- trunk/src/orxonox/gamestates/GSDedicated.cc 2009-06-20 13:26:42 UTC (rev 3197)
+++ trunk/src/orxonox/gamestates/GSDedicated.cc 2009-06-20 14:27:38 UTC (rev 3198)
@@ -32,19 +32,40 @@
#include "util/Sleep.h"
#include "core/Clock.h"
#include "core/CommandLine.h"
+#include "core/CommandExecutor.h"
#include "core/Game.h"
#include "core/GameMode.h"
#include "network/Server.h"
+#include <iostream>
+#include <iomanip>
+#include <boost/bind.hpp>
+
+#ifndef ORXONOX_PLATFORM_WINDOWS
+#include <termios.h>
+#endif
+
+
namespace orxonox
{
+ const unsigned int MAX_COMMAND_LENGTH = 255;
+
AddGameState(GSDedicated, "dedicated");
+
+ termios* GSDedicated::originalTerminalSettings_;
GSDedicated::GSDedicated(const std::string& name)
: GameState(name)
, server_(0)
, timeSinceLastUpdate_(0)
+ , closeThread_(false)
+ , inputIterator_(0)
+ , cleanLine_(true)
+ , cursorX_(0)
+ , cursorY_(0)
{
+ this->commandLine_ = new unsigned char[MAX_COMMAND_LENGTH];
+// memset( this->commandLine_, 0, MAX_COMMAND_LENGTH );
}
GSDedicated::~GSDedicated()
@@ -54,6 +75,13 @@
void GSDedicated::activate()
{
GameMode::setHasServer(true);
+
+ this->inputThread_ = new boost::thread(boost::bind(&GSDedicated::inputThread, this));
+
+#ifndef ORXONOX_PLATFORM_WINDOWS
+ this->originalTerminalSettings_ = new termios;
+ this->setTerminalMode();
+#endif
this->server_ = new Server(CommandLine::getValue("port"));
COUT(0) << "Loading scene in server mode" << std::endl;
@@ -65,26 +93,210 @@
{
this->server_->close();
delete this->server_;
+
+ closeThread_ = true;
+#ifndef ORXONOX_PLATFORM_WINDOWS
+ std::cout << "\033[0G\033[K";
+ std::cout.flush();
+ resetTerminalMode();
+ delete this->originalTerminalSettings_;
+#endif
+ //inputThread_->join();
GameMode::setHasServer(false);
}
void GSDedicated::update(const Clock& time)
{
-// static float startTime = time.getSecondsPrecise();
-// static int nrOfTicks = 0;
timeSinceLastUpdate_ += time.getDeltaTime();
if (timeSinceLastUpdate_ >= NETWORK_PERIOD)
{
-// ++nrOfTicks;
-// COUT(0) << "estimated ticks/sec: " << nrOfTicks/(time.getSecondsPrecise()-startTime) << endl;
timeSinceLastUpdate_ -= static_cast<unsigned int>(timeSinceLastUpdate_ / NETWORK_PERIOD) * NETWORK_PERIOD;
server_->update(time);
}
else
{
- usleep((int)((NETWORK_PERIOD - timeSinceLastUpdate_) * 1000 * 1000));
+ usleep((unsigned int)((NETWORK_PERIOD - timeSinceLastUpdate_)*1000*1000 ));
+ usleep(NETWORK_PERIOD*1000*1000); // NOTE: this is to throttle the non-network framerate
// COUT(0) << "sleeping for " << (int)((NETWORK_PERIOD - timeSinceLastUpdate_) * 1000 * 1000) << " usec" << endl;
}
+ processQueue();
+ printLine();
}
+
+ void GSDedicated::inputThread()
+ {
+ unsigned char c;
+ unsigned int escapeChar=0;
+ while(!closeThread_)
+ {
+ c = getchar();
+ {
+// boost::recursive_mutex::scoped_lock(this->inputLineMutex_);
+ if ( inputIterator_>=MAX_COMMAND_LENGTH-1 && c!='\n' )
+ continue;
+ if( escapeChar > 0 )
+ {
+ if( c == '[' )
+ {
+ escapeChar = 2;
+ continue;
+ }
+ else if ( escapeChar == 2 )
+ {
+ switch (c)
+ {
+ case 'A': //keyup
+
+ break;
+ case 'B': //keydown
+
+ break;
+ case 'C': //keyright
+ if(cursorX_<inputIterator_)
+ ++cursorX_;
+ break;
+ case 'D': //keyleft
+ if(cursorX_>0)
+ --cursorX_;
+ break;
+ default: //not supported...
+// std::cout << endl << c << endl;
+ break;
+ }
+ escapeChar = 0;
+ }
+ }
+ else // not in escape sequence mode
+ {
+ switch (c)
+ {
+ case '\n':
+ this->cleanLine_ = true;
+ {
+ boost::recursive_mutex::scoped_lock(this->inputQueueMutex_);
+ boost::recursive_mutex::scoped_lock(this->inputLineMutex_);
+ this->commandQueue_.push( std::string((const char*)this->commandLine_,inputIterator_) );
+ }
+ memset( this->commandLine_, 0, inputIterator_ );
+ inputIterator_ = 0;
+ this->cursorX_ = 0;
+ this->cursorY_ = 0;
+ std::cout << endl;
+ break;
+ case 127: // backspace
+ case '\b':
+ deleteCharacter( this->cursorX_ );
+ break;
+ case '\t':
+ {
+// boost::recursive_mutex::scoped_lock(this->inputLineMutex_);
+ std::cout << endl << CommandExecutor::hint( std::string((const char*)this->commandLine_,inputIterator_) ) << endl;
+ strncpy((char*)this->commandLine_, CommandExecutor::complete( std::string((const char*)this->commandLine_,inputIterator_) ).c_str(), MAX_COMMAND_LENGTH);
+ inputIterator_ = strlen((const char*)this->commandLine_);
+ break;
+ }
+ case '\033': // 1. escape character
+ escapeChar = 1;
+ break;
+ default:
+ insertCharacter( this->cursorX_, c );
+ break;
+ }
+ }
+ }
+ }
+ }
+
+ void GSDedicated::printLine()
+ {
+#ifndef ORXONOX_PLATFORM_WINDOWS
+ // set cursor to the begining of the line and erase the line
+ std::cout << "\033[0G\033[K";
+// boost::recursive_mutex::scoped_lock(this->inputLineMutex_);
+ // print status line
+ std::cout << std::fixed << std::setprecision(2) << std::setw(5) << Game::getInstance().getAvgFPS() << " fps, " << std::setprecision(2) << std::setw(5) << Game::getInstance().getAvgTickTime() << " ms avg ticktime # ";
+ //save cursor position
+ std::cout << "\033[s";
+ //print commandLine buffer
+ std::cout << std::string((const char*)this->commandLine_, inputIterator_);
+ //restore cursor position and move it cursorX_ to the right
+ std::cout << "\033[u";
+ if( this->cursorX_ > 0 )
+ std::cout << "\033[" << this->cursorX_ << "C";
+ std::cout.flush();
+#endif
+ }
+
+ void GSDedicated::processQueue()
+ {
+ std::string tempstr;
+ {
+ boost::recursive_mutex::scoped_lock lock1(this->inputQueueMutex_);
+ while(true)
+ {
+ if ( !this->commandQueue_.empty() )
+ {
+ tempstr = this->commandQueue_.front();
+ this->commandQueue_.pop();
+ lock1.unlock();
+ }
+ else
+ break;
+ CommandExecutor::execute(tempstr, true);
+ }
+ }
+ }
+
+ void GSDedicated::setTerminalMode()
+ {
+#ifndef ORXONOX_PLATFORM_WINDOWS
+ termios new_settings;
+
+ tcgetattr(0,this->originalTerminalSettings_);
+ new_settings = *this->originalTerminalSettings_;
+ new_settings.c_lflag &= ~( ICANON | ECHO );
+// new_settings.c_lflag |= ( ISIG | IEXTEN );
+ new_settings.c_cc[VTIME] = 0;
+ new_settings.c_cc[VMIN] = 1;
+ tcsetattr(0,TCSANOW,&new_settings);
+ COUT(0) << endl;
+// atexit(&GSDedicated::resetTerminalMode);
+#endif
+ }
+
+ void GSDedicated::resetTerminalMode()
+ {
+#ifndef ORXONOX_PLATFORM_WINDOWS
+ tcsetattr(0, TCSANOW, GSDedicated::originalTerminalSettings_);
+#endif
+ }
+
+ void GSDedicated::insertCharacter( unsigned int position, char c )
+ {
+// std::cout << endl << (unsigned int)c << endl;
+ // check that we do not exceed MAX_COMMAND_LENGTH
+ if( inputIterator_+1 < MAX_COMMAND_LENGTH )
+ {
+ // if cursor not at end of line then move the rest of the line
+ if( position != this->inputIterator_ )
+ memmove( this->commandLine_+position+1, this->commandLine_+position, this->inputIterator_-position);
+// boost::recursive_mutex::scoped_lock(this->inputLineMutex_);
+ this->commandLine_[position] = c;
+ ++this->cursorX_;
+ ++this->inputIterator_;
+ }
+ }
+ void GSDedicated::deleteCharacter( unsigned int position )
+ {
+// boost::recursive_mutex::scoped_lock(this->inputLineMutex_);
+ if ( this->inputIterator_>0 && position>0 )
+ {
+ if ( position != this->inputIterator_ )
+ memmove( this->commandLine_+position-1, this->commandLine_+position, this->inputIterator_-position);
+ --this->cursorX_;
+ --this->inputIterator_;
+ }
+ }
+
}
Modified: trunk/src/orxonox/gamestates/GSDedicated.h
===================================================================
--- trunk/src/orxonox/gamestates/GSDedicated.h 2009-06-20 13:26:42 UTC (rev 3197)
+++ trunk/src/orxonox/gamestates/GSDedicated.h 2009-06-20 14:27:38 UTC (rev 3198)
@@ -33,9 +33,17 @@
#include "core/GameState.h"
#include "network/NetworkPrereqs.h"
+#include <queue>
+#include <cstring>
+#include <boost/thread/thread.hpp>
+#include <boost/thread/mutex.hpp>
+#include <boost/thread/recursive_mutex.hpp>
+struct termios;
+
namespace orxonox
{
+
class _OrxonoxExport GSDedicated : public GameState
{
public:
@@ -47,8 +55,30 @@
void update(const Clock& time);
private:
- Server* server_;
- float timeSinceLastUpdate_;
+ void inputThread();
+ void printLine();
+ void processQueue();
+ void setTerminalMode();
+ static void resetTerminalMode();
+
+ void insertCharacter( unsigned int position, char c );
+ void deleteCharacter( unsigned int position );
+
+ Server* server_;
+ float timeSinceLastUpdate_;
+
+ boost::thread *inputThread_;
+ boost::recursive_mutex inputLineMutex_;
+ boost::recursive_mutex inputQueueMutex_;
+ bool closeThread_;
+ bool cleanLine_;
+ unsigned char* commandLine_;
+ unsigned int inputIterator_;
+ std::queue<std::string> commandQueue_;
+ static termios* originalTerminalSettings_;
+
+ unsigned int cursorX_;
+ unsigned int cursorY_;
};
}
Modified: trunk/src/util/OutputBuffer.cc
===================================================================
--- trunk/src/util/OutputBuffer.cc 2009-06-20 13:26:42 UTC (rev 3197)
+++ trunk/src/util/OutputBuffer.cc 2009-06-20 14:27:38 UTC (rev 3198)
@@ -35,8 +35,6 @@
namespace orxonox
{
- const int OUTPUTBUFFER_MAX_LINE_LENGTH = 16384; //! The maximal number of lines that can be stored within the OutputBuffer.
-
/**
@brief Adds a new listener to the list.
@param listener The new listener
@@ -104,11 +102,8 @@
*/
bool OutputBuffer::getLine(std::string* output)
{
- char line[OUTPUTBUFFER_MAX_LINE_LENGTH];
+ std::getline(this->stream_, *output);
- this->stream_.getline(line, OUTPUTBUFFER_MAX_LINE_LENGTH);
- (*output) = std::string(line);
-
bool eof = this->stream_.eof();
bool fail = this->stream_.fail();
Modified: trunk/src/util/SignalHandler.cc
===================================================================
--- trunk/src/util/SignalHandler.cc 2009-06-20 13:26:42 UTC (rev 3197)
+++ trunk/src/util/SignalHandler.cc 2009-06-20 14:27:38 UTC (rev 3198)
@@ -106,11 +106,6 @@
*/
void SignalHandler::sigHandler( int sig )
{
- for ( SignalCallbackList::iterator it = SignalHandler::getInstance().callbackList.begin(); it != SignalHandler::getInstance().callbackList.end(); it++ )
- {
- (*(it->cb))( it->someData );
- }
-
std::string sigName = "UNKNOWN";
switch ( sig )
@@ -125,7 +120,19 @@
sigName = "SIGILL";
break;
}
+ // if the signalhandler has already been destroyed then don't do anything
+ if( SignalHandler::singletonRef_s == 0 )
+ {
+ COUT(0) << "recieved signal " << sigName.c_str() << std::endl << "can't write backtrace because SignalHandler already destroyed" << std::endl;
+ exit(EXIT_FAILURE);
+ }
+ for ( SignalCallbackList::iterator it = SignalHandler::getInstance().callbackList.begin(); it != SignalHandler::getInstance().callbackList.end(); it++ )
+ {
+ (*(it->cb))( it->someData );
+ }
+
+
COUT(0) << "recieved signal " << sigName.c_str() << std::endl << "try to write backtrace to file orxonox_crash.log" << std::endl;
int sigPipe[2];
More information about the Orxonox-commit
mailing list