/* Part of the WEBSERVER MODULE Copyright (C) 2016-2019 by Xose PĂ©rez */ #pragma once #include "web.h" #include "libs/TypeChecks.h" #include #if WEB_SUPPORT namespace asyncwebprint { namespace traits { template using print_callable_t = decltype(std::declval()(std::declval())); template using is_print_callable = is_detected; } } template void AsyncWebPrint::scheduleFromRequest(const AsyncWebPrintConfig& config, AsyncWebServerRequest* request, CallbackType callback) { static_assert(asyncwebprint::traits::is_print_callable::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(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(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(); }); } constexpr AsyncWebPrintConfig AsyncWebPrintDefaults { /*mimeType =*/ "text/plain", /*backlogCountMax=*/ 2, /*backlogSizeMax= */ TCP_MSS, /*backlogTimeout= */ 5000 }; template void AsyncWebPrint::scheduleFromRequest(AsyncWebServerRequest* request, CallbackType callback) { AsyncWebPrint::scheduleFromRequest(AsyncWebPrintDefaults, request, callback); } #endif