Modify the HttpBinder class template
This commit is contained in:
parent
01de7f4f1e
commit
0b53021358
|
@ -120,10 +120,10 @@ class HttpAppFramework : public trantor::NonCopyable
|
|||
const std::vector<any> &filtersAndMethods = std::vector<any>())
|
||||
{
|
||||
LOG_TRACE << "pathPattern:" << pathPattern;
|
||||
HttpBinderBasePtr binder;
|
||||
internal::HttpBinderBasePtr binder;
|
||||
|
||||
binder = std::make_shared<
|
||||
HttpBinder<FUNCTION>>(std::forward<FUNCTION>(function));
|
||||
internal::HttpBinder<FUNCTION>>(std::forward<FUNCTION>(function));
|
||||
|
||||
std::vector<HttpMethod> validMethods;
|
||||
std::vector<std::string> filters;
|
||||
|
@ -193,7 +193,7 @@ class HttpAppFramework : public trantor::NonCopyable
|
|||
|
||||
private:
|
||||
virtual void registerHttpController(const std::string &pathPattern,
|
||||
const HttpBinderBasePtr &binder,
|
||||
const internal::HttpBinderBasePtr &binder,
|
||||
const std::vector<HttpMethod> &validMethods = std::vector<HttpMethod>(),
|
||||
const std::vector<std::string> &filters = std::vector<std::string>()) = 0;
|
||||
};
|
||||
|
|
|
@ -23,12 +23,15 @@
|
|||
#include <sstream>
|
||||
#include <memory>
|
||||
|
||||
/// The classes in the file are internal tool classes. Do not include this
|
||||
/// The classes in the file are internal tool classes. Do not include this
|
||||
/// file directly and use any of these classes directly.
|
||||
|
||||
namespace drogon
|
||||
{
|
||||
//we only accept value type or const lreference type as handle method parameters type
|
||||
namespace internal
|
||||
{
|
||||
|
||||
//we only accept value type or const lreference type or right reference type as the handle method parameters type
|
||||
template <typename T>
|
||||
struct BinderArgTypeTraits
|
||||
{
|
||||
|
@ -67,10 +70,6 @@ class HttpBinderBase
|
|||
const HttpRequestPtr &req, std::function<void(const HttpResponsePtr &)> callback) = 0;
|
||||
virtual size_t paramCount() = 0;
|
||||
virtual ~HttpBinderBase() {}
|
||||
|
||||
protected:
|
||||
static std::map<std::string, std::shared_ptr<drogon::DrObjectBase>> _objMap;
|
||||
static std::mutex _objMutex;
|
||||
};
|
||||
typedef std::shared_ptr<HttpBinderBase> HttpBinderBasePtr;
|
||||
template <typename FUNCTION>
|
||||
|
@ -99,7 +98,7 @@ class HttpBinder : public HttpBinderBase
|
|||
private:
|
||||
FUNCTION _func;
|
||||
|
||||
typedef utility::FunctionTraits<FUNCTION> traits;
|
||||
typedef FunctionTraits<FUNCTION> traits;
|
||||
template <
|
||||
std::size_t Index>
|
||||
using nth_argument_type = typename traits::template argument<Index>;
|
||||
|
@ -149,19 +148,7 @@ class HttpBinder : public HttpBinderBase
|
|||
Values &&... values)
|
||||
{
|
||||
static auto className = drogon::DrObjectBase::demangle(typeid(typename traits::class_type).name());
|
||||
std::shared_ptr<typename traits::class_type> obj;
|
||||
{
|
||||
std::lock_guard<std::mutex> guard(_objMutex);
|
||||
if (_objMap.find(className) == _objMap.end())
|
||||
{
|
||||
obj = std::shared_ptr<typename traits::class_type>(new typename traits::class_type);
|
||||
_objMap[className] = obj;
|
||||
}
|
||||
else
|
||||
{
|
||||
obj = std::dynamic_pointer_cast<typename traits::class_type>(_objMap[className]);
|
||||
}
|
||||
}
|
||||
auto &obj=getObj();
|
||||
assert(obj);
|
||||
((*obj).*_func)(req, callback, std::move(values)...);
|
||||
};
|
||||
|
@ -173,5 +160,23 @@ class HttpBinder : public HttpBinderBase
|
|||
{
|
||||
_func(req, callback, std::move(values)...);
|
||||
};
|
||||
template <bool isClassFunction = traits::isClassFunction>
|
||||
typename std::enable_if<isClassFunction, const std::shared_ptr<typename traits::class_type> &>::type getObj()
|
||||
{
|
||||
//Initialization of function-local statics is guaranteed to occur only once even when
|
||||
//called from multiple threads, and may be more efficient than the equivalent code using std::call_once.
|
||||
static auto obj = std::shared_ptr<typename traits::class_type>(new typename traits::class_type);
|
||||
return obj;
|
||||
}
|
||||
template <bool isClassFunction = traits::isClassFunction>
|
||||
typename std::enable_if<!isClassFunction, const std::shared_ptr<void> &>::type getObj()
|
||||
{
|
||||
//This function will never be called
|
||||
static auto obj = std::shared_ptr<void>(nullptr);
|
||||
assert(0);
|
||||
return obj;
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace internal
|
||||
} // namespace drogon
|
||||
|
|
|
@ -26,7 +26,7 @@ class HttpResponse;
|
|||
typedef std::shared_ptr<HttpRequest> HttpRequestPtr;
|
||||
typedef std::shared_ptr<HttpResponse> HttpResponsePtr;
|
||||
|
||||
namespace utility
|
||||
namespace internal
|
||||
{
|
||||
|
||||
template <typename>
|
||||
|
@ -38,6 +38,7 @@ struct FunctionTraits : public FunctionTraits<
|
|||
decltype(&std::remove_reference<Function>::type::operator())>
|
||||
{
|
||||
static const bool isClassFunction = false;
|
||||
typedef void class_type;
|
||||
static const std::string name()
|
||||
{
|
||||
return std::string("Functor");
|
||||
|
@ -78,6 +79,7 @@ struct FunctionTraits<
|
|||
ReturnType (*)(const HttpRequestPtr &req, const std::function<void(const HttpResponsePtr &)> &callback, Arguments...)> : FunctionTraits<ReturnType (*)(Arguments...)>
|
||||
{
|
||||
static const bool isHTTPFunction = true;
|
||||
typedef void class_type;
|
||||
};
|
||||
|
||||
//normal function
|
||||
|
@ -95,11 +97,11 @@ struct FunctionTraits<
|
|||
std::tuple<Arguments...>>::type;
|
||||
|
||||
static const std::size_t arity = sizeof...(Arguments);
|
||||
|
||||
typedef void class_type;
|
||||
static const bool isHTTPFunction = false;
|
||||
static const bool isClassFunction = false;
|
||||
static const std::string name() { return std::string("Normal or Static Function"); }
|
||||
};
|
||||
|
||||
} // namespace utility
|
||||
} // namespace internal
|
||||
} // namespace drogon
|
||||
|
|
|
@ -43,8 +43,6 @@
|
|||
|
||||
using namespace drogon;
|
||||
using namespace std::placeholders;
|
||||
std::map<std::string, std::shared_ptr<drogon::DrObjectBase>> HttpBinderBase::_objMap;
|
||||
std::mutex HttpBinderBase::_objMutex;
|
||||
|
||||
static void godaemon(void)
|
||||
{
|
||||
|
@ -189,7 +187,7 @@ void HttpAppFrameworkImpl::registerHttpSimpleController(const std::string &pathN
|
|||
}
|
||||
}
|
||||
void HttpAppFrameworkImpl::addHttpPath(const std::string &path,
|
||||
const HttpBinderBasePtr &binder,
|
||||
const internal::HttpBinderBasePtr &binder,
|
||||
const std::vector<HttpMethod> &validMethods,
|
||||
const std::vector<std::string> &filters)
|
||||
{
|
||||
|
@ -261,7 +259,7 @@ void HttpAppFrameworkImpl::addHttpPath(const std::string &path,
|
|||
}
|
||||
}
|
||||
void HttpAppFrameworkImpl::registerHttpController(const std::string &pathPattern,
|
||||
const HttpBinderBasePtr &binder,
|
||||
const internal::HttpBinderBasePtr &binder,
|
||||
const std::vector<HttpMethod> &validMethods,
|
||||
const std::vector<std::string> &filters)
|
||||
{
|
||||
|
|
|
@ -111,7 +111,7 @@ class HttpAppFrameworkImpl : public HttpAppFramework
|
|||
#endif
|
||||
private:
|
||||
virtual void registerHttpController(const std::string &pathPattern,
|
||||
const HttpBinderBasePtr &binder,
|
||||
const internal::HttpBinderBasePtr &binder,
|
||||
const std::vector<HttpMethod> &validMethods = std::vector<HttpMethod>(),
|
||||
const std::vector<std::string> &filters = std::vector<std::string>()) override;
|
||||
|
||||
|
@ -125,7 +125,7 @@ class HttpAppFrameworkImpl : public HttpAppFramework
|
|||
void onConnection(const TcpConnectionPtr &conn);
|
||||
void readSendFile(const std::string &filePath, const HttpRequestImplPtr &req, const HttpResponsePtr &resp);
|
||||
void addHttpPath(const std::string &path,
|
||||
const HttpBinderBasePtr &binder,
|
||||
const internal::HttpBinderBasePtr &binder,
|
||||
const std::vector<HttpMethod> &validMethods,
|
||||
const std::vector<std::string> &filters);
|
||||
void initRegex();
|
||||
|
@ -176,7 +176,7 @@ class HttpAppFrameworkImpl : public HttpAppFramework
|
|||
std::string pathParameterPattern;
|
||||
std::vector<size_t> parameterPlaces;
|
||||
std::map<std::string, size_t> queryParametersPlaces;
|
||||
HttpBinderBasePtr binderPtr;
|
||||
internal::HttpBinderBasePtr binderPtr;
|
||||
std::vector<std::string> filtersName;
|
||||
std::unique_ptr<std::mutex> binderMtx = std::unique_ptr<std::mutex>(new std::mutex);
|
||||
std::weak_ptr<HttpResponse> responsePtr;
|
||||
|
|
Loading…
Reference in New Issue