Panda3DS/include/http_server.hpp
2023-07-28 14:21:00 +03:00

81 lines
No EOL
2.3 KiB
C++

#ifdef PANDA3DS_ENABLE_HTTP_SERVER
#pragma once
#include <array>
#include <atomic>
#include <condition_variable>
#include <filesystem>
#include <map>
#include <memory>
#include <mutex>
#include <queue>
#include <thread>
#include "helpers.hpp"
enum class HttpActionType { None, Screenshot, Key, TogglePause, Reset, LoadRom, Step };
class Emulator;
namespace httplib {
class Server;
struct Response;
}
// Wrapper for httplib::Response that allows the HTTP server to wait for the response to be ready
struct DeferredResponseWrapper {
DeferredResponseWrapper(httplib::Response& response) : inner_response(response) {}
httplib::Response& inner_response;
std::mutex mutex;
std::condition_variable cv;
bool ready = false;
};
// Actions derive from this class and are used to communicate with the HTTP server
class HttpAction {
HttpActionType type;
public:
HttpAction(HttpActionType type) : type(type) {}
virtual ~HttpAction() = default;
HttpActionType getType() const { return type; }
static std::unique_ptr<HttpAction> createScreenshotAction(DeferredResponseWrapper& response);
static std::unique_ptr<HttpAction> createKeyAction(u32 key, bool state);
static std::unique_ptr<HttpAction> createLoadRomAction(DeferredResponseWrapper& response, const std::filesystem::path& path, bool paused);
static std::unique_ptr<HttpAction> createTogglePauseAction();
static std::unique_ptr<HttpAction> createResetAction();
static std::unique_ptr<HttpAction> createStepAction(DeferredResponseWrapper& response, int frames);
};
struct HttpServer {
HttpServer(Emulator* emulator);
~HttpServer();
void processActions();
private:
static constexpr const char* httpServerScreenshotPath = "screenshot.png";
Emulator* emulator;
std::unique_ptr<httplib::Server> server;
std::thread httpServerThread;
std::queue<std::unique_ptr<HttpAction>> actionQueue;
std::mutex actionQueueMutex;
std::unique_ptr<HttpAction> currentStepAction {};
std::map<std::string, u32> keyMap;
bool paused = false;
int framesToRun = 0;
void startHttpServer();
void pushAction(std::unique_ptr<HttpAction> action);
std::string status();
u32 stringToKey(const std::string& key_name);
HttpServer(const HttpServer&) = delete;
HttpServer& operator=(const HttpServer&) = delete;
};
#endif // PANDA3DS_ENABLE_HTTP_SERVER