Files
espurna/code/espurna/web_asyncwebprint.ipp
Maxim Prokhorov 16960067d8 system: some refactoring
There's no need to move a temporary which is already an rvalue

Clean-up some redundant attributes and function in settings.
Make sure C types are proxied to fixed-sized ones, not the other way around.

Clean-up webprint implementation
- use typed duration for the backlog
- don't duplicate members and types for config, just re-use the struct as-is
- don't go over-the-top with const members, just proxy through a method
2021-12-08 13:48:40 +03:00

73 lines
2.1 KiB
C++

/*
Part of the WEBSERVER MODULE
Copyright (C) 2016-2019 by Xose Pérez <xose dot perez at gmail dot com>
*/
#pragma once
#include "web.h"
#include "libs/TypeChecks.h"
#include <Schedule.h>
#if WEB_SUPPORT
namespace asyncwebprint {
namespace traits {
template <typename T>
using print_callable_t = decltype(std::declval<T>()(std::declval<Print&>()));
template <typename T>
using is_print_callable = is_detected<print_callable_t, T>;
}
}
template<typename CallbackType>
void AsyncWebPrint::scheduleFromRequest(AsyncWebPrintConfig config, AsyncWebServerRequest* request, CallbackType callback) {
static_assert(asyncwebprint::traits::is_print_callable<CallbackType>::value, "CallbackType needs to be a callable with void(Print&)");
// because of async nature of the server, we need to make sure we outlive 'request' object
auto print = std::shared_ptr<AsyncWebPrint>(new AsyncWebPrint(config, request));
// attach one ptr to onDisconnect capture, so we can detect disconnection before scheduled function runs
request->onDisconnect([print, request]() {
#if API_SUPPORT
// TODO: in case this comes from `apiRegister`'ed endpoint, there's still a lingering ApiRequestHelper that we must remove
if (request->_tempObject) {
auto* ptr = reinterpret_cast<ApiRequestHelper*>(request->_tempObject);
delete ptr;
request->_tempObject = nullptr;
}
#endif
print->setState(AsyncWebPrint::State::Done);
});
// attach another capture to the scheduled function, so we execute as soon as we exit next loop()
schedule_function([callback, print]() {
if (State::None != print->getState()) return;
callback(*print.get());
print->flush();
});
}
static constexpr AsyncWebPrintConfig AsyncWebPrintDefaults {
.mimeType = "text/plain",
.backlog = {
.count = 2,
.size = TCP_MSS,
.timeout = espurna::duration::Seconds(5)
}
};
template<typename CallbackType>
void AsyncWebPrint::scheduleFromRequest(AsyncWebServerRequest* request, CallbackType callback) {
AsyncWebPrint::scheduleFromRequest(AsyncWebPrintDefaults, request, callback);
}
#endif