17
0
mirror of https://github.com/MaSzyna-EU07/maszyna.git synced 2026-10-17 16:49:21 +02:00
Files
maszyna/network/network.cppm
maj00r b8f040e6fd propagate template headers transitively, import Console where used
AnimModel.cpp reaches cParser through the simulation core, not a direct
import, so the previous pass missed it; the propagation now follows the
whole import closure. Train.cpp, drivermode.cpp and Globals.cpp call
Console:: inside _WIN32 guards without importing eu07.console - invisible
on Linux, where those blocks are skipped.
2026-09-10 01:41:24 +02:00

143 lines
3.4 KiB
C++

module;
#include <array>
#include <limits>
#include <mutex>
#include <ostream>
#include <sstream>
#include <type_traits>
#include <utility>
#include <deque>
#include <cstddef>
#include <string>
#include <tuple>
#include <unordered_map>
#include <vector>
#include <memory>
#include <istream>
#include <fstream>
#include <functional>
#include <optional>
#include <queue>
#include <chrono>
export module eu07.network.network;
import eu07.network.message;
import eu07.input.command;
export {
namespace network
{
//m7todo: separate client/server connection class?
class connection
{
friend class server;
friend class client;
private:
const int CATCHUP_PACKETS = 300;
bool is_client;
protected:
std::shared_ptr<std::istream> backbuffer;
size_t backbuffer_pos;
size_t packet_counter;
void send_complete(std::shared_ptr<std::string> buf);
void catch_up();
public:
std::function<void(const message &msg)> message_handler;
virtual void connected() = 0;
virtual void send_message(const message &msg) = 0;
virtual void send_messages(const std::vector<std::shared_ptr<message>> &messages) = 0;
connection(bool client = false, size_t counter = 0);
void set_handler(std::function<void(const message &msg)> handler);
virtual void disconnect() = 0;
enum peer_state {
AWAITING_HELLO,
CATCHING_UP,
ACTIVE,
DEAD
};
peer_state state;
};
class server
{
private:
std::shared_ptr<std::istream> backbuffer;
protected:
void handle_message(std::shared_ptr<connection> conn, const message &msg);
std::vector<std::shared_ptr<connection>> clients;
command_queue::commands_map client_commands_queue;
public:
server(std::shared_ptr<std::istream> buf);
void push_delta(const frame_info &msg);
command_queue::commands_map pop_commands();
};
class client
{
protected:
virtual void connect() = 0;
void handle_message(std::shared_ptr<connection> conn, const message &msg);
std::shared_ptr<connection> conn;
size_t resume_frame_counter = 0;
size_t reconnect_delay = 0;
const size_t RECONNECT_DELAY_FRAMES = 60;
const float MAX_BUFFER_SIZE = 60.0f;
const float JITTERINESS_MIX = 0.998f;
const float TARGET_MIN = 2.0f;
const float TARGET_MIX = 0.98f;
const float JITTERINESS_MULTIPIER = 2.0f;
const float CONSUME_MULTIPIER = 0.05f;
std::queue<frame_info> delta_queue;
float last_target = 20.0f;
float jitteriness = 1.0f;
float consume_counter = 0.0f;
std::chrono::high_resolution_clock::time_point last_rcv;
std::chrono::high_resolution_clock::time_point last_frame;
std::chrono::high_resolution_clock::duration frame_time;
public:
void update();
std::tuple<double, double, command_queue::commands_map> get_next_delta(int counter);
void send_commands(command_queue::commands_map commands);
int get_frame_counter() {
return resume_frame_counter;
}
int get_awaiting_frames() {
return delta_queue.size();
}
};
class backend_manager
{
public:
virtual std::shared_ptr<server> create_server(std::shared_ptr<std::fstream>, const std::string &conf) = 0;
virtual std::shared_ptr<client> create_client(const std::string &conf) = 0;
virtual void update() = 0;
};
// HACK: static initialization order fiasco fix
// extern std::unordered_map<std::string, backend_manager*> backend_list;
using backend_list_t = std::unordered_map<std::string, backend_manager*>;
backend_list_t& backend_list();
}
} // export