Main Page | Modules | Class Hierarchy | Alphabetical List | Class List | Directories | File List | Class Members | Related Pages | Examples

7. Destruction of objects

This test will set up a ServerData object on the server, replicate it to the client and then destroy it on the server. This should result in a call to ServerData::sendDestroyToAll() and the client should destroy the object as well.

Client Application

There is not much to notice in this client-application. All it does it print out when ever an object is constructed and when ever it is destructed. Every pass in the mainLoop it prints out how many objects are registered in the framework, to make sure that they are also unregistered upon destruction.

/// @cond EXCLUDEDTESTSOURCES
/***************************************************************************
 * The contents of this file are subject to the Mozilla Public             *
 * License Version 1.1 (the "License"); you may not use this file          *
 * except in compliance with the License. You may obtain a copy of         *
 * the License at http://www.mozilla.org/MPL/                              *
 *                                                                         *
 * Software distributed under the License is distributed on an "AS         *
 * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or              *
 * implied. See the License for the specific language governing            *
 * rights and limitations under the License.                               *
 *                                                                         *
 * The Original Code is Game Network Framework (GaNeF).                    *
 *                                                                         *
 * The Initial Developers of the Original Code are                         *
 * Lars Langer and Emanuel Greisen                                         *
 * Copyright (C) 2005. Lars Langer & Emanuel Greisen                       *
 * All Rights Reserved.                                                    *
 *                                                                         *
 * Contributor(s):                                                         *
 *   none yet....                                                          *
 *                                                                         *
 ***************************************************************************/

#include <iostream>
#include <cstdlib>

#include "../Ganef/client/clientframework.h"
#include "../Ganef/client/clientdata.h"


class MyClientData : public ClientData
{
   public:
      MyClientData(ClientFramework * f, ClientPacket * p) : ClientData(f,p)
      {
         std::cout << "Construct: object " << getFrameworkId() << std::endl;
      }
      ~MyClientData()
      {
         std::cout << "Destruct:  object " << getFrameworkId() << std::endl;
      }
      virtual void updatePacket(ClientFramework * f, unsigned char updatetype, ClientPacket * p)
      {
         // We receive no updates in this test
      }
      static ClientData * constructMyClientData(ClientFramework * f, ClientPacket * p)
      {
         return new MyClientData(f,p);
      }
};


/**
 * This is just a test-client-framework.
 * @author Lars Langer and Emanuel Greisen
 */
class TestClientFramework : public ClientFramework
{
   private:
      bool is_running;
      std::string server_hostname;

   public:
      TestClientFramework(const std::string & server_hostname) : ClientFramework(int(0)),server_hostname(server_hostname)
      {
         registerConstructor(0x424242, MyClientData::constructMyClientData);
      }
      ~TestClientFramework()
      {
      };

   protected: // These must be implemented in a derived class
      virtual void writeHandshakeInitMessage( ClientPacket * fp ){}
      virtual void onHandshakingDiscontinue( ClientPacket * fp ){}
      virtual bool onHandshakeDescription( ClientPacket * fp, ClientPacket * reply )
      {
         return true;
      }
      virtual void onDisconnect( ) { std::cout << "Disconnected\n"; }
      virtual void onConnect( ){ std::cout << "Connected\n"; }

   public:
      void mainLoop( )
      {
         std::cout << "Connecting to: " << server_hostname <<":"<< 8000<< std::endl;
         initServerConnection(server_hostname, 8000);
         is_running = true;
         while(is_running)
         {
            // Get/handle Packets from the framework
            keepAlive();

            // Just print out how many objects we have registrered.
            std::cout << "We have " << getClientDataObjects().size() << " objects on the client" << std::endl;

            // Then we sleep to let the CPU live
            psleep(50);
         }
      }
};




int main(int argc, char *argv[])
{
   std::string server_host("localhost");
   if(argc > 1)
      server_host = argv[1];
   TestClientFramework app(server_host);

   // Start the Application
   app.mainLoop();
}

/// @endcond

Server Application

The server just creates new objects every 5th pass in the mainLoop, and destroys them all again every 27th pass. Before it destroys them, it calls the method:
virtual void sendDestroyObjectToAll();
To make sure all connected clients receive word of the object no longer being on the server. You should note however that you can instruct a client to destroy an object even though this object remains on the server, this could be the case if the object for some reason is no longer visible to a specific client.

