Created
January 6, 2012 05:59
-
-
Save j0sh/1569246 to your computer and use it in GitHub Desktop.
Add to protocol factory at runtime.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| From 884e6614fbe3dffec655ca6f24ced224bc25cb43 Mon Sep 17 00:00:00 2001 | |
| From: Josh Allmann <joshua.allmann@gmail.com> | |
| Date: Wed, 11 Jan 2012 00:39:48 -0800 | |
| Subject: [PATCH 0/2] BaseProtocolFactory simplifications | |
| This patchset removes the need to subclass BaseProtocolFactory. | |
| Protocols can now be added to a factory instance at runtime | |
| before being registered with the factory manager. This greatly | |
| reduces the amount of boilerplate needed to add new protocols. | |
| Josh Allmann (2): | |
| Make BaseProtocolFactory non-abstract and modifiable at runtime. | |
| Convert samplefactory to use simplified protocol factory. | |
| .../samplefactory/include/protocolfactory.h | 44 --------- | |
| .../samplefactory/src/protocolfactory.cpp | 95 -------------------- | |
| .../samplefactory/src/samplefactory.cpp | 17 +++- | |
| .../thelib/include/protocols/baseprotocolfactory.h | 27 +++++- | |
| .../thelib/src/protocols/baseprotocolfactory.cpp | 46 ++++++++++ | |
| 5 files changed, 84 insertions(+), 145 deletions(-) | |
| delete mode 100644 sources/applications/samplefactory/include/protocolfactory.h | |
| delete mode 100644 sources/applications/samplefactory/src/protocolfactory.cpp | |
| -- | |
| 1.7.5.4 |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| From 6c04576a2685d922778b8dd268cadcc31f236421 Mon Sep 17 00:00:00 2001 | |
| From: Josh Allmann <joshua.allmann@gmail.com> | |
| Date: Wed, 11 Jan 2012 00:34:16 -0800 | |
| Subject: [PATCH 1/2] Make BaseProtocolFactory non-abstract and modifiable at | |
| runtime. | |
| --- | |
| .../thelib/include/protocols/baseprotocolfactory.h | 27 ++++++++++-- | |
| .../thelib/src/protocols/baseprotocolfactory.cpp | 46 ++++++++++++++++++++ | |
| 2 files changed, 69 insertions(+), 4 deletions(-) | |
| diff --git a/sources/thelib/include/protocols/baseprotocolfactory.h b/sources/thelib/include/protocols/baseprotocolfactory.h | |
| index bcb0c0c..2cdf4d9 100644 | |
| --- a/sources/thelib/include/protocols/baseprotocolfactory.h | |
| +++ b/sources/thelib/include/protocols/baseprotocolfactory.h | |
| @@ -23,6 +23,11 @@ | |
| #include "common.h" | |
| +#define PROTOCOL_CONSTRUCTOR(type) \ | |
| + static BaseProtocol* new_##type() { \ | |
| + return new type(); \ | |
| + } | |
| + | |
| class BaseProtocol; | |
| /*! | |
| @@ -33,6 +38,10 @@ class DLLEXP BaseProtocolFactory { | |
| private: | |
| static uint32_t _idGenerator; | |
| uint32_t _id; | |
| + | |
| + typedef BaseProtocol*(*ConstructorType)(); | |
| + map<string, vector<uint64_t> > _protocols; | |
| + map<uint64_t, ConstructorType> _constructors; | |
| public: | |
| /*! | |
| @brief Constructor: Increments the _idGenerator parameter. | |
| @@ -48,22 +57,32 @@ public: | |
| /*! | |
| @brief Function that will contain all the protocols that will be handled by the factory. | |
| */ | |
| - virtual vector<uint64_t> HandledProtocols() = 0; | |
| + virtual vector<uint64_t> HandledProtocols(); | |
| /*! | |
| @brief Function that will contain all the protocol chains that will be handled by the factory. | |
| */ | |
| - virtual vector<string> HandledProtocolChains() = 0; | |
| + virtual vector<string> HandledProtocolChains(); | |
| /*! | |
| @brief This functions is where the protocol chains whose names are all defined, are resolved. | |
| @param name: The name given to the protocol chain. | |
| */ | |
| - virtual vector<uint64_t> ResolveProtocolChain(string name) = 0; | |
| + virtual vector<uint64_t> ResolveProtocolChain(string name); | |
| /*! | |
| @brief This function is where protocols are spawned. | |
| @param type: The protocol to be spawned. | |
| @param parameters: Each protocol can have parameters. This is optional. | |
| */ | |
| - virtual BaseProtocol *SpawnProtocol(uint64_t type, Variant ¶meters) = 0; | |
| + virtual BaseProtocol *SpawnProtocol(uint64_t type, Variant ¶meters); | |
| + | |
| + /*! | |
| + @brief Add a new protocol to the factory. | |
| + @param name: Name of the protocol. | |
| + @param constructor: Function returning an instance of the protocol. | |
| + @param chain_length number of levels in the protocol chain. | |
| + @param varargs The protocol chain proper, uint64_t typesd. | |
| + */ | |
| + virtual void AddProtocol(const string &name, BaseProtocol*(*constructor)(), int chain_length, ...); | |
| + | |
| }; | |
| #endif /* _BASEPROTOCOLFACTORY_H */ | |
| diff --git a/sources/thelib/src/protocols/baseprotocolfactory.cpp b/sources/thelib/src/protocols/baseprotocolfactory.cpp | |
| index 180b8dd..dfd6e2f 100644 | |
| --- a/sources/thelib/src/protocols/baseprotocolfactory.cpp | |
| +++ b/sources/thelib/src/protocols/baseprotocolfactory.cpp | |
| @@ -18,6 +18,7 @@ | |
| */ | |
| #include "protocols/baseprotocolfactory.h" | |
| +#include "protocols/baseprotocol.h" | |
| uint32_t BaseProtocolFactory::_idGenerator = 0; | |
| @@ -32,4 +33,49 @@ uint32_t BaseProtocolFactory::GetId() { | |
| return _id; | |
| } | |
| +vector<uint64_t> BaseProtocolFactory::HandledProtocols() { | |
| + vector<uint64_t> result; | |
| + FOR_MAP(_constructors, uint64_t, ConstructorType, i) { | |
| + ADD_VECTOR_END(result, MAP_KEY(i)); | |
| + } | |
| + return result; | |
| +} | |
| + | |
| +vector<string> BaseProtocolFactory::HandledProtocolChains() { | |
| + vector<string> result; | |
| + FOR_MAP(_protocols, string, vector<uint64_t>, i) { | |
| + ADD_VECTOR_END(result, MAP_KEY(i)); | |
| + } | |
| + return result; | |
| +} | |
| + | |
| +vector<uint64_t> BaseProtocolFactory::ResolveProtocolChain(string name) { | |
| + if (MAP_HAS1(_protocols, name)) { | |
| + return _protocols[name]; | |
| + } | |
| + vector<uint64_t> result; | |
| + return result; | |
| +} | |
| +BaseProtocol* BaseProtocolFactory::SpawnProtocol(uint64_t type, Variant ¶meters) | |
| +{ | |
| + if (MAP_HAS1(_constructors, type)) return _constructors[type](); | |
| + return NULL; | |
| +} | |
| + | |
| +void BaseProtocolFactory::AddProtocol(const string &name, | |
| + BaseProtocol* (*constructor)(), int chain_length, ...) { | |
| + if (name.size() == 0 || chain_length <= 0) return; | |
| + | |
| + va_list args; | |
| + va_start(args, chain_length); | |
| + vector<uint64_t> chain; | |
| + uint64_t type; | |
| + for (int i = 0; i < chain_length; i++) { | |
| + type = va_arg(args, uint64_t); | |
| + ADD_VECTOR_END(chain, type); | |
| + } | |
| + va_end(args); | |
| + _protocols[name] = chain; | |
| + _constructors[type] = constructor; | |
| +} | |
| -- | |
| 1.7.5.4 |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| From 987dee886cb39e7050f97b41e549dca77ba2dfff Mon Sep 17 00:00:00 2001 | |
| From: Josh Allmann <joshua.allmann@gmail.com> | |
| Date: Wed, 11 Jan 2012 00:37:36 -0800 | |
| Subject: [PATCH 2/2] Convert samplefactory to use simplified protocol | |
| factory. | |
| --- | |
| .../samplefactory/include/protocolfactory.h | 44 --------- | |
| .../samplefactory/src/protocolfactory.cpp | 95 -------------------- | |
| .../samplefactory/src/samplefactory.cpp | 17 +++- | |
| .../samplefactory/src/samplefactoryapplication.cpp | 1 - | |
| 4 files changed, 15 insertions(+), 142 deletions(-) | |
| delete mode 100644 sources/applications/samplefactory/include/protocolfactory.h | |
| delete mode 100644 sources/applications/samplefactory/src/protocolfactory.cpp | |
| diff --git a/sources/applications/samplefactory/include/protocolfactory.h b/sources/applications/samplefactory/include/protocolfactory.h | |
| deleted file mode 100644 | |
| index 163e0e7..0000000 | |
| --- a/sources/applications/samplefactory/include/protocolfactory.h | |
| +++ /dev/null | |
| @@ -1,44 +0,0 @@ | |
| -/* | |
| - * Copyright (c) 2010, | |
| - * Gavriloaie Eugen-Andrei (shiretu@gmail.com) | |
| - * | |
| - * This file is part of crtmpserver. | |
| - * crtmpserver is free software: you can redistribute it and/or modify | |
| - * it under the terms of the GNU General Public License as published by | |
| - * the Free Software Foundation, either version 3 of the License, or | |
| - * (at your option) any later version. | |
| - * | |
| - * crtmpserver is distributed in the hope that it will be useful, | |
| - * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
| - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
| - * GNU General Public License for more details. | |
| - * | |
| - * You should have received a copy of the GNU General Public License | |
| - * along with crtmpserver. If not, see <http://www.gnu.org/licenses/>. | |
| - */ | |
| - | |
| - | |
| -#ifndef _PROTOCOLFACTORY_H | |
| -#define _PROTOCOLFACTORY_H | |
| - | |
| -#include "protocols/baseprotocolfactory.h" | |
| -#include "protocols/protocoltypes.h" | |
| - | |
| -namespace app_samplefactory { | |
| - | |
| - class DLLEXP ProtocolFactory | |
| - : public BaseProtocolFactory { | |
| - public: | |
| - ProtocolFactory(); | |
| - virtual ~ProtocolFactory(); | |
| - | |
| - virtual vector<uint64_t> HandledProtocols(); | |
| - virtual vector<string> HandledProtocolChains(); | |
| - virtual vector<uint64_t> ResolveProtocolChain(string name); | |
| - virtual BaseProtocol *SpawnProtocol(uint64_t type, Variant ¶meters); | |
| - }; | |
| -} | |
| - | |
| -#endif /* _PROTOCOLFACTORY_H */ | |
| - | |
| - | |
| diff --git a/sources/applications/samplefactory/src/protocolfactory.cpp b/sources/applications/samplefactory/src/protocolfactory.cpp | |
| deleted file mode 100644 | |
| index a30a90a..0000000 | |
| --- a/sources/applications/samplefactory/src/protocolfactory.cpp | |
| +++ /dev/null | |
| @@ -1,95 +0,0 @@ | |
| -/* | |
| - * Copyright (c) 2010, | |
| - * Gavriloaie Eugen-Andrei (shiretu@gmail.com) | |
| - * | |
| - * This file is part of crtmpserver. | |
| - * crtmpserver is free software: you can redistribute it and/or modify | |
| - * it under the terms of the GNU General Public License as published by | |
| - * the Free Software Foundation, either version 3 of the License, or | |
| - * (at your option) any later version. | |
| - * | |
| - * crtmpserver is distributed in the hope that it will be useful, | |
| - * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
| - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
| - * GNU General Public License for more details. | |
| - * | |
| - * You should have received a copy of the GNU General Public License | |
| - * along with crtmpserver. If not, see <http://www.gnu.org/licenses/>. | |
| - */ | |
| - | |
| - | |
| -#include "protocolfactory.h" | |
| -#include "protocols/baseprotocol.h" | |
| -#include "localdefines.h" | |
| -#include "echoprotocol.h" | |
| -#include "httpdownloadprotocol.h" | |
| -using namespace app_samplefactory; | |
| - | |
| -ProtocolFactory::ProtocolFactory() { | |
| - | |
| -} | |
| - | |
| -ProtocolFactory::~ProtocolFactory() { | |
| -} | |
| - | |
| -vector<uint64_t> ProtocolFactory::HandledProtocols() { | |
| - vector<uint64_t> result; | |
| - ADD_VECTOR_END(result, PT_ECHO_PROTOCOL); | |
| - ADD_VECTOR_END(result, PT_HTTP_DOWNLOAD_PROTOCOL); | |
| - return result; | |
| -} | |
| - | |
| -vector<string> ProtocolFactory::HandledProtocolChains() { | |
| - vector<string> result; | |
| - ADD_VECTOR_END(result, "echoProtocol"); | |
| - ADD_VECTOR_END(result, "httpEchoProtocol"); | |
| - ADD_VECTOR_END(result, "httpDownload"); | |
| - return result; | |
| -} | |
| - | |
| -vector<uint64_t> ProtocolFactory::ResolveProtocolChain(string name) { | |
| - vector<uint64_t> result; | |
| - if (name == "echoProtocol") { | |
| - ADD_VECTOR_END(result, PT_TCP); | |
| - ADD_VECTOR_END(result, PT_ECHO_PROTOCOL); | |
| - } else if (name == "httpEchoProtocol") { | |
| - ADD_VECTOR_END(result, PT_TCP); | |
| - ADD_VECTOR_END(result, PT_INBOUND_HTTP); | |
| - ADD_VECTOR_END(result, PT_ECHO_PROTOCOL); | |
| - } else if (name == "httpDownload") { | |
| - ADD_VECTOR_END(result, PT_TCP); | |
| - ADD_VECTOR_END(result, PT_OUTBOUND_HTTP); | |
| - ADD_VECTOR_END(result, PT_HTTP_DOWNLOAD_PROTOCOL); | |
| - } else { | |
| - ASSERT("This protocol stack should not land here"); | |
| - } | |
| - return result; | |
| -} | |
| - | |
| -BaseProtocol *ProtocolFactory::SpawnProtocol(uint64_t type, Variant ¶meters) { | |
| - BaseProtocol *pResult = NULL; | |
| - switch (type) { | |
| - case PT_ECHO_PROTOCOL: | |
| - pResult = new EchoProtocol(); | |
| - break; | |
| - case PT_HTTP_DOWNLOAD_PROTOCOL: | |
| - pResult = new HTTPDownloadProtocol(); | |
| - break; | |
| - default: | |
| - FATAL("Spawning protocol %s not yet implemented", | |
| - STR(tagToString(type))); | |
| - break; | |
| - } | |
| - | |
| - if (pResult != NULL) { | |
| - if (!pResult->Initialize(parameters)) { | |
| - FATAL("Unable to initialize protocol %s", | |
| - STR(tagToString(type))); | |
| - delete pResult; | |
| - pResult = NULL; | |
| - } | |
| - } | |
| - | |
| - return pResult; | |
| -} | |
| - | |
| diff --git a/sources/applications/samplefactory/src/samplefactory.cpp b/sources/applications/samplefactory/src/samplefactory.cpp | |
| index a576f2e..6d2ba66 100644 | |
| --- a/sources/applications/samplefactory/src/samplefactory.cpp | |
| +++ b/sources/applications/samplefactory/src/samplefactory.cpp | |
| @@ -18,17 +18,30 @@ | |
| */ | |
| #include "application/baseclientapplication.h" | |
| +#include "protocols/baseprotocolfactory.h" | |
| #include "samplefactory.h" | |
| #include "samplefactoryapplication.h" | |
| -#include "protocolfactory.h" | |
| +#include "echoprotocol.h" | |
| +#include "httpdownloadprotocol.h" | |
| +#include "localdefines.h" | |
| using namespace app_samplefactory; | |
| +PROTOCOL_CONSTRUCTOR(EchoProtocol) | |
| +PROTOCOL_CONSTRUCTOR(HTTPDownloadProtocol) | |
| + | |
| extern "C" BaseClientApplication *GetApplication_samplefactory(Variant configuration) { | |
| return new SampleFactoryApplication( | |
| configuration); | |
| } | |
| extern "C" DLLEXP BaseProtocolFactory *GetFactory_samplefactory(Variant configuration) { | |
| - return new ProtocolFactory(); | |
| + BaseProtocolFactory *f = new BaseProtocolFactory(); | |
| + f->AddProtocol("echoProtocol", new_EchoProtocol, 2, | |
| + PT_TCP, PT_ECHO_PROTOCOL); | |
| + f->AddProtocol("httpEchoProtocol", new_EchoProtocol, 3, | |
| + PT_TCP, PT_INBOUND_HTTP, PT_ECHO_PROTOCOL); | |
| + f->AddProtocol("httpDownload", new_HTTPDownloadProtocol, 3, | |
| + PT_TCP, PT_OUTBOUND_HTTP, PT_HTTP_DOWNLOAD_PROTOCOL); | |
| + return f; | |
| } | |
| diff --git a/sources/applications/samplefactory/src/samplefactoryapplication.cpp b/sources/applications/samplefactory/src/samplefactoryapplication.cpp | |
| index 074f591..01c9c8a 100644 | |
| --- a/sources/applications/samplefactory/src/samplefactoryapplication.cpp | |
| +++ b/sources/applications/samplefactory/src/samplefactoryapplication.cpp | |
| @@ -20,7 +20,6 @@ | |
| #include "samplefactoryapplication.h" | |
| #include "protocols/baseprotocol.h" | |
| -#include "protocolfactory.h" | |
| #include "protocols/protocolfactorymanager.h" | |
| #include "localdefines.h" | |
| #include "echoappprotocolhandler.h" | |
| -- | |
| 1.7.5.4 |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment