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

frameworkseqnolist.h

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 FRAMEWORKSEQNOLIST_H
00024 #define FRAMEWORKSEQNOLIST_H
00025 
00026 #include <pasync.h>
00027 USING_PTYPES
00028 #include <map>
00029 #include <iostream>
00030 
00031 class FrameworkPacket;
00032 
00033 #define SEQUENCE_CHANNELS  256+1/*The last one is for plugins*/
00034 /**
00035  * @ingroup Common
00036  * @brief This class takes care of keeping track of ingoing/outgoing sequence numbers.
00037  * It contains two sequencenumbers for each priority (0-255), and two for the plugin-packets.
00038  * @author Lars Langer and Emanuel Greisen
00039 */
00040 template<class PacketType, class SocketType>
00041 class FrameworkSeqNoList
00042 {
00043 private:
00044    unsigned int buffered_packet_count;
00045    mutex next_seq_mutex;
00046    unsigned int ingoing_reliable_seq_numbers[SEQUENCE_CHANNELS];
00047    unsigned int outgoing_reliable_seq_numbers[SEQUENCE_CHANNELS];
00048    unsigned int ingoing_unreliable_seq_numbers[SEQUENCE_CHANNELS];
00049    unsigned int outgoing_unreliable_seq_numbers[SEQUENCE_CHANNELS];
00050    std::map<unsigned int, PacketType *> buffered_packets[SEQUENCE_CHANNELS];
00051 
00052 private:
00053    void clear();
00054 
00055 public:
00056    FrameworkSeqNoList();
00057    ~FrameworkSeqNoList();
00058 
00059 public:
00060    unsigned int getNextIngoingSeqNo(PacketType * packet) const;
00061    bool isNext(PacketType * packet) const;
00062    bool isFuture(PacketType * packet) const;
00063    unsigned int getNextOutgoingSeqNo( PacketType * packet );
00064    PacketType * incrementNextIngoingSeqNo(PacketType * packet);
00065    void bufferPacket(PacketType * packet);
00066    inline unsigned int bufferePacketsTotal() const { return buffered_packet_count; };
00067    static int getChannel(const PacketType * packet);
00068 
00069 };
00070 
00071 
00072 
00073 template<class PacketType, class SocketType>
00074 FrameworkSeqNoList<PacketType, SocketType>::FrameworkSeqNoList() : buffered_packet_count(0)
00075 {
00076    clear();
00077 }
00078 
00079 
00080 template<class PacketType, class SocketType>
00081 FrameworkSeqNoList<PacketType, SocketType>::~FrameworkSeqNoList()
00082 {
00083 }
00084 
00085 template<class PacketType, class SocketType>
00086 void FrameworkSeqNoList<PacketType, SocketType>::clear( )
00087 {
00088    for(int i = 0; i < SEQUENCE_CHANNELS; i++)
00089    {
00090       // Reliable part
00091       ingoing_reliable_seq_numbers[i] = 0x100;
00092       outgoing_reliable_seq_numbers[i] = 0x100;
00093       buffered_packets[i].clear();
00094 
00095       // Unreliable part
00096       ingoing_unreliable_seq_numbers[i] = 0x100;
00097       outgoing_unreliable_seq_numbers[i] = 0x100;
00098    }
00099 }
00100 
00101 template<class PacketType, class SocketType>
00102 unsigned int FrameworkSeqNoList<PacketType, SocketType>::getNextOutgoingSeqNo( PacketType * packet )
00103 {
00104    int channel = getChannel(packet);
00105    int next_seq;
00106    next_seq_mutex.enter();
00107    if(packet->isReliable())
00108    {
00109       next_seq = outgoing_reliable_seq_numbers[channel]++;
00110    }
00111    else
00112    {
00113       next_seq = outgoing_unreliable_seq_numbers[channel]++;
00114    }
00115    next_seq_mutex.leave();
00116    return next_seq;
00117 }
00118 
00119 template<class PacketType, class SocketType>
00120 unsigned int FrameworkSeqNoList<PacketType, SocketType>::getNextIngoingSeqNo( PacketType * packet ) const
00121 {
00122    int channel = getChannel(packet);
00123    //std::cout << "Channel:"<<(int)channel<<": Seq: "<<ingoing_reliable_seq_numbers[channel]<<" ? "<<packet->getSequenceNumber()<<std::endl;
00124 
00125    return packet->isReliable() ? ingoing_reliable_seq_numbers[channel] : ingoing_unreliable_seq_numbers[channel];
00126 }
00127 
00128 
00129 template<class PacketType, class SocketType>
00130 PacketType * FrameworkSeqNoList<PacketType, SocketType>::incrementNextIngoingSeqNo( PacketType * packet )
00131 {
00132    int channel = getChannel(packet);
00133    PacketType * next_packet = 0;
00134 
00135    if(packet->isReliable())
00136    {
00137       ingoing_reliable_seq_numbers[channel] = packet->getSequenceNumber() + 1;
00138 
00139       if(buffered_packets[channel].find(ingoing_reliable_seq_numbers[channel]) != buffered_packets[channel].end())
00140       {
00141          next_packet = buffered_packets[channel][ingoing_reliable_seq_numbers[channel]];
00142          buffered_packets[channel].erase(ingoing_reliable_seq_numbers[channel]);
00143          buffered_packet_count--;
00144       }
00145    }
00146    else
00147    {
00148       ingoing_unreliable_seq_numbers[channel] = packet->getSequenceNumber() + 1;
00149    }
00150    return next_packet;
00151 }
00152 
00153 template<class PacketType, class SocketType>
00154 void FrameworkSeqNoList<PacketType, SocketType>::bufferPacket( PacketType * packet )
00155 {
00156    int channel = getChannel(packet);
00157 
00158    //std::cout << "BufferPacket: " << *packet << std::endl;
00159    //std::cout << "ingoing_reliable_seq_numbers[channel]:" << ingoing_reliable_seq_numbers[channel] << std::endl;
00160    if(buffered_packets[channel].find(packet->getSequenceNumber()) != buffered_packets[channel].end())
00161    {
00162       // Duplicate future packet
00163       //std::cout << "Discard buffering of duplicate reliable packet" << std::endl;
00164       delete packet;
00165    }
00166    else
00167    {
00168       buffered_packets[channel].insert(std::make_pair(packet->getSequenceNumber(),packet));
00169       buffered_packet_count++;
00170    }
00171 }
00172 
00173 template<class PacketType, class SocketType>
00174 bool FrameworkSeqNoList<PacketType, SocketType>::isNext( PacketType * packet ) const
00175 {
00176    //std::cout << "isNext(seq:";
00177    //std::cout << getNextIngoingSeqNo(packet) <<" == "<<packet->getSequenceNumber()<<std::endl;
00178    return getNextIngoingSeqNo(packet) == packet->getSequenceNumber();
00179 }
00180 
00181 template<class PacketType, class SocketType>
00182 bool FrameworkSeqNoList<PacketType, SocketType>::isFuture( PacketType * packet ) const
00183 {
00184    //std::cout << "isFuture(seq:";
00185    //std::cout << getNextIngoingSeqNo(packet) <<" == "<<packet->getSequenceNumber()<<std::endl;
00186    return getNextIngoingSeqNo(packet) < packet->getSequenceNumber();
00187 }
00188 
00189 
00190 template<class PacketType, class SocketType>
00191 int FrameworkSeqNoList<PacketType, SocketType>::getChannel( const PacketType * packet )
00192 {
00193    return packet->isPluginPacket() ? 256 : (int)packet->getPriority();
00194 }
00195 
00196 
00197 
00198 #endif

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