Alex Bikfalvi
SimStream Documentation
HostClient.cpp
00001 #include "Headers.h" 00002 #include "HostClient.h" 00003 #include "EventClientWatch.h" 00004 #include "Console.h" 00005 #include "Debug.h" 00006 00007 CHostClient::CHostClient( 00008 __uint32 id, 00009 CSimHandler* sim, 00010 CAddress address, 00011 CInfo* info, 00012 CData* data, 00013 __bitrate bw 00014 ) : CHost(id, sim, address, info, data) 00015 { 00016 // Initial host state is off 00017 this->state = CHostClient::STATE_OFF; 00018 this->channel = NULL; 00019 00020 // Stat 00021 this->statFramesRecv = 0; 00022 this->statFramesDiscarded = 0; 00023 this->statFramesExpected = 0; 00024 } 00025 00026 CHostClient::~CHostClient() 00027 { 00028 } 00029 00030 void CHostClient::EventArrive() 00031 { 00032 assert(CHostClient::STATE_OFF == this->state); 00033 00034 // Change state to on-idle 00035 this->state = CHostClient::STATE_ON_IDLE; 00036 00037 // Start watching first channel 00038 // Generate next channel to watch 00039 __uint32 channel; 00040 __time duration; 00041 00042 this->info->ModelChannel()->GenerateUptime(channel, duration); 00043 00044 // Call the watch event 00045 this->EventWatch(this->info->Channel(channel), duration); 00046 } 00047 00048 void CHostClient::EventLeave() 00049 { 00050 assert(CHostClient::STATE_OFF != this->state); 00051 00052 if(CHostClient::STATE_ON_IDLE == this->state) 00053 // If host state is on-idle, change state to off 00054 this->state = CHostClient::STATE_OFF; 00055 else 00056 // If host state is on-watching, call disconnect method to terminate gracefully 00057 this->ChannelDisconnect(); 00058 } 00059 00060 void CHostClient::EventWatch(CChannel* channel, __time duration) 00061 { 00062 assert(STATE_OFF != this->state); 00063 00064 if(STATE_ON_IDLE == this->state) 00065 // If host state is on-idle, call connect method 00066 this->ChannelConnect(channel); 00067 else 00068 // If host state is on-watching, call switch method 00069 this->ChannelSwitch(channel); 00070 00071 // Schedule watching the next channel 00072 // Generate next channel to watch 00073 __uint32 newChannel; 00074 __time newDuration; 00075 00076 this->info->ModelChannel()->GenerateUptime(channel->Id(), duration, newChannel, newDuration); 00077 00078 // Schedule the watch event 00079 CEventClientWatch* evt = new CEventClientWatch( 00080 this, 00081 this->info->Channel(newChannel), 00082 newDuration); 00083 00084 this->sim->ScheduleEventAfter(duration, evt); 00085 } 00086 00087 void CHostClient::ChannelConnect(CChannel* channel) 00088 { 00089 assert(channel); 00090 assert(NULL == this->channel); 00091 00092 switch(channel->Type()) 00093 { 00094 case CChannel::CHANNEL_MULTICAST: this->ChannelConnectMcast(channel); break; 00095 case CChannel::CHANNEL_UNICAST: this->ChannelConnectUcast(channel); break; 00096 } 00097 00098 // Set session stat 00099 this->sessionTimeStart = this->sim->Time(); 00100 00101 // Save the channel 00102 this->channel = channel; 00103 00104 // Change the state 00105 this->state = CHostClient::STATE_ON_WATCHING; 00106 } 00107 00108 void CHostClient::ChannelDisconnect() 00109 { 00110 assert(this->channel); 00111 00112 switch(channel->Type()) 00113 { 00114 case CChannel::CHANNEL_MULTICAST: this->ChannelDisconnectMcast(); break; 00115 case CChannel::CHANNEL_UNICAST: this->ChannelDisconnectUcast(); break; 00116 } 00117 00118 // Set session stat 00119 this->sessionTimeFinish = this->sim->Time(); 00120 00121 // Set the channel 00122 this->channel = NULL; 00123 00124 // Change the state 00125 this->state = STATE_ON_IDLE; 00126 } 00127 00128 void CHostClient::ChannelSwitch(CChannel* channel) 00129 { 00130 CChannel* oldChannel = this->channel; 00131 00132 // Disconnect from old channels 00133 this->ChannelDisconnect(); 00134 00135 __uint32 statFramesExpected = (__uint32)(oldChannel->Fps() * (this->sessionTimeFinish - this->sessionTimeStart)); 00136 00137 this->data->Session( 00138 this->id, 00139 oldChannel->Id(), 00140 this->sessionTimeFinish - this->sessionTimeStart, 00141 this->streamClient->StatTimeClientStart(), 00142 this->streamClient->StatTimeRecvStart(), 00143 this->streamClient->StatTimePlayStart(), 00144 this->streamClient->StatTimeFinish(), 00145 this->streamClient->StatTimeWait(), 00146 this->streamClient->StatSyncDelay(), 00147 this->streamClient->StatRecvFrames(), 00148 this->streamClient->StatPlayFrames(), 00149 this->streamClient->StatSuccessFrames(), 00150 this->streamClient->StatFailFrames() 00151 ); 00152 00153 // Statistics 00154 this->statFramesRecv += this->streamClient->StatRecvFrames(); 00155 this->statFramesDiscarded += this->streamClient->StatDiscardedFrames(); 00156 this->statFramesExpected += statFramesExpected; 00157 00158 #if (defined(_RELEASEASSERT) || defined(_RELEASELOG) || defined(_DEBUG)) && (!defined(LOG)) 00159 00160 // Move before ChannelConnect() to display correct information 00161 double quality = ((this->streamClient->StatPlayFrames() != 0) ? ((double)( 00162 this->streamClient->StatSuccessFrames()[0] + 00163 this->streamClient->StatSuccessFrames()[1] + 00164 this->streamClient->StatSuccessFrames()[2] ) / 00165 (double)this->streamClient->StatPlayFrames()) : 0); 00166 00167 __time interrupt = (1 - quality) * (this->sessionTimeFinish - this->sessionTimeStart); 00168 bool play = this->streamClient->StatTimePlayStart() >= this->streamClient->StatTimeClientStart(); 00169 00170 //if(quality == 0) 00171 //{ 00172 // if(this->sessionTimeFinish - this->sessionTimeStart < 2.0) 00173 // CConsole::SetColor(CConsole::LIGHT_GREEN); 00174 // else 00175 // CConsole::SetColor(CConsole::LIGHT_RED); 00176 //} 00177 //else if(quality == 1) 00178 // CConsole::SetColor(CConsole::LIGHT_GRAY); 00179 //else if(quality < 0.9) 00180 // CConsole::SetColor(CConsole::LIGHT_MAGENTA); 00181 //else 00182 // CConsole::SetColor(CConsole::LIGHT_CYAN); 00183 00184 #ifndef LOG_VERBOSE 00185 switch(channel->Type()) 00186 { 00187 case CChannel::CHANNEL_MULTICAST: CConsole::SetColor(CConsole::LIGHT_CYAN); printf("\n[M] "); break; 00188 case CChannel::CHANNEL_UNICAST: CConsole::SetColor(CConsole::LIGHT_YELLOW); printf("\n[U] "); break; 00189 } 00190 00191 #endif 00192 00193 if(play) 00194 { 00195 if(interrupt == 0) CConsole::SetColor(CConsole::WHITE); 00196 else if(interrupt < 2) CConsole::SetColor(CConsole::LIGHT_GREEN); 00197 else if(interrupt < 4) CConsole::SetColor(CConsole::LIGHT_CYAN); 00198 else if(interrupt < 8) CConsole::SetColor(CConsole::LIGHT_YELLOW); 00199 else if(interrupt < 16) CConsole::SetColor(CConsole::LIGHT_MAGENTA); 00200 else CConsole::SetColor(CConsole::LIGHT_RED); 00201 } 00202 else 00203 { 00204 CConsole::SetColor(CConsole::LIGHT_BLUE); 00205 } 00206 00207 #ifdef LOG_VERBOSE 00208 #ifdef LOG 00209 if((this->address.Address() == LOG_ADDRESS) && (oldChannel->Id() == LOG_CHANNEL)) 00210 //#else 00211 // if(quality < 1) 00212 #endif 00213 printf("\nT = %8.3lf P = %4u C = %3u D = %5.0lf S = %u | %4u %4u %4d | %4u %4u %4u | %4u %4u %4u | %7.3lf %7.3lf %7.3lf %7.3lf %7.3lf %7.3lf | %.3lf %7.1lf", 00214 this->sim->Time(), 00215 this->address.Address(), 00216 oldChannel->Id(), 00217 this->sessionTimeFinish - this->sessionTimeStart, 00218 // Session time 00219 play, 00220 // Frames 00221 this->streamClient->StatRecvFrames(), 00222 this->streamClient->StatPlayFrames(), 00223 this->streamClient->StatRecvFrames() - this->streamClient->StatPlayFrames(), 00224 // Success frames 00225 this->streamClient->StatSuccessFrames()[0], 00226 this->streamClient->StatSuccessFrames()[1], 00227 this->streamClient->StatSuccessFrames()[2], 00228 // Failed frames 00229 this->streamClient->StatFailFrames()[0], 00230 this->streamClient->StatFailFrames()[1], 00231 this->streamClient->StatFailFrames()[2], 00232 // Session times (verbose) 00233 this->streamClient->StatTimeClientStart(), 00234 this->streamClient->StatTimeRecvStart(), 00235 this->streamClient->StatTimePlayStart(), 00236 this->streamClient->StatTimeFinish(), 00237 this->streamClient->StatTimeWait(), 00238 this->streamClient->StatSyncDelay(), 00239 // Quality 00240 quality, 00241 interrupt 00242 ); 00243 #else 00244 printf("T = %8.3lf PEER %4u WATCHED %3u for %5.0lf (%5.0lf - %5.0lf) | %7.3lf %7.3lf %7.3lf %7.3lf %7.3lf | %.3lf %7.1lf | %6.3lf", 00245 this->sim->Time(), 00246 this->address.Address(), 00247 oldChannel->Id(), 00248 this->sessionTimeFinish - this->sessionTimeStart, 00249 // Session time 00250 this->sessionTimeStart, 00251 this->sessionTimeFinish, 00252 // Session times (verbose) 00253 this->streamClient->StatTimeClientStart(), 00254 this->streamClient->StatTimeRecvStart(), 00255 this->streamClient->StatTimePlayStart(), 00256 this->streamClient->StatTimeFinish(), 00257 this->streamClient->StatTimeWait(), 00258 // Quality 00259 quality, 00260 interrupt, 00261 // Delay 00262 this->streamClient->StatSyncDelay() 00263 ); 00264 #endif 00265 00266 CConsole::SetColor(CConsole::LIGHT_GRAY); 00267 #endif 00268 00269 // Connect to new channel 00270 this->ChannelConnect(channel); 00271 } 00272 00273 void CHostClient::Finalize() 00274 { 00275 // Call the base class finalizer 00276 CHost::Finalize(); 00277 }
Last updated: February 8, 2011