replacing folly with ConcurrenCpp

This commit is contained in:
Selim Mustafaev 2022-08-21 09:54:45 +03:00
parent 5dd32e92b8
commit 4814d9002d
8 changed files with 53 additions and 75 deletions

View File

@ -1,12 +1,13 @@
cmake_minimum_required(VERSION 3.0) cmake_minimum_required(VERSION 3.16)
project(autocat_gnome) project(autocat_gnome)
include(ExternalProject)
set(CMAKE_CXX_STANDARD 20) set(CMAKE_CXX_STANDARD 20)
set(CMAKE_CXX_STANDARD_REQUIRED ON) set(CMAKE_CXX_STANDARD_REQUIRED ON)
if(APPLE) #if(APPLE)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fcoroutines-ts") # set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fno-coroutines-ts")
endif() #endif()
#set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fsanitize=undefined -g -Og") #set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fsanitize=undefined -g -Og")
@ -14,21 +15,14 @@ if(APPLE)
set(ENV{PKG_CONFIG_PATH} "$ENV{PKG_CONFIG_PATH}:/usr/local/opt/libsoup@2/lib/pkgconfig:/usr/local/opt/icu4c/lib/pkgconfig") set(ENV{PKG_CONFIG_PATH} "$ENV{PKG_CONFIG_PATH}:/usr/local/opt/libsoup@2/lib/pkgconfig:/usr/local/opt/icu4c/lib/pkgconfig")
set(OPENSSL_ROOT_DIR /usr/local/opt/openssl) set(OPENSSL_ROOT_DIR /usr/local/opt/openssl)
set(OPENSSL_LIBRARIES /usr/local/opt/openssl/lib) set(OPENSSL_LIBRARIES /usr/local/opt/openssl/lib)
set(FOLLY_DEP folly)
include(FetchContent)
FetchContent_Declare(
folly
GIT_REPOSITORY https://github.com/facebook/folly.git
GIT_TAG v2022.05.16.00
)
FetchContent_MakeAvailable(folly)
else()
find_package(folly REQUIRED)
set(FOLLY_DEP Folly::folly)
endif() endif()
#list(APPEND CMAKE_MODULE_PATH /usr/local/lib/cmake/concurrencpp-0.1.4)
find_package(PkgConfig REQUIRED) find_package(PkgConfig REQUIRED)
find_package(nlohmann_json REQUIRED) find_package(nlohmann_json REQUIRED)
find_package(concurrencpp REQUIRED)
find_package(Threads REQUIRED)
pkg_check_modules(GTK REQUIRED gtk4) pkg_check_modules(GTK REQUIRED gtk4)
pkg_check_modules(GLIB REQUIRED glib-2.0) pkg_check_modules(GLIB REQUIRED glib-2.0)
@ -36,6 +30,8 @@ pkg_check_modules(LIBSOUP REQUIRED libsoup-2.4)
pkg_check_modules(LIBADWAITA REQUIRED libadwaita-1) pkg_check_modules(LIBADWAITA REQUIRED libadwaita-1)
pkg_check_modules(LIBSIGCPP REQUIRED sigc++-3.0) pkg_check_modules(LIBSIGCPP REQUIRED sigc++-3.0)
#ExternalProject_Add(concurrencpp GIT_REPOSITORY https://github.com/David-Haim/concurrencpp)
include_directories(${GTK_INCLUDE_DIRS} include_directories(${GTK_INCLUDE_DIRS}
${GLIB_INCLUDE_DIRS} ${GLIB_INCLUDE_DIRS}
${LIBSOUP_INCLUDE_DIRS} ${LIBSOUP_INCLUDE_DIRS}
@ -89,7 +85,8 @@ target_link_libraries(autocat_gnome ${GTK_LIBRARIES}
${LIBADWAITA_LIBRARIES} ${LIBADWAITA_LIBRARIES}
${LIBSIGCPP_LIBRARIES} ${LIBSIGCPP_LIBRARIES}
nlohmann_json::nlohmann_json nlohmann_json::nlohmann_json
${FOLLY_DEP}) concurrencpp::concurrencpp
Threads::Threads)
set(XML gui/MainWindow.xml gui/AddNumberDialog.xml) set(XML gui/MainWindow.xml gui/AddNumberDialog.xml)

View File

@ -5,6 +5,8 @@
#include "GLibMainContextExecutor.h" #include "GLibMainContextExecutor.h"
#include <glib.h> #include <glib.h>
/*
int callback(void* data) { int callback(void* data) {
auto executor = reinterpret_cast<GLibMainContextExecutor*>(data); auto executor = reinterpret_cast<GLibMainContextExecutor*>(data);
executor->runFront(); executor->runFront();
@ -30,3 +32,4 @@ folly::Executor::KeepAlive<GLibMainContextExecutor> GLibMainContextExecutor::ins
static GLibMainContextExecutor instance; static GLibMainContextExecutor instance;
return folly::getKeepAliveToken(instance); return folly::getKeepAliveToken(instance);
} }
*/

View File

@ -5,20 +5,16 @@
#ifndef AUTOCAT_GNOME_GLIBMAINCONTEXTEXECUTOR_H #ifndef AUTOCAT_GNOME_GLIBMAINCONTEXTEXECUTOR_H
#define AUTOCAT_GNOME_GLIBMAINCONTEXTEXECUTOR_H #define AUTOCAT_GNOME_GLIBMAINCONTEXTEXECUTOR_H
#include <folly/Executor.h>
#include <queue> #include <queue>
#include <mutex> #include <mutex>
class GLibMainContextExecutor: public folly::Executor { class GLibMainContextExecutor {
private: private:
std::queue<folly::Func> _tasks; //std::queue<folly::Func> _tasks;
std::mutex _mutex; std::mutex _mutex;
public: public:
static folly::Executor::KeepAlive<GLibMainContextExecutor> instance(); //~GLibMainContextExecutor() override = default;
~GLibMainContextExecutor() override = default;
void add(folly::Func func) override;
void runFront();
}; };

View File

@ -12,8 +12,6 @@
#include <iostream> #include <iostream>
#include <utility> #include <utility>
#include <folly/experimental/coro/Task.h>
#include <folly/executors/IOThreadPoolExecutor.h>
LoginWindow::LoginWindow(std::shared_ptr<gtkpp::Application> app): gtkpp::Window(std::move(app), false) { LoginWindow::LoginWindow(std::shared_ptr<gtkpp::Application> app): gtkpp::Window(std::move(app), false) {
@ -57,7 +55,7 @@ void LoginWindow::loginClicked() {
_spinner.start(); _spinner.start();
try { try {
User user = co_await Api::login(email, password).scheduleOn(GLibMainContextExecutor::instance()); User user = co_await Api::login(email, password);
if(auto app = this->application()) { if(auto app = this->application()) {
auto mainWindow = std::make_shared<MainWindow>(app); auto mainWindow = std::make_shared<MainWindow>(app);
mainWindow->show(); mainWindow->show();

View File

@ -5,7 +5,6 @@
#include "gtkpp/Window.h" #include "gtkpp/Window.h"
#include <memory> #include <memory>
#include <folly/init/Init.h>
#include <iostream> #include <iostream>
std::shared_ptr<gtkpp::Window> createMainWindow(std::shared_ptr<gtkpp::Application> app) { std::shared_ptr<gtkpp::Window> createMainWindow(std::shared_ptr<gtkpp::Application> app) {
@ -19,7 +18,6 @@ std::shared_ptr<gtkpp::Window> createMainWindow(std::shared_ptr<gtkpp::Applicati
int main(int argc, char* argv[]) { int main(int argc, char* argv[]) {
folly::init(&argc, &argv);
g_resources_register(g_resource_load("resources.gresource", nullptr)); g_resources_register(g_resource_load("resources.gresource", nullptr));
auto app = std::make_shared<gtkpp::Application>("pro.aliencat.autocat"); auto app = std::make_shared<gtkpp::Application>("pro.aliencat.autocat");

View File

@ -19,6 +19,7 @@ public:
public: public:
User() = default; User() = default;
User(const User& user) = default; User(const User& user) = default;
User(User&&) = default;
User(std::string_view email, std::string_view token); User(std::string_view email, std::string_view token);
NLOHMANN_DEFINE_TYPE_INTRUSIVE(User, email, token) NLOHMANN_DEFINE_TYPE_INTRUSIVE(User, email, token)

View File

@ -5,53 +5,39 @@
#include "Api.h" #include "Api.h"
#include "Settings.h" #include "Settings.h"
#include <memory> #include <memory>
#include <folly/futures/Promise.h>
template<class...Args>
struct Callback {
void(*function)(Args..., void*) = nullptr;
void* state = nullptr;
};
template<typename... Args, typename Lambda>
Callback<Args...> voidify(Lambda&& l) {
using Func = typename std::decay<Lambda>::type;
auto data = new Func(std::forward<Lambda>(l));
return {
+[](Args... args, void* v)->void {
Func* f = static_cast< Func* >(v);
(*f)(std::forward<Args>(args)...);
delete f;
},
data
};
}
const std::string Api::_baseUrl = "https://vps.aliencat.pro:8443/"; const std::string Api::_baseUrl = "https://vps.aliencat.pro:8443/";
SoupSession* Api::_session = soup_session_new(); SoupSession* Api::_session = soup_session_new();
template<typename T> template<typename T>
folly::Future<T> Api::post(const std::string &method, const nlohmann::json& params) { void callback(SoupSession* session, SoupMessage* message, gpointer userData) {
auto promise = reinterpret_cast<cc::result_promise<T>*>(userData);
if(message->status_code >= 200 && message->status_code < 300) {
auto responseString = std::string(message->response_body->data, message->response_body->length);
auto json = nlohmann::json::parse(responseString);
if(json["success"].get<bool>()) {
//std::cout << "response: " << responseString << std::endl;
auto data = json["data"].get<T>();
promise->set_result(data);
} else {
auto error = json["error"].get<std::string>();
promise->set_exception(std::make_exception_ptr(std::runtime_error(error)));
}
} else {
promise->set_exception(std::make_exception_ptr(std::runtime_error(message->reason_phrase)));
}
delete promise;
}
template<typename T>
cc::result<T> Api::post(const std::string &method, const nlohmann::json& params) {
std::string url = _baseUrl + method; std::string url = _baseUrl + method;
auto msg = soup_message_new(SOUP_METHOD_POST, url.c_str()); auto msg = soup_message_new(SOUP_METHOD_POST, url.c_str());
auto promise = std::make_shared<folly::Promise<T>>(); auto promise = new cc::result_promise<T>();
auto callback = voidify<SoupSession*, SoupMessage*>([&, promise](SoupSession* session, SoupMessage* message) { auto result = promise->get_result();
if(message->status_code >= 200 && message->status_code < 300) {
auto responseString = std::string(message->response_body->data, message->response_body->length);
auto json = nlohmann::json::parse(responseString);
if(json["success"].get<bool>()) {
//std::cout << "response: " << responseString << std::endl;
auto user = json["data"].get<T>();
promise->setValue(user);
} else {
auto error = json["error"].get<std::string>();
promise->setException(std::runtime_error(error));
}
} else {
promise->setException(std::runtime_error(message->reason_phrase));
}
});
auto jsonStr = params.dump(); auto jsonStr = params.dump();
@ -60,12 +46,12 @@ folly::Future<T> Api::post(const std::string &method, const nlohmann::json& para
jsonStr.c_str(), jsonStr.c_str(),
jsonStr.size()); jsonStr.size());
soup_session_queue_message(_session, msg, callback.function, callback.state); soup_session_queue_message(_session, msg, callback<T>, promise);
return promise->getFuture(); return result;
} }
fc::Task<User> Api::login(std::string email, std::string password) { cc::result<User> Api::login(std::string email, std::string password) {
nlohmann::json params = { nlohmann::json params = {
{ "email", email }, { "email", email },

View File

@ -8,13 +8,12 @@
#include <string> #include <string>
#include <libsoup/soup.h> #include <libsoup/soup.h>
#include <nlohmann/json.hpp> #include <nlohmann/json.hpp>
#include <folly/futures/Future.h> #include <concurrencpp/concurrencpp.h>
#include <folly/experimental/coro/Task.h>
#include "../models/User.h" #include "../models/User.h"
#include "../coro/Coro.h" #include "../coro/Coro.h"
namespace fc = folly::coro; namespace cc = concurrencpp;
class Api { class Api {
private: private:
@ -23,10 +22,10 @@ private:
private: private:
template<typename T> template<typename T>
static folly::Future<T> post(const std::string& method, const nlohmann::json& params); static cc::result<T> post(const std::string& method, const nlohmann::json& params);
public: public:
static fc::Task<User> login(std::string email, std::string password); static cc::result<User> login(std::string email, std::string password);
}; };