From: <sv...@ww...> - 2004-12-18 11:28:23
|
Author: mkrose Date: 2004-12-18 03:28:17 -0800 (Sat, 18 Dec 2004) New Revision: 1407 Modified: trunk/CSP/SimCore/Battlefield/LocalBattlefield.cpp trunk/CSP/SimCore/Battlefield/LocalBattlefield.h trunk/CSP/SimCore/SConscript Log: Add player join and quit signals to allow the main sim to trigger actions on these events. This change makes SimCore depend on libsigc++-1.2. ==>WINDOWS users: add libsigc++-1.2 to the SimCore build. Browse at: https://www.zerobar.net/viewcvs/viewcvs.cgi?view=rev&rev=1407 Modified: trunk/CSP/SimCore/Battlefield/LocalBattlefield.cpp =================================================================== --- trunk/CSP/SimCore/Battlefield/LocalBattlefield.cpp 2004-12-18 11:05:26 UTC (rev 1406) +++ trunk/CSP/SimCore/Battlefield/LocalBattlefield.cpp 2004-12-18 11:28:17 UTC (rev 1407) @@ -26,6 +26,7 @@ #include <SimCore/Battlefield/Battlefield.h> #include <SimCore/Battlefield/SceneManager.h> #include <SimCore/Util/SynchronousUpdate.h> +#include <SimCore/Util/Callback.h> #include <SimNet/ClientServer.h> #include <SimNet/DispatchHandler.h> @@ -195,7 +196,9 @@ m_ServerTimeOffset(0), m_ScanElapsedTime(0), m_ScanRate(0), - m_ScanIndex(0) + m_ScanIndex(0), + m_PlayerJoinSignal(new simcore::Signal2<int, const std::string&>()), + m_PlayerQuitSignal(new simcore::Signal2<int, const std::string&>()) { // if no network connection, ids will be assigned sequentially // starting at 1024. otherwise, the id pool is initialized when @@ -369,28 +372,42 @@ void LocalBattlefield::onPlayerQuit(simdata::Ref<PlayerQuit> const &msg, simdata::Ref<simnet::MessageQueue> const &) { SIMNET_LOG(MESSAGE, INFO, *msg); const PeerId id = msg->peer_id(); + PlayerInfoMap::iterator iter = m_PlayerInfoMap.find(id); + if (iter != m_PlayerInfoMap.end()) { + CSP_LOG(BATTLEFIELD, INFO, iter->second->GetName() << " just quit the game! (id " << id << ")"); + m_PlayerQuitSignal->emit(id, iter->second->GetName()); + m_PlayerInfoMap.erase(iter); + } else { + CSP_LOG(BATTLEFIELD, WARNING, "received quit message for unmapped peer " << id); + } if (m_NetworkClient->getPeer(id)) { - PlayerInfoMap::iterator iter = m_PlayerInfoMap.find(id); - if (iter != m_PlayerInfoMap.end()) { - CSP_LOG(BATTLEFIELD, INFO, iter->second->GetName() << " just quit the game!"); - m_PlayerInfoMap.erase(iter); - } m_NetworkClient->disconnectPeer(id); // the global battlefield should send separate messages to remove // all objects owned by this peer + } else { + CSP_LOG(BATTLEFIELD, WARNING, "received quit message for unknown peer " << id); } } +void LocalBattlefield::registerPlayerJoinCallback(simcore::Callback2<int, const std::string&> &callback) { + m_PlayerJoinSignal->connect(callback); +} + +void LocalBattlefield::registerPlayerQuitCallback(simcore::Callback2<int, const std::string&> &callback) { + m_PlayerQuitSignal->connect(callback); +} + void LocalBattlefield::onPlayerJoin(simdata::Ref<PlayerJoin> const &msg, simdata::Ref<simnet::MessageQueue> const &) { SIMNET_LOG(MESSAGE, INFO, *msg); const PeerId id = msg->peer_id(); if (!m_NetworkClient->getPeer(id)) { - CSP_LOG(BATTLEFIELD, INFO, msg->user_name() << " just joined the game!"); const simnet::NetworkNode remote_node(msg->ip_addr(), msg->port()); + CSP_LOG(BATTLEFIELD, INFO, msg->user_name() << " just joined the game! (id " << id << ", ip " << remote_node << ")"); const int incoming_bw = msg->incoming_bw(); const int outgoing_bw = msg->outgoing_bw(); m_PlayerInfoMap[id] = new PlayerInfo(id, msg->user_name()); m_NetworkClient->addPeer(id, remote_node, incoming_bw, outgoing_bw); + m_PlayerJoinSignal->emit(id, msg->user_name()); } } @@ -731,21 +748,31 @@ const int detail = m_PeerUpdates[n_updates - 1].detail; assert(detail >=0 && detail < DETAIL_LEVELS); + // the object may choose to skip an update due to low estimated error + bool skipped = false; + // ok to use slightly stale messages. note that if we refresh the cache for any // peer, all other peers at that detail level will get the new message. if (m_UpdateTime - m_DetailCache[detail].last_refresh > interval / 10) { // FIXME the state message will be used for multiple peers that are updated at different // intervals, so the content should not depend on interval. simnet::NetworkMessage::Ref msg = m_Wrapper->unit()->getState(timestamp, 0 /*interval*/, detail); - msg->setRoutingType(ROUTE_UNIT_UPDATE); - msg->setRoutingData(m_Wrapper->id()); - msg->setPriority(2); // XXX msg/detail dependent? - m_DetailCache[detail].msg = msg; - m_DetailCache[detail].last_refresh = m_UpdateTime; + if (msg.valid()) { + msg->setRoutingType(ROUTE_UNIT_UPDATE); + msg->setRoutingData(m_Wrapper->id()); + msg->setPriority(2); // XXX msg/detail dependent? + m_DetailCache[detail].msg = msg; + m_DetailCache[detail].last_refresh = m_UpdateTime; + } else { + skipped = true; + } } - // hack for sorting by detail level, see below - targets[target_count++] = (detail << 24) | m_PeerUpdates[n_updates - 1].id; + if (!skipped) { + // hack for sorting by detail level, see below + targets[target_count++] = (detail << 24) | m_PeerUpdates[n_updates - 1].id; + } + std::push_heap(m_PeerUpdates.begin(), m_PeerUpdates.end()); } @@ -769,7 +796,7 @@ } void LocalBattlefield::UnitUpdateProxy::setUpdateParameters(PeerId id, double interval, simdata::uint16 detail) { - assert(detail >= 0 && detail < DETAIL_LEVELS); + assert(detail < DETAIL_LEVELS); simdata::uint16 interval_ms = static_cast<simdata::uint16>(interval * 1000.0); const unsigned n = m_PeerUpdates.size(); for (unsigned i = 0; i < n; ++i) { Modified: trunk/CSP/SimCore/Battlefield/LocalBattlefield.h =================================================================== --- trunk/CSP/SimCore/Battlefield/LocalBattlefield.h 2004-12-18 11:05:26 UTC (rev 1406) +++ trunk/CSP/SimCore/Battlefield/LocalBattlefield.h 2004-12-18 11:28:17 UTC (rev 1407) @@ -30,9 +30,8 @@ #include <SimCore/Battlefield/Battlefield.h> #include <SimCore/Battlefield/BattlefieldMessages.h> +#include <SimCore/Util/CallbackDecl.h> -#include <SimNet/NetworkNode.h> // XXX forward declare InetHostAddress - class SceneManager; class UpdateMaster; @@ -87,6 +86,9 @@ return m_ConnectionState == CONNECTION_ACTIVE; } + void registerPlayerJoinCallback(simcore::Callback2<int, const std::string&> &callback); + void registerPlayerQuitCallback(simcore::Callback2<int, const std::string&> &callback); + private: struct ObjectIdPool; @@ -185,6 +187,9 @@ void scanUnit(LocalUnitWrapper *wrapper); void continueUnitScan(double dt); + + simdata::ScopedPointer<simcore::Signal2<int, const std::string&> > m_PlayerJoinSignal; + simdata::ScopedPointer<simcore::Signal2<int, const std::string&> > m_PlayerQuitSignal; }; Modified: trunk/CSP/SimCore/SConscript =================================================================== --- trunk/CSP/SimCore/SConscript 2004-12-18 11:05:26 UTC (rev 1406) +++ trunk/CSP/SimCore/SConscript 2004-12-18 11:28:17 UTC (rev 1407) @@ -23,8 +23,18 @@ 'Util', ] +def PackageConfig(env): + print '<< SimCore Config >>' + conf = build.CustomConfigure(env) + conf.CheckPkgConfig('sigc++-1.2', version='1.2.5', lib_name='sigc') + env = conf.Finish() + env.ParseConfig('pkg-config --cflags --libs sigc++-1.2') + env = env.Copy() +env.SetConfig(PackageConfig) + OBJECTS = build.BuildModules(env, MODULES) libsimcore = env.StaticLibrary('simcore', OBJECTS) Alias(['all', 'simcore'], [libsimcore]) + |