delete old server

This commit is contained in:
sfja 2026-04-09 15:20:40 +02:00
parent ace572d6c1
commit 5f231954ef
11 changed files with 3 additions and 527 deletions

View File

@ -1,12 +0,0 @@
#pragma once
#include <cerrno>
#include <cstring>
#include <format>
#include <string_view>
namespace mst {
auto inline errno_shim(std::string_view message) -> std::string
{
return std::format("{} ({})", message, strerror(errno));
}
}

View File

@ -1,117 +0,0 @@
#include "event_loop.hpp"
#include "errno_shim.hpp"
#include "server.hpp"
#include <algorithm>
#include <print>
#include <stdexcept>
#include <sys/epoll.h>
#include <utility>
#define CHECK(EXPR) \
do { \
if (!(EXPR).has_value()) [[unlikely]] { \
return std::unexpected((EXPR).error()); \
} \
} while (false)
namespace mst::event {
auto Event::fd() -> int
{
switch (this->kind) {
case mst::event::EventKind::Server: {
auto& ref = std::get<std::unique_ptr<mst::Server>>(this->data);
return ref->fd();
break;
}
case mst::event::EventKind::Client: {
auto& ref = std::get<std::unique_ptr<mst::Client>>(this->data);
return ref->fd();
}
default:
std::unreachable();
}
}
auto Manager::start() -> Result<void>
{
epoll_event events[128] = { };
while (true) {
auto events_len = ::epoll_wait(this->epoll_fd, events, 128, -1);
if (events_len < 0) {
return std::unexpected(errno_shim("could not poll"));
}
for (int i = 0; i < events_len; ++i) {
auto event = (mst::event::Event*)events[i].data.ptr;
switch (event->kind) {
case mst::event::EventKind::Server: {
auto& ref
= std::get<std::unique_ptr<mst::Server>>(event->data);
auto res = ref->wake(*this);
CHECK(res);
break;
}
case mst::event::EventKind::Client: {
auto& ref
= std::get<std::unique_ptr<mst::Client>>(event->data);
auto res = ref->wake();
CHECK(res);
auto do_now = res.value();
if (do_now == Client::lllll::Disconnect) {
CHECK(this->deregister_event(ref->fd()));
}
break;
}
default:
std::unreachable();
}
}
}
}
auto Manager::register_event(std::unique_ptr<Event> event, int fd)
-> Result<void>
{
this->events.emplace_back(std::move(event));
auto poll_event = epoll_event { .events = EPOLLIN,
.data = { .ptr = events.back().get() } };
if (::epoll_ctl(this->epoll_fd, EPOLL_CTL_ADD, fd, &poll_event) < 0) {
return std::unexpected(errno_shim("could not add listener to epoll"));
}
return { };
}
auto Manager::deregister_event(int fd) -> Result<void>
{
auto poll_event = epoll_event { .events = EPOLLIN, .data = { } };
if (::epoll_ctl(this->epoll_fd, EPOLL_CTL_DEL, fd, &poll_event) < 0) {
return std::unexpected(
errno_shim("could not remove listener to epoll"));
}
size_t idx = this->events.size();
for (size_t i = 0; i < this->events.size(); ++i) {
if (this->events[i]->fd() == fd) {
idx = i;
}
}
if (idx == this->events.size()) {
throw std::runtime_error("contract broken");
}
this->events.erase(std::find_if(this->events.begin(),
this->events.end(),
[&](auto& e) { return e->fd() == fd; }));
return { };
}
auto Manager::create() -> Result<Manager>
{
auto epoll_fd = ::epoll_create1(0);
if (epoll_fd < 0) {
std::unexpected(mst::errno_shim("could not create epoll"));
}
return Manager(epoll_fd);
}
}

View File

