add state saving and loading
This commit is contained in:
parent
f7e6699fec
commit
28e662b393
@ -7,7 +7,7 @@ add_subdirectory(libuv)
|
|||||||
add_subdirectory(spdlog)
|
add_subdirectory(spdlog)
|
||||||
add_subdirectory(td)
|
add_subdirectory(td)
|
||||||
|
|
||||||
add_executable(${PROJECT_NAME} main.cpp http.cpp vk.cpp)
|
add_executable(${PROJECT_NAME} main.cpp http.cpp state.cpp vk.cpp)
|
||||||
|
|
||||||
target_compile_options(${PROJECT_NAME} PRIVATE -std=c++2b)
|
target_compile_options(${PROJECT_NAME} PRIVATE -std=c++2b)
|
||||||
|
|
||||||
|
14
main.cpp
14
main.cpp
@ -1,4 +1,6 @@
|
|||||||
#include "http.h"
|
#include "spdlog/spdlog.h"
|
||||||
|
#include "state.h"
|
||||||
|
#include <filesystem>
|
||||||
#include <uv.h>
|
#include <uv.h>
|
||||||
#include <td/telegram/td_api.h>
|
#include <td/telegram/td_api.h>
|
||||||
#include <td/telegram/td_api.hpp>
|
#include <td/telegram/td_api.hpp>
|
||||||
@ -20,7 +22,17 @@ int main() {
|
|||||||
uv_signal_t signalHandles[2] = {};
|
uv_signal_t signalHandles[2] = {};
|
||||||
create_signal_handles(loop, signalHandles);
|
create_signal_handles(loop, signalHandles);
|
||||||
|
|
||||||
|
state::AppState state;
|
||||||
|
try {
|
||||||
|
state = state::AppState("bridge_state.json");
|
||||||
|
spdlog::info("state: {}", state.to_string());
|
||||||
|
} catch (state::InvalidSavedStateException &e) {
|
||||||
|
spdlog::error("invalid saved state: {}", e.message);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
uv_run(loop, UV_RUN_DEFAULT);
|
uv_run(loop, UV_RUN_DEFAULT);
|
||||||
spdlog::info("event loop ended");
|
spdlog::info("event loop ended");
|
||||||
|
state.save();
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
67
state.cpp
Normal file
67
state.cpp
Normal file
@ -0,0 +1,67 @@
|
|||||||
|
#include "state.h"
|
||||||
|
#include "spdlog/spdlog.h"
|
||||||
|
#include <fstream>
|
||||||
|
#include <nlohmann/json.hpp>
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
using namespace state;
|
||||||
|
using namespace nlohmann;
|
||||||
|
|
||||||
|
AppState::AppState(std::string filename) : m_saveFilename(filename) {
|
||||||
|
std::ifstream f(filename);
|
||||||
|
if (f.fail()) {
|
||||||
|
spdlog::info("no state file");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
json state = json::parse(f);
|
||||||
|
if (state.type() != json::value_t::object) {
|
||||||
|
throw InvalidSavedStateException("JSON root must be an object");
|
||||||
|
}
|
||||||
|
if (state.contains("vk")) {
|
||||||
|
json vkState = state["vk"];
|
||||||
|
if (vkState.type() == json::value_t::object) {
|
||||||
|
if (vkState.contains("last_post_id")) {
|
||||||
|
json lastPostId = vkState["last_post_id"];
|
||||||
|
if (lastPostId.type() == json::value_t::number_integer || lastPostId.type() == json::value_t::number_unsigned) {
|
||||||
|
vkLastPostId = lastPostId;
|
||||||
|
} else {
|
||||||
|
throw InvalidSavedStateException("key vk.last_post_id must be an integer");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
throw InvalidSavedStateException("key vk must be an object");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (state.contains("tg")) {
|
||||||
|
json tgState = state["tg"];
|
||||||
|
if (tgState.type() == json::value_t::object) {
|
||||||
|
if (tgState.contains("last_post_id")) {
|
||||||
|
json lastPostId = tgState["last_post_id"];
|
||||||
|
if (lastPostId.type() == json::value_t::number_integer || lastPostId.type() == json::value_t::number_unsigned) {
|
||||||
|
tgLastPostId = lastPostId;
|
||||||
|
} else {
|
||||||
|
throw InvalidSavedStateException("key tg.last_post_id must be an integer");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
throw InvalidSavedStateException("key tg must be an object");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void AppState::save() {
|
||||||
|
if (m_saveFilename.empty()) return;
|
||||||
|
spdlog::info("saving state");
|
||||||
|
json state = {{"vk", {{"last_post_id", vkLastPostId}}}, {"tg", {{"last_post_id", tgLastPostId}}}};
|
||||||
|
std::ofstream f(m_saveFilename.c_str());
|
||||||
|
if (f.fail()) {
|
||||||
|
spdlog::error("failed to open state file '{}'", m_saveFilename);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
f << state << std::endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string AppState::to_string() {
|
||||||
|
return std::format("AppState {{ tgLastPostId: {}, vkLastPostId: {} }}", tgLastPostId, vkLastPostId);
|
||||||
|
}
|
26
state.h
Normal file
26
state.h
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <cstdint>
|
||||||
|
#include <exception>
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
namespace state {
|
||||||
|
class InvalidSavedStateException : std::exception {
|
||||||
|
public:
|
||||||
|
inline InvalidSavedStateException(const char *message): message(message) {};
|
||||||
|
const char *message;
|
||||||
|
};
|
||||||
|
|
||||||
|
class AppState {
|
||||||
|
public:
|
||||||
|
inline AppState() {};
|
||||||
|
AppState(std::string filename);
|
||||||
|
std::string to_string();
|
||||||
|
void save();
|
||||||
|
|
||||||
|
int64_t tgLastPostId = 0;
|
||||||
|
int64_t vkLastPostId = 0;
|
||||||
|
private:
|
||||||
|
std::string m_saveFilename;
|
||||||
|
};
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user