From: g0dil Date: Tue, 4 May 2010 22:12:40 +0000 (+0000) Subject: Packets: Packet Registry unregister() support X-Git-Url: http://g0dil.de/git?p=senf.git;a=commitdiff_plain;h=3e2082d6966ef4e61ff8a2070b157251e5cb08a6 Packets: Packet Registry unregister() support git-svn-id: https://svn.berlios.de/svnroot/repos/senf/trunk@1619 270642c3-0616-0410-b53a-bc976706d245 --- diff --git a/.project.el b/.project.el index b691d2a..307ad27 100644 --- a/.project.el +++ b/.project.el @@ -71,8 +71,8 @@ checks for C/C++ preproc directives. Additionally, anything after ^L is ignored (Those are the file local variables and local words)." (let ((f (get-text-property (point) 'face))) (and (memq f flyspell-prog-text-faces) - (not (save-excursion - (beginning-of-line) + (not (save-excursion + (beginning-of-line) (looking-at "\\(//\\)?#"))) (not (let ((l (max (point-min) (- (point-max) 4096)))) (and (< l (point)) @@ -101,7 +101,10 @@ is ignored (Those are the file local variables and local words)." (add-hook 'ccide-new-file-hooks 'senf-new-file-hook nil t) +(setq indent-tabs-mode nil) ;; needed since whitespace-mode caches this value ... +(whitespace-mode 1) + -// Local Variables: -// indent-tabs-mode: nil -// End: +;; Local Variables: +;; indent-tabs-mode: nil +;; End: diff --git a/senf/Packets/PacketRegistry.ct b/senf/Packets/PacketRegistry.ct index b4babcc..0048815 100644 --- a/senf/Packets/PacketRegistry.ct +++ b/senf/Packets/PacketRegistry.ct @@ -53,6 +53,13 @@ prefix_ std::string senf::detail::PkReg_EntryImpl::name() return prettyName(typeid(PacketType)); } +template +prefix_ senf::TypeIdValue senf::detail::PkReg_EntryImpl::typeIdValue() + const +{ + return typeid(PacketType); +} + /////////////////////////////////////////////////////////////////////////// // senf::PacketRegistry @@ -89,6 +96,30 @@ prefix_ void senf::detail::PacketRegistryImpl::registerPacket(key_t key } template +template +prefix_ void senf::detail::PacketRegistryImpl::unregisterPacket() +{ + typename PacketMap::iterator i (registry_.find(key(typeIdValue()))); + typename ReversePacketMap::iterator j (reverseRegistry_.find(typeIdValue())); + if (i != registry_.end()) + registry_.erase(i); + if (j != reverseRegistry_.end()) + reverseRegistry_.erase(j); +} + +template +prefix_ void senf::detail::PacketRegistryImpl::unregisterPacket(key_t key) +{ + typename PacketMap::iterator i (registry_.find(key)); + if (i == registry_.end()) + throw PacketTypeNotRegisteredException(); + typename ReversePacketMap::iterator j (reverseRegistry_.find(i->second->typeIdValue())); + registry_.erase(i); + if (j != reverseRegistry_.end()) + reverseRegistry_.erase(j); +} + +template prefix_ typename senf::detail::PacketRegistryImpl::key_t senf::detail::PacketRegistryImpl::key(senf::TypeIdValue const & type) { diff --git a/senf/Packets/PacketRegistry.cti b/senf/Packets/PacketRegistry.cti index 2a519b5..a99c59b 100644 --- a/senf/Packets/PacketRegistry.cti +++ b/senf/Packets/PacketRegistry.cti @@ -41,6 +41,17 @@ RegistrationProxy(typename Tag::key_t key) PacketRegistry::template registerPacket(key); } +template +template +prefix_ senf::PacketRegistry::RegistrationProxy::~RegistrationProxy() +{ + try { + PacketRegistry::template unregisterPacket(); + } + catch (PacketTypeNotRegisteredException & ex) + {} +} + /////////////////////////////////////////////////////////////////////////// // senf::PacketRegistry @@ -53,6 +64,19 @@ prefix_ void senf::PacketRegistry::registerPacket(typename Tag::key_t key) template template +prefix_ void senf::PacketRegistry::unregisterPacket() +{ + registry().unregisterPacket(); +} + +template +prefix_ void senf::PacketRegistry::unregisterPacket(typename Tag::key_t key) +{ + registry().unregisterPacket(key); +} + +template +template prefix_ typename Tag::key_t senf::PacketRegistry::key() { return registry().key(senf::typeIdValue()); diff --git a/senf/Packets/PacketRegistry.hh b/senf/Packets/PacketRegistry.hh index fe21ab5..e766914 100644 --- a/senf/Packets/PacketRegistry.hh +++ b/senf/Packets/PacketRegistry.hh @@ -109,6 +109,7 @@ namespace senf { struct RegistrationProxy { RegistrationProxy(typename Tag::key_t key); + ~RegistrationProxy(); }; /** \brief Register new packet type @@ -126,6 +127,10 @@ namespace senf { template static void registerPacket(typename Tag::key_t key); + template + static void unregisterPacket(); + static void unregisterPacket(typename Tag::key_t key); + /** \brief Find key of a packet type Return the key of \a PacketType as registered in the \a Tag registry @@ -245,4 +250,3 @@ namespace senf { // compile-command: "scons -u test" // comment-column: 40 // End: - diff --git a/senf/Packets/PacketRegistry.ih b/senf/Packets/PacketRegistry.ih index 169d275..a1d66ba 100644 --- a/senf/Packets/PacketRegistry.ih +++ b/senf/Packets/PacketRegistry.ih @@ -48,6 +48,7 @@ namespace senf { virtual Packet::factory_t factory() const = 0; ///< Get factory of the registered packet type virtual std::string name() const = 0; + virtual TypeIdValue typeIdValue() const = 0; }; namespace detail { @@ -62,6 +63,7 @@ namespace detail { { virtual Packet::factory_t factory() const; virtual std::string name() const; + virtual TypeIdValue typeIdValue() const ; }; /** \brief Internal: Registry implementation base-class and registry of registries @@ -123,6 +125,10 @@ namespace detail { template void registerPacket(key_t key); + template + void unregisterPacket(); + void unregisterPacket(key_t key); + key_t key(senf::TypeIdValue const & type); boost::optional key(senf::TypeIdValue const & type, bool); diff --git a/senf/Packets/PacketRegistry.test.cc b/senf/Packets/PacketRegistry.test.cc index 9c596e9..ddb1088 100644 --- a/senf/Packets/PacketRegistry.test.cc +++ b/senf/Packets/PacketRegistry.test.cc @@ -56,48 +56,93 @@ namespace { struct OtherPacketType : public PacketTypeBase {}; typedef senf::ConcretePacket OtherPacket; + bool contains(std::string a, std::string b) + { return a.find(b) != std::string::npos; } + + bool contains_not(std::string a, std::string b) + { return a.find(b) == std::string::npos; } + } SENF_PACKET_REGISTRY_REGISTER(StringTag, "foo", FooPacket); -SENF_PACKET_REGISTRY_REGISTER(StringTag, "bar", BarPacket); SENF_AUTO_UNIT_TEST(packetRegistry_test) { - PacketRegistry::registerPacket(1u); - PacketRegistry::registerPacket(2u); - - BOOST_CHECK_EQUAL( PacketRegistry::key(), 1u ); - BOOST_CHECK_EQUAL( PacketRegistry::key(), 2u ); - BOOST_CHECK_THROW( PacketRegistry::key(), - PacketTypeNotRegisteredException ); - - BOOST_CHECK_EQUAL( PacketRegistry::key(), "foo" ); - BOOST_CHECK( ! PacketRegistry::lookup("blub", senf::nothrow) ); - BOOST_CHECK( PacketRegistry::lookup(1u, senf::nothrow) ); - - unsigned elts1[] = { 1u, 2u }; - BOOST_CHECK_EQUAL_COLLECTIONS( PacketRegistry::begin(), PacketRegistry::end(), - elts1+0, elts1+sizeof(elts1)/sizeof(elts1[0]) ); - - std::string elts2[] = { "bar", "foo" }; - BOOST_CHECK_EQUAL_COLLECTIONS( PacketRegistry::begin(), PacketRegistry::end(), - elts2+0, elts2+sizeof(elts2)/sizeof(elts2[0]) ); - - std::stringstream s; - senf::dumpPacketRegistries(s); - BOOST_CHECK_EQUAL( s.str(), - "(anonymous namespace)::BaseTag:\n" - " 0x00000001 ( 1) (....) (anonymous namespace)::FooPacketType\n" - " 0x00000002 ( 2) (....) (anonymous namespace)::BarPacketType\n" - "\n" - "(anonymous namespace)::RegTag:\n" - " 0x00000001 ( 1) (....) (anonymous namespace)::FooPacketType\n" - " 0x00000002 ( 2) (....) (anonymous namespace)::BarPacketType\n" - "\n" - "(anonymous namespace)::StringTag:\n" - " bar (anonymous namespace)::BarPacketType\n" - " foo (anonymous namespace)::FooPacketType\n" - "\n" ); + { + PacketRegistry::registerPacket("bar"); + PacketRegistry::registerPacket(1u); + senf::PacketRegistry::RegistrationProxy registerBarInBase (2u); + + BOOST_CHECK_EQUAL( PacketRegistry::key(), 1u ); + BOOST_CHECK_EQUAL( PacketRegistry::key(), 2u ); + BOOST_CHECK_THROW( PacketRegistry::key(), + PacketTypeNotRegisteredException ); + + BOOST_CHECK_EQUAL( PacketRegistry::key(), "foo" ); + BOOST_CHECK( ! PacketRegistry::lookup("blub", senf::nothrow) ); + BOOST_CHECK( PacketRegistry::lookup(1u, senf::nothrow) ); + + unsigned elts1[] = { 1u, 2u }; + BOOST_CHECK_EQUAL_COLLECTIONS( PacketRegistry::begin(), + PacketRegistry::end(), + elts1+0, elts1+sizeof(elts1)/sizeof(elts1[0]) ); + + std::string elts2[] = { "bar", "foo" }; + BOOST_CHECK_EQUAL_COLLECTIONS( PacketRegistry::begin(), + PacketRegistry::end(), + elts2+0, elts2+sizeof(elts2)/sizeof(elts2[0]) ); + + std::stringstream s; + senf::dumpPacketRegistries(s); + BOOST_CHECK_PREDICATE( + contains, + (s.str()) + ("(anonymous namespace)::BaseTag:\n" + " 0x00000001 ( 1) (....) (anonymous namespace)::FooPacketType\n" + " 0x00000002 ( 2) (....) (anonymous namespace)::BarPacketType\n" + "\n")); + BOOST_CHECK_PREDICATE( + contains, + (s.str()) + ("(anonymous namespace)::StringTag:\n" + " bar (anonymous namespace)::BarPacketType\n" + " foo (anonymous namespace)::FooPacketType\n" + "\n" )); + } + + { + std::stringstream s; + senf::dumpPacketRegistries(s); + BOOST_CHECK_PREDICATE( + contains, + (s.str()) + ("(anonymous namespace)::BaseTag:\n" + " 0x00000001 ( 1) (....) (anonymous namespace)::FooPacketType\n" + "\n")); + BOOST_CHECK_PREDICATE( + contains, + (s.str()) + ("(anonymous namespace)::StringTag:\n" + " bar (anonymous namespace)::BarPacketType\n" + " foo (anonymous namespace)::FooPacketType\n" + "\n" )); + + SENF_CHECK_NO_THROW( PacketRegistry::unregisterPacket(1u) ); + SENF_CHECK_NO_THROW( PacketRegistry::unregisterPacket() ); + + s.str(""); + senf::dumpPacketRegistries(s); + BOOST_CHECK_PREDICATE( + contains_not, + (s.str()) + ("(anonymous namespace)::BaseTag:\n")); + BOOST_CHECK_PREDICATE( + contains, + (s.str()) + ("(anonymous namespace)::StringTag:\n" + " foo (anonymous namespace)::FooPacketType\n" + "\n" )); + } } ///////////////////////////////cc.e////////////////////////////////////////