#ifdef PANDA3DS_ENABLE_HTTP_SERVER #pragma once #include #include #include #include #include #include #include #include #include #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 createScreenshotAction(DeferredResponseWrapper& response); static std::unique_ptr createKeyAction(u32 key, bool state); static std::unique_ptr createLoadRomAction(DeferredResponseWrapper& response, const std::filesystem::path& path, bool paused); static std::unique_ptr createTogglePauseAction(); static std::unique_ptr createResetAction(); static std::unique_ptr 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 server; std::thread httpServerThread; std::queue> actionQueue; std::mutex actionQueueMutex; std::unique_ptr currentStepAction {}; std::map keyMap; bool paused = false; int framesToRun = 0; void startHttpServer(); void pushAction(std::unique_ptr 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