[Opentnl-cvs] tnl/tnl tnlString.h,NONE,1.1 bitStream.cpp,1.6,1.7 connectionStringTable.cpp,1.2,1.3 e
Brought to you by:
mark_frohnmayer,
s_alanet
Update of /cvsroot/opentnl/tnl/tnl In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv24496/tnl Modified Files: bitStream.cpp connectionStringTable.cpp eventConnection.cpp ghostConnection.cpp journal.cpp netConnection.cpp netObject.cpp rpc.cpp thread.cpp tnlBitStream.h tnlConnectionStringTable.h tnlEventConnection.h tnlJournal.h tnlMethodDispatch.cpp tnlMethodDispatch.h tnlNetConnection.h tnlNetObject.h tnlRPC.h tnlThread.h Added Files: tnlString.h Removed Files: tnl.dsp Log Message: Added template-based RPC marshalling Updated master, masterclient and test projects to use new RPC format Removed VC6 projects due to template incompatibility Index: tnlJournal.h =================================================================== RCS file: /cvsroot/opentnl/tnl/tnl/tnlJournal.h,v retrieving revision 1.9 retrieving revision 1.10 diff -C2 -d -r1.9 -r1.10 *** tnlJournal.h 28 Sep 2004 18:45:25 -0000 1.9 --- tnlJournal.h 21 Feb 2005 07:48:14 -0000 1.10 *************** *** 68,72 **** void load(const char *fileName); ! void callEntry(const char *funcName, MarshalledCall *theCall); void processNextJournalEntry(); --- 68,72 ---- void load(const char *fileName); ! void callEntry(const char *funcName, Functor *theCall); void processNextJournalEntry(); *************** *** 85,122 **** U32 mEntryIndex; const char *mFunctionName; - MethodArgList *mMethodArgList; JournalEntryRecord *mNext; static Vector<JournalEntryRecord *> *mEntryVector; ! JournalEntryRecord(const char *functionName, MethodArgList *methodArgList); virtual ~JournalEntryRecord(); - - virtual void getFuncPtr(MethodPointer &m) = 0; }; #ifdef TNL_ENABLE_JOURNALING #define TNL_DECLARE_JOURNAL_ENTRYPOINT(func, args) \ ! virtual void FN_CDECL func args; \ ! virtual void FN_CDECL func##_body args ! #define TNL_IMPLEMENT_JOURNAL_ENTRYPOINT(className, func, args) \ ! TNL::MethodArgList Journal_##className##_##func(#className, #args); \ struct Journal_##className##_##func##_er : public JournalEntryRecord { \ ! void getFuncPtr(MethodPointer &m) { \ ! void (FN_CDECL className::*fptr) args; \ ! fptr = &className::func##_body; \ ! m.v1 = *((U32 *) &fptr); \ ! if(sizeof(fptr) > sizeof(U32)) m.v2 = *(((U32 *) &fptr) + 1); \ ! if(sizeof(fptr) > 2*sizeof(U32)) m.v3 = *(((U32 *) &fptr) + 2); \ ! }; \ ! Journal_##className##_##func##_er(const char *name, MethodArgList *methodArgList) : JournalEntryRecord(name, methodArgList) {} \ ! } gJournal_##className##_##func##_er(#func, &Journal_##className##_##func); \ ! void FN_CDECL className::func args { \ ! SAVE_PARAMS \ ! MarshalledCall call(&Journal_##className##_##func); \ ! call.marshall(); \ ! callEntry(#func, &call); \ } \ ! void FN_CDECL className::func##_body args class JournalToken --- 85,112 ---- U32 mEntryIndex; const char *mFunctionName; JournalEntryRecord *mNext; + Functor *mFunctor; + static Vector<JournalEntryRecord *> *mEntryVector; ! JournalEntryRecord(const char *functionName); virtual ~JournalEntryRecord(); }; #ifdef TNL_ENABLE_JOURNALING #define TNL_DECLARE_JOURNAL_ENTRYPOINT(func, args) \ ! void func args; \ ! void func##_body args ! #define TNL_IMPLEMENT_JOURNAL_ENTRYPOINT(className, func, args, argNames) \ struct Journal_##className##_##func##_er : public JournalEntryRecord { \ ! FunctorDecl<void (className::*) args> mFunctorDecl; \ ! Journal_##className##_##func##_er(const char *name) : JournalEntryRecord(name), mFunctorDecl(className::func##_body) { mFunctor = &mFunctorDecl; } \ ! } gJournal_##className##_##func##_er(#func); \ ! void className::func args { \ ! gJournal_##className##_##func##_er.mFunctorDecl.set argNames; \ ! callEntry(#func, gJournal_##className##_##func##_er.mFunctor); \ } \ ! void className::func##_body args class JournalToken Index: tnlNetConnection.h =================================================================== RCS file: /cvsroot/opentnl/tnl/tnl/tnlNetConnection.h,v retrieving revision 1.9 retrieving revision 1.10 diff -C2 -d -r1.9 -r1.10 *** tnlNetConnection.h 14 Feb 2005 06:15:28 -0000 1.9 --- tnlNetConnection.h 21 Feb 2005 07:48:14 -0000 1.10 *************** *** 44,47 **** --- 44,51 ---- #endif + #ifndef _TNL_CONNECTIONSTRINGTABLE_H_ + #include "tnlConnectionStringTable.h" + #endif + namespace TNL { *************** *** 131,137 **** --- 135,147 ---- /// to read and write packet data, as well as handle packet delivery notification. /// + /// Because string data can easily soak up network bandwidth, for + /// efficiency NetConnection implements an optional networked string table. + /// Users can then notify the connection of strings it references often, such as player names, + /// and transmit only a tag, instead of the whole string. + /// class NetConnection : public Object { friend class NetInterface; + friend class ConnectionStringTable; typedef Object Parent; *************** *** 249,256 **** virtual void readPacket(BitStream *bstream); ///< Called to read a subclass's packet data from the packet. ! virtual void prepareWritePacket(); ///< Called to prepare the connection for packet writing. ! /// ! /// Any setup work to determine if there isDataToTransmit() should happen in ! /// this function. prepareWritePacket should _always_ call the Parent:: function. virtual void writePacket(BitStream *bstream, PacketNotify *note); ///< Called to write a subclass's packet data into the packet. --- 259,266 ---- virtual void readPacket(BitStream *bstream); ///< Called to read a subclass's packet data from the packet. ! virtual void prepareWritePacket(); ///< Called to prepare the connection for packet writing. ! /// ! /// Any setup work to determine if there isDataToTransmit() should happen in ! /// this function. prepareWritePacket should _always_ call the Parent:: function. virtual void writePacket(BitStream *bstream, PacketNotify *note); ///< Called to write a subclass's packet data into the packet. *************** *** 343,346 **** --- 353,357 ---- bool rateChanged; ///< True if this packet requested a change of rate. U32 sendTime; ///< Platform::getRealMilliseconds() when packet was sent. + ConnectionStringTable::PacketList stringList; ///< List of string table entries sent in this packet PacketNotify *nextPacket; ///< Pointer to the next packet sent on this connection *************** *** 575,578 **** --- 586,594 ---- /// @} + private: + ConnectionStringTable *mStringTable; ///< Helper for managing translation between global NetStringTable ids to local ids for this connection. + public: + /// Enables string tag translation on this connection. + void setTranslatesStrings(); }; Index: thread.cpp =================================================================== RCS file: /cvsroot/opentnl/tnl/tnl/thread.cpp,v retrieving revision 1.1 retrieving revision 1.2 diff -C2 -d -r1.1 -r1.2 *** thread.cpp 14 Feb 2005 06:15:28 -0000 1.1 --- thread.cpp 21 Feb 2005 07:48:14 -0000 1.2 *************** *** 190,194 **** void *ThreadStorage::get() { ! pthread_getspecific(mThreadKey); } --- 190,194 ---- void *ThreadStorage::get() { ! return pthread_getspecific(mThreadKey); } *************** *** 262,275 **** return; } ! ThreadQueueCall c = mThreadCalls.first(); mThreadCalls.pop_front(); unlock(); ! BitStream unmarshallData(c.c->marshalledData.getBuffer(), c.c->marshalledData.getBytePosition()); ! c.c->unmarshall(&unmarshallData); ! c.c->dispatch(this, &c.p); ! delete c.c; } ! void ThreadQueue::postCall(ThreadQueueCall &theCall) { lock(); --- 262,273 ---- return; } ! Functor *c = mThreadCalls.first(); mThreadCalls.pop_front(); unlock(); ! c->dispatch(this); ! delete c; } ! void ThreadQueue::postCall(Functor *theCall) { lock(); *************** *** 292,300 **** for(S32 i = 0; i < mResponseCalls.size(); i++) { ! ThreadQueueCall c = mResponseCalls[i]; ! BitStream unmarshallData(c.c->marshalledData.getBuffer(), c.c->marshalledData.getBytePosition()); ! c.c->unmarshall(&unmarshallData); ! c.c->dispatch(this, &c.p); ! delete c.c; } mResponseCalls.clear(); --- 290,296 ---- for(S32 i = 0; i < mResponseCalls.size(); i++) { ! Functor *c = mResponseCalls[i]; ! c->dispatch(this); ! delete c; } mResponseCalls.clear(); Index: tnlRPC.h =================================================================== RCS file: /cvsroot/opentnl/tnl/tnl/tnlRPC.h,v retrieving revision 1.11 retrieving revision 1.12 diff -C2 -d -r1.11 -r1.12 *** tnlRPC.h 28 Sep 2004 18:59:23 -0000 1.11 --- tnlRPC.h 21 Feb 2005 07:48:14 -0000 1.12 *************** *** 138,141 **** --- 138,159 ---- }; + /// Macro used to declare the implementation of an RPC method on an EventConnection subclass. + /// + /// The macro should be used in place of a member function parameter declaration, + /// with the body code (to be executed on the remote side of the RPC) immediately + /// following the TNL_IMPLEMENT_RPC macro call. + #define TNL_IMPLEMENT_RPC(className, name, args, argNames, groupMask, guaranteeType, eventDirection, rpcVersion) \ + class RPC_##className##_##name : public TNL::RPCEvent { \ + public: \ + TNL::FunctorDecl<void (className::*) args > mFunctorDecl;\ + RPC_##className##_##name() : mFunctorDecl(className::name##_remote), TNL::RPCEvent(guaranteeType, eventDirection) { mFunctor = &mFunctorDecl; } \ + TNL_DECLARE_CLASS( RPC_##className##_##name ); \ + bool checkClassType(TNL::Object *theObject) { return dynamic_cast<className *>(theObject) != NULL; } }; \ + TNL_IMPLEMENT_NETEVENT( RPC_##className##_##name, groupMask, rpcVersion ); \ + void className::name args { RPC_##className##_##name *theEvent = new RPC_##className##_##name; theEvent->mFunctorDecl.set argNames ; postNetEvent(theEvent); } \ + TNL::NetEvent * className::name##_construct args { RPC_##className##_##name *theEvent = new RPC_##className##_##name; theEvent->mFunctorDecl.set argNames ; return theEvent; } \ + void className::name##_test args { RPC_##className##_##name *theEvent = new RPC_##className##_##name; theEvent->mFunctorDecl.set argNames ; TNL::PacketStream ps; theEvent->pack(this, &ps); ps.setBytePosition(0); theEvent->unpack(this, &ps); theEvent->process(this); } \ + void className::name##_remote args + /// Base class for RPC events. /// *************** *** 144,180 **** { public: ! MarshalledCall mCall; ///< Call arguments marshalled into a buffer on the sender and represented for the stack on the receiver ! /// Constructor call from within the rpc<i>Something</i> method generated by the TNL_IMPLEMENT_RPC macro. ! RPCEvent(MethodArgList *aMarshaller, RPCGuaranteeType gType, RPCDirection dir); ! ! /// Copies the argument list into the event data. ! void marshallArguments(); ! ! /// Returns the base address of the class member function pointer for the _remote version of the RPC function ! virtual void getFuncPtr(MethodPointer &m) = 0; ! ! /// Writes the marshalled data into the BitStream. void pack(EventConnection *ps, BitStream *bstream); - - /// Unmarshalls the data from the BitStream and stores it in mData. void unpack(EventConnection *ps, BitStream *bstream); - /// Copies the unmarshalled member function arguments onto the stack and invokes the remote method. void process(EventConnection *ps); - - /// Returns true if this RPC is being sent to an object of the appropriate class. - virtual bool checkClassType(Object *theObject) = NULL; }; /// Declares an RPC method within a class declaration. Creates two method prototypes - one for the host side of the RPC call, and one for the receiver, which performs the actual method. ! #define TNL_DECLARE_RPC(name, args) virtual void FN_CDECL name args; void FN_CDECL name##_test args; virtual TNL::NetEvent * FN_CDECL name##_construct args; virtual void FN_CDECL name##_remote args /// Declares an override to an RPC method declared in a parent class. ! #define TNL_DECLARE_RPC_OVERRIDE(name, args) void FN_CDECL name##_remote args /// Macro used to declare the body of an overridden RPC method. #define TNL_IMPLEMENT_RPC_OVERRIDE(className, name, args) \ ! void FN_CDECL className::name##_remote args /// Constructs a NetEvent that will represent the specified RPC invocation. This --- 162,184 ---- { public: ! Functor *mFunctor; /// Constructor call from within the rpc<i>Something</i> method generated by the TNL_IMPLEMENT_RPC macro. ! RPCEvent(RPCGuaranteeType gType, RPCDirection dir); void pack(EventConnection *ps, BitStream *bstream); void unpack(EventConnection *ps, BitStream *bstream); + virtual bool checkClassType(Object *theObject) = 0; void process(EventConnection *ps); }; /// Declares an RPC method within a class declaration. Creates two method prototypes - one for the host side of the RPC call, and one for the receiver, which performs the actual method. ! #define TNL_DECLARE_RPC(name, args) void name args; void name##_test args; virtual TNL::NetEvent * name##_construct args; virtual void name##_remote args /// Declares an override to an RPC method declared in a parent class. ! #define TNL_DECLARE_RPC_OVERRIDE(name, args) void name##_remote args /// Macro used to declare the body of an overridden RPC method. #define TNL_IMPLEMENT_RPC_OVERRIDE(className, name, args) \ ! void className::name##_remote args /// Constructs a NetEvent that will represent the specified RPC invocation. This *************** *** 183,209 **** #define TNL_RPC_CONSTRUCT_NETEVENT(object, rpcMethod, args) (object)->rpcMethod##_construct args - /// Macro used to declare the implementation of an RPC method on an EventConnection subclass. - /// - /// The macro should be used in place of a member function parameter declaration, - /// with the body code (to be executed on the remote side of the RPC) immediately - /// following the TNL_IMPLEMENT_RPC macro call. - #define TNL_IMPLEMENT_RPC(className, name, args, groupMask, guaranteeType, eventDirection, rpcVersion) \ - extern TNL::MethodArgList RPC##className##name; \ - class RPC_##className##_##name : public TNL::RPCEvent { \ - public: \ - void (FN_CDECL className::*mFuncPtr) args; \ - RPC_##className##_##name() : TNL::RPCEvent(&RPC##className##name, guaranteeType, eventDirection) \ - { mFuncPtr = &className::name##_remote; } \ - TNL_DECLARE_CLASS( RPC_##className##_##name ); \ - bool checkClassType(TNL::Object *theObject) { return dynamic_cast<className *>(theObject) != NULL; } \ - void getFuncPtr(TNL::MethodPointer &m) { m.v1=*((TNL::U32 *) &mFuncPtr); \ - if(sizeof(mFuncPtr) > sizeof(TNL::U32)) m.v2 = *(((TNL::U32 *) &mFuncPtr) + 1); \ - if(sizeof(mFuncPtr) > 2*sizeof(TNL::U32)) m.v3 = *(((TNL::U32 *) &mFuncPtr) + 2); } }; \ - TNL_IMPLEMENT_NETEVENT( RPC_##className##_##name, groupMask, rpcVersion ); \ - TNL::MethodArgList RPC##className##name (#className, #args); \ - void FN_CDECL className::name args { SAVE_PARAMS RPC_##className##_##name *theEvent = new RPC_##className##_##name; theEvent->marshallArguments(); postNetEvent(theEvent); } \ - TNL::NetEvent * FN_CDECL className::name##_construct args { SAVE_PARAMS RPC_##className##_##name *theEvent = new RPC_##className##_##name; theEvent->marshallArguments(); return theEvent; } \ - void FN_CDECL className::name##_test args { SAVE_PARAMS RPC_##className##_##name *ev = new RPC_##className##_##name; TNL::PacketStream ps; ev->marshallArguments(); ev->pack(this, &ps); ps.setBytePosition(0); ev->unpack(this, &ps); ev->process(this); } \ - void FN_CDECL className::name##_remote args }; --- 187,190 ---- --- tnl.dsp DELETED --- Index: tnlBitStream.h =================================================================== RCS file: /cvsroot/opentnl/tnl/tnl/tnlBitStream.h,v retrieving revision 1.6 retrieving revision 1.7 diff -C2 -d -r1.6 -r1.7 *** tnlBitStream.h 11 Jun 2004 19:16:35 -0000 1.6 --- tnlBitStream.h 21 Feb 2005 07:48:14 -0000 1.7 *************** *** 32,35 **** --- 32,39 ---- #endif + #ifndef _TNL_CONNECTIONSTRINGTABLE_H_ + #include "tnlConnectionStringTable.h" + #endif + namespace TNL { *************** *** 69,73 **** U32 maxReadBitNum; ///< Last valid read bit position. U32 maxWriteBitNum; ///< Last valid write bit position. ! /// String buffer holds the last string written into the stream for substring compression. char mStringBuffer[256]; --- 73,77 ---- U32 maxReadBitNum; ///< Last valid read bit position. U32 maxWriteBitNum; ///< Last valid write bit position. ! ConnectionStringTable *mStringTable; ///< String table used to compress StringTableEntries over the network. /// String buffer holds the last string written into the stream for substring compression. char mStringBuffer[256]; *************** *** 106,109 **** --- 110,116 ---- void clearStringBuffer() { mStringBuffer[0] = 0; } + /// sets the ConnectionStringTable for compressing string table entries across the network + void setStringTable(ConnectionStringTable *table) { mStringTable = table; } + /// clears the error state from an attempted read or write overrun void clearError() { error = false; } *************** *** 236,239 **** --- 243,252 ---- void readString(char stringBuf[256]); + /// Writes a string table entry into the stream + void writeStringTableEntry(const StringTableEntry &ste); + + /// Reads a string table entry from the stream + void readStringTableEntry(StringTableEntry *ste); + /// Writes byte data into the stream. bool write(const U32 in_numBytes, const void* in_pBuffer); *************** *** 276,294 **** //------------------------------------------------------------------------------ - - /// PacketStream provides a network interface to the BitStream for easy construction of data packets. - class PacketStream : public BitStream - { - U8 buffer[MaxPacketDataSize]; ///< internal buffer for packet data, sized to the maximum UDP packet size. - public: - /// Constructor assigns the internal buffer to the BitStream. - PacketStream(U32 targetPacketSize = MaxPacketDataSize) : BitStream(buffer, targetPacketSize, MaxPacketDataSize) {} - /// Sends this packet to the specified address through the specified socket. - NetError sendto(Socket &outgoingSocket, const Address &theAddress); - /// Reads a packet into the stream from the specified socket. - NetError recvfrom(Socket &incomingSocket, Address *recvAddress); - }; - - //------------------------------------------------------------------------------ //------------------------------------------------------------------------------ --- 289,292 ---- *************** *** 389,392 **** --- 387,405 ---- } + /// PacketStream provides a network interface to the BitStream for easy construction of data packets. + class PacketStream : public BitStream + { + typedef BitStream Parent; + U8 buffer[MaxPacketDataSize]; ///< internal buffer for packet data, sized to the maximum UDP packet size. + public: + /// Constructor assigns the internal buffer to the BitStream. + PacketStream(U32 targetPacketSize = MaxPacketDataSize) : BitStream(buffer, targetPacketSize, MaxPacketDataSize) {} + /// Sends this packet to the specified address through the specified socket. + NetError sendto(Socket &outgoingSocket, const Address &theAddress); + /// Reads a packet into the stream from the specified socket. + NetError recvfrom(Socket &incomingSocket, Address *recvAddress); + }; + + }; #endif //_TNL_BITSTREAM_H_ Index: netObject.cpp =================================================================== RCS file: /cvsroot/opentnl/tnl/tnl/netObject.cpp,v retrieving revision 1.4 retrieving revision 1.5 diff -C2 -d -r1.4 -r1.5 *** netObject.cpp 24 Jun 2004 01:12:09 -0000 1.4 --- netObject.cpp 21 Feb 2005 07:48:14 -0000 1.5 *************** *** 261,267 **** NetObject::mRPCSourceConnection = (GhostConnection *) ps; ! MethodPointer p; ! getFuncPtr(p); ! mCall.dispatch(thisPointer, &p); NetObject::mRPCSourceConnection = NULL; } --- 261,266 ---- NetObject::mRPCSourceConnection = (GhostConnection *) ps; ! mFunctor->dispatch(thisPointer); ! NetObject::mRPCSourceConnection = NULL; } Index: rpc.cpp =================================================================== RCS file: /cvsroot/opentnl/tnl/tnl/rpc.cpp,v retrieving revision 1.4 retrieving revision 1.5 diff -C2 -d -r1.4 -r1.5 *** rpc.cpp 19 May 2004 20:47:46 -0000 1.4 --- rpc.cpp 21 Feb 2005 07:48:14 -0000 1.5 *************** *** 30,74 **** #include "tnlNetEvent.h" #include "tnlRPC.h" - #include "tnlNetStringTable.h" #include "tnlEventConnection.h" namespace TNL { ! RPCEvent::RPCEvent(MethodArgList *aMarshaller, RPCGuaranteeType gType, RPCDirection dir) : ! NetEvent((NetEvent::GuaranteeType) gType, (NetEvent::EventDirection) dir), ! mCall(aMarshaller) ! { ! } ! ! void RPCEvent::marshallArguments() { - mCall.marshall(); } void RPCEvent::pack(EventConnection *ps, BitStream *bstream) { ! bstream->clearStringBuffer(); ! bstream->writeBits(mCall.marshalledData.getBitPosition(), mCall.marshalledData.getBuffer()); ! for(S32 i = 0; i < mCall.mSTEs.size(); i++) ! ps->packStringTableEntry(bstream, mCall.mSTEs[i]); } void RPCEvent::unpack(EventConnection *ps, BitStream *bstream) { ! bstream->clearStringBuffer(); ! mCall.unmarshall(bstream); ! bstream->clearStringBuffer(); ! for(S32 i = 0; i < mCall.mSTEs.size(); i++) ! mCall.mSTEs[i] = ps->unpackStringTableEntry(bstream); } void RPCEvent::process(EventConnection *ps) { ! if(!checkClassType(ps)) ! return; ! ! MethodPointer p; ! getFuncPtr(p); ! mCall.dispatch(ps, &p); } --- 30,56 ---- #include "tnlNetEvent.h" #include "tnlRPC.h" #include "tnlEventConnection.h" namespace TNL { ! RPCEvent::RPCEvent(RPCGuaranteeType gType, RPCDirection dir) : ! NetEvent((NetEvent::GuaranteeType) gType, (NetEvent::EventDirection) dir) { } void RPCEvent::pack(EventConnection *ps, BitStream *bstream) { ! mFunctor->write(*bstream); } void RPCEvent::unpack(EventConnection *ps, BitStream *bstream) { ! mFunctor->read(*bstream); } void RPCEvent::process(EventConnection *ps) { ! if(checkClassType(ps)) ! mFunctor->dispatch(ps); } Index: ghostConnection.cpp =================================================================== RCS file: /cvsroot/opentnl/tnl/tnl/ghostConnection.cpp,v retrieving revision 1.13 retrieving revision 1.14 diff -C2 -d -r1.13 -r1.14 *** ghostConnection.cpp 24 Jun 2004 01:12:09 -0000 1.13 --- ghostConnection.cpp 21 Feb 2005 07:48:14 -0000 1.14 *************** *** 696,701 **** } ! TNL_DECLARE_MEMBER_ENUM(GhostConnection, GhostCountBitSize); ! TNL_IMPLEMENT_RPC(GhostConnection, rpcStartGhosting, (U32 sequence), NetClassGroupGameMask, RPCGuaranteedOrdered, RPCDirAny, 0) { --- 696,701 ---- } ! TNL_IMPLEMENT_RPC(GhostConnection, rpcStartGhosting, ! (U32 sequence), (sequence), NetClassGroupGameMask, RPCGuaranteedOrdered, RPCDirAny, 0) { *************** *** 711,715 **** } ! TNL_IMPLEMENT_RPC(GhostConnection, rpcReadyForNormalGhosts, (U32 sequence), NetClassGroupGameMask, RPCGuaranteedOrdered, RPCDirAny, 0) { --- 711,716 ---- } ! TNL_IMPLEMENT_RPC(GhostConnection, rpcReadyForNormalGhosts, ! (U32 sequence), (sequence), NetClassGroupGameMask, RPCGuaranteedOrdered, RPCDirAny, 0) { *************** *** 725,729 **** } ! TNL_IMPLEMENT_RPC(GhostConnection, rpcEndGhosting, (), NetClassGroupGameMask, RPCGuaranteedOrdered, RPCDirAny, 0) { --- 726,730 ---- } ! TNL_IMPLEMENT_RPC(GhostConnection, rpcEndGhosting, (), (), NetClassGroupGameMask, RPCGuaranteedOrdered, RPCDirAny, 0) { Index: tnlConnectionStringTable.h =================================================================== RCS file: /cvsroot/opentnl/tnl/tnl/tnlConnectionStringTable.h,v retrieving revision 1.2 retrieving revision 1.3 diff -C2 -d -r1.2 -r1.3 *** tnlConnectionStringTable.h 23 Apr 2004 01:49:46 -0000 1.2 --- tnlConnectionStringTable.h 21 Feb 2005 07:48:14 -0000 1.3 *************** *** 34,39 **** namespace TNL { ! class EventConnection; ! class EventPacketNotify; /// ConnectionStringTable is a helper class to EventConnection for reducing duplicated string data sends --- 34,39 ---- namespace TNL { ! class NetConnection; ! class BitStream; /// ConnectionStringTable is a helper class to EventConnection for reducing duplicated string data sends *************** *** 81,85 **** Entry mLRUHead, mLRUTail; ! EventConnection *mParent; /// Pushes an entry to the back of the LRU list. --- 81,85 ---- Entry mLRUHead, mLRUTail; ! NetConnection *mParent; /// Pushes an entry to the back of the LRU list. *************** *** 94,100 **** } public: ! ConnectionStringTable(EventConnection *parent); ! void writeStringTableEntry(BitStream *stream, StringTableEntryRef string, PacketList *note); StringTableEntry readStringTableEntry(BitStream *stream); --- 94,100 ---- } public: ! ConnectionStringTable(NetConnection *parent); ! void writeStringTableEntry(BitStream *stream, StringTableEntryRef string); StringTableEntry readStringTableEntry(BitStream *stream); --- NEW FILE: tnlString.h --- //----------------------------------------------------------------------------------- // // Torque Network Library // Copyright (C) 2004 GarageGames.com, Inc. // For more information see http://www.opentnl.org // // This program is free software; you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation; either version 2 of the License, or // (at your option) any later version. // // For use in products that are not compatible with the terms of the GNU // General Public License, alternative licensing options are available // from GarageGames.com. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA // //------------------------------------------------------------------------------------ #ifndef _TNL_STRING_H_ #define _TNL_STRING_H_ namespace TNL { struct StringData { U32 mRefCount; char mStringData[1]; }; class StringPtr { StringData *mString; void alloc(const char *string) { mString = (StringData *) malloc(sizeof(StringData) + strlen(string)); strcpy(mString->mStringData, string); mString->mRefCount = 1; } void decRef() { if(mString && !--mString->mRefCount) free(mString); } public: StringPtr() { mString = NULL; } StringPtr(const char *string) { alloc(string); } StringPtr(const StringPtr &string) { mString = string.mString; if(mString) mString->mRefCount++; } ~StringPtr() { decRef(); } StringPtr &operator=(const StringPtr &ref) { decRef(); mString = ref.mString; mString->mRefCount++; return *this; } StringPtr &operator=(const char *string) { decRef(); alloc(string); return *this; } operator const char *() const { if(mString) return mString->mStringData; else return ""; } const char *getString() const { if(mString) return mString->mStringData; else return ""; } }; }; #endif Index: eventConnection.cpp =================================================================== RCS file: /cvsroot/opentnl/tnl/tnl/eventConnection.cpp,v retrieving revision 1.6 retrieving revision 1.7 diff -C2 -d -r1.6 -r1.7 *** eventConnection.cpp 14 Feb 2005 06:15:28 -0000 1.6 --- eventConnection.cpp 21 Feb 2005 07:48:13 -0000 1.7 *************** *** 49,53 **** mNextRecvEventSeq = FirstValidSendEventSeq; mLastAckedEventSeq = -1; - mStringTable = NULL; mEventClassCount = 0; mEventClassBitSize = 0; --- 49,52 ---- *************** *** 81,85 **** mEventNoteChunker.free(temp); } - delete mStringTable; } --- 80,83 ---- *************** *** 136,145 **** } - void EventConnection::setTranslatesStrings() - { - if(!mStringTable) - mStringTable = new ConnectionStringTable(this); - } - void EventConnection::processEvent(NetEvent *theEvent) { --- 134,137 ---- *************** *** 153,159 **** EventPacketNotify *notify = static_cast<EventPacketNotify *>(pnotify); - if(mStringTable) - mStringTable->packetDropped(¬ify->stringList); - EventNote *walk = notify->eventList; EventNote **insertList = &mSendEventQueueHead; --- 145,148 ---- *************** *** 207,213 **** EventPacketNotify *notify = static_cast<EventPacketNotify *>(pnotify); - if(mStringTable) - mStringTable->packetReceived(¬ify->stringList); - EventNote *walk = notify->eventList; EventNote **noteList = &mNotifyEventList; --- 196,199 ---- *************** *** 501,524 **** } - void EventConnection::packStringTableEntry(BitStream *stream, StringTableEntryRef h) - { - if(!mStringTable) - stream->writeString(h.getString()); - else - mStringTable->writeStringTableEntry(stream, h, &((EventPacketNotify *) getCurrentWritePacketNotify())->stringList); - } - - StringTableEntry EventConnection::unpackStringTableEntry(BitStream *stream) - { - if(!mStringTable) - { - char buf[256]; - stream->readString(buf); - return StringTableEntry(buf); - } - else - return mStringTable->readStringTableEntry(stream); - } - bool EventConnection::isDataToTransmit() { --- 487,490 ---- Index: tnlMethodDispatch.cpp =================================================================== RCS file: /cvsroot/opentnl/tnl/tnl/tnlMethodDispatch.cpp,v retrieving revision 1.17 retrieving revision 1.18 diff -C2 -d -r1.17 -r1.18 *** tnlMethodDispatch.cpp 14 Feb 2005 06:15:28 -0000 1.17 --- tnlMethodDispatch.cpp 21 Feb 2005 07:48:14 -0000 1.18 *************** *** 28,880 **** #include "tnlNetStringTable.h" #include "tnlThread.h" - namespace TNL - { - - struct TypeInfo - { - const char *name; - U32 size; - bool allowedAsArg; - bool allowedInVector; - }; - - enum ArgTypeId { - TypeS8, - TypeU8, - TypeS16, - TypeU16, - TypeS32, - TypeU32, - TypeF32, - TypeF64, - TypeSignedInt, - TypeInt, - TypeSignedFloat, - TypeFloat, - TypeString, - TypeRangedU32, - TypeBool, - TypeStringTableEntryRef, - TypeStringTableEntry, - TypeByteBufferPtr, - TypeIPAddressRef, - TypeIPAddress, - NumTypes, - }; ! TypeInfo gTypes[] = { ! ! { "S8", sizeof(S8), true, true }, ! { "U8", sizeof(U8), true, true }, ! { "S16", sizeof(S16), true, true }, ! { "U16", sizeof(U16), true, true }, ! { "S32", sizeof(S32), true, true }, ! { "U32", sizeof(U32), true, true }, ! { "F32", sizeof(F32), true, true }, ! { "F64", sizeof(F64), false, true }, ! { "SignedInt<", sizeof(SignedInt<32>), true, true }, ! { "Int<", sizeof(Int<32>), true, true }, ! { "SignedFloat<", sizeof(SignedFloat<32>), true, true }, ! { "Float<", sizeof(Float<32>), true, true }, ! { "const char *", sizeof(const char *), true, true }, ! { "RangedU32<", sizeof(RangedU32<0,U32_MAX>), true, true }, ! { "bool", sizeof(bool), true, true }, ! { "StringTableEntryRef", sizeof(StringTableEntry *), true, false }, ! { "StringTableEntry", sizeof(StringTableEntry), false, true }, ! { "ByteBufferRef", sizeof(ByteBuffer *), true, false }, ! { "IPAddressRef", sizeof(IPAddress *), true, false }, ! { "IPAddress", sizeof(IPAddress), false, true }, ! { 0, 0, 0, 0 }, ! }; ! ! MethodEnum *MethodEnum::mLinkedList = NULL; ! ! U32 MethodArgList::getValue(const char *buffer) { ! while(*buffer == ' ') ! buffer++; ! if(buffer[0] >= '0' && buffer[0] <= '9') ! return atoi(buffer); ! else ! { ! U32 len = 0; ! while((buffer[len] >= 'a' && buffer[len] <= 'z') || ! (buffer[len] >= 'A' && buffer[len] <= 'Z') || ! (buffer[len] == ':' || buffer[len] == '_')) ! len++; ! for(MethodEnum *walk = MethodEnum::mLinkedList; walk; walk = walk->mNext) ! { ! if(!strncmp(buffer, walk->mSymbol, len) && walk->mSymbol[len] == 0) ! return walk->mValue; ! } ! } ! TNLAssert(0, "Undeclared method enumeration! Use TNL_DECLARE_ENUM."); ! return 0; ! } ! ! typedef StringTableEntry &StringTableEntryType; ! ! MethodArgList::MethodArgList(const char *className, const char *anArgList) { ! argListSize = 0; ! argListString = anArgList; ! mClassName = className; ! ! // first strip off the leading paren. ! const char *aptr = argListString + 1; ! U32 numFloats = 0; ! ! for(;;) ! { ! U32 type = 0; ! MethodArgInfo info; ! ! // remove leading spaces ! while(*aptr == ' ') ! aptr++; ! if(*aptr == ')') ! break; ! ! info.isVector = false; ! ! // this can let some errors through - for example we don't check that ! // the vector is passed as a reference, but it has to be. ! // Ideally we should do a simple lexer/parser for the argument ! // lists in flex/bison. This would let us grow the parser a lot ! // more easily. ! if(!strncmp(aptr, "const Vector<", 13)) ! { ! info.isVector = true; ! aptr += 13; ! } ! else if(!strncmp(aptr, "const TNL::Vector<", 18)) ! { ! info.isVector = true; ! aptr += 18; ! } ! ! // strip off any TNL namespace stuff ! if(!strncmp(aptr, "TNL::", 5)) ! aptr += 5; ! ! U32 len = 0; ! // grab the type off the arg list pointer: ! for(;type < NumTypes; type++) ! { ! // figure out the base type: ! len = strlen(gTypes[type].name); ! if(!strncmp(aptr, gTypes[type].name, len)) ! break; ! } ! ! TNLAssert(type != NumTypes, "Invalid type in method declaration."); ! TNLAssert(!info.isVector || gTypes[type].allowedInVector, ("Invalid vector subtype (%s) in method declaration.", aptr)); ! TNLAssert(info.isVector || gTypes[type].allowedAsArg, ("Invalid type (%s) in method declaration.", aptr)); ! ! aptr += len; ! info.argType = type; ! ! // figure out the template arguments, if any: ! if(type == TypeSignedInt || type == TypeInt || ! type == TypeSignedFloat || type == TypeFloat || ! type == TypeRangedU32) ! { ! const char *walk = aptr; ! aptr = strchr(aptr, '>') + 1; ! ! if(type == TypeRangedU32) ! { ! info.rangeStart = getValue(walk); ! info.rangeEnd = getValue(strchr(walk, ',') + 1); ! } ! else ! info.bitCount = getValue(walk); ! } ! if(!info.isVector && (type == TypeF32 || type == TypeFloat || type == TypeSignedFloat)) ! { ! if(numFloats < 13) ! { ! floatRegOffsets[numFloats] = argList.size() * sizeof(U32); ! numFloats++; ! } ! } ! argList.push_back(info); ! ! if(gTypes[type].size > sizeof(U32)) ! argListSize += gTypes[type].size; ! else ! argListSize += sizeof(U32); ! ! // lop off the name of the var... ! aptr = strchr(aptr, ','); ! if(!aptr) ! break; ! aptr++; ! } ! if(numFloats < 13) ! floatRegOffsets[numFloats] = -1; } ! ThreadStorage gRPCThreadStorage; ! ! RPCThreadStorage &getRPCThreadStorage() { ! RPCThreadStorage *val = (RPCThreadStorage *) gRPCThreadStorage.get(); ! if(!val) ! { ! val = new RPCThreadStorage; ! gRPCThreadStorage.set(val); ! } ! return *val; } ! void MethodArgList::marshall(MarshalledCall *theEvent) { ! PacketStream bstream; ! RPCThreadStorage &sto = getRPCThreadStorage(); ! ! #if defined (TNL_CPU_PPC) ! U32 *intArg = sto.registerSaves; ! F32 *floatArg = (F32 *) (&sto.registerSaves[8]); ! void *stackPtr = (void *) sto.registerSaves[8 + 13]; ! stackPtr = (void *) (*((U8 **) stackPtr) + 24); // advance past linkage area of stack ! intArg++; // get rid of the "this" pointer. ! bool floatInRegs = true; ! #else ! U8 *ptr = (U8 *) sto.basePtr; ! ptr += 4; // get rid of the return address and saved base ptr. ! #endif ! U32 whichSTE = 0; ! ! for(S32 i = 0; i < argList.size(); i++) ! { ! #if !defined (TNL_CPU_PPC) ! void *arg = ptr; ! U32 *intArg = (U32 *) arg; ! F32 *floatArg = (F32 *) arg; ! #else ! if(!floatInRegs) ! floatArg = ((F32 *) stackPtr) + i + 1; // the +1 skips the this pointer which is an arg, but not in the arg list. ! #endif ! U32 count = 1; ! U32 *intArgSave = intArg; ! F32 *floatArgSave = floatArg; ! ! if(argList[i].isVector) ! { ! VectorRep *vector = *((VectorRep **) intArg); ! bstream.writeInt(vector->elementCount, VectorSizeBitSize); ! intArg = (U32 *) vector->array; ! floatArg = (F32 *) vector->array; ! count = vector->elementCount; ! } ! for(U32 j = 0; j < count; j++) ! { ! switch(argList[i].argType) ! { ! case TypeS8: ! #ifdef TNL_BIG_ENDIAN ! if(!argList[i].isVector) ! { ! bstream.write(((S8 *) intArg)[3]); ! } ! else ! #endif ! bstream.write(*((S8 *) intArg)); ! break; ! case TypeU8: ! #ifdef TNL_BIG_ENDIAN ! if(!argList[i].isVector) ! { ! bstream.write(((U8 *) intArg)[3]); ! } ! else ! #endif ! bstream.write(*((U8 *) intArg)); ! break; ! case TypeS16: ! #ifdef TNL_BIG_ENDIAN ! if(!argList[i].isVector) ! { ! bstream.write(((S16 *) intArg)[1]); ! } ! else ! #endif ! bstream.write(*((S16 *) intArg)); ! break; ! case TypeU16: ! #ifdef TNL_BIG_ENDIAN ! if(!argList[i].isVector) ! { ! bstream.write(((U16 *) intArg)[1]); ! } ! else ! #endif ! bstream.write(*((U16 *) intArg)); ! break; ! case TypeS32: ! bstream.write(*((S32 *) intArg)); ! break; ! case TypeU32: ! bstream.write(*((U32 *) intArg)); ! break; ! case TypeF32: ! bstream.write(*((F32 *) floatArg)); ! floatArg++; ! break; ! case TypeF64: ! bstream.write(*((F64 *) intArg)); ! break; ! case TypeSignedInt: ! bstream.writeSignedInt(((SignedInt<32> *) intArg)->value, argList[i].bitCount); ! break; ! case TypeInt: ! bstream.writeInt(((Int<32> *) intArg)->value, argList[i].bitCount); ! break; ! case TypeSignedFloat: ! bstream.writeSignedFloat(((SignedFloat<32> *) floatArg)->value, argList[i].bitCount); ! floatArg++; ! break; ! case TypeFloat: ! bstream.writeFloat(((Float<32> *) floatArg)->value, argList[i].bitCount); ! floatArg++; ! break; ! case TypeString: ! bstream.writeString(*((const char **) intArg)); ! break; ! case TypeStringTableEntryRef: ! theEvent->mSTEs.push_back(**((StringTableEntry **) intArg)); ! break; ! case TypeStringTableEntry: ! theEvent->mSTEs.push_back(*((StringTableEntry *) intArg)); ! break; ! case TypeRangedU32: ! bstream.writeRangedU32(((RangedU32<0,U32_MAX> *) intArg)->value, argList[i].rangeStart, argList[i].rangeEnd); ! break; ! case TypeBool: ! bstream.writeFlag(*((bool *) intArg)); ! break; ! case TypeByteBufferPtr: ! { ! ByteBuffer *buffer = *((ByteBuffer **) intArg); ! bstream.writeInt(buffer->getBufferSize(), ByteBufferSizeBitSize); ! bstream.write(buffer->getBufferSize(), buffer->getBuffer()); ! } ! break; ! case TypeIPAddressRef: ! bstream.write((*((IPAddress **) intArg))->netNum); ! bstream.write((*((IPAddress **) intArg))->port); ! break; ! case TypeIPAddress: ! bstream.write(((IPAddress *) intArg)->netNum); ! bstream.write(((IPAddress *) intArg)->port); ! break; ! } ! if(count != 1) ! { ! *((U8 **) &intArg) += gTypes[argList[i].argType].size; ! // float args already get incremented above ! //*((U8 **) &floatArg) += typeSizes[argList[i].argType]; ! } ! } ! if(argList[i].isVector) ! { ! intArg = intArgSave; ! floatArg = floatArgSave; ! } ! intArg++; ! #ifdef TNL_CPU_PPC ! if(i == 6) // we're on our 8th register... start reading ints from the stack: ! { ! intArg = ((U32 *) stackPtr) + 8; // skip 8 registers. ! } ! if(floatArg == (F32 *) &gRegisterSaves[8+13]) // we're on our 13th register... start reading floats from the stack: ! floatInRegs = false; ! #else ! if(argList[i].isVector || gTypes[argList[i].argType].size <= sizeof(U32)) ! ptr += sizeof(U32); ! else ! ptr += gTypes[argList[i].argType].size; ! #endif ! } ! theEvent->marshalledData.setBuffer(bstream.getBuffer(), bstream.getBytePosition()); ! theEvent->marshalledData.takeOwnership(); ! theEvent->marshalledData.setBitPosition(bstream.getBitPosition()); } ! ! inline U8 *allocSpace(U8 **offsetDest, U32 ¤tSize, U32 requestSize, RPCThreadStorage &sto) { ! if(sto.rpcNumOffsets >= MethodArgList::MaxOffsets) ! return NULL; ! ! currentSize = fourByteAlign(currentSize); ! sto.rpcReadOffsets[sto.rpcNumOffsets++] = ((U8 *) offsetDest) - sto.rpcReadData; ! ! if(requestSize + currentSize > MethodArgList::MaxRPCDataSize) ! return NULL; ! ! U8 *ret = sto.rpcReadData + currentSize; ! *offsetDest = ret; ! ! currentSize += requestSize; ! return ret; } ! ! bool MethodArgList::unmarshall(BitStream *bstream, MarshalledCall *theEvent) { ! RPCThreadStorage &sto = getRPCThreadStorage(); ! sto.rpcNumOffsets = 0; ! sto.rpcNumSTEs = 0; ! U32 rpcCurrentSTEIndex = 0; ! ! U32 currentSize = argListSize; ! #ifdef TNL_CPU_PPC ! currentSize = getMax(currentSize, U32(28)); ! #endif ! U32 whichSTE = 0; ! U8 *argPtr= sto.rpcReadData; ! for(S32 i = 0; i < argList.size(); i++) ! { ! U8 *arg = argPtr; ! U32 count = 1; ! if(argList[i].isVector) ! { ! VectorRep *vector = (VectorRep *) allocSpace((U8 **) arg, currentSize, sizeof(VectorRep), sto); ! if(!vector) ! goto errorOut; ! ! vector->arraySize = bstream->readInt(VectorSizeBitSize); ! vector->elementCount = vector->arraySize; ! ! if(argList[i].argType == TypeStringTableEntry) ! { ! sto.rpcSTEIndex[sto.rpcNumSTEs] = rpcCurrentSTEIndex; ! sto.rpcSTEOffsets[sto.rpcNumSTEs] = (U8 *) &vector->array; ! sto.rpcNumSTEs++; ! rpcCurrentSTEIndex += vector->elementCount; ! argPtr += sizeof(U32); ! continue; ! } ! else ! { ! vector->array = allocSpace(&vector->array, currentSize, vector->elementCount * gTypes[argList[i].argType].size, sto); ! if(!vector->array) ! goto errorOut; ! *((VectorRep **) arg) = vector; ! count = vector->elementCount; ! arg = vector->array; ! } ! } ! for(U32 j = 0; j < count; j++) ! { ! switch(argList[i].argType) ! { ! case TypeS8: ! #ifdef TNL_BIG_ENDIAN ! if(!argList[i].isVector) ! { ! bstream->read(((S8 *) arg) + 3); ! } ! else ! #endif ! bstream->read((S8 *) arg); ! break; ! case TypeU8: ! #ifdef TNL_BIG_ENDIAN ! if(!argList[i].isVector) ! { ! bstream->read(((U8 *) arg) + 3); ! } ! else ! #endif ! bstream->read((U8 *) arg); ! break; ! case TypeS16: ! #ifdef TNL_BIG_ENDIAN ! if(!argList[i].isVector) ! { ! bstream->read(((S16 *) arg) + 1); ! } ! else ! #endif ! bstream->read((S16 *) arg); ! break; ! case TypeU16: ! #ifdef TNL_BIG_ENDIAN ! if(!argList[i].isVector) ! { ! bstream->read(((U16 *) arg) + 1); ! } ! else ! #endif ! bstream->read((S16 *) arg); ! break; ! case TypeS32: ! bstream->read((S32 *) arg); ! break; ! case TypeU32: ! bstream->read((U32 *) arg); ! break; ! case TypeF32: ! bstream->read((F32 *) arg); ! break; ! case TypeF64: ! bstream->read((F64 *) arg); ! break; ! case TypeSignedInt: ! ((SignedInt<32> *) arg)->value = bstream->readSignedInt(argList[i].bitCount); ! break; ! case TypeInt: ! ((Int<32> *) arg)->value = bstream->readInt(argList[i].bitCount); ! break; ! case TypeSignedFloat: ! ((SignedFloat<32> *) arg)->value = bstream->readSignedFloat(argList[i].bitCount); ! break; ! case TypeFloat: ! ((Float<32> *) arg)->value = bstream->readFloat(argList[i].bitCount); ! break; ! case TypeString: ! { ! char **stringPtr = (char **) arg; ! *stringPtr = (char *) allocSpace((U8 **) arg, currentSize, 256, sto); ! if(!*stringPtr) ! goto errorOut; ! bstream->readString(*stringPtr); ! // back off the end pointer. ! currentSize -= (255 - strlen(*stringPtr)); ! } ! break; ! case TypeStringTableEntryRef: ! if(sto.rpcNumSTEs >= MethodArgList::MaxOffsets) ! goto errorOut; ! sto.rpcSTEIndex[sto.rpcNumSTEs] = rpcCurrentSTEIndex; ! sto.rpcSTEOffsets[sto.rpcNumSTEs] = arg; ! sto.rpcNumSTEs++; ! rpcCurrentSTEIndex++; ! break; ! case TypeRangedU32: ! ((RangedU32<0,U32_MAX> *) arg)->value = bstream->readRangedU32(argList[i].rangeStart, argList[i].rangeEnd); ! break; ! case TypeBool: ! *((bool *) arg) = bstream->readFlag(); ! break; ! case TypeByteBufferPtr: ! { ! ByteBuffer *buffer = (ByteBuffer *) allocSpace((U8 **) arg, currentSize, sizeof(ByteBuffer), sto); ! if(!buffer) ! goto errorOut; ! buffer->mOwnsMemory = false; ! buffer->mBufSize = bstream->readInt(ByteBufferSizeBitSize); ! buffer->mDataPtr = (U8 *) allocSpace(&buffer->mDataPtr, currentSize, buffer->mBufSize, sto); ! if(!buffer->mDataPtr) ! goto errorOut; ! bstream->read(buffer->mBufSize, buffer->mDataPtr); ! *((ByteBuffer **) arg) = buffer; ! } ! break; ! case TypeIPAddressRef: ! { ! IPAddress *ip = (IPAddress *) allocSpace((U8 **) arg, currentSize, sizeof(IPAddress), sto); ! if(!ip) ! goto errorOut; ! bstream->read(&ip->netNum); ! bstream->read(&ip->port); ! *((IPAddress **) arg) = (IPAddress *) ip; ! } ! break; ! case TypeIPAddress: ! bstream->read(&((IPAddress *) arg)->netNum); ! bstream->read(&((IPAddress *) arg)->port); ! break; ! } ! *((U8 **) &arg) += gTypes[argList[i].argType].size; ! } ! if(argList[i].isVector || gTypes[argList[i].argType].size <= sizeof(U32)) ! argPtr += sizeof(U32); ! else ! argPtr += gTypes[argList[i].argType].size; ! } ! theEvent->mSTEs.setSize(rpcCurrentSTEIndex); ! for(U32 i = 0; i < sto.rpcNumSTEs; i++) ! *((StringTableEntry **) sto.rpcSTEOffsets[i]) = &theEvent->mSTEs[sto.rpcSTEIndex[i]]; ! ! theEvent->unmarshalledData.setBuffer(sto.rpcReadData, currentSize, false); ! theEvent->unmarshalledData.takeOwnership(); ! ! U32 delta; ! U8 *data; ! data = theEvent->unmarshalledData.getBuffer(); ! delta = data - sto.rpcReadData; ! ! for(U32 i = 0; i < sto.rpcNumOffsets; i++) ! { ! *((U8 **) (data + sto.rpcReadOffsets[i])) += delta; ! } ! return true; ! errorOut: ! return false; } ! ! void MarshalledCall::dispatch(void *thisPtr, MethodPointer *method) { ! U32 func; ! U32 funcOffset; ! func = method->v1; ! funcOffset = method->v2; ! void *mptr = &method->v1; ! void *args = unmarshalledData.getBuffer(); ! ! #ifdef TNL_CPU_X86 ! S32 sz = mMarshaller->argListSize; ! U32 saveESP; ! #endif ! // CallMethod(ps, data); ! ! #if defined(TNL_SUPPORTS_VC_INLINE_X86_ASM) ! _asm ! { ! push esi ! push edi ! push ecx ! push edx ! push ebx ! mov saveESP, esp ! ! mov ecx, sz // get size of buffer ! mov esi, args // get buffer ! sub esp, ecx // allocate stack space ! mov edi, esp // start of destination stack frame ! shr ecx, 2 // make it dwords ! rep movsd // copy it ! mov ecx, thisPtr // set "this" ! push ecx ! call [func] // call the function ! mov esp, saveESP ! ! pop ebx ! pop edx ! pop ecx ! pop edi ! pop esi ! } ! ! #elif defined(TNL_SUPPORTS_MWERKS_INLINE_X86_ASM) ! _asm ! { ! push esi ! push edi ! push ecx ! push edx ! push ebx ! mov saveESP, esp ! ! mov ecx, sz // get size of buffer ! mov esi, args // get buffer ! sub esp, ecx // allocate stack space ! mov edi, esp // start of destination stack frame ! shr ecx, 2 // make it dwords ! rep movsd // copy it ! mov ecx, thisPtr // set "this" ! push ecx ! mov eax, mptr ! push eax ! call jmp_method ! mov esp, saveESP ! ! pop ebx ! pop edx ! pop ecx ! pop edi ! pop esi ! jmp jmp_continue ! ! jmp_method: ! pop eax ! pop edx ! mov ecx,dword ptr [esp] ! push eax ! add ecx,dword ptr [edx] ! mov dword ptr [esp+0x4],ecx ! cmp dword ptr [edx+0x4],0xffffffff ! je jmp_now ! mov eax,dword ptr [edx+0x8] ! mov eax,dword ptr [ecx+eax] ! add eax,dword ptr [edx+0x4] ! jmp dword ptr [eax] ! lea eax,dword ptr [eax+0x0] ! jmp_now: ! jmp dword ptr [edx+0x8] ! ! jmp_continue: } - #elif defined(TNL_SUPPORTS_GCC_INLINE_X86_ASM) - - #if defined ( TNL_GCC_3 ) - U8 *funcPtr = ((U8 *) thisPtr) + funcOffset; - funcPtr = *((U8 **) funcPtr); - funcPtr += func; - funcPtr--; - funcPtr = *((U8 **) funcPtr); - #elif defined ( TNL_GCC_2 ) - U8 *funcPtr = ((U8 *) thisPtr) + (funcOffset & 0xFFFF); - funcPtr = *((U8 **) funcPtr) + (func >> 14); - funcPtr = *((U8 **) (funcPtr - 4)); - #endif - - asm( - "mov %%esp, %0 \n" - - "mov %1, %%ecx \n" // get size of buffer - "mov %2, %%esi \n" // get buffer - "sub %%ecx, %%esp \n" // allocate stack space - "mov %%esp, %%edi \n" // start of destination stack frame - "shr $2, %%ecx \n" // make it dwords - "rep\nmovsl \n" // copy it - "mov %4, %%ecx \n" // set "this" - "push %%ecx \n" // gcc expects this pointer to be on the stack - "call *%3 \n" // call the function - - "mov %0, %%esp \n" - - : /* nothing out */ - : "m" (saveESP), "m" (sz), "m" (args), "m" (funcPtr), "m" (thisPtr) - : "ebx", "edx", "ecx", "edi", "esi" - ); - #elif defined (TNL_SUPPORTS_GCC_INLINE_PPC_ASM) - register S32 *floatOffsets = mMarshaller->floatRegOffsets; - - S32 argAreaSize = mMarshaller->argList.size() * sizeof(U32); - if(argAreaSize < 28) - argAreaSize = 28; - - S32 copySize = 28 - argAreaSize; // negative - stack grows down - - // load up the floating point registers - asm(" \n" - "mflr r0\n" - "stw r0, 8(r1)\n" // save off link register - "mr r9, %4\n" // load up the copy size - "addi r9, r9, -24-32-4\n" // 24 for linkage area, 32 for register arguments, 4 for r20 - "stw r20, -4(r1)\n" // save off r20 into the red zone - "mr r20, r9\n" // save the grow amount - - "subfic r9, r9, -24-32-4\n" // compute byte total to copy to the stack - "mr r10, %1\n" - "addi r10, r10, 28\n" - "sub r12, r1, r9\n" // write offset from stack (into red zone) - "addi r12, r12, -4\n" // skip past r20 save area. - "li r2, 0\n" - - "stackCopyLoop:\n" - "cmpw r2, r9\n" - "beq stackCopyDone\n" - "lwzx r3, r2, r10\n" - "stwx r3, r2, r12\n" - "addi r2, r2, 4\n" // increment the loop counter... - "b stackCopyLoop\n" - "stackCopyDone:\n" - - "mr r10, %1\n" - "mr r3, %3\n" - "mr r12, %2\n" - "mr r9, %0\n" - - "stwux r1, r1, r20\n" // create some stack space for us to work in - - "lwz r2, 0(r9)\n" - "subic. r2, r2, 0\n" - "blt floatsDone\n" - "lfsx f1, r2, r10\n" - - "lwz r2, 4(r9)\n" - "subic. r2, r2, 0\n" - "blt floatsDone\n" - "lfsx f2, r2, r10\n" - - "lwz r2, 8(r9)\n" - "subic. r2, r2, 0\n" - "blt floatsDone\n" - "lfsx f3, r2, r10\n" - - "lwz r2, 12(r9)\n" - "subic. r2, r2, 0\n" - "blt floatsDone\n" - "lfsx f4, r2, r10\n" - - "lwz r2, 16(r9)\n" - "subic. r2, r2, 0\n" - "blt floatsDone\n" - "lfsx f5, r2, r10\n" - - "lwz r2, 20(r9)\n" - "subic. r2, r2, 0\n" - "blt floatsDone\n" - "lfsx f6, r2, r10\n" - - "lwz r2, 24(r9)\n" - "subic. r2, r2, 0\n" - "blt floatsDone\n" - "lfsx f7, r2, r10\n" - - "lwz r2, 28(r9)\n" - "subic. r2, r2, 0\n" - "blt floatsDone\n" - "lfsx f8, r2, r10\n" - - "lwz r2, 32(r9)\n" - "subic. r2, r2, 0\n" - "blt floatsDone\n" - "lfsx f9, r2, r10\n" - - "lwz r2, 36(r9)\n" - "subic. r2, r2, 0\n" - "blt floatsDone\n" - "lfsx f10, r2, r10\n" - - "lwz r2, 40(r9)\n" - "subic. r2, r2, 0\n" - "blt floatsDone\n" - "lfsx f11, r2, r10\n" ! "lwz r2, 44(r9)\n" ! "subic. r2, r2, 0\n" ! "blt floatsDone\n" ! "lfsx f12, r2, r10\n" ! ! "lwz r2, 48(r9)\n" ! "subic. r2, r2, 0\n" ! "blt floatsDone\n" ! "lfsx f13, r2, r10\n" ! ! "floatsDone:\n" ! ! // load up the virtual function pointer ! "mr r4, %5\n" ! // r4 has funcOffset, r12 has the function index ! "add r4, r4, r3\n" ! "lwz r4, 0(r4)\n" ! "add r4, r4, r12\n" ! "addi r4, r4, -1\n" ! "lwz r12, 0(r4)\n" ! "lwz r4, 0(r10)\n" ! "lwz r5, 4(r10)\n" ! "lwz r6, 8(r10)\n" ! "lwz r7, 12(r10)\n" ! "lwz r8, 16(r10)\n" ! "lwz r9, 20(r10)\n" ! "lwz r10, 24(r10)\n" ! "mtctr r12\n" ! "bctrl\n" ! "sub r1, r1, r20\n" ! "lwz r20, -4(r1)\n" //addic r1, r1, 424\n" ! "lwz r0, 8(r1)\n" ! "mtlr r0\n" - : : "r" (floatOffsets), "r" (args), "r" (func), "r" (thisPtr), "r" (copySize), "r" (funcOffset) : "r2", "r9", "r10", "r12", "r3", "r0"); - #endif - } }; --- 28,75 ---- #include "tnlNetStringTable.h" #include "tnlThread.h" ! namespace Types { ! void read(TNL::BitStream &s, TNL::StringPtr *val) { ! char buffer[256]; ! s.readString(buffer); ! *val = buffer; } ! void write(TNL::BitStream &s, TNL::StringPtr &val) { ! s.writeString(val.getString()); } ! void read(TNL::BitStream &s, TNL::ByteBufferPtr *val) { ! TNL::U32 size = s.readInt(ByteBufferSizeBitSize); ! *val = new TNL::ByteBuffer(size); ! s.read(size, (*val)->getBuffer()); } ! void write(TNL::BitStream &s, TNL::ByteBufferPtr &val) { ! s.writeInt(val->getBufferSize(), ByteBufferSizeBitSize); ! s.write(val->getBufferSize(), val->getBuffer()); } ! void read(TNL::BitStream &s, TNL::IPAddress *val) { ! s.read(&val->netNum); ! s.read(&val->port); } ! void write(TNL::BitStream &s, TNL::IPAddress &val) { ! s.write(val.netNum); ! s.write(val.port); } ! }; ! namespace TNL ! { }; Index: journal.cpp =================================================================== RCS file: /cvsroot/opentnl/tnl/tnl/journal.cpp,v retrieving revision 1.6 retrieving revision 1.7 diff -C2 -d -r1.6 -r1.7 *** journal.cpp 20 May 2004 20:16:07 -0000 1.6 --- journal.cpp 21 Feb 2005 07:48:14 -0000 1.7 *************** *** 97,101 **** } ! JournalEntryRecord::JournalEntryRecord(const char *functionName, MethodArgList *methodArgList) { S32 i; --- 97,101 ---- } ! JournalEntryRecord::JournalEntryRecord(const char *functionName) { S32 i; *************** *** 111,115 **** (*mEntryVector)[i] = this; mFunctionName = functionName; - mMethodArgList = methodArgList; mEntryIndex = 0; } --- 111,114 ---- *************** *** 204,208 ... [truncated message content] |