mirror of
https://github.com/Mercantec-GHC/h5-projekt-mst.git
synced 2026-08-27 05:37:39 +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 "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();
|
||||||
|
|||||||
@ -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)]
|
#![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 {
|
||||||
|
|||||||
@ -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