|
@@ -4,6 +4,7 @@
|
|
|
#include "OverworldDimension.h"
|
|
|
#include "AddChunkUpdate.h"
|
|
|
#include "NoBlock.h"
|
|
|
+#include "AsynchronCall.h"
|
|
|
|
|
|
using namespace Framework;
|
|
|
|
|
@@ -13,11 +14,40 @@ GameClient::GameClient( Player* zPlayer, FCKlient* client )
|
|
|
client( client ),
|
|
|
viewDistance( DEFAULT_VIEW_DISTANCE ),
|
|
|
first( 1 ),
|
|
|
- online( 1 )
|
|
|
-{}
|
|
|
+ online( 1 ),
|
|
|
+ finished( 0 )
|
|
|
+{
|
|
|
+ new AsynchronCall( [this]() {
|
|
|
+ while( online )
|
|
|
+ {
|
|
|
+ other.lock();
|
|
|
+ if( updateQueue.hat( 0 ) )
|
|
|
+ {
|
|
|
+ WorldUpdate* update = updateQueue.get( 0 );
|
|
|
+ updateQueue.remove( 0 );
|
|
|
+ other.unlock();
|
|
|
+ background.lock();
|
|
|
+ this->client->zBackgroundWriter()->schreibe( (char*)&Message::WORLD_UPDATE, 1 );
|
|
|
+ update->write( this->client->zBackgroundWriter() );
|
|
|
+ background.unlock();
|
|
|
+ update->release();
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ other.unlock();
|
|
|
+ updateSync.wait();
|
|
|
+ }
|
|
|
+ }
|
|
|
+ finished = 1;
|
|
|
+ } );
|
|
|
+}
|
|
|
|
|
|
GameClient::~GameClient()
|
|
|
{
|
|
|
+ online = 0;
|
|
|
+ updateSync.notify();
|
|
|
+ while( !finished )
|
|
|
+ Sleep( 100 );
|
|
|
client->release();
|
|
|
}
|
|
|
|
|
@@ -30,17 +60,18 @@ void GameClient::sendWorldUpdate( WorldUpdate* update )
|
|
|
int dist = update->distanceTo( pos.x, pos.y );
|
|
|
if( dist < viewDistance * CHUNK_SIZE )
|
|
|
{
|
|
|
- other.Enter();
|
|
|
+ other.lock();
|
|
|
int index = 0;
|
|
|
for( auto update2 : updateQueue )
|
|
|
{
|
|
|
- int dist2 = update2->distanceTo( pos.x, pos.y );
|
|
|
+ int dist2 = update2->distanceTo( pohen world is s.x, pos.y );
|
|
|
if( dist2 >= dist )
|
|
|
break;
|
|
|
index++;
|
|
|
}
|
|
|
updateQueue.add( update, index );
|
|
|
- other.Leave();
|
|
|
+ other.unlock();
|
|
|
+ updateSync.notify();
|
|
|
add = 1;
|
|
|
}
|
|
|
}
|
|
@@ -50,15 +81,15 @@ void GameClient::sendWorldUpdate( WorldUpdate* update )
|
|
|
|
|
|
void GameClient::reply( Game* zGame )
|
|
|
{
|
|
|
- other.Enter();
|
|
|
+ other.lock();
|
|
|
for( auto req : requests )
|
|
|
zGame->api( req, this );
|
|
|
requests.leeren();
|
|
|
- other.Leave();
|
|
|
+ other.unlock();
|
|
|
int x = (int)zPlayer->getPosition().x;
|
|
|
int y = (int)zPlayer->getPosition().y;
|
|
|
int d = zPlayer->getCurrentDimensionId();
|
|
|
- foreground.Enter();
|
|
|
+ foreground.lock();
|
|
|
client->zForegroundWriter()->schreibe( (char*)&Message::POSITION_UPDATE, 1 );
|
|
|
float f = zPlayer->getPosition().x;
|
|
|
client->zForegroundWriter()->schreibe( (char*)&f, 4 );
|
|
@@ -70,17 +101,7 @@ void GameClient::reply( Game* zGame )
|
|
|
client->zForegroundWriter()->schreibe( (char*)&f, 4 );
|
|
|
f = zPlayer->getFaceDir().y;
|
|
|
client->zForegroundWriter()->schreibe( (char*)&f, 4 );
|
|
|
- foreground.Leave();
|
|
|
- other.Enter();
|
|
|
- if( updateQueue.hat( 0 ) )
|
|
|
- {
|
|
|
- background.Enter();
|
|
|
- client->zBackgroundWriter()->schreibe( (char*)&Message::WORLD_UPDATE, 1 );
|
|
|
- updateQueue.z( 0 )->write( client->zBackgroundWriter() );
|
|
|
- updateQueue.remove( 0 );
|
|
|
- background.Leave();
|
|
|
- }
|
|
|
- other.Leave();
|
|
|
+ foreground.unlock();
|
|
|
// send world to client
|
|
|
if( first )
|
|
|
{
|
|
@@ -134,9 +155,9 @@ void GameClient::addMessage( StreamReader* reader )
|
|
|
reader->lese( tmp, len );
|
|
|
buffer->schreibe( tmp, len );
|
|
|
delete[]tmp;
|
|
|
- other.Enter();
|
|
|
+ other.lock();
|
|
|
requests.add( buffer );
|
|
|
- other.Leave();
|
|
|
+ other.unlock();
|
|
|
}
|
|
|
|
|
|
bool GameClient::isOnline() const
|
|
@@ -150,17 +171,17 @@ void GameClient::sendResponse( NetworkResponse* zResponse )
|
|
|
{
|
|
|
if( zResponse->isUseBackground() )
|
|
|
{
|
|
|
- background.Leave();
|
|
|
+ background.unlock();
|
|
|
client->zBackgroundWriter()->schreibe( (char*)&Message::API_MESSAGE, 1 );
|
|
|
zResponse->writeTo( client->zBackgroundWriter() );
|
|
|
- background.Leave();
|
|
|
+ background.unlock();
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
- foreground.Leave();
|
|
|
+ foreground.unlock();
|
|
|
client->zForegroundWriter()->schreibe( (char*)&Message::API_MESSAGE, 1 );
|
|
|
zResponse->writeTo( client->zForegroundWriter() );
|
|
|
- foreground.Leave();
|
|
|
+ foreground.unlock();
|
|
|
}
|
|
|
}
|
|
|
}
|
|
@@ -221,7 +242,7 @@ void Game::thread()
|
|
|
m.messungStart();
|
|
|
ticker->nextTick();
|
|
|
Array<int> removed;
|
|
|
- cs.Enter();
|
|
|
+ cs.lock();
|
|
|
int index = 0;
|
|
|
for( auto player : *clients )
|
|
|
{
|
|
@@ -237,10 +258,10 @@ void Game::thread()
|
|
|
}
|
|
|
for( auto i : removed )
|
|
|
clients->remove( i );
|
|
|
- cs.Leave();
|
|
|
+ cs.unlock();
|
|
|
for( auto dim : *dimensions )
|
|
|
dim->tickEntities( this );
|
|
|
- cs.Enter();
|
|
|
+ cs.lock();
|
|
|
while( updates->hat( 0 ) )
|
|
|
{
|
|
|
WorldUpdate* update = updates->z( 0 );
|
|
@@ -251,7 +272,7 @@ void Game::thread()
|
|
|
update->onUpdate( zDimension( update->getAffectedDimension() ) );
|
|
|
updates->remove( 0 );
|
|
|
}
|
|
|
- cs.Leave();
|
|
|
+ cs.unlock();
|
|
|
for( auto client : *clients )
|
|
|
client->reply( this );
|
|
|
m.messungEnde();
|
|
@@ -305,14 +326,14 @@ void Game::distributeResponse( NetworkResponse* zResponse )
|
|
|
|
|
|
void Game::requestWorldUpdate( WorldUpdate* update )
|
|
|
{
|
|
|
- cs.Enter();
|
|
|
+ cs.lock();
|
|
|
updates->add( update );
|
|
|
- cs.Leave();
|
|
|
+ cs.unlock();
|
|
|
}
|
|
|
|
|
|
GameClient* Game::addPlayer( FCKlient* client, Framework::Text name )
|
|
|
{
|
|
|
- cs.Enter();
|
|
|
+ cs.lock();
|
|
|
Datei pFile;
|
|
|
pFile.setDatei( path + "/player/" + name );
|
|
|
Player* player;
|
|
@@ -331,9 +352,9 @@ GameClient* Game::addPlayer( FCKlient* client, Framework::Text name )
|
|
|
requestArea( { (int)player->getPosition().x - DEFAULT_VIEW_DISTANCE * CHUNK_SIZE, (int)player->getPosition().y - DEFAULT_VIEW_DISTANCE * CHUNK_SIZE, (int)player->getPosition().x + DEFAULT_VIEW_DISTANCE * CHUNK_SIZE, (int)player->getPosition().y + DEFAULT_VIEW_DISTANCE * CHUNK_SIZE, player->getCurrentDimensionId() } );
|
|
|
while( !zDimension( OverworldDimension::ID ) || (isNew && !zDimension( OverworldDimension::ID )->zChunk( getChunkCenter( (int)player->getPosition().x, (int)player->getPosition().y ) )) )
|
|
|
{
|
|
|
- cs.Leave();
|
|
|
+ cs.unlock();
|
|
|
Sleep( 1000 );
|
|
|
- cs.Enter();
|
|
|
+ cs.lock();
|
|
|
}
|
|
|
if( isNew )
|
|
|
{
|
|
@@ -346,7 +367,7 @@ GameClient* Game::addPlayer( FCKlient* client, Framework::Text name )
|
|
|
zDimension( OverworldDimension::ID )->addEntity( player );
|
|
|
GameClient* gameClient = new GameClient( player, client );
|
|
|
clients->add( gameClient );
|
|
|
- cs.Leave();
|
|
|
+ cs.unlock();
|
|
|
return dynamic_cast<GameClient*>(gameClient->getThis());
|
|
|
}
|
|
|
|
|
@@ -358,17 +379,17 @@ bool Game::isChunkLoaded( int x, int y, int dimension ) const
|
|
|
|
|
|
bool Game::doesChunkExist( int x, int y, int dimension )
|
|
|
{
|
|
|
- cs.Enter();
|
|
|
+ cs.lock();
|
|
|
bool result = isChunkLoaded( x, y, dimension ) || loader->existsChunk( x, y, dimension );
|
|
|
if( !result )
|
|
|
{
|
|
|
for( WorldUpdate* update : *updates )
|
|
|
{
|
|
|
if( update->getType() == AddChunkUpdateType::ID )
|
|
|
- result |= ((AddChunkUpdate*)update)->zChunk()->getCenter() == Framework::Punkt( x, y );
|
|
|
+ result |= ((AddChunkUpdate*)update)->zChunk()->getClock() == Framework::Punkt( x, y );
|
|
|
}
|
|
|
}
|
|
|
- cs.Leave();
|
|
|
+ cs.unlock();
|
|
|
return result;
|
|
|
}
|
|
|
|
|
@@ -435,9 +456,9 @@ void Game::addDimension( Dimension* d )
|
|
|
|
|
|
int Game::getNextEntityId()
|
|
|
{
|
|
|
- cs.Enter();
|
|
|
+ cs.lock();
|
|
|
int result = nextEntityId++;
|
|
|
- cs.Leave();
|
|
|
+ cs.unlock();
|
|
|
return result;
|
|
|
}
|
|
|
|