00001 /*************************************************************************** 00002 * The contents of this file are subject to the Mozilla Public * 00003 * License Version 1.1 (the "License"); you may not use this file * 00004 * except in compliance with the License. You may obtain a copy of * 00005 * the License at http://www.mozilla.org/MPL/ * 00006 * * 00007 * Software distributed under the License is distributed on an "AS * 00008 * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or * 00009 * implied. See the License for the specific language governing * 00010 * rights and limitations under the License. * 00011 * * 00012 * The Original Code is Game Network Framework (GaNeF). * 00013 * * 00014 * The Initial Developers of the Original Code are * 00015 * Lars Langer and Emanuel Greisen * 00016 * Copyright (C) 2005. Lars Langer & Emanuel Greisen * 00017 * All Rights Reserved. * 00018 * * 00019 * Contributor(s): * 00020 * none yet.... * 00021 * * 00022 ***************************************************************************/ 00023 #ifndef CLIENTDATA_H 00024 #define CLIENTDATA_H 00025 00026 00027 #include "../common/frameworkdata.h" 00028 #include "clientpacket.h" 00029 #include "clientframework.h" 00030 00031 #include <ptypes.h> 00032 00033 /// @example testclient/testclientsnakebite.h 00034 /** 00035 * @ingroup Client 00036 * @brief This interface must be implemented by data on the client. 00037 * It is very important that the constructor of the subclass calls the constructor of ClientData before reading from the framework packet. This ensures that reading of data is not mixed. 00038 * 00039 * @author Lars Langer and Emanuel Greisen 00040 */ 00041 class ClientData : public FrameworkData 00042 { 00043 protected: 00044 ClientFramework * client_framework; 00045 00046 public: 00047 ClientData(ClientFramework *f, ClientPacket *p); 00048 virtual ~ClientData(); 00049 00050 protected: 00051 void enqueuePacket(ClientPacket * packet) const; 00052 00053 public: 00054 /// This method will be called when ever we receive an update packet from the server. 00055 virtual void updatePacket(ClientFramework * f, unsigned char updatetype, ClientPacket * packet) = 0; 00056 /// This method just returns the framework-pointer. 00057 inline ClientFramework * getFramework() const { return client_framework; }; 00058 00059 }; 00060 00061 template<class T> 00062 T * ClientPacket::readObject( ClientFramework * f ) 00063 { 00064 // this can be a null-thingy !!! 00065 unsigned int id = readUInt32(); 00066 if(id) 00067 { 00068 // Construct a new object 00069 T * obj = new T(f, this); 00070 00071 // Test that T is a subclass of ClientData 00072 // (a clever compiler will optimize this block out) 00073 if(false) ClientData * dummyptr = obj; 00074 00075 return obj; 00076 } 00077 return NULL; 00078 } 00079 00080 template<class T> 00081 void ClientPacket::readPtr( ClientData * receiver, T ** ptrptr, ClientFramework * framework ) 00082 { 00083 unsigned int objid = readUInt32(); 00084 if(framework->unregisterPointer(receiver->getFrameworkId(), objid, (ClientData **)ptrptr)) 00085 { 00086 00087 // Null pointers are represented with 0 as ID (hence we just write null in the pointer and we don't need to register anything) 00088 if(objid == 0) 00089 { 00090 *ptrptr = NULL; 00091 return; 00092 } 00093 00094 // Do a lookup in framework 00095 ClientData * ptr = framework->getDataObject(objid); 00096 //This will also make sure that T is a subclass of ClientData 00097 *ptrptr = static_cast<T *>(ptr); 00098 00099 // Set this as pending in framework 00100 // This C-like cast is safe because of the previous static_cast 00101 framework->registerPointer(receiver->getFrameworkId(), objid, (ClientData **)ptrptr); 00102 } 00103 } 00104 00105 00106 #endif