mirror of
https://github.com/Mercantec-GHC/h5-projekt-mst.git
synced 2026-08-26 21:27:38 +02:00
delete old server
This commit is contained in:
parent
ace572d6c1
commit
5f231954ef
@ -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));
|
||||
}
|
||||
}
|
||||
@ -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);
|
||||
}
|
||||
}
|
||||
@ -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) { };
|
||||
};
|
||||
}
|
||||
}
|
||||
@ -1,8 +1,6 @@
|
||||
#include "server2.hpp"
|
||||
// #include "event_loop.hpp"
|
||||
#include "json.hpp"
|
||||
#include "mqtt.hpp"
|
||||
// #include "server.hpp"
|
||||
#include "server2.hpp"
|
||||
#include <print>
|
||||
#include <stdexcept>
|
||||
#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();
|
||||
|
||||
mqtt_thread.join();
|
||||
|
||||
@ -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 { };
|
||||
}
|
||||
|
||||
}
|
||||
@ -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;
|
||||
};
|
||||
|
||||
}
|
||||
@ -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);
|
||||
}
|
||||
|
||||
}
|
||||
@ -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;
|
||||
};
|
||||
}
|
||||
@ -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);
|
||||
}
|
||||
}
|
||||
@ -1,9 +1,7 @@
|
||||
#![allow(dead_code)]
|
||||
|
||||
mod engine;
|
||||
mod event_queue;
|
||||
mod server2;
|
||||
pub mod vermiparous;
|
||||
|
||||
use core::panic;
|
||||
use std::{
|
||||
@ -16,9 +14,7 @@ use std::{
|
||||
|
||||
use crate::{
|
||||
engine::{Color, Key, Renderer, Scene, Shape, V2, V3},
|
||||
event_queue::EventQueue,
|
||||
server2::Server2,
|
||||
vermiparous::Server,
|
||||
};
|
||||
|
||||
struct Skateboard {
|
||||
@ -159,12 +155,11 @@ struct Game {
|
||||
segments: Vec<Segment>,
|
||||
camera_pos: V3,
|
||||
next_object_id: u32,
|
||||
event_queue: Arc<Mutex<EventQueue>>,
|
||||
keys_pressed: HashSet<Key>,
|
||||
}
|
||||
|
||||
impl Game {
|
||||
fn new(event_queue: Arc<Mutex<EventQueue>>) -> Self {
|
||||
fn new() -> Self {
|
||||
let start_pos = V3(0.0, -0.15, -0.4);
|
||||
Self {
|
||||
skateboard: Skateboard {
|
||||
@ -179,7 +174,6 @@ impl Game {
|
||||
camera_pos: V3(0.0, 0.0, -1.0),
|
||||
segments: Vec::new(),
|
||||
next_object_id: 0,
|
||||
event_queue,
|
||||
keys_pressed: HashSet::new(),
|
||||
}
|
||||
}
|
||||
@ -404,8 +398,7 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {
|
||||
t.join().unwrap();
|
||||
|
||||
let mut sdl_io = engine::SdlIo::new()?;
|
||||
let event_queue = Arc::new(Mutex::new(EventQueue::new()));
|
||||
let mut game = Game::new(event_queue.clone());
|
||||
let mut game = Game::new();
|
||||
let segments: Vec<Segment> = vec![Segment::new(
|
||||
0,
|
||||
vec![Obstacle {
|
||||
|
||||
@ -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)?,
|
||||
})
|
||||
}
|
||||
}
|
||||
Loading…
x
Reference in New Issue
Block a user