#include "ComKit.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 #include #include #include #include #include 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(); console_sink->set_level(spdlog::level::info); console_sink->set_pattern("[%T] [%^%l%$] %v"); auto string_sink = std::make_shared(ComKit::oss); string_sink->set_level(spdlog::level::debug); string_sink->set_pattern("[%T] [%^%l%$] %v"); auto file_sink = std::make_shared( std::format("./log/{}.txt", GetTimeNow()), false); file_sink->set_level(spdlog::level::debug); file_sink->set_pattern("[%T] [%l] %v"); std::vector sinks{console_sink, string_sink, file_sink}; auto logger = std::make_shared("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(); } 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; }