Skip to content

Commit

Permalink
Circle, NineSlice, Result, Console (#77)
Browse files Browse the repository at this point in the history
* Refactor ui::View into that + ui::Element.

Move build version into generated header.

* Add ui::Element::m_active

* Add Engine::min_frame_time.

Improve engine stats.

* Make Primitive movable.

Fix dangling access in `Resources::store()`.
Add some consts in lit.frag.

* Set window and framebuffer extents on startup.

* Add graphics::Circle.

* Move RenderLayer to dedicated header.

* Move PolygonMode out of PipelineState into Renderer.

* Add graphics::NineSlice

* RoundedQuad, NineSlice.

- Fix sector UVs and verts.

* Add FDuration<PeriodT>.

* Use dynamic_cast fallback in find_component.

* Add ParticleSystem::respawn_all().

* Use radial spread for particle velocity.

* Add ComponentMap

* Add Fog.

Improve lit shaders: pass fewer outputs in vertex shader, have fragment shader reference view set directly.

* No fog by default.

* Store and retrieve `this` as GLFW user data.

* Remove reversed, fixup ext CMake script.

* Track GPU memory.

- Add `format_unit`.

* Remove Component::setup.

* Remove ui::Element::setup.

* Remove ui::View::setup().

* Fix clang 15 reverse_view borking.

* Fix some clang-tidy warnings.

* Add Result and basic test framework.

* Move ui::Quad to its own header.

- Use `RoundedQuad`.

* Add console window.

* Add StringTrie, use in console window.

* WIP: cli

* Start with absolute path in find_super_directory.

* Refactor cli, remove StringTrie.

* Refactor console again

Remove `le::cli`, add new stuff in `le::console`.
Refactor `le::imcpp::ConsoleWindow` for `le::console`.

* Fix NoPCH builds

* Improve tests.

- Use a single executable.
- Use GLOB_RECURSE on all cpp files in tests/tests.

* Improve Signal.

* Include missing headers.
  • Loading branch information
karnkaul committed Oct 2, 2023
1 parent 309bfcf commit 518eab7
Show file tree
Hide file tree
Showing 73 changed files with 1,279 additions and 258 deletions.
6 changes: 6 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ option(LE_BUILD_SCENE "Build little-engine scene library" ON)
option(LE_BUILD_TOOLS "Build little-engine tools" ${is_root_project})
option(LE_USE_FREETYPE "Use Freetype as the font backend" ON)
option(LE_BUILD_EXAMPLE "Build little-engine example" ${is_root_project})
option(LE_BUILD_TESTS "Build little-engine tests" ${is_root_project})

add_library(le-compile-options INTERFACE)
add_library(le::le-compile-options ALIAS le-compile-options)
Expand Down Expand Up @@ -45,3 +46,8 @@ endif()
if(LE_BUILD_EXAMPLE)
add_subdirectory(example)
endif()

if(LE_BUILD_TESTS)
enable_testing()
add_subdirectory(tests)
endif()
16 changes: 14 additions & 2 deletions engine/header_list.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,12 @@ set(core_headers
${prefix}/core/not_null.hpp
${prefix}/core/nvec3.hpp
${prefix}/core/offset_span.hpp
${prefix}/core/polymorphic.hpp
${prefix}/core/ptr.hpp
${prefix}/core/radians.hpp
${prefix}/core/random.hpp
${prefix}/core/reversed.hpp
${prefix}/core/result.hpp
${prefix}/core/reverse_view.hpp
${prefix}/core/signal.hpp
${prefix}/core/time.hpp
${prefix}/core/version.hpp
Expand Down Expand Up @@ -122,11 +124,20 @@ set(audio_headers
${prefix}/audio/volume.hpp
)

set(console_headers
${prefix}/console/console.hpp
${prefix}/console/command.hpp
${prefix}/console/property.hpp
${prefix}/console/trigger.hpp
)

set(imcpp_headers
${prefix}/imcpp/common.hpp
${prefix}/imcpp/console_window.hpp
${prefix}/imcpp/engine_stats.hpp
${prefix}/imcpp/input_text.hpp
${prefix}/imcpp/reflector.hpp
${prefix}/imcpp/str_buf.hpp
)

set(header_list
Expand All @@ -135,8 +146,9 @@ set(header_list
${vfs_headers}
${resources_headers}
${graphics_headers}
${imcpp_headers}
${audio_headers}
${console_headers}
${imcpp_headers}

${prefix}/engine.hpp
${prefix}/environment.hpp
Expand Down
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
37 changes: 37 additions & 0 deletions engine/include/le/core/format_unit.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
#pragma once
#include <array>
#include <format>
#include <span>

namespace le {
template <typename Type, Type Multiplier>
auto format_unit(Type const value, std::span<std::string_view const> suffix_map, int precision = 3) -> std::string {
if (suffix_map.empty() || Multiplier == Type(0)) { return std::format("{}", value); }

static constexpr auto m = static_cast<float>(Multiplier);

auto const negative = value < Type(0);
auto f = std::abs(static_cast<float>(value));
auto i = std::size_t{};
while (f > Multiplier && i + 1 < suffix_map.size()) {
f = f / m;
++i;
}

auto const fmt = std::format("{{}}{{:.{}}}{{}}", precision);
return std::vformat(fmt, std::make_format_args((negative ? "-" : ""), f, suffix_map[i]));
}

template <typename Type>
auto format_bytes(Type const count, int precision = 3) -> std::string {
using namespace std::string_view_literals;
static constexpr auto suffix_map_v = std::array{
"B"sv,
"KiB"sv,
"MiB"sv,
"GiB"sv,
};
static constexpr auto multiplier_v = Type(1024);
return format_unit<Type, multiplier_v>(count, suffix_map_v, precision);
}
} // namespace le
14 changes: 14 additions & 0 deletions engine/include/le/core/polymorphic.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
#pragma once

namespace le {
class Polymorphic {
public:
Polymorphic(Polymorphic const&) = default;
Polymorphic(Polymorphic&&) = default;
auto operator=(Polymorphic const&) -> Polymorphic& = default;
auto operator=(Polymorphic&&) -> Polymorphic& = default;

Polymorphic() = default;
virtual ~Polymorphic() = default;
};
} // namespace le

0 comments on commit 518eab7

Please sign in to comment.