#include "httplib.h" #include "wren.h" // A struct to hold the context for an asynchronous HTTP request struct RequestContext { std::string url; WrenHandle* callback; WrenVM* vm; std::string response; bool error; }; // A class to manage asynchronous HTTP requests class AsyncHttp { public: AsyncHttp(WrenVM* vm) : vm_(vm), running_(true) { // Create a pool of worker threads for (int i = 0; i < 4; ++i) { threads_.emplace_back([this] { while (running_) { RequestContext* context = requestQueue_.pop(); if (!running_) break; httplib::Client cli("http://example.com"); if (auto res = cli.Get(context->url.c_str())) { context->response = res->body; context->error = false; } else { context->response = "Error: " + to_string(res.error()); context->error = true; } completionQueue_.push(context); } }); } } ~AsyncHttp() { running_ = false; // Add dummy requests to unblock worker threads for (size_t i = 0; i < threads_.size(); ++i) { requestQueue_.push(nullptr); } for (auto& thread : threads_) { thread.join(); } } void request(const std::string& url, WrenHandle* callback) { RequestContext* context = new RequestContext{url, callback, vm_}; requestQueue_.push(context); } void processCompletions() { while (!completionQueue_.empty()) { RequestContext* context = completionQueue_.pop(); // Create a handle for the callback function WrenHandle* callHandle = wrenMakeCallHandle(vm_, "call(_)"); wrenEnsureSlots(vm_, 2); wrenSetSlotHandle(vm_, 0, context->callback); wrenSetSlotString(vm_, 1, context->response.c_str()); wrenCall(vm_, callHandle); wrenReleaseHandle(vm_, callHandle); wrenReleaseHandle(vm_, context->callback); delete context; } } private: WrenVM* vm_; bool running_; std::vector threads_; ThreadSafeQueue requestQueue_; ThreadSafeQueue completionQueue_; };