mirror of https://github.com/AxioDL/metaforce.git
Merge branch 'master' of ssh://gitlab.axiodl.com:6431/AxioDL/hecl
This commit is contained in:
commit
590fdb7a29
|
@ -53,13 +53,13 @@ class ToolPackage final : public ToolBase
|
||||||
CheckFile(childPath);
|
CheckFile(childPath);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Directory with 2 components not "Shared" or macOS app buundle
|
/* Directory with 2 components not "Shared" or macOS app bundle
|
||||||
* and no nested !world.blend files == General PAK */
|
* and no nested !world.blend files == General PAK */
|
||||||
if (checkGeneral && origSize == m_selectedItems.size())
|
if (checkGeneral && origSize == m_selectedItems.size())
|
||||||
{
|
{
|
||||||
auto pathComps = path.getPathComponents();
|
auto pathComps = path.getPathComponents();
|
||||||
if (pathComps.size() == 2 && pathComps[0] != _S("out") &&
|
if (pathComps.size() == 2 && pathComps[0] != _S("out") &&
|
||||||
pathComps[1] != _S("Shared") && pathComps[0].find(".app") == hecl::SystemString::npos)
|
pathComps[1] != _S("Shared") && pathComps[0].find(_S(".app")) == hecl::SystemString::npos)
|
||||||
AddSelectedItem(path);
|
AddSelectedItem(path);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -78,6 +78,7 @@ public:
|
||||||
std::string_view name() const { return m_name; }
|
std::string_view name() const { return m_name; }
|
||||||
std::string_view rawHelp() const { return m_help; }
|
std::string_view rawHelp() const { return m_help; }
|
||||||
std::string help() const;
|
std::string help() const;
|
||||||
|
std::string value() const { return m_value; }
|
||||||
|
|
||||||
atVec4f toVec4f(bool* isValid = nullptr) const;
|
atVec4f toVec4f(bool* isValid = nullptr) const;
|
||||||
float toFloat(bool* isValid = nullptr) const;
|
float toFloat(bool* isValid = nullptr) const;
|
||||||
|
@ -92,6 +93,8 @@ public:
|
||||||
bool fromInteger(int val);
|
bool fromInteger(int val);
|
||||||
bool fromLiteral(std::string_view val);
|
bool fromLiteral(std::string_view val);
|
||||||
bool fromLiteral(std::wstring_view val);
|
bool fromLiteral(std::wstring_view val);
|
||||||
|
bool fromLiteralToType(std::string_view val);
|
||||||
|
bool fromLiteralToType(std::wstring_view val);
|
||||||
|
|
||||||
bool isFloat() const { return m_type == EType::Float; }
|
bool isFloat() const { return m_type == EType::Float; }
|
||||||
bool isBoolean() const { return m_type == EType::Boolean; }
|
bool isBoolean() const { return m_type == EType::Boolean; }
|
||||||
|
@ -132,7 +135,8 @@ private:
|
||||||
std::string m_help;
|
std::string m_help;
|
||||||
std::string m_defaultValue;
|
std::string m_defaultValue;
|
||||||
EFlags m_flags;
|
EFlags m_flags;
|
||||||
bool m_allowedWrite;
|
EFlags m_oldFlags;
|
||||||
|
bool m_unlocked = false;
|
||||||
|
|
||||||
CVarManager& m_mgr;
|
CVarManager& m_mgr;
|
||||||
|
|
||||||
|
|
|
@ -5,6 +5,7 @@
|
||||||
#include <unordered_map>
|
#include <unordered_map>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include <functional>
|
#include <functional>
|
||||||
|
#include "boo/IWindow.hpp"
|
||||||
#include "logvisor/logvisor.hpp"
|
#include "logvisor/logvisor.hpp"
|
||||||
|
|
||||||
namespace hecl
|
namespace hecl
|
||||||
|
@ -49,17 +50,28 @@ public:
|
||||||
Error, /**< Recoverable error message */
|
Error, /**< Recoverable error message */
|
||||||
Fatal /**< Non-recoverable error message (Kept for compatibility with logvisor) */
|
Fatal /**< Non-recoverable error message (Kept for compatibility with logvisor) */
|
||||||
};
|
};
|
||||||
|
|
||||||
|
enum State
|
||||||
|
{
|
||||||
|
Closed,
|
||||||
|
Closing,
|
||||||
|
Opened,
|
||||||
|
Opening
|
||||||
|
};
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::unordered_map<std::string, SConsoleCommand> m_commands;
|
std::unordered_map<std::string, SConsoleCommand> m_commands;
|
||||||
std::vector<std::pair<std::string, Level>> m_log;
|
std::vector<std::pair<std::string, Level>> m_log;
|
||||||
void visorReport(Level level, const char* mod, const char* fmt, va_list list);
|
int m_logOffset;
|
||||||
void visorReport(Level level, const char* mod, const char* fmt, ...);
|
std::string m_commandString;
|
||||||
void visorReportSource(Level, const char* mod, const char* file, unsigned line, const char* fmt, va_list);
|
std::vector<std::string> m_commandHistory;
|
||||||
void visorReportSource(Level, const char* mod, const char* file, unsigned line, const char* fmt, ...);
|
int m_cursorPosition = -1;
|
||||||
void visorReport(Level level, const char* mod, const wchar_t* fmt, va_list list);
|
int m_currentCommand = -1;
|
||||||
void visorReport(Level level, const char* mod, const wchar_t* fmt, ...);
|
int m_maxLines = 0;
|
||||||
void visorReportSource(Level, const char* mod, const char* file, unsigned line, const wchar_t* fmt, va_list);
|
bool m_overwrite : 1;
|
||||||
void visorReportSource(Level, const char* mod, const char* file, unsigned line, const wchar_t* fmt, ...);
|
bool m_cursorAtEnd : 1;
|
||||||
|
State m_state = State::Closed;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
Console(class CVarManager*);
|
Console(class CVarManager*);
|
||||||
void registerCommand(std::string_view name, std::string_view helpText, std::string_view usage, const std::function<void(Console*, const std::vector<std::string>&)>&& func);
|
void registerCommand(std::string_view name, std::string_view helpText, std::string_view usage, const std::function<void(Console*, const std::vector<std::string>&)>&& func);
|
||||||
|
@ -71,7 +83,13 @@ public:
|
||||||
bool commandExists(std::string_view cmd);
|
bool commandExists(std::string_view cmd);
|
||||||
|
|
||||||
void report(Level level, const char *fmt, va_list list);
|
void report(Level level, const char *fmt, va_list list);
|
||||||
void report(Level, const char* fmt, ...);
|
void report(Level level, const char* fmt, ...);
|
||||||
|
|
||||||
|
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();
|
void dumpLog();
|
||||||
static Console* instance();
|
static Console* instance();
|
||||||
static void RegisterLogger(Console* con);
|
static void RegisterLogger(Console* con);
|
||||||
|
|
|
@ -21,14 +21,12 @@ CVar::CVar(std::string_view name, std::string_view value, std::string_view help,
|
||||||
m_help = help;
|
m_help = help;
|
||||||
m_type = type;
|
m_type = type;
|
||||||
m_flags = flags;
|
m_flags = flags;
|
||||||
m_allowedWrite = false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
CVar::CVar(std::string_view name, std::string_view value, std::string_view help, CVar::EFlags flags, CVarManager& parent)
|
CVar::CVar(std::string_view name, std::string_view value, std::string_view help, CVar::EFlags flags, CVarManager& parent)
|
||||||
: m_mgr(parent)
|
: m_mgr(parent)
|
||||||
{
|
{
|
||||||
m_flags = flags;
|
m_flags = flags;
|
||||||
m_allowedWrite = false;
|
|
||||||
m_name = std::string(name);
|
m_name = std::string(name);
|
||||||
m_help = help;
|
m_help = help;
|
||||||
m_type = EType::Literal;
|
m_type = EType::Literal;
|
||||||
|
@ -52,7 +50,6 @@ CVar::CVar(std::string_view name, const atVec4f& value, std::string_view help, E
|
||||||
m_help = help;
|
m_help = help;
|
||||||
m_type = EType::Vec4f;
|
m_type = EType::Vec4f;
|
||||||
m_flags = flags;
|
m_flags = flags;
|
||||||
m_allowedWrite = false;
|
|
||||||
|
|
||||||
// Unlock the cvar for writing if readonly
|
// Unlock the cvar for writing if readonly
|
||||||
unlock();
|
unlock();
|
||||||
|
@ -73,7 +70,6 @@ CVar::CVar(std::string_view name, float value, std::string_view help, EFlags fla
|
||||||
m_help = help;
|
m_help = help;
|
||||||
m_type = EType::Float;
|
m_type = EType::Float;
|
||||||
m_flags = flags;
|
m_flags = flags;
|
||||||
m_allowedWrite = false;
|
|
||||||
|
|
||||||
// Unlock the cvar for writing if readonly
|
// Unlock the cvar for writing if readonly
|
||||||
unlock();
|
unlock();
|
||||||
|
@ -94,7 +90,6 @@ CVar::CVar(std::string_view name, bool value, std::string_view help, CVar::EFlag
|
||||||
m_help = help;
|
m_help = help;
|
||||||
m_type = EType::Boolean;
|
m_type = EType::Boolean;
|
||||||
m_flags = flags;
|
m_flags = flags;
|
||||||
m_allowedWrite = false;
|
|
||||||
|
|
||||||
// Unlock the cvar for writing if readonly
|
// Unlock the cvar for writing if readonly
|
||||||
unlock();
|
unlock();
|
||||||
|
@ -115,7 +110,6 @@ CVar::CVar(std::string_view name, int value, std::string_view help, CVar::EFlags
|
||||||
m_help = help;
|
m_help = help;
|
||||||
m_type = EType::Integer;
|
m_type = EType::Integer;
|
||||||
m_flags = flags;
|
m_flags = flags;
|
||||||
m_allowedWrite = false;
|
|
||||||
|
|
||||||
// Unlock the cvar for writing if readonly
|
// Unlock the cvar for writing if readonly
|
||||||
unlock();
|
unlock();
|
||||||
|
@ -178,7 +172,7 @@ bool CVar::toBoolean(bool* isValid) const
|
||||||
|
|
||||||
// We don't want to modify the original value;
|
// We don't want to modify the original value;
|
||||||
std::string tmp = m_value;
|
std::string tmp = m_value;
|
||||||
std::transform(tmp.begin(), tmp.end(), tmp.begin(), ::tolower);
|
athena::utility::tolower(tmp);
|
||||||
|
|
||||||
if (!tmp.compare("yes") || !tmp.compare("true") || !tmp.compare("1"))
|
if (!tmp.compare("yes") || !tmp.compare("true") || !tmp.compare("1"))
|
||||||
{
|
{
|
||||||
|
@ -351,6 +345,84 @@ bool CVar::fromLiteral(std::wstring_view val)
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool CVar::fromLiteralToType(std::string_view val)
|
||||||
|
{
|
||||||
|
switch (m_type)
|
||||||
|
{
|
||||||
|
case EType::Literal: return fromLiteral(val);
|
||||||
|
case EType::Boolean:
|
||||||
|
{
|
||||||
|
std::stringstream ss;
|
||||||
|
ss << std::boolalpha << val;
|
||||||
|
bool v;
|
||||||
|
ss >> v;
|
||||||
|
return fromBoolean(v);
|
||||||
|
}
|
||||||
|
case EType::Float:
|
||||||
|
{
|
||||||
|
std::stringstream ss;
|
||||||
|
ss << val;
|
||||||
|
float v;
|
||||||
|
ss >> v;
|
||||||
|
return fromFloat(v);
|
||||||
|
}
|
||||||
|
case EType::Integer:
|
||||||
|
{
|
||||||
|
std::stringstream ss;
|
||||||
|
ss << val;
|
||||||
|
int v;
|
||||||
|
ss >> v;
|
||||||
|
return fromInteger(v);
|
||||||
|
}
|
||||||
|
case EType::Vec4f:
|
||||||
|
{
|
||||||
|
atVec4f vec;
|
||||||
|
std::sscanf(val.data(), "%f %f %f %f", &vec.vec[0], &vec.vec[1], &vec.vec[2], &vec.vec[3]);
|
||||||
|
return fromVec4f(vec);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CVar::fromLiteralToType(std::wstring_view val)
|
||||||
|
{
|
||||||
|
switch (m_type)
|
||||||
|
{
|
||||||
|
case EType::Literal: return fromLiteral(val);
|
||||||
|
case EType::Boolean:
|
||||||
|
{
|
||||||
|
std::wstringstream ss;
|
||||||
|
ss << std::boolalpha << val;
|
||||||
|
bool v;
|
||||||
|
ss >> v;
|
||||||
|
return fromBoolean(v);
|
||||||
|
}
|
||||||
|
case EType::Float:
|
||||||
|
{
|
||||||
|
std::wstringstream ss;
|
||||||
|
ss << val;
|
||||||
|
float v;
|
||||||
|
ss >> v;
|
||||||
|
return fromFloat(v);
|
||||||
|
}
|
||||||
|
case EType::Integer:
|
||||||
|
{
|
||||||
|
std::wstringstream ss;
|
||||||
|
ss << val;
|
||||||
|
int v;
|
||||||
|
ss >> v;
|
||||||
|
return fromInteger(v);
|
||||||
|
}
|
||||||
|
case EType::Vec4f:
|
||||||
|
{
|
||||||
|
atVec4f vec;
|
||||||
|
std::swscanf(val.data(), L"%f %f %f %f", &vec.vec[0], &vec.vec[1], &vec.vec[2], &vec.vec[3]);
|
||||||
|
return fromVec4f(vec);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
bool CVar::isModified() const { return int(m_flags & EFlags::Modified) != 0;}
|
bool CVar::isModified() const { return int(m_flags & EFlags::Modified) != 0;}
|
||||||
bool CVar::modificationRequiresRestart() const { return int(m_flags & EFlags::ModifyRestart) != 0; }
|
bool CVar::modificationRequiresRestart() const { return int(m_flags & EFlags::ModifyRestart) != 0; }
|
||||||
|
|
||||||
|
@ -362,32 +434,30 @@ bool CVar::isHidden() const { return int(m_flags & EFlags::Hidden) != 0; }
|
||||||
|
|
||||||
bool CVar::isArchive() const { return int(m_flags & EFlags::Archive) != 0; }
|
bool CVar::isArchive() const { return int(m_flags & EFlags::Archive) != 0; }
|
||||||
|
|
||||||
void CVar::clearModified() { m_flags &= ~EFlags::Modified; }
|
void CVar::clearModified()
|
||||||
|
{
|
||||||
|
if (!modificationRequiresRestart())
|
||||||
|
m_flags &= ~EFlags::Modified;
|
||||||
|
}
|
||||||
|
|
||||||
void CVar::setModified() { m_flags |= EFlags::Modified; }
|
void CVar::setModified() { m_flags |= EFlags::Modified; }
|
||||||
|
|
||||||
void CVar::unlock()
|
void CVar::unlock()
|
||||||
{
|
{
|
||||||
if (!isReadOnly())
|
if (isReadOnly() && !m_unlocked)
|
||||||
return;
|
|
||||||
|
|
||||||
if (!m_allowedWrite)
|
|
||||||
{
|
{
|
||||||
m_allowedWrite = true;
|
m_oldFlags = m_flags;
|
||||||
m_flags &= ~EFlags::ReadOnly;
|
m_flags &= ~EFlags::ReadOnly;
|
||||||
|
m_unlocked = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void CVar::lock()
|
void CVar::lock()
|
||||||
{
|
{
|
||||||
if (!isReadOnly())
|
if (!isReadOnly() && m_unlocked)
|
||||||
return;
|
|
||||||
|
|
||||||
if (m_allowedWrite)
|
|
||||||
{
|
{
|
||||||
m_flags |= EFlags::ReadOnly;
|
m_flags = m_oldFlags;
|
||||||
m_allowedWrite = false;
|
m_unlocked = false;
|
||||||
clearModified();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -129,10 +129,7 @@ void CVarManager::deserialize(CVar* cvar)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (cvar->m_value != tmp.m_value)
|
if (cvar->m_value != tmp.m_value)
|
||||||
{
|
|
||||||
cvar->m_value = tmp.m_value;
|
cvar->m_value = tmp.m_value;
|
||||||
cvar->m_flags |= CVar::EFlags::Modified;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -178,16 +175,57 @@ CVarManager* CVarManager::instance()
|
||||||
|
|
||||||
void CVarManager::list(Console* con, const std::vector<std::string> &args)
|
void CVarManager::list(Console* con, const std::vector<std::string> &args)
|
||||||
{
|
{
|
||||||
|
for (const auto& cvar : m_cvars)
|
||||||
|
{
|
||||||
|
if (!cvar.second->isHidden())
|
||||||
|
con->report(Console::Level::Info, "%s: %s", cvar.first.c_str(), cvar.second->help().c_str());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void CVarManager::setCVar(Console* con, const std::vector<std::string> &args)
|
void CVarManager::setCVar(Console* con, const std::vector<std::string> &args)
|
||||||
{
|
{
|
||||||
|
if (args.size() < 2)
|
||||||
|
{
|
||||||
|
con->report(Console::Level::Info, "Usage setCvar <cvar> <value>");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string cvName = args[0];
|
||||||
|
athena::utility::tolower(cvName);
|
||||||
|
if (m_cvars.find(cvName) == m_cvars.end())
|
||||||
|
{
|
||||||
|
con->report(Console::Level::Error, "CVar '%s' does not exist", args[0].c_str());
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
CVar* cv = m_cvars[cvName];
|
||||||
|
std::string value = args[1];
|
||||||
|
auto it = args.begin() + 2;
|
||||||
|
for (; it != args.end(); ++it)
|
||||||
|
value += " " + *it;
|
||||||
|
|
||||||
|
if (!cv->fromLiteralToType(value))
|
||||||
|
con->report(Console::Level::Warning, "Unable to cvar '%s' to value '%s'", args[0].c_str(), value.c_str());
|
||||||
}
|
}
|
||||||
|
|
||||||
void CVarManager::getCVar(Console* con, const std::vector<std::string> &args)
|
void CVarManager::getCVar(Console* con, const std::vector<std::string> &args)
|
||||||
{
|
{
|
||||||
|
if (args.empty())
|
||||||
|
{
|
||||||
|
con->report(Console::Level::Info, "Usage getCVar <cvar>");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string cvName = args[0];
|
||||||
|
athena::utility::tolower(cvName);
|
||||||
|
if (m_cvars.find(cvName) == m_cvars.end())
|
||||||
|
{
|
||||||
|
con->report(Console::Level::Error, "CVar '%s' does not exist", args[0].c_str());
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const CVar* cv = m_cvars[cvName];
|
||||||
|
con->report(Console::Level::Info, "'%s' = '%s'", cv->name().data(), cv->value().c_str());
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CVarManager::restartRequired() const
|
bool CVarManager::restartRequired() const
|
||||||
|
|
|
@ -7,6 +7,8 @@ namespace hecl
|
||||||
{
|
{
|
||||||
Console* Console::m_instance = nullptr;
|
Console* Console::m_instance = nullptr;
|
||||||
Console::Console(CVarManager* cvarMgr)
|
Console::Console(CVarManager* cvarMgr)
|
||||||
|
: m_overwrite(false)
|
||||||
|
, m_cursorAtEnd(false)
|
||||||
{
|
{
|
||||||
m_instance = this;
|
m_instance = this;
|
||||||
registerCommand("help", "Prints information about a given function", "<command>", std::bind(&Console::help, this, std::placeholders::_1, std::placeholders::_2));
|
registerCommand("help", "Prints information about a given function", "<command>", std::bind(&Console::help, this, std::placeholders::_1, std::placeholders::_2));
|
||||||
|
@ -95,6 +97,7 @@ void Console::report(Level level, const char* fmt, va_list list)
|
||||||
char tmp[2048];
|
char tmp[2048];
|
||||||
vsnprintf(tmp, 2048, fmt, list);
|
vsnprintf(tmp, 2048, fmt, list);
|
||||||
m_log.emplace_back(std::string(tmp), level);
|
m_log.emplace_back(std::string(tmp), level);
|
||||||
|
printf("%s\n", tmp);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Console::report(Level level, const char* fmt, ...)
|
void Console::report(Level level, const char* fmt, ...)
|
||||||
|
@ -105,91 +108,256 @@ void Console::report(Level level, const char* fmt, ...)
|
||||||
va_end(ap);
|
va_end(ap);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Console::visorReport(Console::Level level, const char* mod, const wchar_t* fmt, va_list list)
|
void Console::proc()
|
||||||
{
|
{
|
||||||
wchar_t tmp[2048];
|
if (m_state == State::Opened)
|
||||||
vswprintf(tmp, 2048, fmt, list);
|
{
|
||||||
std::string v = athena::utility::sprintf("[%s] %s", mod, athena::utility::wideToUtf8(tmp).c_str());
|
printf("\r%s ", m_commandString.c_str());
|
||||||
m_log.emplace_back(athena::utility::wideToUtf8(tmp), level);
|
fflush(stdout);
|
||||||
|
}
|
||||||
|
else if (m_state == State::Opening)
|
||||||
|
m_state = State::Opened;
|
||||||
|
else if (m_state == State::Closing)
|
||||||
|
m_state = State::Closed;
|
||||||
|
|
||||||
|
|
||||||
|
if (m_cursorPosition > (int)m_commandString.size() - 1)
|
||||||
|
m_cursorPosition = (int)m_commandString.size() - 1;
|
||||||
|
if (m_cursorPosition < -1)
|
||||||
|
m_cursorPosition = -1;
|
||||||
|
|
||||||
|
if (m_logOffset > (int)m_log.size() - 1)
|
||||||
|
m_logOffset = (int)m_log.size() - 1;
|
||||||
|
if (m_logOffset < 0)
|
||||||
|
m_logOffset = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Console::visorReport(Console::Level level, const char* mod, const wchar_t* fmt, ...)
|
void Console::draw(boo::IGraphicsCommandQueue* gfxQ)
|
||||||
{
|
{
|
||||||
va_list ap;
|
|
||||||
va_start(ap, fmt);
|
|
||||||
report(level, mod, fmt, ap);
|
|
||||||
va_end(ap);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Console::visorReportSource(Console::Level level, const char* mod, const char* file, unsigned line, const char* fmt, ...)
|
void Console::handleCharCode(unsigned long chr, boo::EModifierKey mod, bool repeat)
|
||||||
{
|
{
|
||||||
va_list ap;
|
if (chr == U'`' || chr == U'~')
|
||||||
va_start(ap, fmt);
|
{
|
||||||
visorReportSource(level, mod, file, line, fmt, ap);
|
if (m_state == State::Closed || m_state == State::Closing)
|
||||||
va_end(ap);
|
m_state = State::Opening;
|
||||||
|
else
|
||||||
|
m_state = State::Closing;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Console::visorReportSource(Console::Level level, const char *mod, const char *file, unsigned line, const wchar_t *fmt, va_list ap)
|
if (m_state == State::Opened)
|
||||||
{
|
{
|
||||||
wchar_t tmp[2048];
|
if (!m_commandString.empty() && m_cursorPosition + 1 < m_commandString.size())
|
||||||
vswprintf(tmp, 2048, fmt, ap);
|
{
|
||||||
std::string v = athena::utility::sprintf("[%s] %s %s:%i", mod, athena::utility::wideToUtf8(tmp).c_str(), file, line);
|
if (m_overwrite)
|
||||||
m_log.emplace_back(v, level);
|
m_commandString[m_cursorPosition + 1] = chr;
|
||||||
|
else
|
||||||
|
m_commandString.insert(m_commandString.begin() + m_cursorPosition + 1, chr);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
m_commandString += chr;
|
||||||
|
|
||||||
|
++m_cursorPosition;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Console::visorReportSource(Console::Level level, const char *mod, const char* file, unsigned line, const wchar_t* fmt, ...)
|
void Console::handleSpecialKeyDown(boo::ESpecialKey sp, boo::EModifierKey mod, bool repeat)
|
||||||
{
|
{
|
||||||
va_list ap;
|
if (m_state != Opened)
|
||||||
va_start(ap, fmt);
|
return;
|
||||||
visorReportSource(level, mod, file, line, fmt, ap);
|
|
||||||
va_end(ap);
|
switch (sp)
|
||||||
|
{
|
||||||
|
case boo::ESpecialKey::Insert:
|
||||||
|
m_overwrite ^= 1;
|
||||||
|
break;
|
||||||
|
case boo::ESpecialKey::Backspace:
|
||||||
|
{
|
||||||
|
if (!m_commandString.empty())
|
||||||
|
{
|
||||||
|
if (int(mod & boo::EModifierKey::Ctrl) != 0)
|
||||||
|
{
|
||||||
|
int index = m_commandString.rfind(' ', m_cursorPosition - 1);
|
||||||
|
|
||||||
|
if (index == (int)std::string::npos)
|
||||||
|
{
|
||||||
|
m_commandString.clear();
|
||||||
|
m_cursorPosition = -1;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
m_commandString.erase(index, (index - m_commandString.size()));
|
||||||
|
m_cursorPosition = index;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (m_cursorPosition < 0)
|
||||||
|
break;
|
||||||
|
|
||||||
|
m_commandString.erase(m_cursorPosition, 1);
|
||||||
|
--m_cursorPosition;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case boo::ESpecialKey::Delete:
|
||||||
|
{
|
||||||
|
if (!m_commandString.empty())
|
||||||
|
{
|
||||||
|
// Don't try to delete if the cursor is at the end of the line
|
||||||
|
if ((m_cursorPosition + 1) >= (int)m_commandString.size())
|
||||||
|
break;
|
||||||
|
|
||||||
|
if (int(mod & boo::EModifierKey::Ctrl) != 0)
|
||||||
|
{
|
||||||
|
int index = m_commandString.find_first_of(' ', m_cursorPosition + 1);
|
||||||
|
if (index != std::string::npos)
|
||||||
|
m_commandString.erase(m_cursorPosition + 1, index + 1);
|
||||||
|
else
|
||||||
|
m_commandString.erase(m_cursorPosition + 1, (m_cursorPosition + 1) - m_commandString.size());
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
m_commandString.erase(m_cursorPosition + 1, 1);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case boo::ESpecialKey::PgUp:
|
||||||
|
{
|
||||||
|
if (m_logOffset < (int)(m_log.size() - m_maxLines) - 1)
|
||||||
|
m_logOffset++;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case boo::ESpecialKey::PgDown:
|
||||||
|
{
|
||||||
|
if (m_logOffset > 0)
|
||||||
|
m_logOffset--;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case boo::ESpecialKey::Enter:
|
||||||
|
{
|
||||||
|
printf("\n");
|
||||||
|
executeString(m_commandString);
|
||||||
|
m_cursorPosition = -1;
|
||||||
|
m_commandHistory.insert(m_commandHistory.begin(), m_commandString);
|
||||||
|
m_commandString.clear();
|
||||||
|
//m_showCursor = true;
|
||||||
|
//m_cursorTime = 0;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case boo::ESpecialKey::Left:
|
||||||
|
{
|
||||||
|
if (m_cursorPosition < 0)
|
||||||
|
break;
|
||||||
|
|
||||||
|
if (int(mod & boo::EModifierKey::Ctrl) != 0)
|
||||||
|
m_cursorPosition = (int)m_commandString.rfind(' ', m_cursorPosition) - 1;
|
||||||
|
else
|
||||||
|
m_cursorPosition--;
|
||||||
|
|
||||||
|
//m_showCursor = true;
|
||||||
|
//m_cursorTime = 0;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case boo::ESpecialKey::Right:
|
||||||
|
{
|
||||||
|
if (m_cursorPosition >= (int)m_commandString.size() - 1)
|
||||||
|
break;
|
||||||
|
|
||||||
|
if (int(mod & boo::EModifierKey::Ctrl) != 0)
|
||||||
|
{
|
||||||
|
if (m_commandString[m_cursorPosition] == ' ')
|
||||||
|
m_cursorPosition++;
|
||||||
|
|
||||||
|
int tmpPos = m_commandString.find(' ', m_cursorPosition);
|
||||||
|
if (tmpPos == std::string::npos)
|
||||||
|
m_cursorPosition = m_commandString.size() - 1;
|
||||||
|
else
|
||||||
|
m_cursorPosition = tmpPos;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
m_cursorPosition++;
|
||||||
|
|
||||||
|
// m_showCursor = true;
|
||||||
|
// m_cursorTime = 0;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Console::visorReport(Console::Level level, const char* mod, const char* fmt, va_list ap)
|
case boo::ESpecialKey::Up:
|
||||||
{
|
{
|
||||||
char tmp[2048];
|
if (m_commandHistory.size() == 0)
|
||||||
vsnprintf(tmp, 2048, fmt, ap);
|
break;
|
||||||
std::string v = athena::utility::sprintf("[%s] %s", mod, tmp);
|
|
||||||
m_log.emplace_back(v, level);
|
m_currentCommand++;
|
||||||
|
|
||||||
|
if (m_currentCommand > (int)m_commandHistory.size() - 1)
|
||||||
|
m_currentCommand = (int)m_commandHistory.size() - 1;
|
||||||
|
|
||||||
|
m_commandString = m_commandHistory[m_currentCommand];
|
||||||
|
m_cursorPosition = m_commandString.size();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case boo::ESpecialKey::Down:
|
||||||
|
{
|
||||||
|
if (m_commandHistory.empty())
|
||||||
|
break;
|
||||||
|
m_currentCommand--;
|
||||||
|
if (m_currentCommand >= 0)
|
||||||
|
{
|
||||||
|
m_commandString = m_commandHistory[m_currentCommand];
|
||||||
|
}
|
||||||
|
else if (m_currentCommand <= -1)
|
||||||
|
{
|
||||||
|
m_currentCommand = -1;
|
||||||
|
m_commandString.clear();
|
||||||
|
}
|
||||||
|
m_cursorPosition = m_commandString.size();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case boo::ESpecialKey::Home:
|
||||||
|
m_cursorPosition = -1;
|
||||||
|
break;
|
||||||
|
case boo::ESpecialKey::End:
|
||||||
|
m_cursorPosition = m_commandString.size() - 1;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Console::visorReport(Console::Level level, const char* mod, const char *fmt, ...)
|
void Console::handleSpecialKeyUp(boo::ESpecialKey sp, boo::EModifierKey mod)
|
||||||
{
|
{
|
||||||
va_list ap;
|
|
||||||
va_start(ap, fmt);
|
|
||||||
report(level, mod, fmt, ap);
|
|
||||||
va_end(ap);
|
|
||||||
}
|
|
||||||
|
|
||||||
void Console::visorReportSource(Console::Level level, const char* mod, const char* file, unsigned line, const char* fmt, va_list ap)
|
|
||||||
{
|
|
||||||
char tmp[2048];
|
|
||||||
vsnprintf(tmp, 2048, fmt, ap);
|
|
||||||
std::string v = athena::utility::sprintf("[%s] %s %s:%i", mod, tmp, file, line);
|
|
||||||
m_log.emplace_back(v, level);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Console::LogVisorAdapter::report(const char* modName, logvisor::Level severity, const char *format, va_list ap)
|
void Console::LogVisorAdapter::report(const char* modName, logvisor::Level severity, const char *format, va_list ap)
|
||||||
{
|
{
|
||||||
m_con->visorReport(Console::Level(severity), modName, format, ap);
|
char tmp[2048];
|
||||||
|
vsnprintf(tmp, 2048, format, ap);
|
||||||
|
std::string v = athena::utility::sprintf("[%s] %s", modName, tmp);
|
||||||
|
m_con->m_log.emplace_back(v, Console::Level(severity));
|
||||||
}
|
}
|
||||||
|
|
||||||
void Console::LogVisorAdapter::report(const char* modName, logvisor::Level severity, const wchar_t* format, va_list ap)
|
void Console::LogVisorAdapter::report(const char* modName, logvisor::Level severity, const wchar_t* format, va_list ap)
|
||||||
{
|
{
|
||||||
m_con->visorReport(Console::Level(severity), modName, format, ap);
|
wchar_t tmp[2048];
|
||||||
|
vswprintf(tmp, 2048, format, ap);
|
||||||
|
std::string v = athena::utility::sprintf("[%s] %s", modName, athena::utility::wideToUtf8(tmp).c_str());
|
||||||
|
m_con->m_log.emplace_back(v, Console::Level(severity));
|
||||||
}
|
}
|
||||||
|
|
||||||
void Console::LogVisorAdapter::reportSource(const char* modName, logvisor::Level severity, const char* file, unsigned linenum, const char* format, va_list ap)
|
void Console::LogVisorAdapter::reportSource(const char* modName, logvisor::Level severity, const char* file, unsigned linenum, const char* format, va_list ap)
|
||||||
{
|
{
|
||||||
m_con->visorReportSource(Console::Level(severity), modName, file, linenum, format, ap);
|
char tmp[2048];
|
||||||
|
vsnprintf(tmp, 2048, format, ap);
|
||||||
|
std::string v = athena::utility::sprintf("[%s] %s %s:%i", modName, tmp, file, linenum);
|
||||||
|
m_con->m_log.emplace_back(v, Console::Level(severity));
|
||||||
}
|
}
|
||||||
|
|
||||||
void Console::LogVisorAdapter::reportSource(const char* modName, logvisor::Level severity, const char* file, unsigned linenum, const wchar_t* format, va_list ap)
|
void Console::LogVisorAdapter::reportSource(const char* modName, logvisor::Level severity, const char* file, unsigned linenum, const wchar_t* format, va_list ap)
|
||||||
{
|
{
|
||||||
wchar_t tmp[2048];
|
wchar_t tmp[2048];
|
||||||
vswprintf(tmp, 2048, format, ap);
|
vswprintf(tmp, 2048, format, ap);
|
||||||
std::string v = athena::utility::wideToUtf8(tmp);
|
std::string v = athena::utility::sprintf("[%s] %s %s:%i", modName, athena::utility::wideToUtf8(tmp).c_str(), file, linenum);
|
||||||
m_con->visorReportSource(Console::Level(severity), modName, file, linenum, format, ap);
|
m_con->m_log.emplace_back(v, Console::Level(severity));
|
||||||
}
|
}
|
||||||
|
|
||||||
void Console::dumpLog()
|
void Console::dumpLog()
|
||||||
|
|
|
@ -1,14 +1,17 @@
|
||||||
#include <boo/boo.hpp>
|
#include <boo/boo.hpp>
|
||||||
#include "logvisor/logvisor.hpp"
|
#include "logvisor/logvisor.hpp"
|
||||||
|
#include "hecl/Console.hpp"
|
||||||
|
#include "hecl/CVarManager.hpp"
|
||||||
#include <athena/MemoryWriter.hpp>
|
#include <athena/MemoryWriter.hpp>
|
||||||
#include "hecl/Runtime.hpp"
|
#include "hecl/Runtime.hpp"
|
||||||
#include "hecl/HMDLMeta.hpp"
|
#include "hecl/HMDLMeta.hpp"
|
||||||
|
|
||||||
#include <cmath>
|
#include <cmath>
|
||||||
#include <thread>
|
#include <thread>
|
||||||
#include <mutex>
|
#include <mutex>
|
||||||
#include <condition_variable>
|
#include <condition_variable>
|
||||||
|
|
||||||
|
using namespace std::literals;
|
||||||
|
|
||||||
namespace hecl::Database
|
namespace hecl::Database
|
||||||
{
|
{
|
||||||
std::vector<const struct DataSpecEntry*> DATA_SPEC_REGISTRY;
|
std::vector<const struct DataSpecEntry*> DATA_SPEC_REGISTRY;
|
||||||
|
@ -18,7 +21,7 @@ struct HECLWindowCallback : boo::IWindowCallback
|
||||||
{
|
{
|
||||||
bool m_sizeDirty = false;
|
bool m_sizeDirty = false;
|
||||||
boo::SWindowRect m_latestSize;
|
boo::SWindowRect m_latestSize;
|
||||||
void resized(const boo::SWindowRect& rect)
|
void resized(const boo::SWindowRect& rect, bool sync)
|
||||||
{
|
{
|
||||||
m_sizeDirty = true;
|
m_sizeDirty = true;
|
||||||
m_latestSize = rect;
|
m_latestSize = rect;
|
||||||
|
@ -29,14 +32,38 @@ struct HECLWindowCallback : boo::IWindowCallback
|
||||||
{
|
{
|
||||||
m_destroyed = true;
|
m_destroyed = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void charKeyDown(unsigned long charCode, boo::EModifierKey mods, bool isRepeat)
|
||||||
|
{
|
||||||
|
hecl::Console::instance()->handleCharCode(charCode, mods, isRepeat);
|
||||||
|
}
|
||||||
|
void specialKeyDown(boo::ESpecialKey key, boo::EModifierKey mods, bool isRepeat)
|
||||||
|
{
|
||||||
|
hecl::Console::instance()->handleSpecialKeyDown(key, mods, isRepeat);
|
||||||
|
}
|
||||||
|
void specialKeyUp(boo::ESpecialKey key, boo::EModifierKey mods)
|
||||||
|
{
|
||||||
|
hecl::Console::instance()->hecl::Console::handleSpecialKeyUp(key, mods);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
struct HECLApplicationCallback : boo::IApplicationCallback
|
struct HECLApplicationCallback : boo::IApplicationCallback
|
||||||
{
|
{
|
||||||
HECLWindowCallback m_windowCb;
|
HECLWindowCallback m_windowCb;
|
||||||
|
hecl::Runtime::FileStoreManager m_fileStoreMgr;
|
||||||
|
hecl::CVarManager m_cvarManager;
|
||||||
|
hecl::Console m_console;
|
||||||
std::shared_ptr<boo::IWindow> m_mainWindow;
|
std::shared_ptr<boo::IWindow> m_mainWindow;
|
||||||
bool m_running = true;
|
bool m_running = true;
|
||||||
|
|
||||||
|
HECLApplicationCallback()
|
||||||
|
: m_fileStoreMgr("heclTest"),
|
||||||
|
m_cvarManager(m_fileStoreMgr),
|
||||||
|
m_console(&m_cvarManager)
|
||||||
|
{
|
||||||
|
m_console.registerCommand("quit"sv, "Quits application"sv, "", std::bind(&HECLApplicationCallback::quit, this, std::placeholders::_1, std::placeholders::_2));
|
||||||
|
}
|
||||||
|
|
||||||
int appMain(boo::IApplication* app)
|
int appMain(boo::IApplication* app)
|
||||||
{
|
{
|
||||||
hecl::VerbosityLevel = 2;
|
hecl::VerbosityLevel = 2;
|
||||||
|
@ -195,6 +222,8 @@ struct HECLApplicationCallback : boo::IApplicationCallback
|
||||||
m_windowCb.m_sizeDirty = false;
|
m_windowCb.m_sizeDirty = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
m_console.proc();
|
||||||
|
|
||||||
gfxQ->setRenderTarget(renderTex);
|
gfxQ->setRenderTarget(renderTex);
|
||||||
boo::SWindowRect r = m_windowCb.m_latestSize;
|
boo::SWindowRect r = m_windowCb.m_latestSize;
|
||||||
r.location[0] = 0;
|
r.location[0] = 0;
|
||||||
|
@ -212,6 +241,7 @@ struct HECLApplicationCallback : boo::IApplicationCallback
|
||||||
gfxQ->setShaderDataBinding(binding);
|
gfxQ->setShaderDataBinding(binding);
|
||||||
gfxQ->drawIndexed(0, 4);
|
gfxQ->drawIndexed(0, 4);
|
||||||
gfxQ->resolveDisplay(renderTex);
|
gfxQ->resolveDisplay(renderTex);
|
||||||
|
m_console.draw(gfxQ);
|
||||||
gfxQ->execute();
|
gfxQ->execute();
|
||||||
|
|
||||||
++frameIdx;
|
++frameIdx;
|
||||||
|
@ -228,6 +258,11 @@ struct HECLApplicationCallback : boo::IApplicationCallback
|
||||||
{
|
{
|
||||||
m_running = false;
|
m_running = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void quit(hecl::Console* con, const std::vector<std::string>& args)
|
||||||
|
{
|
||||||
|
m_running = false;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
void AthenaExcHandler(athena::error::Level level,
|
void AthenaExcHandler(athena::error::Level level,
|
||||||
|
|
Loading…
Reference in New Issue