Skip to content

Commit

Permalink
Refactor console again
Browse files Browse the repository at this point in the history
Remove `le::cli`, add new stuff in `le::console`.
Refactor `le::imcpp::ConsoleWindow` for `le::console`.
  • Loading branch information
karnkaul committed Oct 2, 2023
1 parent 48d793a commit 962c26b
Show file tree
Hide file tree
Showing 18 changed files with 356 additions and 348 deletions.
13 changes: 6 additions & 7 deletions engine/header_list.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -124,12 +124,11 @@ set(audio_headers
${prefix}/audio/volume.hpp
)

set(cli_headers
${prefix}/cli/args.hpp
${prefix}/cli/command.hpp
${prefix}/cli/console.hpp
${prefix}/cli/driver.hpp
${prefix}/cli/responder.hpp
set(console_headers
${prefix}/console/console.hpp
${prefix}/console/command.hpp
${prefix}/console/property.hpp
${prefix}/console/trigger.hpp
)

set(imcpp_headers
Expand All @@ -148,7 +147,7 @@ set(header_list
${resources_headers}
${graphics_headers}
${audio_headers}
${cli_headers}
${console_headers}
${imcpp_headers}

${prefix}/engine.hpp
Expand Down
36 changes: 0 additions & 36 deletions engine/include/le/cli/args.hpp

This file was deleted.

41 changes: 0 additions & 41 deletions engine/include/le/cli/command.hpp

This file was deleted.

43 changes: 0 additions & 43 deletions engine/include/le/cli/console.hpp

This file was deleted.

26 changes: 0 additions & 26 deletions engine/include/le/cli/driver.hpp

This file was deleted.

11 changes: 0 additions & 11 deletions engine/include/le/cli/responder.hpp

This file was deleted.

22 changes: 22 additions & 0 deletions engine/include/le/console/command.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
#pragma once
#include <le/core/polymorphic.hpp>
#include <string>

namespace le::console {
class Command : public Polymorphic {
public:
struct Response {
std::string message{};
std::string error{};
};

explicit Command(std::string name) : m_name(std::move(name)) {}

[[nodiscard]] auto get_name() const -> std::string_view { return m_name; }

virtual auto process(std::string_view argument) -> Response = 0;

private:
std::string m_name{};
};
} // namespace le::console
69 changes: 69 additions & 0 deletions engine/include/le/console/console.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
#pragma once
#include <le/console/command.hpp>
#include <deque>
#include <functional>
#include <memory>
#include <unordered_map>

namespace le::console {
struct Entry {
std::string request{};
Command::Response response{};
};

struct Autocomplete {
std::string_view common_suffix{};
std::vector<std::string_view> candidates{};
};

class Console {
public:
static constexpr std::size_t max_entries_v{100};
static constexpr std::size_t max_log_entries_v{100};
static constexpr std::size_t max_history_v{100};

Console();

template <std::derived_from<Command> Type, typename... Args>
requires(std::constructible_from<Type, Args...>)
auto add(Args&&... args) -> Type& {
auto t = std::make_unique<Type>(std::forward<Args>(args)...);
auto& ret = *t;
auto name = static_cast<Command const&>(ret).get_name();
m_commands.insert_or_assign(name, std::move(t));
return ret;
}

void submit(std::string_view text);
[[nodiscard]] auto autocomplete(std::string_view text, std::size_t cursor) const -> Autocomplete;

void add_entry(Entry entry);
void add_entry(Autocomplete const& ac);
void add_to_history(std::string text);

[[nodiscard]] auto get_entries() const -> std::deque<Entry> const& { return m_entries; }
[[nodiscard]] auto get_history() const -> std::deque<std::string> const& { return m_history; }

void clear_log() { m_entries.clear(); }
void clear_history() { m_history.clear(); }

std::size_t max_entries{max_log_entries_v};
std::size_t max_log_entries{max_log_entries_v};
std::size_t max_history{max_history_v};

private:
struct Builtin {
std::string_view name{};
std::function<void(Console&)> command{};
};

[[nodiscard]] auto autocomplete(std::string_view fragment) const -> std::vector<std::string_view>;
auto builtin(std::string_view cmd) -> bool;
[[nodiscard]] auto get_builtin_names(std::string_view fragment) const -> std::vector<std::string_view>;

std::unordered_map<std::string_view, std::unique_ptr<Command>> m_commands{};
std::vector<Builtin> m_builtins{};
std::deque<Entry> m_entries{};
std::deque<std::string> m_history{};
};
} // namespace le::console
61 changes: 61 additions & 0 deletions engine/include/le/console/property.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
#pragma once
#include <le/console/command.hpp>
#include <charconv>
#include <concepts>
#include <format>

namespace le::console {
template <typename Type>
concept PropertyT = std::same_as<Type, bool> || std::integral<Type> || std::floating_point<Type> || std::same_as<Type, std::string>;

template <PropertyT Type>
constexpr auto to_str() {
if constexpr (std::same_as<Type, bool>) {
return "boolean";
} else if constexpr (std::integral<Type>) {
return "integer";
} else if constexpr (std::floating_point<Type>) {
return "float";
} else {
return "string";
}
}

template <PropertyT Type>
class Property : public Command {
public:
using Base = Property<Type>;

using Command::Command;

virtual void on_changed() = 0;

Type value{};

private:
auto process(std::string_view const argument) -> Response final {
if (argument.empty()) { return Response{.message = std::format("{}", value)}; }

auto invalid_arg = [&] { return Response{.error = std::format("invalid argument, expected {}", to_str<Type>())}; };

if constexpr (std::same_as<Type, bool>) {
if (argument == "true" || argument == "1") {
value = true;
} else if (argument == "false" || argument == "0") {
value = false;
} else {
return invalid_arg();
}
} else if constexpr (std::same_as<Type, std::string>) {
value = argument;
} else {
auto const* end = argument.data() + argument.size();
auto [ptr, ec] = std::from_chars(argument.data(), end, value);
if (ec != std::errc{} || ptr != end) { return invalid_arg(); }
}

on_changed();
return {};
}
};
} // namespace le::console
19 changes: 19 additions & 0 deletions engine/include/le/console/trigger.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
#pragma once
#include <le/console/command.hpp>

namespace le::console {
class Trigger : public Command {
public:
using Base = Trigger;

using Command::Command;

virtual void on_triggered() = 0;

private:
auto process(std::string_view const /*unused*/) -> Response final {
on_triggered();
return {};
}
};
} // namespace le::console
Loading

0 comments on commit 962c26b

Please sign in to comment.