@ -1,56 +0,0 @@
#pragma once
#include "errno_shim.hpp"
#include "result.hpp"
#include "server.hpp"
#include <algorithm>
#include <memory>
#include <sys/epoll.h>
#include <utility>
#include <variant>
#include <vector>
namespace mst {
class Server;
class Client;
namespace event {
enum class EventKind {
Server,
Client,
};
class Event {
public:
Event(std::variant<std::unique_ptr<mst::Server>,
std::unique_ptr<mst::Client>> data)
: data(std::move(data))
, kind(data.index() == 0 ? EventKind::Server : EventKind::Client)
{
}
auto fd() -> int;
std::variant<std::unique_ptr<mst::Server>, std::unique_ptr<mst::Client>>
data;
EventKind kind;
};
template <typename Data>
static auto make_event(Data&& data) -> std::unique_ptr<Event>
{
return std::make_unique<Event>(std::make_unique<Data>(std::move(data)));
}
class Manager {
public:
auto start() -> Result<void>;
auto register_event(std::unique_ptr<Event> event, int fd)
-> Result<void>;
auto deregister_event(int fd) -> Result<void>;
static auto create() -> Result<Manager>;
private:
int epoll_fd;
std::vector<std::unique_ptr<Event>> events;
Manager(int epoll_fd)
: epoll_fd(epoll_fd) { };
};
}
}

View File

@ -1,8 +1,6 @@
#include "server2.hpp"
// #include "event_loop.hpp"
#include "json.hpp" #include "json.hpp"
#include "mqtt.hpp" #include "mqtt.hpp"
// #include "server.hpp" #include "server2.hpp"
#include <print> #include <print>
#include <stdexcept> #include <stdexcept>
#include <string_view> #include <string_view>
@ -53,17 +51,6 @@ int main(void)
} }
}); });
// auto mgr = mst::event::Manager::create().value();
// auto x = mst::Server::bind(mgr, "0.0.0.0", PORT);
// if (!x) {
// std::println("{}", x.error());
// return 1;
// }
// std::println("starting");
// {
// auto x = mgr.start();
// }
server.listen(); server.listen();
mqtt_thread.join(); mqtt_thread.join();

View File

@ -1,57 +0,0 @@
#include "server.hpp"
#include "event_loop.hpp"
#include <print>
#include <sys/epoll.h>
namespace mst {
auto Client::wake() -> Result<Client::lllll>
{
uint8_t buffer[128] = { };
auto x = this->connection.read(buffer, 128);
if (!x) {
return std::unexpected(x.error());
}
auto bytes_read = x.value();
if (bytes_read == 0) {
return { Client::lllll::Disconnect };
}
for (size_t i = 0; i < bytes_read; ++i) {
std::println("{:c}", buffer[i]);
}
return { Client::lllll::Ok };
}
auto Server::bind(
mst::event::Manager& mgr, const std::string& host, uint16_t port)
-> Result<void>
{
auto x = TcpListener::bind(host, port);
if (!x) {
return std::unexpected(x.error());
}
auto listener = x.value();
auto res
= mgr.register_event(event::make_event(Server(listener)), listener.fd);
if (!res) {
return std::unexpected(res.error());
}
return { };
}
auto Server::wake(event::Manager& mgr) -> Result<void>
{
auto x = this->listener.accept();
auto connection = x.value();
auto res = mgr.register_event(
event::make_event(mst::Client(*this, connection)), connection.fd);
if (!res) {
return std::unexpected(res.error());
}
return { };
}
}

View File

@ -1,54 +0,0 @@
#pragma once
#include "event_loop.hpp"
#include "tcp.hpp"
namespace mst {
namespace event {
class Manager;
}
class Server {
public:
auto wake(mst::event::Manager& mgr) -> Result<void>;
static auto bind(
mst::event::Manager& mgr, const std::string& host, uint16_t port)
-> Result<void>;
auto fd() -> int
{
return this->listener.fd;
};
private:
TcpListener listener;
Server(TcpListener listener)
: listener(listener)
{
}
};
class Client {
public:
enum class lllll {
Ok,
Disconnect,
};
auto wake() -> Result<lllll>;
auto fd() -> int
{
return this->connection.fd;
};
Client(Server&, TcpConnection connection)
: connection(connection)
{
}
private:
TcpConnection connection;
};
}

