serialWatch/src/main.cc

176 lines
7.1 KiB
C++

#include "ComKit.h"
#include "ComWatch.h"
#include "imgui_helper.h"
#include "imgui_stdlib.h"
#include "spdlog/sinks/basic_file_sink.h"
#include "spdlog/sinks/ostream_sink.h"
#include "spdlog/sinks/stdout_color_sinks.h"
#include "spdlog/spdlog.h"
#include <Windows.h>
#include <array>
#include <filesystem>
#include <fstream>
#include <sstream>
#include <toml.h>
namespace filesystem = std::filesystem;
static std::string GetTimeNow() {
auto now = std::chrono::system_clock::now();
auto now_c = std::chrono::system_clock::to_time_t(now);
std::tm now_tm;
localtime_s(&now_tm, &now_c);
std::ostringstream oss;
oss << std::put_time(&now_tm, "%Y-%m-%d");
return oss.str();
}
constexpr int CLIENT_WIDTH = 500;
constexpr int CLIENT_HEIGHT = 550;
#ifdef _WIN32
int WINAPI WinMain(HINSTANCE hINstance, HINSTANCE preInstance, LPSTR lpCmdLine,
int nShowCmd) {
#elif __linux__
int main(int argc, char **) {
#endif
auto console_sink = std::make_shared<spdlog::sinks::stdout_color_sink_mt>();
console_sink->set_level(spdlog::level::info);
console_sink->set_pattern("[%T] [%^%l%$] %v");
auto string_sink =
std::make_shared<spdlog::sinks::ostream_sink_mt>(ComKit::oss);
string_sink->set_level(spdlog::level::debug);
string_sink->set_pattern("[%T] [%^%l%$] %v");
auto file_sink = std::make_shared<spdlog::sinks::basic_file_sink_mt>(
std::format("./log/{}.txt", GetTimeNow()), false);
file_sink->set_level(spdlog::level::debug);
file_sink->set_pattern("[%T] [%l] %v");
std::vector<spdlog::sink_ptr> sinks{console_sink, string_sink, file_sink};
auto logger = std::make_shared<spdlog::logger>("multi_sink", sinks.begin(),
sinks.end());
spdlog::set_default_logger(logger);
spdlog::set_level(spdlog::level::debug);
spdlog::flush_on(spdlog::level::info);
spdlog::flush_every(std::chrono::milliseconds(200));
const auto comPortNames = ComKit::GetAllComPortNames();
const int columns = 2;
bool dontPop = false;
ImGuiHelper helper{CLIENT_WIDTH, CLIENT_HEIGHT};
bool isRunning = true;
std::string filterComName;
std::string inputCommands;
std::stringstream oss;
if (filesystem::exists("./config.toml")) {
const auto config = toml::parse("./config.toml");
filterComName = config.at("ComPorts").as_string();
inputCommands = config.at("Commands").as_string();
}
SerialWatch watcher;
watcher.set_callback([](const std::string &port_name, SIGNAL_TYPE type) {
switch (type) {
case SIGNAL_TYPE::REMOVE_:
spdlog::log(spdlog::level::debug,
std::format("port: [{}] removed", port_name));
ComKit::FlushLog();
ComKit::GetAllComPortNames();
break;
case SIGNAL_TYPE::ADD_:
spdlog::log(spdlog::level::debug,
std::format("port: [{}] add", port_name));
ComKit::FlushLog();
ComKit::GetAllComPortNames();
ComKit::Work(port_name);
break;
}
});
watcher.work();
while (isRunning)
helper.Render(
[&]() {
ImGui::Begin("ComKit", &isRunning,
ImGuiWindowFlags_NoResize |
ImGuiWindowFlags_NoSavedSettings);
if (ImGui::BeginTable("StartTable", columns,
ImGuiTableFlags_ScrollY |
ImGuiTableFlags_Resizable |
ImGuiTableFlags_Borders |
ImGuiTableFlags_NoHostExtendX,
ImVec2(CLIENT_WIDTH - 10, 100))) {
ImGui::TableSetupColumn("LOCATION_PATHS",
ImGuiTableColumnFlags_WidthFixed);
ImGui::TableSetupColumn("COM_PORT_NAME",
ImGuiTableColumnFlags_WidthStretch);
ImGui::TableHeadersRow();
for (int row = 0; row < comPortNames->size(); row++) {
ImGui::TableNextRow();
for (int column = 0; column < columns; column++) {
ImGui::TableSetColumnIndex(column);
if (column == 0) {
ImGui::Text("%s",
comPortNames->at(row)
.comPortInstancePath.c_str());
} else if (column == 1) {
ImGui::Text(
"%s",
comPortNames->at(row).comPortName.c_str());
}
}
}
ImGui::EndTable();
}
ImGui::Text("Filter Com:");
ImGui::InputTextMultiline(
"comNameFilter", &filterComName,
ImVec2(-FLT_MIN, ImGui::GetTextLineHeight() * 3));
ImGui::Text("Commands:");
ImGui::InputTextMultiline(
"inputCommands", &inputCommands,
ImVec2(-FLT_MIN, ImGui::GetTextLineHeight() * 5),
ImGuiInputTextFlags_AllowTabInput);
ImGui::Text("Log:");
ImGui::InputTextMultiline(
"logContent", &ComKit::logContent,
ImVec2(-FLT_MIN, ImGui::GetTextLineHeight() * 16),
ImGuiInputTextFlags_AllowTabInput |
ImGuiInputTextFlags_ReadOnly);
float window_width = ImGui::GetWindowSize().x;
float start_button_width =
ImGui::CalcTextSize("Start").x +
ImGui::GetStyle().FramePadding.x * 2.0f;
float button_start = (window_width - start_button_width) / 2.0f;
ImGui::SetCursorPosX(button_start);
if (ImGui::Button("Start")) {
ComKit::Start(filterComName, inputCommands);
}
ImGui::SameLine();
auto end_button_width = ImGui::CalcTextSize("End").x +
ImGui::GetStyle().FramePadding.x * 2.0f;
button_start = (window_width - end_button_width) / 2.0f +
start_button_width;
ImGui::SetCursorPosX(button_start);
if (ImGui::Button("End")) {
ComKit::End();
}
if (ComKit::isWorking) {
ImGui::SameLine();
ImGui::Text("Working");
}
ImGui::End();
},
isRunning);
const toml::value v(
toml::table{{"ComPorts", filterComName}, {"Commands", inputCommands}});
const auto content = toml::format(v);
auto file = std::ofstream("./config.toml", std::ios::out | std::ios::trunc);
file << content;
file.close();
return 0;
}