Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034 #include "srv-players.h"
00035
00036 #include "common/wave_ex.h"
00037
00038 #include "threadsafe/smart_mutex.h"
00039
00040
00041 namespace aesop {
00042
00043
00044 PlayerManager::~PlayerManager(void) throw() { }
00045
00046
00047
00048
00050
00051
00052
00054
00055 class PlayerMgr : public PlayerManager {
00056 public:
00057 PlayerMgr(void) throw();
00058 ~PlayerMgr(void) throw() { }
00059
00060
00061 void initialize(IN smart_ptr<UserManager>& userMgr);
00062
00063
00064 void updatePlayer(IN player_rec_t& pr);
00065 bool getPlayerByHostAndPlayerId(IN conn_id_t udpConnId,
00066 IN int playerId,
00067 OUT player_rec_t& pr);
00068 void getIterator(IN conn_id_t udpConnId, OUT iterator_t& iterator);
00069 bool getNextPlayer(IO iterator_t& iterator,
00070 OUT player_rec_t& pr);
00071
00072 private:
00073
00074 typedef std::map<int, player_rec_t> player_map_t;
00075 struct host_rec_t {
00076 host_rec_t(void) throw() { playerRvn = 0; }
00077
00078 player_map_t players;
00079 long playerRvn;
00080 };
00081
00082 typedef std::map<conn_id_t, smart_ptr<host_rec_t> > host_map_t;
00083
00084 struct real_iter_t {
00085 conn_id_t udpConnId;
00086 dword_t rvn;
00087 bool playerValid;
00088 host_map_t::iterator hostIter;
00089 player_map_t::iterator playerIter;
00090 };
00091
00092
00093 host_rec_t * getHostRecord(IN conn_id_t udpConnId,
00094 IN bool createIfNecessary = false);
00095 player_rec_t * getPlayerRecord(IN host_rec_t * hr,
00096 IN int playerId,
00097 IN bool createIfNecessary = false);
00098 static real_iter_t * castIterator(IN iterator_t& i) throw()
00099 { return (real_iter_t *) &i; }
00100
00101
00102 smart_mutex m_mutex;
00103 smart_ptr<UserManager> m_userMgr;
00104 host_map_t m_hosts;
00105 dword_t m_rvn;
00106 };
00107
00108
00109
00110 PlayerMgr::PlayerMgr(void)
00111 throw()
00112 {
00113 m_rvn = 0;
00114 }
00115
00116
00117
00118 void
00119 PlayerMgr::initialize
00120 (
00121 IN smart_ptr<UserManager>& userMgr
00122 )
00123 {
00124 ASSERT(userMgr, "null");
00125
00126
00127 m_userMgr = userMgr;
00128
00129
00130 ASSERT2(sizeof(iterator_t) >= sizeof(real_iter_t),
00131 "public iterator is too small! " << sizeof(iterator_t)
00132 << " bytes vs. " << sizeof(real_iter_t) << " bytes.");
00133 }
00134
00135
00136
00138
00139
00140
00142
00143 void
00144 PlayerMgr::updatePlayer
00145 (
00146 IN player_rec_t& pr
00147 )
00148 {
00149 ASSERT(pr.udpConnId, "null");
00150 ASSERT(pr.playerId > 0, "bad player id: %d", pr.playerId);
00151
00152
00153 mlock l(m_mutex);
00154
00155
00156 host_rec_t * hr = this->getHostRecord(pr.udpConnId, true);
00157 ASSERT(hr, "failed to create host record?");
00158
00159
00160 player_rec_t * prec = this->getPlayerRecord(hr, pr.playerId, true);
00161 ASSERT(prec, "failed to create player record?");
00162
00163
00164 *prec = pr;
00165 }
00166
00167
00168
00169 bool
00170 PlayerMgr::getPlayerByHostAndPlayerId
00171 (
00172 IN conn_id_t udpConnId,
00173 IN int playerId,
00174 OUT player_rec_t& pr
00175 )
00176 {
00177 ASSERT(udpConnId, "null");
00178 ASSERT(playerId > 0, "Bad player id: %d", playerId);
00179
00180 pr.clear();
00181
00182
00183 mlock l(m_mutex);
00184
00185
00186 host_rec_t * hr = this->getHostRecord(udpConnId);
00187 if (!hr)
00188 return false;
00189
00190
00191 player_rec_t * rec = this->getPlayerRecord(hr, playerId);
00192 if (!rec)
00193 return false;
00194
00195
00196 pr = *rec;
00197 return true;
00198 }
00199
00200
00201
00202 void
00203 PlayerMgr::getIterator
00204 (
00205 IN conn_id_t udpConnId,
00206 OUT iterator_t& iterator
00207 )
00208 {
00209
00210 real_iter_t * ri = castIterator(iterator);
00211 ASSERT(ri, "null");
00212
00213
00214 mlock l(m_mutex);
00215
00216
00217 ri->udpConnId = udpConnId;
00218 ri->rvn = m_rvn;
00219 ri->playerValid = false;
00220
00221 if (udpConnId) {
00222 ri->hostIter = m_hosts.find(udpConnId);
00223 } else {
00224 ri->hostIter = m_hosts.begin();
00225 }
00226 }
00227
00228
00229
00230 bool
00231 PlayerMgr::getNextPlayer
00232 (
00233 IO iterator_t& iterator,
00234 OUT player_rec_t& pr
00235 )
00236 {
00237 pr.clear();
00238
00239 real_iter_t * ri = castIterator(iterator);
00240 ASSERT(ri, "null");
00241
00242
00243 mlock l(m_mutex);
00244
00245
00246
00247
00248
00249
00250
00251
00252
00253
00254
00255
00256
00257
00258
00259 if (ri->rvn != m_rvn)
00260 return false;
00261
00262
00263 for (;;) {
00264
00265 if (m_hosts.end() == ri->hostIter)
00266 return false;
00267
00268
00269 host_rec_t * hr = ri->hostIter->second;
00270 ASSERT(hr, "null host record in map?");
00271
00272
00273 if (!ri->playerValid) {
00274 ri->playerIter = hr->players.begin();
00275 ri->playerValid = true;
00276 }
00277
00278
00279 if (hr->players.end() != ri->playerIter) {
00280
00281 pr = ri->playerIter->second;
00282 ++ri->playerIter;
00283 return true;
00284 }
00285
00286
00287
00288 if (ri->udpConnId) {
00289
00290 return false;
00291 }
00292
00293
00294 ri->playerValid = false;
00295 ++ri->hostIter;
00296 }
00297
00298
00299 ASSERT(false, "invalid");
00300 return false;
00301 }
00302
00303
00304
00306
00307
00308
00310
00311 PlayerMgr::host_rec_t *
00312 PlayerMgr::getHostRecord
00313 (
00314 IN conn_id_t udpConnId,
00315 IN bool createIfNecessary
00316 )
00317 {
00318 ASSERT(udpConnId, "null");
00319
00320 host_map_t::iterator i = m_hosts.find(udpConnId);
00321 if (m_hosts.end() == i) {
00322 if (!createIfNecessary)
00323 return NULL;
00324
00325
00326 ++m_rvn;
00327
00328 smart_ptr<host_rec_t> hr = new host_rec_t;
00329 ASSERT(hr, "null");
00330
00331 m_hosts[udpConnId] = hr;
00332 return hr;
00333 }
00334 host_rec_t * phr = i->second;
00335 ASSERT(phr, "null host record in map");
00336 return phr;
00337 }
00338
00339
00340
00341 player_rec_t *
00342 PlayerMgr::getPlayerRecord
00343 (
00344 IN host_rec_t * hr,
00345 IN int playerId,
00346 IN bool createIfNecessary
00347 )
00348 {
00349 ASSERT(hr, "null");
00350 ASSERT(playerId > 0, "Bad player id: %d", playerId);
00351
00352 player_map_t::iterator i = hr->players.find(playerId);
00353 if (hr->players.end() == i) {
00354 if (!createIfNecessary)
00355 return NULL;
00356
00357
00358 ++m_rvn;
00359
00360 player_rec_t pr;
00361 hr->players[playerId] = pr;
00362 return &hr->players[playerId];
00363 }
00364 return &i->second;
00365 }
00366
00367
00368
00370
00371
00372
00374
00375 smart_ptr<PlayerManager>
00376 PlayerManager::create
00377 (
00378 IN smart_ptr<UserManager>& userMgr
00379 )
00380 {
00381 ASSERT(userMgr, "null");
00382
00383 smart_ptr<PlayerMgr> local = new PlayerMgr;
00384 ASSERT(local, "out of memory");
00385
00386 local->initialize(userMgr);
00387
00388 return local;
00389 }
00390
00391
00392
00393 };
00394