protobuf server
This commit is contained in:
@@ -0,0 +1,4 @@
|
|||||||
|
/proto/service.grpc.pb.cc
|
||||||
|
/proto/service.grpc.pb.h
|
||||||
|
/proto/service.pb.cc
|
||||||
|
/proto/service.pb.h
|
||||||
+35
-7
@@ -1,10 +1,9 @@
|
|||||||
cmake_minimum_required(VERSION 3.10)
|
cmake_minimum_required(VERSION 3.20)
|
||||||
project(serial_sample CXX)
|
project(serial_sample CXX)
|
||||||
|
|
||||||
set(CMAKE_CXX_STANDARD 20)
|
set(CMAKE_CXX_STANDARD 20)
|
||||||
set(CMAKE_CXX_STANDARD_REQUIRED ON)
|
set(CMAKE_CXX_STANDARD_REQUIRED ON)
|
||||||
|
|
||||||
# 1. FIX: Tell CMake to use modern GLVND OpenGL libraries and suppress the warning
|
|
||||||
set(OpenGL_GL_PREFERENCE GLVND)
|
set(OpenGL_GL_PREFERENCE GLVND)
|
||||||
|
|
||||||
# Define file paths for thirdparty modules
|
# Define file paths for thirdparty modules
|
||||||
@@ -16,9 +15,10 @@ find_package(PkgConfig REQUIRED)
|
|||||||
find_package(OpenGL REQUIRED)
|
find_package(OpenGL REQUIRED)
|
||||||
pkg_check_modules(GLFW REQUIRED glfw3)
|
pkg_check_modules(GLFW REQUIRED glfw3)
|
||||||
pkg_check_modules(LIBSERIALPORT REQUIRED IMPORTED_TARGET libserialport)
|
pkg_check_modules(LIBSERIALPORT REQUIRED IMPORTED_TARGET libserialport)
|
||||||
|
find_package(Protobuf REQUIRED)
|
||||||
|
find_package(gRPC REQUIRED)
|
||||||
|
|
||||||
|
# ImGUI things
|
||||||
# Collect core library source files
|
|
||||||
set(IMGUI_SOURCES
|
set(IMGUI_SOURCES
|
||||||
${IMGUI_DIR}/imgui.cpp
|
${IMGUI_DIR}/imgui.cpp
|
||||||
${IMGUI_DIR}/imgui_demo.cpp
|
${IMGUI_DIR}/imgui_demo.cpp
|
||||||
@@ -37,6 +37,34 @@ set(IMPLOT_SOURCES
|
|||||||
include/SerialApp.h
|
include/SerialApp.h
|
||||||
)
|
)
|
||||||
|
|
||||||
|
set(proto_srcs "${CMAKE_CURRENT_BINARY_DIR}/service.pb.cc")
|
||||||
|
set(proto_hdrs "${CMAKE_CURRENT_BINARY_DIR}/service.pb.h")
|
||||||
|
set(grpc_srcs "${CMAKE_CURRENT_BINARY_DIR}/service.grpc.pb.cc")
|
||||||
|
set(grpc_hdrs "${CMAKE_CURRENT_BINARY_DIR}/service.grpc.pb.h")
|
||||||
|
|
||||||
|
add_custom_command(
|
||||||
|
OUTPUT "${proto_srcs}" "${proto_hdrs}" "${grpc_srcs}" "${grpc_hdrs}"
|
||||||
|
COMMAND ${Protobuf_PROTOC_EXECUTABLE}
|
||||||
|
ARGS --grpc_out="${CMAKE_CURRENT_BINARY_DIR}"
|
||||||
|
--cpp_out="${CMAKE_CURRENT_BINARY_DIR}"
|
||||||
|
-I "${CMAKE_CURRENT_SOURCE_DIR}/proto"
|
||||||
|
--plugin=protoc-gen-grpc=/usr/bin/grpc_cpp_plugin
|
||||||
|
"${CMAKE_CURRENT_SOURCE_DIR}/proto/service.proto"
|
||||||
|
DEPENDS "${CMAKE_CURRENT_SOURCE_DIR}/proto/service.proto"
|
||||||
|
)
|
||||||
|
|
||||||
|
set_source_files_properties(
|
||||||
|
"${proto_srcs}" "${proto_hdrs}" "${grpc_srcs}" "${grpc_hdrs}"
|
||||||
|
PROPERTIES GENERATED TRUE
|
||||||
|
)
|
||||||
|
|
||||||
|
add_library(proto_lib STATIC ${proto_srcs} ${grpc_srcs} proto/service.proto)
|
||||||
|
target_link_libraries(proto_lib PUBLIC gRPC::grpc++ ${Protobuf_LIBRARIES})
|
||||||
|
target_include_directories(proto_lib PUBLIC
|
||||||
|
${CMAKE_CURRENT_BINARY_DIR}
|
||||||
|
${Protobuf_INCLUDE_DIRS}
|
||||||
|
)
|
||||||
|
|
||||||
add_executable(${PROJECT_NAME} main.cpp
|
add_executable(${PROJECT_NAME} main.cpp
|
||||||
${IMGUI_SOURCES}
|
${IMGUI_SOURCES}
|
||||||
${IMPLOT_SOURCES}
|
${IMPLOT_SOURCES}
|
||||||
@@ -48,10 +76,10 @@ add_executable(${PROJECT_NAME} main.cpp
|
|||||||
include/LogWindow.h
|
include/LogWindow.h
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
# Provide Header Search Paths
|
|
||||||
target_include_directories(${PROJECT_NAME} PRIVATE
|
target_include_directories(${PROJECT_NAME} PRIVATE
|
||||||
${CMAKE_CURRENT_SOURCE_DIR}/src
|
${CMAKE_CURRENT_SOURCE_DIR}/src
|
||||||
|
${CMAKE_CURRENT_BINARY_DIR}
|
||||||
|
${Protobuf_INCLUDE_DIRS}
|
||||||
${IMGUI_DIR}
|
${IMGUI_DIR}
|
||||||
${IMGUI_DIR}/backends
|
${IMGUI_DIR}/backends
|
||||||
${IMPLOT_DIR}
|
${IMPLOT_DIR}
|
||||||
@@ -59,7 +87,6 @@ target_include_directories(${PROJECT_NAME} PRIVATE
|
|||||||
${OPENGL_INCLUDE_DIR}
|
${OPENGL_INCLUDE_DIR}
|
||||||
)
|
)
|
||||||
|
|
||||||
# Link Libraries
|
|
||||||
target_link_libraries(${PROJECT_NAME} PRIVATE
|
target_link_libraries(${PROJECT_NAME} PRIVATE
|
||||||
${GLFW_LIBRARIES}
|
${GLFW_LIBRARIES}
|
||||||
OpenGL::GL
|
OpenGL::GL
|
||||||
@@ -67,6 +94,7 @@ target_link_libraries(${PROJECT_NAME} PRIVATE
|
|||||||
pthread
|
pthread
|
||||||
dl
|
dl
|
||||||
PkgConfig::LIBSERIALPORT
|
PkgConfig::LIBSERIALPORT
|
||||||
|
proto_lib
|
||||||
)
|
)
|
||||||
|
|
||||||
configure_file(style/dracula.theme ${CMAKE_CURRENT_BINARY_DIR}/dracula.theme COPYONLY)
|
configure_file(style/dracula.theme ${CMAKE_CURRENT_BINARY_DIR}/dracula.theme COPYONLY)
|
||||||
|
|||||||
@@ -11,10 +11,10 @@ public:
|
|||||||
~ConnectionWindow();
|
~ConnectionWindow();
|
||||||
|
|
||||||
void initialize();
|
void initialize();
|
||||||
void render(bool* p_open);
|
void render(bool* paramOpen);
|
||||||
|
|
||||||
bool isConnected() const { return connected; }
|
[[nodiscard]] bool isConnected() const { return connected; }
|
||||||
struct sp_port* getActivePort() const { return activePort; }
|
[[nodiscard]] sp_port* getActivePort() const { return activePort; }
|
||||||
|
|
||||||
void forceLogMessage(const std::string& msg);
|
void forceLogMessage(const std::string& msg);
|
||||||
std::string& getSharedLog() { return txLog; }
|
std::string& getSharedLog() { return txLog; }
|
||||||
|
|||||||
+1
-1
@@ -8,7 +8,7 @@ public:
|
|||||||
LogWindow() = default;
|
LogWindow() = default;
|
||||||
~LogWindow() = default;
|
~LogWindow() = default;
|
||||||
|
|
||||||
void render(bool* paramOpen, ConnectionWindow& connectionWindow);
|
static void render(bool* paramOpen, ConnectionWindow& connectionWindow);
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // SERIAL_SAMPLE_LOGWINDOW_H
|
#endif // SERIAL_SAMPLE_LOGWINDOW_H
|
||||||
|
|||||||
@@ -15,8 +15,8 @@ public:
|
|||||||
void render(bool* p_open, ConnectionWindow& connectionWindow);
|
void render(bool* p_open, ConnectionWindow& connectionWindow);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void sendHexPayload(const std::string& hexString, ConnectionWindow& connectionWindow);
|
static void sendHexPayload(const std::string& hexString, ConnectionWindow& connectionWindow);
|
||||||
char hexInputBuffer[256];
|
char hexInputBuffer[256]{};
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // SERIAL_SAMPLE_PAYLOADWINDOW_H
|
#endif // SERIAL_SAMPLE_PAYLOADWINDOW_H
|
||||||
|
|||||||
+3
-2
@@ -14,11 +14,12 @@ public:
|
|||||||
void initialize();
|
void initialize();
|
||||||
void renderUI();
|
void renderUI();
|
||||||
|
|
||||||
bool isClosing() const { return shouldClose; }
|
[[nodiscard]] bool isClosing() const { return shouldClose; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void renderMainMenuBar();
|
void renderMainMenuBar();
|
||||||
bool loadTheme(const std::string& filepath); // Метод парсинга файла темы
|
|
||||||
|
static bool loadTheme(const std::string& filepath); // Метод парсинга файла темы
|
||||||
|
|
||||||
bool showConnectionWindow = true;
|
bool showConnectionWindow = true;
|
||||||
bool showPayloadWindow = true;
|
bool showPayloadWindow = true;
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
#include <memory>
|
||||||
|
#include <thread> // Добавили для работы с потоками
|
||||||
#include "imgui.h"
|
#include "imgui.h"
|
||||||
#include "imgui_impl_glfw.h"
|
#include "imgui_impl_glfw.h"
|
||||||
#include "imgui_impl_opengl3.h"
|
#include "imgui_impl_opengl3.h"
|
||||||
@@ -7,56 +8,79 @@
|
|||||||
#include <GLFW/glfw3.h>
|
#include <GLFW/glfw3.h>
|
||||||
|
|
||||||
#include "include/SerialApp.h"
|
#include "include/SerialApp.h"
|
||||||
|
#include <grpcpp/grpcpp.h>
|
||||||
|
|
||||||
|
// работает только после первой генерации
|
||||||
|
#include "service.grpc.pb.h"
|
||||||
|
|
||||||
static void glfw_error_callback(int error, const char* description) {
|
static void glfw_error_callback(int error, const char* description) {
|
||||||
fprintf(stderr, "GLFW Error %d: %s\n", error, description);
|
fprintf(stderr, "GLFW Error %d: %s\n", error, description);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Простейшая реализация вашего сервиса gRPC (для примера)
|
||||||
|
class MyServiceImpl final : public serial_sample::Greeter::Service {
|
||||||
|
grpc::Status SayHello(grpc::ServerContext* context,
|
||||||
|
const serial_sample::HelloRequest* request,
|
||||||
|
serial_sample::HelloReply* reply) override {
|
||||||
|
reply->set_message("Hello, " + request->name() + "!");
|
||||||
|
return grpc::Status::OK;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
int main(int, char**) {
|
int main(int, char**) {
|
||||||
glfwSetErrorCallback(glfw_error_callback);
|
glfwSetErrorCallback(glfw_error_callback);
|
||||||
if (!glfwInit()) return 1;
|
if (!glfwInit()) return 1;
|
||||||
|
|
||||||
// Настройка версии OpenGL (3.3 Core)
|
|
||||||
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
|
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
|
||||||
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
|
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
|
||||||
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
|
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
|
||||||
|
|
||||||
// Создание окна ОС
|
|
||||||
GLFWwindow* window = glfwCreateWindow(1280, 720, "Serial App", nullptr, nullptr);
|
GLFWwindow* window = glfwCreateWindow(1280, 720, "Serial App", nullptr, nullptr);
|
||||||
if (window == nullptr) return 1;
|
if (window == nullptr) return 1;
|
||||||
glfwMakeContextCurrent(window);
|
glfwMakeContextCurrent(window);
|
||||||
glfwSwapInterval(1); // Включение вертикальной синхронизации (V-Sync)
|
glfwSwapInterval(1);
|
||||||
|
|
||||||
// Инициализация контекста ImGui
|
|
||||||
IMGUI_CHECKVERSION();
|
IMGUI_CHECKVERSION();
|
||||||
ImGui::CreateContext();
|
ImGui::CreateContext();
|
||||||
ImGuiIO& io = ImGui::GetIO(); (void)io;
|
ImGuiIO& io = ImGui::GetIO(); (void)io;
|
||||||
ImGui::StyleColorsDark();
|
ImGui::StyleColorsDark();
|
||||||
|
|
||||||
// Инициализация платформных бэкендов внутри ImGui
|
|
||||||
ImGui_ImplGlfw_InitForOpenGL(window, true);
|
ImGui_ImplGlfw_InitForOpenGL(window, true);
|
||||||
ImGui_ImplOpenGL3_Init("#version 130");
|
ImGui_ImplOpenGL3_Init("#version 130");
|
||||||
|
|
||||||
// Создаем и инициализируем наше изолированное приложение
|
|
||||||
SerialApp app;
|
SerialApp app;
|
||||||
app.initialize();
|
app.initialize();
|
||||||
|
|
||||||
// Главный цикл приложения
|
// === НАЧАЛО ИНИЦИАЛИЗАЦИИ gRPC СЕРВЕРА ===
|
||||||
|
std::string server_address("0.0.0.0:50051");
|
||||||
|
MyServiceImpl grpc_service;
|
||||||
|
|
||||||
|
grpc::ServerBuilder builder;
|
||||||
|
builder.AddListeningPort(server_address, grpc::InsecureServerCredentials());
|
||||||
|
builder.RegisterService(&grpc_service);
|
||||||
|
|
||||||
|
std::unique_ptr<grpc::Server> grpc_server(builder.BuildAndStart());
|
||||||
|
std::cout << "gRPC Server listening on " << server_address << std::endl;
|
||||||
|
|
||||||
|
// Запускаем сервер в фоновом потоке
|
||||||
|
std::thread grpc_thread([&grpc_server]() {
|
||||||
|
grpc_server->Wait(); // Блокирует фоновый поток, пока сервер работает
|
||||||
|
});
|
||||||
|
// =========================================
|
||||||
|
|
||||||
|
// Главный цикл приложения (GUI поток)
|
||||||
while (!glfwWindowShouldClose(window)) {
|
while (!glfwWindowShouldClose(window)) {
|
||||||
glfwPollEvents();
|
glfwPollEvents();
|
||||||
|
|
||||||
// Старт нового кадра ImGui
|
|
||||||
ImGui_ImplOpenGL3_NewFrame();
|
ImGui_ImplOpenGL3_NewFrame();
|
||||||
ImGui_ImplGlfw_NewFrame();
|
ImGui_ImplGlfw_NewFrame();
|
||||||
ImGui::NewFrame();
|
ImGui::NewFrame();
|
||||||
|
|
||||||
// Рендерим наше кастомное UI
|
|
||||||
app.renderUI();
|
app.renderUI();
|
||||||
if (app.isClosing()) {
|
if (app.isClosing()) {
|
||||||
glfwSetWindowShouldClose(window, GLFW_TRUE);
|
glfwSetWindowShouldClose(window, GLFW_TRUE);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Рендеринг графики
|
|
||||||
ImGui::Render();
|
ImGui::Render();
|
||||||
int display_w, display_h;
|
int display_w, display_h;
|
||||||
glfwGetFramebufferSize(window, &display_w, &display_h);
|
glfwGetFramebufferSize(window, &display_w, &display_h);
|
||||||
@@ -68,7 +92,18 @@ int main(int, char**) {
|
|||||||
glfwSwapBuffers(window);
|
glfwSwapBuffers(window);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Очистка ресурсов перед выходом
|
// === КОРРЕКТНОЕ ВЫКЛЮЧЕНИЕ gRPC СЕРВЕРА ===
|
||||||
|
std::cout << "Shutting down gRPC server..." << std::endl;
|
||||||
|
// Останавливаем сервер (это разблокирует метод Wait() в фоновом потоке)
|
||||||
|
grpc_server->Shutdown();
|
||||||
|
|
||||||
|
// Обязательно дожидаемся завершения фонового потока перед выходом из main
|
||||||
|
if (grpc_thread.joinable()) {
|
||||||
|
grpc_thread.join();
|
||||||
|
}
|
||||||
|
std::cout << "gRPC server thread joined." << std::endl;
|
||||||
|
// =========================================
|
||||||
|
|
||||||
ImGui_ImplOpenGL3_Shutdown();
|
ImGui_ImplOpenGL3_Shutdown();
|
||||||
ImGui_ImplGlfw_Shutdown();
|
ImGui_ImplGlfw_Shutdown();
|
||||||
ImGui::DestroyContext();
|
ImGui::DestroyContext();
|
||||||
|
|||||||
@@ -0,0 +1,15 @@
|
|||||||
|
syntax = "proto3";
|
||||||
|
|
||||||
|
package serial_sample;
|
||||||
|
|
||||||
|
service Greeter {
|
||||||
|
rpc SayHello (HelloRequest) returns (HelloReply) {}
|
||||||
|
}
|
||||||
|
|
||||||
|
message HelloRequest {
|
||||||
|
string name = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
message HelloReply {
|
||||||
|
string message = 1;
|
||||||
|
}
|
||||||
@@ -1,6 +1,5 @@
|
|||||||
#include "../include/ConnectionWindow.h"
|
#include "../include/ConnectionWindow.h"
|
||||||
#include "imgui.h"
|
#include "imgui.h"
|
||||||
#include <cstdio>
|
|
||||||
|
|
||||||
ConnectionWindow::ConnectionWindow()
|
ConnectionWindow::ConnectionWindow()
|
||||||
: selectedPortIdx(0), connected(false), activePort(nullptr) {
|
: selectedPortIdx(0), connected(false), activePort(nullptr) {
|
||||||
@@ -27,10 +26,10 @@ void ConnectionWindow::refreshPorts() {
|
|||||||
ports.clear();
|
ports.clear();
|
||||||
selectedPortIdx = 0;
|
selectedPortIdx = 0;
|
||||||
|
|
||||||
struct sp_port** port_list;
|
sp_port** portList;
|
||||||
if (sp_list_ports(&port_list) == SP_OK) {
|
if (sp_list_ports(&portList) == SP_OK) {
|
||||||
for (int i = 0; port_list[i] != nullptr; i++) {
|
for (int i = 0; portList[i] != nullptr; i++) {
|
||||||
struct sp_port* port = port_list[i];
|
const sp_port* port = portList[i];
|
||||||
SerialPortInfo info;
|
SerialPortInfo info;
|
||||||
const char* name = sp_get_port_name(port);
|
const char* name = sp_get_port_name(port);
|
||||||
info.portName = name ? name : "Unknown";
|
info.portName = name ? name : "Unknown";
|
||||||
@@ -38,7 +37,7 @@ void ConnectionWindow::refreshPorts() {
|
|||||||
info.description = desc ? desc : "No Description";
|
info.description = desc ? desc : "No Description";
|
||||||
ports.push_back(info);
|
ports.push_back(info);
|
||||||
}
|
}
|
||||||
sp_free_port_list(port_list);
|
sp_free_port_list(portList);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ports.empty()) {
|
if (ports.empty()) {
|
||||||
@@ -50,8 +49,8 @@ void ConnectionWindow::forceLogMessage(const std::string& msg) {
|
|||||||
txLog += msg + "\n";
|
txLog += msg + "\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
void ConnectionWindow::render(bool* p_open) {
|
void ConnectionWindow::render(bool* paramOpen) {
|
||||||
if (!ImGui::Begin("Connection Settings", p_open)) {
|
if (!ImGui::Begin("Connection Settings", paramOpen)) {
|
||||||
ImGui::End();
|
ImGui::End();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -62,17 +61,17 @@ void ConnectionWindow::render(bool* p_open) {
|
|||||||
ImGui::SameLine();
|
ImGui::SameLine();
|
||||||
|
|
||||||
// 1. Выбор COM-порта
|
// 1. Выбор COM-порта
|
||||||
std::string combo_preview = ports[selectedPortIdx].portName;
|
std::string preview = ports[selectedPortIdx].portName;
|
||||||
if (ports[selectedPortIdx].portName != "None") {
|
if (ports[selectedPortIdx].portName != "None") {
|
||||||
combo_preview += " (" + ports[selectedPortIdx].description + ")";
|
preview += " (" + ports[selectedPortIdx].description + ")";
|
||||||
}
|
}
|
||||||
|
|
||||||
ImGui::BeginDisabled(connected);
|
ImGui::BeginDisabled(connected);
|
||||||
if (ImGui::BeginCombo("Serial Port", combo_preview.c_str())) {
|
if (ImGui::BeginCombo("Serial Port", preview.c_str())) {
|
||||||
for (int n = 0; n < ports.size(); n++) {
|
for (int n = 0; n < ports.size(); n++) {
|
||||||
const bool is_selected = (selectedPortIdx == n);
|
const bool isSelected = (selectedPortIdx == n);
|
||||||
std::string item_text = ports[n].portName + " - " + ports[n].description;
|
std::string item_text = ports[n].portName + " - " + ports[n].description;
|
||||||
if (ImGui::Selectable(item_text.c_str(), is_selected)) {
|
if (ImGui::Selectable(item_text.c_str(), isSelected)) {
|
||||||
selectedPortIdx = n;
|
selectedPortIdx = n;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -80,13 +79,13 @@ void ConnectionWindow::render(bool* p_open) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 2. Выбор Baud Rate через выпадающий список
|
// 2. Выбор Baud Rate через выпадающий список
|
||||||
std::string baud_preview = std::to_string(baudRates[selectedBaudIdx]);
|
const std::string baudPreview = std::to_string(baudRates[selectedBaudIdx]);
|
||||||
if (ImGui::BeginCombo("Baud Rate", baud_preview.c_str())) {
|
if (ImGui::BeginCombo("Baud Rate", baudPreview.c_str())) {
|
||||||
for (int b = 0; b < baudRates.size(); b++) {
|
for (int b = 0; b < baudRates.size(); b++) {
|
||||||
const bool is_selected = (selectedBaudIdx == b);
|
const bool isSelected = (selectedBaudIdx == b);
|
||||||
std::string baud_item_text = std::to_string(baudRates[b]);
|
std::string baud_item_text = std::to_string(baudRates[b]);
|
||||||
|
|
||||||
if (ImGui::Selectable(baud_item_text.c_str(), is_selected)) {
|
if (ImGui::Selectable(baud_item_text.c_str(), isSelected)) {
|
||||||
selectedBaudIdx = b;
|
selectedBaudIdx = b;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -102,15 +101,15 @@ void ConnectionWindow::render(bool* p_open) {
|
|||||||
if (sp_open(activePort, SP_MODE_READ_WRITE) == SP_OK) {
|
if (sp_open(activePort, SP_MODE_READ_WRITE) == SP_OK) {
|
||||||
|
|
||||||
// Передаем реальное значение скорости из выбранного индекса массива
|
// Передаем реальное значение скорости из выбранного индекса массива
|
||||||
int real_baud = baudRates[selectedBaudIdx];
|
const int selectedBaud = baudRates[selectedBaudIdx];
|
||||||
sp_set_baudrate(activePort, real_baud);
|
sp_set_baudrate(activePort, selectedBaud);
|
||||||
|
|
||||||
sp_set_bits(activePort, 8);
|
sp_set_bits(activePort, 8);
|
||||||
sp_set_parity(activePort, SP_PARITY_NONE);
|
sp_set_parity(activePort, SP_PARITY_NONE);
|
||||||
sp_set_stopbits(activePort, 1);
|
sp_set_stopbits(activePort, 1);
|
||||||
|
|
||||||
connected = true;
|
connected = true;
|
||||||
forceLogMessage("[SYSTEM] Connected to " + ports[selectedPortIdx].portName + " at " + std::to_string(real_baud) + " baud.");
|
forceLogMessage("[SYSTEM] Connected to " + ports[selectedPortIdx].portName + " at " + std::to_string(selectedBaud) + " baud.");
|
||||||
} else {
|
} else {
|
||||||
forceLogMessage("[SYSTEM ERROR] Could not open port " + ports[selectedPortIdx].portName);
|
forceLogMessage("[SYSTEM ERROR] Could not open port " + ports[selectedPortIdx].portName);
|
||||||
sp_free_port(activePort);
|
sp_free_port(activePort);
|
||||||
|
|||||||
@@ -33,13 +33,18 @@ void PayloadWindow::sendHexPayload(const std::string& hexString, ConnectionWindo
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
int bytes_written = sp_nonblocking_write(port, bytes.data(), bytes.size());
|
const int bytesWritten = sp_nonblocking_write(port, bytes.data(), bytes.size());
|
||||||
|
|
||||||
if (bytes_written >= 0) {
|
if (bytesWritten >= 0) {
|
||||||
std::stringstream log_ss;
|
std::stringstream log_ss;
|
||||||
log_ss << "[TX] Sent " << bytes_written << " bytes: ";
|
log_ss << "[TX] Sent " << bytesWritten << " bytes: ";
|
||||||
for (size_t i = 0; i < bytes.size(); ++i) {
|
for (unsigned char byte : bytes) {
|
||||||
log_ss << std::uppercase << std::hex << std::setw(2) << std::setfill('0') << (int)bytes[i] << " ";
|
log_ss << std::uppercase
|
||||||
|
<< std::hex
|
||||||
|
<< std::setw(2)
|
||||||
|
<< std::setfill('0')
|
||||||
|
<< static_cast<int>(byte)
|
||||||
|
<< " ";
|
||||||
}
|
}
|
||||||
connectionWindow.forceLogMessage(log_ss.str());
|
connectionWindow.forceLogMessage(log_ss.str());
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
+11
-4
@@ -19,7 +19,9 @@ void SerialApp::initialize() {
|
|||||||
|
|
||||||
// Вспомогательная функция перевода HEX строки (например, "282a36ff") в ImVec4
|
// Вспомогательная функция перевода HEX строки (например, "282a36ff") в ImVec4
|
||||||
static ImVec4 HexToImVec4(const std::string& hex_str) {
|
static ImVec4 HexToImVec4(const std::string& hex_str) {
|
||||||
if (hex_str.length() < 8) return ImVec4(1.0f, 1.0f, 1.0f, 1.0f);
|
if (hex_str.length() < 8) {
|
||||||
|
return {1.0f, 1.0f, 1.0f, 1.0f};
|
||||||
|
}
|
||||||
|
|
||||||
unsigned int r, g, b, a;
|
unsigned int r, g, b, a;
|
||||||
std::stringstream ss;
|
std::stringstream ss;
|
||||||
@@ -28,7 +30,12 @@ static ImVec4 HexToImVec4(const std::string& hex_str) {
|
|||||||
ss << std::hex << hex_str.substr(4, 2); ss >> b; ss.clear();
|
ss << std::hex << hex_str.substr(4, 2); ss >> b; ss.clear();
|
||||||
ss << std::hex << hex_str.substr(6, 2); ss >> a;
|
ss << std::hex << hex_str.substr(6, 2); ss >> a;
|
||||||
|
|
||||||
return ImVec4(r / 255.0f, g / 255.0f, b / 255.0f, a / 255.0f);
|
return {
|
||||||
|
static_cast<float>(r) / 255.0f,
|
||||||
|
static_cast<float>(g) / 255.0f,
|
||||||
|
static_cast<float>(b) / 255.0f,
|
||||||
|
static_cast<float>(a) / 255.0f
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
bool SerialApp::loadTheme(const std::string& filepath) {
|
bool SerialApp::loadTheme(const std::string& filepath) {
|
||||||
@@ -82,7 +89,7 @@ bool SerialApp::loadTheme(const std::string& filepath) {
|
|||||||
// Читаем HEX цвета
|
// Читаем HEX цвета
|
||||||
std::string hex_val;
|
std::string hex_val;
|
||||||
ss >> hex_val;
|
ss >> hex_val;
|
||||||
if (color_map.find(key) != color_map.end()) {
|
if (color_map.contains(key)) {
|
||||||
style.Colors[color_map[key]] = HexToImVec4(hex_val);
|
style.Colors[color_map[key]] = HexToImVec4(hex_val);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@@ -110,7 +117,7 @@ void SerialApp::renderUI() {
|
|||||||
payloadWindow.render(&showPayloadWindow, connectionWindow);
|
payloadWindow.render(&showPayloadWindow, connectionWindow);
|
||||||
}
|
}
|
||||||
if (showLogWindow) {
|
if (showLogWindow) {
|
||||||
logWindow.render(&showLogWindow, connectionWindow);
|
LogWindow::render(&showLogWindow, connectionWindow);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user