/// @cond EXCLUDEDTESTSOURCES
/***************************************************************************
 * The contents of this file are subject to the Mozilla Public             *
 * License Version 1.1 (the "License"); you may not use this file          *
 * except in compliance with the License. You may obtain a copy of         *
 * the License at http://www.mozilla.org/MPL/                              *
 *                                                                         *
 * Software distributed under the License is distributed on an "AS         *
 * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or              *
 * implied. See the License for the specific language governing            *
 * rights and limitations under the License.                               *
 *                                                                         *
 * The Original Code is Game Network Framework (GaNeF).                    *
 *                                                                         *
 * The Initial Developers of the Original Code are                         *
 * Lars Langer and Emanuel Greisen                                         *
 * Copyright (C) 2005. Lars Langer & Emanuel Greisen                       *
 * All Rights Reserved.                                                    *
 *                                                                         *
 * Contributor(s):                                                         *
 *   none yet....                                                          *
 *                                                                         *
 ***************************************************************************/

#include <iostream>
#include <cstdlib>
#include <vector>


#include "../Ganef/server/serverframework.h"


class MyServerData : public ServerData
{
   private:
      std::string name;
   public:
      // The two last parameters for ServerData is the priority of its updatepackets
      //  and wether they should be sent reliable.
      MyServerData(ServerFramework * fw, const std::string & name) : ServerData(fw, 10, false),name(name)
      {
      };
   public:
      virtual const unsigned int getClassId() const { return 0x424242; };
      virtual void fillUpdatePacket(ServerPacket * packet, unsigned char type) const
      {
         // We send no updates
      }
      virtual void fillCreateObjectPacket(ServerPacket * packet) const
      {
         // We contain no data
      }
      /// Called when ever we receive a packet for this object from a client.
      virtual void clientPacket(Client * client, unsigned char type, ServerPacket * p)
      {
         // We receive no actions from the clients in this test.
      }
};

/**
 * This is just a test server-framework;
 * @author Lars Langer and Emanuel Greisen
 */
class TestServerFramework : public ServerFramework
{
   public:
      TestServerFramework() : ServerFramework(8000)
      {
      }

      ~TestServerFramework()
      {
      }

   protected: // These method should be implemented on the GameServer
      virtual bool onInitialHandshake(ServerPacket * handshake, ServerPacket * reply)
      {
         return true; // Accept all clients.
      }
      virtual void onClientConnected(Client * client)
      {
         std::cout << "Client: " << client->getId() << " connected\n";
      }
      virtual void onClientDisconnected(Client * client)
      {
         std::cout << "Client: " << client->getId() << " disconnected\n";
      }
      virtual Client * createClient(const ipaddress &addr, int port)
      {
         Client * client = new Client(this, addr, port);
         // Here we send the construction packages for all ServerData
         //   already in the framework
         std::map<unsigned int, ServerData *>::const_iterator it;
         for(it = getServerDataObjects().begin(); it != getServerDataObjects().end(); ++it)
         {
            ServerData * s_data = it->second;
            s_data->sendCreateObject(client);
         }

         return client;
      }

   public:
      void mainLoop()
      {
         std::cout << "TestServerFramework: Running\n";
         int counter = 0;
         std::vector<MyServerData *> data;
         data.clear();
         while(true)
         {
            // Get all incomming messages
            keepAlive();

            // Construct a new one every 5th tick.
            if(counter % 5 == 0)
            {
               MyServerData * d = new MyServerData(this, "SomeData");
               data.push_back(d);
               d->sendCreateObjectToAll();
            }
            counter++;

            // Destruct them all every 27th tick.
            if(counter % 27 == 0)
            {
               std::cout << "Destroy all objects" << std::endl;
               for(std::vector<MyServerData *>::iterator it = data.begin(); it != data.end(); ++it)
               {
                  (*it)->sendDestroyToAll();
                  delete *it;
               }
               data.clear();
            }

            // Sleep a little
            psleep(100);
         }
      }
};




int main(int argc, char *argv[])
{
   try
   {
      // Create a framework
      TestServerFramework framework;

      // Start the framework
      framework.start();

      // GameLoop
      framework.mainLoop();
   }
   catch(FrameworkError *err)
   {
      std::cout << "FrameworkError:" << err->msg << std::endl;
   }
   catch(PacketError *err)
   {
      std::cout << "PacketError:" << err->msg << std::endl;
   }

   return EXIT_SUCCESS;
}

/// @endcond

Generated on Mon Feb 6 12:24:58 2006 for Ganef by  doxygen 1.4.4