View File

@ -1,84 +0,0 @@
#include "tcp.hpp"
#include "errno_shim.hpp"
#include <arpa/inet.h>
#include <cstdlib>
#include <expected>
#include <netdb.h>
#include <netinet/in.h>
#include <stdio.h>
#include <stdlib.h>
#include <string>
#include <sys/epoll.h>
#include <sys/socket.h>
#include <unistd.h>
namespace mst {
auto TcpConnection::write(uint8_t* buffer, size_t len) -> Result<size_t>
{
ssize_t bytes_written = ::write(this->fd, buffer, len);
if (bytes_written < 0) {
return std::unexpected(errno_shim("could not write bytes"));
}
return bytes_written;
}
auto TcpConnection::read(uint8_t* buffer, size_t len) -> Result<size_t>
{
ssize_t bytes_read = ::recv(this->fd, buffer, len, 0);
if (bytes_read < 0) {
return std::unexpected(errno_shim("could not read bytes"));
}
return bytes_read;
}
auto TcpListener::bind(const std::string& host, uint16_t port)
-> Result<TcpListener>
{
int socket_fd = 0;
if ((socket_fd = ::socket(AF_INET, SOCK_STREAM, 0)) < 0) {
return std::unexpected(errno_shim("could not get socket"));
}
struct sockaddr_in address = {
.sin_family = AF_INET,
.sin_port = ::htons(port),
.sin_addr = in_addr { .s_addr = ::inet_addr(host.c_str()) },
.sin_zero = { },
};
// enable immediate reuse of socket address
// see socket(7) about SO_REUSEADDR
// > Argument is an integer boolean flag.
int reuse_address = true;
if (::setsockopt(socket_fd,
SOL_SOCKET,
SO_REUSEADDR,
&reuse_address,
sizeof(reuse_address))) {
return std::unexpected(errno_shim("could not configure socket"));
}
if (::bind(socket_fd, (struct sockaddr*)&address, sizeof(address)) < 0) {
return std::unexpected(errno_shim("could not bind"));
}
if (::listen(socket_fd, 0) < 0) {
return std::unexpected(errno_shim("could not listen"));
}
return TcpListener(address, socket_fd);
}
auto TcpListener::accept() -> Result<TcpConnection>
{
socklen_t size = sizeof(this->address);
int client = ::accept(this->fd, (struct sockaddr*)&address, &size);
if (client < 0) {
return std::unexpected(errno_shim("could not accept"));
}
return TcpConnection(*this, client);
}
}

View File

@ -1,37 +0,0 @@
#pragma once
#include "result.hpp"
#include <cstdint>
#include <netinet/in.h>
#include <string>
#include <unistd.h>
namespace mst {
class TcpListener;
class TcpConnection {
public:
auto write(uint8_t* buffer, size_t len) -> Result<size_t>;
auto read(uint8_t* buffer, size_t len) -> Result<size_t>;
TcpConnection(TcpListener&, int fd)
: fd(fd) { };
int fd;
};
class TcpListener {
public:
static auto bind(const std::string& host, uint16_t port)
-> Result<TcpListener>;
auto accept() -> Result<TcpConnection>;
int fd;
private:
TcpListener(sockaddr_in address, int fd)
: fd(fd)
, address(address) { };
sockaddr_in address;
};
}

View File

@ -1,31 +0,0 @@
use std::collections::VecDeque;
pub enum Event {
Skateboard {
x: f64,
y: f64,
z: f64,
a: f64,
b: f64,
c: f64,
},
}
pub struct EventQueue {
queue: VecDeque<Event>,
}
impl EventQueue {
pub fn new() -> Self {
Self {
queue: VecDeque::new(),
}
}
pub fn poll(&mut self) -> Option<Event> {
self.queue.pop_front()
}
pub fn push(&mut self, event: Event) {
self.queue.push_back(event);
}
}

