Skip to content

Commit

Permalink
[v0.4.0] Switch to klib (#25)
Browse files Browse the repository at this point in the history
* Switch to klib

* Build klib tests

* klib v0.1.2

* Update version, README

* klib v0.1.2 (amended)

* Remove im_text

* klib v0.1.3
  • Loading branch information
karnkaul authored Nov 30, 2024
1 parent 5a3d2d8 commit 2c246b6
Show file tree
Hide file tree
Showing 24 changed files with 89 additions and 149 deletions.
46 changes: 12 additions & 34 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
cmake_minimum_required(VERSION 3.23)

project(locc VERSION "0.3.0")
project(locc VERSION "0.4.0")

set(CMAKE_CXX_STANDARD 23)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
Expand Down Expand Up @@ -32,18 +32,6 @@ include(FetchContent)
set(ext_dir "${CMAKE_CURRENT_SOURCE_DIR}/ext")
set(fetch_targets "")

if(LOCC_BUILD_CLI AND NOT TARGET clap)
set(CLAP_BUILD_TESTS ${PROJECT_IS_TOP_LEVEL})
set(CLAP_BUILD_EXAMPLES ${PROJECT_IS_TOP_LEVEL})
FetchContent_Declare(clap
GIT_REPOSITORY https://github.com/karnkaul/clap
GIT_TAG v0.5.0
GIT_SHALLOW TRUE
SOURCE_DIR "${ext_dir}/src/clap"
)
list(APPEND fetch_targets clap)
endif()

if(LOCC_BUILD_GUI AND NOT TARGET gvdi)
FetchContent_Declare(gvdi
GIT_REPOSITORY https://github.com/karnkaul/gvdi
Expand All @@ -54,27 +42,6 @@ if(LOCC_BUILD_GUI AND NOT TARGET gvdi)
list(APPEND fetch_targets gvdi)
endif()

if(LOCC_BUILD_TESTS AND NOT TARGET ktest)
FetchContent_Declare(ktest
GIT_REPOSITORY https://github.com/karnkaul/ktest
GIT_TAG v0.1.1
GIT_SHALLOW TRUE
SOURCE_DIR "${ext_dir}/src/ktest"
)
list(APPEND fetch_targets ktest)
endif()

if(NOT TARGET ktask)
set(KTASK_BUILD_TESTS ${PROJECT_IS_TOP_LEVEL})
FetchContent_Declare(ktask
GIT_REPOSITORY https://github.com/karnkaul/ktask
GIT_TAG v0.2.2
GIT_SHALLOW TRUE
SOURCE_DIR "${ext_dir}/src/ktask"
)
list(APPEND fetch_targets ktask)
endif()

if(NOT TARGET djson)
FetchContent_Declare(djson
GIT_REPOSITORY https://github.com/karnkaul/djson
Expand All @@ -85,6 +52,17 @@ if(NOT TARGET djson)
list(APPEND fetch_targets djson)
endif()

if(NOT TARGET klib)
set(KLIB_BUILD_TESTS ON)
FetchContent_Declare(klib
GIT_REPOSITORY https://github.com/karnkaul/klib
GIT_TAG v0.1.3
GIT_SHALLOW TRUE
SOURCE_DIR "${ext_dir}/src/klib"
)
list(APPEND fetch_targets klib)
endif()

FetchContent_MakeAvailable(${fetch_targets})

add_subdirectory(lib)
Expand Down
27 changes: 12 additions & 15 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -95,29 +95,26 @@ Pull requests are welcome.

## Architecture

`locc-lib` is a library that can be used by CLI / GUI executables. `locc-cli` is the built-in CLI app that links to `locc-lib` and whose outputs are in this document.
* `locc-lib` is a library that can be used by CLI / GUI executables
* `locc-cli` is the built-in CLI app that links to `locc-lib` and whose outputs are in this document; CMake option: `LOCC_BUILD_CLI`
* `locc-gui` is a built-in GUI app that links to `locc-lib`; CMake option: `LOCC_BUILD_GUI`

### Dependencies

```
locc-gui locc-cli
| |
---------- ------------
| | | |
gvdi locc-lib clap
|
----------
| |
ktask djson
| |
---------- -
| | |
gvdi locc-lib
|
-------
| |
klib djson
```

`djson` deals with parsing JSONs and is used for grammar IO. `ktask` is a lightweight task execution queue, `locc-lib` enqueues a counter task for each file using it. This _counter_ task is internal to `locc-lib` and not exposed to users. Users utilize a single `locc::LineCounter` wrapper task, which reports progress / status, and supports waiting (blocking) until all individual counters have completed (or if any counter has been dropped). It can be used directly or through a `locc::Instance`. Using the instance is convenient when all line counters use the same grammars and file filters. As is evident, multiple line counters can share the same task queue, which can also have other tasks interleaved in between. Note that after a line counter task starts execution, it will flood the queue with its internal counter subtasks. Any custom tasks enqueued after this line counter task - including another line counter task - will not start executing until the first batch of sub-counters completes execution (unless the number of files to count is less than the number of worker threads).

`clap` is a command line argument parser, which `locc-cli` uses. `gvdi` is a GLFW / Dear ImGui / Vulkan lib, which `locc-gui` uses.

* [clap](https://github.com/karnkaul/clap)
* [klib](https://github.com/karnkaul/klib)
* [gvdi](https://github.com/karnkaul/gvdi)
* [ktask](https://github.com/karnkaul/ktask)
* [djson](https://github.com/karnkaul/djson)

[**Original Repository**](https://github.com/karnkaul/locc)
1 change: 0 additions & 1 deletion cli/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@ add_executable(${exe_name})
target_link_libraries(${exe_name} PRIVATE
${PROJECT_NAME}::${PROJECT_NAME}-lib
${PROJECT_NAME}::${PROJECT_NAME}-compile-options
clap::clap
)

target_include_directories(${exe_name} PRIVATE
Expand Down
28 changes: 14 additions & 14 deletions cli/src/app.cpp
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
#include <app.hpp>
#include <clap/parse.hpp>
#include <counter.hpp>
#include <ktask/queue.hpp>
#include <klib/args/parse.hpp>
#include <klib/task/queue.hpp>
#include <array>
#include <print>

Expand All @@ -26,28 +26,28 @@ struct Csv {
} // namespace

auto App::run(int const argc, char const* const* argv) -> int {
m_params.thread_count = std::uint8_t(ktask::Queue::get_max_threads());
m_params.thread_count = std::uint8_t(klib::task::get_max_threads());

auto default_grammars = false;

auto const args = std::array{
clap::option(m_params.sort_column, "c,sort-column", "sort by COLUMN_NAME (default Lines)"),
clap::option(m_params.exclude_patterns, "e,exclude", "comma-separated exclude list (will not be counted)"),
clap::option(m_params.grammars_json, "g,grammars", "path to JSON containing an array of custom grammars"),
clap::option(m_params.thread_count, "t,threads", "number of threads to use"),
clap::flag(m_params.sort_ascending, "a,sort-ascend", "sort in ascending order"),
clap::flag(m_params.no_progress, "p,no-progress", "do not print progress while counting"),
clap::flag(default_grammars, "default-grammars", "output default grammars as JSON and exit"),
clap::flag(m_params.verbose, "v,verbose", "verbose output"),
clap::positional(m_params.path, clap::ArgType::Optional, "path", "path to count for"),
klib::args::option(m_params.sort_column, "c,sort-column", "sort by COLUMN_NAME (default Lines)"),
klib::args::option(m_params.exclude_patterns, "e,exclude", "comma-separated exclude list (will not be counted)"),
klib::args::option(m_params.grammars_json, "g,grammars", "path to JSON containing an array of custom grammars"),
klib::args::option(m_params.thread_count, "t,threads", "number of threads to use"),
klib::args::flag(m_params.sort_ascending, "a,sort-ascend", "sort in ascending order"),
klib::args::flag(m_params.no_progress, "p,no-progress", "do not print progress while counting"),
klib::args::flag(default_grammars, "default-grammars", "output default grammars as JSON and exit"),
klib::args::flag(m_params.verbose, "v,verbose", "verbose output"),
klib::args::positional(m_params.path, klib::args::optional_v, "path", "path to count for"),
};

auto const info = clap::AppInfo{
auto const info = klib::args::ParseInfo{
.help_text = "lines of code counter",
.version = locc::version_v,
};

auto const parse_result = clap::parse(info, args, argc, argv);
auto const parse_result = klib::args::parse(info, args, argc, argv);
if (parse_result.early_return()) { return parse_result.get_return_code(); }

if (default_grammars) {
Expand Down
2 changes: 1 addition & 1 deletion cli/src/counter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ constexpr auto to_metric(std::string_view const sort_by) -> LineCount::Metric {
} // namespace

Counter::Counter(Params const& params, InstanceCreateInfo ici)
: m_params(params), m_queue(ktask::QueueCreateInfo{.thread_count = ktask::ThreadCount{params.thread_count}}), m_locc(m_queue, std::move(ici)) {}
: m_params(params), m_queue(klib::task::QueueCreateInfo{.thread_count = klib::task::ThreadCount{params.thread_count}}), m_locc(m_queue, std::move(ici)) {}

void Counter::run() {
if (m_params.verbose) { print_params(); }
Expand Down
4 changes: 2 additions & 2 deletions cli/src/counter.hpp
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
#pragma once
#include <ktask/queue.hpp>
#include <klib/task/queue.hpp>
#include <locc/instance.hpp>
#include <params.hpp>

Expand All @@ -19,7 +19,7 @@ struct Counter {
static constexpr std::size_t progress_bar_length_v{20};

Params m_params;
ktask::Queue m_queue;
klib::task::Queue m_queue;
Instance m_locc;

std::string m_progress_bar{};
Expand Down
1 change: 0 additions & 1 deletion gui/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,5 @@ target_sources(${exe_name} PRIVATE
src/config.hpp
src/counter.cpp
src/counter.hpp
src/im_text.hpp
src/main.cpp
)
11 changes: 5 additions & 6 deletions gui/src/app.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -14,15 +14,14 @@ namespace {

App::App() : m_instance(m_queue, InstanceCreateInfo{.file_filter = &m_filter}) {
m_config.exclude_patterns.reserve(m_filter.exclude_patterns.size());
for (auto const pattern : m_filter.exclude_patterns) { copy_to(m_config.exclude_patterns.emplace_back(), pattern); }
for (auto const pattern : m_filter.exclude_patterns) { m_config.exclude_patterns.emplace_back(pattern); }
set_filter();
set_config();
}

auto App::run() -> int {
auto buf = CharBuf{};
std::format_to_n(buf.data(), buf.size(), "locc v{}", version_v);
auto window = gvdi::Context::create_window({640.0f, 360.0f}, buf.data());
auto const title = klib::FixedString{"locc v{}", version_v};
auto window = gvdi::Context::create_window({640.0f, 360.0f}, title.c_str());
if (!window) {
std::println(stderr, "Failed to create window");
return EXIT_FAILURE;
Expand Down Expand Up @@ -130,7 +129,7 @@ void App::update_sorting() {
void App::set_filter() {
m_filter.exclude_patterns.clear();
m_filter.exclude_patterns.reserve(m_config.exclude_patterns.size());
for (auto const& pattern : m_config.exclude_patterns) { m_filter.exclude_patterns.emplace_back(pattern.data()); }
for (auto const& pattern : m_config.exclude_patterns) { m_filter.exclude_patterns.emplace_back(pattern); }
}

void App::set_config() { m_config.thread_count = m_queue.thread_count(); }
Expand All @@ -143,7 +142,7 @@ void App::reload(bool const copy_config) {
if (copy_config) { m_config = m_config_modal.config; }

m_queue.~Queue();
new (&m_queue) ktask::Queue{ktask::QueueCreateInfo{.thread_count = m_config.thread_count}};
new (&m_queue) klib::task::Queue{klib::task::QueueCreateInfo{.thread_count = m_config.thread_count}};

set_filter();
set_config();
Expand Down
4 changes: 2 additions & 2 deletions gui/src/app.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
#include <locc/instance.hpp>

#include <gvdi/context.hpp>
#include <ktask/queue.hpp>
#include <klib/task/queue.hpp>

#include <memory>

Expand Down Expand Up @@ -45,7 +45,7 @@ class App {

Counter m_counter{}; // tasks must outlive queue

ktask::Queue m_queue{};
klib::task::Queue m_queue{};
Instance m_instance;
};
} // namespace locc::gui
19 changes: 0 additions & 19 deletions gui/src/char_buf.hpp

This file was deleted.

14 changes: 7 additions & 7 deletions gui/src/config.cpp
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
#include <imgui.h>
#include <config.hpp>
#include <ktask/queue.hpp>
#include <klib/task/queue.hpp>
#include <cstring>

namespace locc::gui {
Config::Modal::Modal() : m_thread_count(int(ktask::Queue::get_max_threads())) {}
Config::Modal::Modal() : m_thread_count(int(klib::task::get_max_threads())) {}

void Config::Modal::open_on_next_update(Config config) {
this->config = std::move(config);
Expand Down Expand Up @@ -41,17 +41,17 @@ auto Config::Modal::update() -> bool {
}

void Config::Modal::inspect() {
auto const max_threads = int(ktask::Queue::get_max_threads());
auto const max_threads = int(klib::task::get_max_threads());
m_thread_count = int(config.thread_count);
ImGui::SetNextItemWidth(140.0f);
if (ImGui::SliderInt("Threads", &m_thread_count, 2, max_threads)) { config.thread_count = ktask::ThreadCount(m_thread_count); }
if (ImGui::SliderInt("Threads", &m_thread_count, 2, max_threads)) { config.thread_count = klib::task::ThreadCount(m_thread_count); }

if (ImGui::BeginListBox("Exclude", {140.0f, 100.0f})) {
if (m_selected_exclude && *m_selected_exclude >= config.exclude_patterns.size()) { m_selected_exclude.reset(); }
std::string_view const selected = m_selected_exclude ? config.exclude_patterns[*m_selected_exclude].data() : "";
std::string_view const selected = m_selected_exclude ? config.exclude_patterns[*m_selected_exclude] : "";
for (std::size_t i = 0; i < config.exclude_patterns.size(); ++i) {
auto const& pattern = config.exclude_patterns[i];
if (ImGui::Selectable(pattern.data(), std::string_view{pattern.data()} == selected)) { m_selected_exclude = i; }
if (ImGui::Selectable(pattern.c_str(), pattern == selected)) { m_selected_exclude = i; }
}
ImGui::EndListBox();
}
Expand All @@ -65,7 +65,7 @@ void Config::Modal::inspect() {
ImGui::InputText("##Add", m_exclude_buf.data(), m_exclude_buf.size());
ImGui::SameLine();
if (ImGui::SmallButton("Add")) {
config.exclude_patterns.push_back(m_exclude_buf);
config.exclude_patterns.emplace_back(m_exclude_buf.data());
m_exclude_buf = {};
}
}
Expand Down
10 changes: 5 additions & 5 deletions gui/src/config.hpp
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
#pragma once
#include <char_buf.hpp>
#include <ktask/queue_create_info.hpp>
#include <klib/fixed_string.hpp>
#include <klib/task/queue_create_info.hpp>
#include <optional>
#include <string_view>
#include <vector>
Expand All @@ -9,8 +9,8 @@ namespace locc::gui {
struct Config {
class Modal;

std::vector<CharBuf> exclude_patterns{};
ktask::ThreadCount thread_count{};
std::vector<klib::FixedString<64>> exclude_patterns{};
klib::task::ThreadCount thread_count{};
};

class Config::Modal {
Expand All @@ -30,7 +30,7 @@ class Config::Modal {

int m_thread_count;

CharBuf m_exclude_buf{};
klib::StrBuf<64> m_exclude_buf{};
std::optional<std::size_t> m_selected_exclude{};

bool m_open_popup{};
Expand Down
9 changes: 5 additions & 4 deletions gui/src/counter.cpp
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
#include <counter.hpp>
#include <im_text.hpp>

#include <klib/fixed_string.hpp>

#include <imgui.h>

Expand Down Expand Up @@ -36,7 +37,7 @@ void Counter::update() {
void Counter::update_progress() {
if (!show_progress) { return; }
auto const progress = m_counter->get_progress();
im_text("Status: {}", to_str(progress.state));
ImGui::TextUnformatted(klib::FixedString{"Status: {}", to_str(progress.state)}.c_str());
m_progress_overlay.clear();
std::format_to(std::back_inserter(m_progress_overlay), "[{}/{}]", progress.counted, progress.total);
ImGui::SetNextItemWidth(-1.0f);
Expand All @@ -52,11 +53,11 @@ void Counter::update_rows() {
auto const update_row = [](DisplayRow const& row) {
ImGui::TableNextRow();
ImGui::TableSetColumnIndex(0);
im_text("{}", row.name);
ImGui::TextUnformatted(klib::FixedString{"{}", row.name}.c_str());
for (std::size_t i = 0; i < LineCount::COUNT_; ++i) {
auto const& metric = row.metrics[i]; // NOLINT(cppcoreguidelines-pro-bounds-constant-array-index)
ImGui::TableSetColumnIndex(int(i) + 1);
im_text("{}", metric);
ImGui::TextUnformatted(klib::FixedString{"{}", metric}.c_str());
}
};

Expand Down
14 changes: 0 additions & 14 deletions gui/src/im_text.hpp

This file was deleted.

Loading

0 comments on commit 2c246b6

Please sign in to comment.