metaforce/hecl/include/hecl/Console.hpp

114 lines
4.0 KiB
C++

#pragma once
#include <functional>
#include <string>
#include <unordered_map>
#include <vector>
#include <boo/System.hpp>
#include <logvisor/logvisor.hpp>
namespace boo {
class IWindow;
enum class EModifierKey;
enum class ESpecialKey;
struct IGraphicsCommandQueue;
} // namespace boo
namespace hecl {
class CVarManager;
class CVar;
struct SConsoleCommand {
enum class ECommandFlags { Normal = 0, Cheat = (1 << 0), Developer = (1 << 1) };
std::string m_displayName;
std::string m_helpString;
std::string m_usage;
std::function<void(class Console*, const std::vector<std::string>&)> m_func;
ECommandFlags m_flags;
};
ENABLE_BITWISE_ENUM(SConsoleCommand::ECommandFlags)
class Console {
friend class LogVisorAdapter;
struct LogVisorAdapter : logvisor::ILogger {
Console* m_con;
LogVisorAdapter(Console* con) : logvisor::ILogger(log_typeid(LogVisorAdapter)), m_con(con) {}
~LogVisorAdapter() override = default;
void report(const char* modName, logvisor::Level severity, fmt::string_view format, fmt::format_args args) override;
void report(const char* modName, logvisor::Level severity, fmt::wstring_view format,
fmt::wformat_args args) override;
void reportSource(const char* modName, logvisor::Level severity, const char* file, unsigned linenum,
fmt::string_view format, fmt::format_args args) override;
void reportSource(const char* modName, logvisor::Level severity, const char* file, unsigned linenum,
fmt::wstring_view format, fmt::wformat_args args) override;
};
public:
static Console* m_instance;
enum class Level {
Info, /**< Non-error informative message */
Warning, /**< Non-error warning message */
Error, /**< Recoverable error message */
Fatal /**< Non-recoverable error message (Kept for compatibility with logvisor) */
};
enum class State { Closed, Closing, Opened, Opening };
private:
CVarManager* m_cvarMgr = nullptr;
boo::IWindow* m_window = nullptr;
std::unordered_map<std::string, SConsoleCommand> m_commands;
std::vector<std::pair<std::string, Level>> m_log;
int m_logOffset = 0;
std::string m_commandString;
std::vector<std::string> m_commandHistory;
int m_cursorPosition = -1;
int m_currentCommand = -1;
size_t m_maxLines = 0;
bool m_overwrite : 1;
bool m_cursorAtEnd : 1;
State m_state = State::Closed;
CVar* m_conSpeed;
CVar* m_conHeight;
float m_cachedConSpeed;
float m_cachedConHeight;
bool m_showCursor = true;
float m_cursorTime = 0.f;
public:
Console(CVarManager*);
void registerCommand(std::string_view name, std::string_view helpText, std::string_view usage,
std::function<void(Console*, const std::vector<std::string>&)>&& func,
SConsoleCommand::ECommandFlags cmdFlags = SConsoleCommand::ECommandFlags::Normal);
void unregisterCommand(std::string_view name);
void executeString(const std::string& strToExec);
void help(Console* con, const std::vector<std::string>& args);
void listCommands(Console* con, const std::vector<std::string>& args);
bool commandExists(std::string_view cmd) const;
void vreport(Level level, fmt::string_view format, fmt::format_args args);
template <typename S, typename... Args, typename Char = fmt::char_t<S>>
void report(Level level, const S& format, Args&&... args) {
vreport(level, fmt::to_string_view<Char>(format),
fmt::basic_format_args<fmt::buffer_context<Char>>(
fmt::make_args_checked<Args...>(format, args...)));
}
void init(boo::IWindow* ctx);
void proc();
void draw(boo::IGraphicsCommandQueue* gfxQ);
void handleCharCode(unsigned long chr, boo::EModifierKey mod, bool repeat);
void handleSpecialKeyDown(boo::ESpecialKey sp, boo::EModifierKey mod, bool repeat);
void handleSpecialKeyUp(boo::ESpecialKey sp, boo::EModifierKey mod);
void dumpLog();
static Console* instance();
static void RegisterLogger(Console* con);
bool isOpen() const { return m_state == State::Opened; }
};
} // namespace hecl