View File

@ -1,9 +1,7 @@
#![allow(dead_code)] #![allow(dead_code)]
mod engine; mod engine;
mod event_queue;
mod server2; mod server2;
pub mod vermiparous;
use core::panic; use core::panic;
use std::{ use std::{
@ -16,9 +14,7 @@ use std::{
use crate::{ use crate::{
engine::{Color, Key, Renderer, Scene, Shape, V2, V3}, engine::{Color, Key, Renderer, Scene, Shape, V2, V3},
event_queue::EventQueue,
server2::Server2, server2::Server2,
vermiparous::Server,
}; };
struct Skateboard { struct Skateboard {
@ -159,12 +155,11 @@ struct Game {
segments: Vec<Segment>, segments: Vec<Segment>,
camera_pos: V3, camera_pos: V3,
next_object_id: u32, next_object_id: u32,
event_queue: Arc<Mutex<EventQueue>>,
keys_pressed: HashSet<Key>, keys_pressed: HashSet<Key>,
} }
impl Game { impl Game {
fn new(event_queue: Arc<Mutex<EventQueue>>) -> Self { fn new() -> Self {
let start_pos = V3(0.0, -0.15, -0.4); let start_pos = V3(0.0, -0.15, -0.4);
Self { Self {
skateboard: Skateboard { skateboard: Skateboard {
@ -179,7 +174,6 @@ impl Game {
camera_pos: V3(0.0, 0.0, -1.0), camera_pos: V3(0.0, 0.0, -1.0),
segments: Vec::new(), segments: Vec::new(),
next_object_id: 0, next_object_id: 0,
event_queue,
keys_pressed: HashSet::new(), keys_pressed: HashSet::new(),
} }
} }
@ -404,8 +398,7 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {
t.join().unwrap(); t.join().unwrap();
let mut sdl_io = engine::SdlIo::new()?; let mut sdl_io = engine::SdlIo::new()?;
let event_queue = Arc::new(Mutex::new(EventQueue::new())); let mut game = Game::new();
let mut game = Game::new(event_queue.clone());
let segments: Vec<Segment> = vec![Segment::new( let segments: Vec<Segment> = vec![Segment::new(
0, 0,
vec![Obstacle { vec![Obstacle {

View File

@ -1,56 +0,0 @@
use std::{
io::{BufRead, BufReader},
net::TcpStream,
sync::{Arc, Mutex},
};
use crate::event_queue::{Event, EventQueue};
pub struct Server(TcpStream);
impl Server {
pub fn start(mut self, event_queue: Arc<Mutex<EventQueue>>) {
loop {
let data = match self.read() {
Ok(data) => data,
Err(err) => {
println!("{}", err);
continue;
}
};
event_queue.lock().unwrap().push(data);
}
}
pub fn bind(addr: &str) -> Self {
Server(TcpStream::connect(addr).unwrap())
}
fn get_fallible(data: &[f64], idx: usize) -> Result<f64, String> {
data.get(idx)
.cloned()
.ok_or_else(|| format!("protocol error: {idx}"))
}
pub fn read(&mut self) -> Result<Event, String> {
let mut reader = BufReader::new(&mut self.0);
let mut data = String::new();
reader
.read_line(&mut data)
.map_err(|err| format!("io error: {err}"))?;
let data = data
.split(",")
.map(|x| x.parse::<f64>())
.collect::<Result<Vec<f64>, _>>();
let data = data.map_err(|err| format!("protocol error: {err}"))?;
Ok(Event::Skateboard {
x: Self::get_fallible(&data, 0)?,
y: Self::get_fallible(&data, 1)?,
z: Self::get_fallible(&data, 2)?,
a: Self::get_fallible(&data, 3)?,
b: Self::get_fallible(&data, 4)?,
c: Self::get_fallible(&data, 5)?,
})
}
}