diff --git a/musique/errors.cc b/musique/errors.cc index 4bdb3e2..2bc15c3 100644 --- a/musique/errors.cc +++ b/musique/errors.cc @@ -150,6 +150,7 @@ std::ostream& operator<<(std::ostream& os, Error const& err) [](errors::Unexpected_Keyword const&) { return "Unexpected keyword"; }, [](errors::Unrecognized_Character const&) { return "Unrecognized character"; }, [](errors::Wrong_Arity_Of const&) { return "Different arity then expected"; }, + [](errors::Temporary_Error_Serial_Port const&) { return "Serial port connection failed"; }, [](errors::internal::Unexpected_Token const&) { return "Unexpected token"; }, [](errors::Arithmetic const& err) { switch (err.type) { @@ -271,6 +272,15 @@ std::ostream& operator<<(std::ostream& os, Error const& err) } }, + [&](errors::Temporary_Error_Serial_Port const& error) { + os << "Error serial port: " << error.message << '\n'; + os << "\n"; + + pretty::begin_comment(os); + os << "This error message is temporary\n"; + pretty::end(os); + }, + [&](errors::Unsupported_Types_For const& err) { switch (err.type) { break; case errors::Unsupported_Types_For::Function: diff --git a/musique/errors.hh b/musique/errors.hh index b5e546a..5e52448 100644 --- a/musique/errors.hh +++ b/musique/errors.hh @@ -169,6 +169,11 @@ namespace errors }; } + struct Temporary_Error_Serial_Port + { + std::string message; + }; + /// All possible error types using Details = std::variant< Arithmetic, @@ -180,6 +185,7 @@ namespace errors Not_Callable, Operation_Requires_Midi_Connection, Out_Of_Range, + Temporary_Error_Serial_Port, Undefined_Operator, Unexpected_Empty_Source, Unexpected_Keyword, diff --git a/musique/interpreter/builtin_functions.cc b/musique/interpreter/builtin_functions.cc index 0ae2bd9..142d7bc 100644 --- a/musique/interpreter/builtin_functions.cc +++ b/musique/interpreter/builtin_functions.cc @@ -1615,6 +1615,18 @@ static Result builtin_peers(Interpreter &interpreter, std::vector) return Number(interpreter.starter.peers()); } +static std::optional ensure_serial_available(Interpreter &interpreter) +{ + if (interpreter.serialport->error_message->empty()) + return std::nullopt; + + return Error{ + errors::Temporary_Error_Serial_Port { + .message = *std::exchange(interpreter.serialport->error_message, std::nullopt), + } + }; +} + //: Ustaw wyjście MIDI w danym kontekście na dany port //: //: Dostępne opcje to numer portu oraz symbol `'virtual` tworzacy port wirtualny MIDI @@ -1660,6 +1672,7 @@ static Result builtin_port(Interpreter &interpreter, std::vector a } if (port_type == "serial") { + Try(ensure_serial_available(interpreter)); if (auto it = Context::established_connections.find(midi::connections::Serial_Port{}); it != Context::established_connections.end()) { interpreter.current_context->port = it->second; return {}; @@ -1685,7 +1698,7 @@ static Result builtin_port(Interpreter &interpreter, std::vector a //: Kolejne parametry tworzą zbiór z którego równomiernie wejście będzie wybierane na podstawie wartości static Result builtin_ctrl(Interpreter &interpreter, std::vector args) { - if (args.size() == 1) { + if (args.empty()) { error: return errors::Unsupported_Types_For { .type = errors::Unsupported_Types_For::Function, @@ -1694,6 +1707,7 @@ static Result builtin_ctrl(Interpreter &interpreter, std::vector a }, }; } + Try(ensure_serial_available(interpreter)); auto input_index = 0; if (auto a = get_if(args.front())) { diff --git a/musique/serialport/serialport.cc b/musique/serialport/serialport.cc index 057120a..62824e2 100644 --- a/musique/serialport/serialport.cc +++ b/musique/serialport/serialport.cc @@ -102,8 +102,13 @@ namespace serialport{ } } catch (std::exception &e) { /// No connection to the device - + state.error_message = e.what(); // std::cerr << "Unhandled Exception: " << e.what() << '\n'; + // + // Sleep until error message is cleared since we don't need to try always to reconnect + while (!state.error_message->empty()) { + std::this_thread::yield(); + } } } return; diff --git a/musique/serialport/serialport.hh b/musique/serialport/serialport.hh index 08e6d90..a494805 100644 --- a/musique/serialport/serialport.hh +++ b/musique/serialport/serialport.hh @@ -1,13 +1,14 @@ #ifndef MUSIQUE_SERIALPORT_SERIALPORT_HH #define MUSIQUE_SERIALPORT_SERIALPORT_HH -#include -#include -#include #include #include #include +#include #include +#include +#include +#include namespace serialport{ constexpr std::size_t MAX_STATE_COUNT = 8; @@ -18,6 +19,9 @@ namespace serialport{ std::array, 128> message_data; std::atomic head = 0; std::atomic tail = 0; + + std::optional error_message; + int test(); Number get(unsigned position) const; void send(uint8_t message_type, uint8_t note_number);