From: Keith F. <ven...@us...> - 2003-03-02 07:54:43
|
Update of /cvsroot/planeshift/planeshift/src/server In directory sc8-pr-cvs1:/tmp/cvs-serv29517 Modified Files: spawnmanager.h spawnmanager.cpp Log Message: Made SpawnManager do all its spawning in the main CS thread, instead of creating entities from the game event thread. It does this through internal messaging on the net queue. Index: spawnmanager.h =================================================================== RCS file: /cvsroot/planeshift/planeshift/src/server/spawnmanager.h,v retrieving revision 1.8 retrieving revision 1.9 diff -C2 -d -r1.8 -r1.9 *** spawnmanager.h 26 Feb 2003 04:42:04 -0000 1.8 --- spawnmanager.h 2 Mar 2003 07:54:40 -0000 1.9 *************** *** 32,35 **** --- 32,36 ---- #include <csgeom/vector3.h> #include "eventmanager.h" + #include "interface/subscriber.h" *************** *** 109,113 **** * do the initial spawns of all live NPCs when the server is started. */ ! class psSpawnManager { protected: --- 110,114 ---- * do the initial spawns of all live NPCs when the server is started. */ ! class psSpawnManager : public iNetSubscriber { protected: *************** *** 123,126 **** --- 124,129 ---- public: + SCF_DECLARE_IBASE; + psSpawnManager(psDatabase *db, psCelServer *celserv, *************** *** 140,143 **** --- 143,154 ---- */ void RepopulateLive(); + + /** + * This function receives inbound net messages with the proper + * structure and vars to respawn an entity. This happens because + * Respawn is handled in the EVENT thread, and any real spawning + * must happen in the main worker thread where HandleMessage is. + */ + void HandleMessage(MsgEntry *me); /** Index: spawnmanager.cpp =================================================================== RCS file: /cvsroot/planeshift/planeshift/src/server/spawnmanager.cpp,v retrieving revision 1.16 retrieving revision 1.17 diff -C2 -d -r1.16 -r1.17 *** spawnmanager.cpp 26 Feb 2003 04:42:04 -0000 1.16 --- spawnmanager.cpp 2 Mar 2003 07:54:40 -0000 1.17 *************** *** 36,39 **** --- 36,44 ---- + SCF_IMPLEMENT_IBASE( psSpawnManager ) + SCF_IMPLEMENTS_INTERFACE( iNetSubscriber ) + SCF_IMPLEMENT_IBASE_END + + psSpawnManager::psSpawnManager(psDatabase *db, psCelServer *celserv, *************** *** 52,59 **** --- 57,68 ---- QueueNextHiddenCrystalSpawn(); #endif + + msghandler->Subscribe(this,MSGTYPESPAWN); } psSpawnManager::~psSpawnManager() { + msghandler->Unsubscribe(this,MSGTYPESPAWN); + #ifdef PS_EGGHUNT delete randomgen; *************** *** 219,257 **** #define SPAWN_BASE_ITEM 1000 ! int psSpawnManager::Respawn(csVector3& where,float rot,csString& sector,int playerID) { // Egghunt logic first ! if (playerID < 0) { ! int itemID = -playerID; if (itemID > SPAWN_POINT_TAKEN) // SPAWN_POINT_TAKEN is special case to skip but still queue next { int itemObjectID = database->CreateItemObject(itemID, ! where.x, where.y, where.z, rot, ! sector); celserver->CreateItem(itemID,itemObjectID); } QueueNextHiddenCrystalSpawn(); ! return 0; } // Update the location before spawning, because cel server gets it from there ! int objectID = database->GetPlayerObjectID(playerID); if (!objectID) { ! printf("Player %d to be respawned does not have a corresponding object!\n", playerID); ! return 0; } int dummy; ! database->UpdateAliveInd(playerID,"Y",dummy); ! database->SetObjectPosition(objectID,where.x,where.y,where.z,rot,sector); ! // database->SetObjectSector(objectID,sector); // Now create the NPC as usual ! celserver->CreateNPC(playerID); return 0; } --- 228,281 ---- #define SPAWN_BASE_ITEM 1000 ! void psSpawnManager::HandleMessage(MsgEntry *me) { + psSpawnMessage spawn(me); + // Egghunt logic first ! if (spawn.playerID < 0) { ! int itemID = -spawn.playerID; if (itemID > SPAWN_POINT_TAKEN) // SPAWN_POINT_TAKEN is special case to skip but still queue next { int itemObjectID = database->CreateItemObject(itemID, ! spawn.where.x, spawn.where.y, spawn.where.z, spawn.rot, ! spawn.sector); celserver->CreateItem(itemID,itemObjectID); } QueueNextHiddenCrystalSpawn(); ! return; } // Update the location before spawning, because cel server gets it from there ! int objectID = database->GetPlayerObjectID(spawn.playerID); if (!objectID) { ! printf("Player %d to be respawned does not have a corresponding object!\n", spawn.playerID); ! return; } int dummy; ! database->UpdateAliveInd(spawn.playerID,"Y",dummy); ! database->SetObjectPosition(objectID,spawn.where.x,spawn.where.y,spawn.where.z,spawn.rot,spawn.sector); // Now create the NPC as usual ! celserver->CreateNPC(spawn.playerID); ! } + int psSpawnManager::Respawn(csVector3& where,float rot,csString& sector,int playerID) + { + psSpawnMessage spawn(where,rot,sector,playerID); + + printf("Respawn triggered by Event Manager here for playerID %d\n",playerID); + + /** + * In this function we are in the Event Manager thread, not the work thread. + * Queuing an inbound net message enables the work thread to pick up the message + * and handle it in the HandleMessage member function of this class. The message + * is a way of cross-thread function calling and marshalling all the vars. + */ + msghandler->AddToLocalQueue(spawn.msg); return 0; } |