mirror of https://github.com/AxioDL/metaforce.git
Restore old CVar system
This commit is contained in:
parent
d3e1829994
commit
24abe43865
|
@ -9,46 +9,97 @@
|
|||
|
||||
namespace hecl
|
||||
{
|
||||
class CVar
|
||||
namespace DNACVAR
|
||||
{
|
||||
enum class EType : atUint8
|
||||
{
|
||||
Boolean,
|
||||
Integer,
|
||||
Float,
|
||||
Literal,
|
||||
Vec4f
|
||||
};
|
||||
|
||||
enum EFlags
|
||||
{
|
||||
System = (1 << 0),
|
||||
Game = (1 << 1),
|
||||
Editor = (1 << 2),
|
||||
Gui = (1 << 3),
|
||||
Cheat = (1 << 4),
|
||||
Hidden = (1 << 5),
|
||||
ReadOnly = (1 << 6),
|
||||
Archive = (1 << 7),
|
||||
InternalArchivable = (1 << 8),
|
||||
Modified = (1 << 9),
|
||||
ModifyRestart = (1 << 10) /*!< If this bit is set, any modification will inform the user that a restart is required */
|
||||
};
|
||||
ENABLE_BITWISE_ENUM(EFlags)
|
||||
|
||||
class CVar : public athena::io::DNAYaml<athena::BigEndian>
|
||||
{
|
||||
public:
|
||||
DECL_YAML
|
||||
String<-1> m_name;
|
||||
String<-1> m_value;
|
||||
};
|
||||
|
||||
struct CVarContainer : public athena::io::DNAYaml<athena::BigEndian>
|
||||
{
|
||||
DECL_YAML
|
||||
Value<atUint32> magic = 'CVAR';
|
||||
Value<atUint32> cvarCount;
|
||||
Vector<CVar, DNA_COUNT(cvarCount)> cvars;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
class CVarManager;
|
||||
class CVar : protected DNACVAR::CVar
|
||||
{
|
||||
friend class CVarManager;
|
||||
public:
|
||||
enum EFlags
|
||||
{
|
||||
System = (1 << 0),
|
||||
Game = (1 << 1),
|
||||
Editor = (1 << 2),
|
||||
Gui = (1 << 3),
|
||||
Cheat = (1 << 4),
|
||||
Hidden = (1 << 5),
|
||||
ReadOnly = (1 << 6),
|
||||
Archive = (1 << 7),
|
||||
InternalArchivable = (1 << 8),
|
||||
Modified = (1 << 9),
|
||||
ModifyRestart = (1 << 10) /*!< If this bit is set, any modification will inform the user that a restart is required */
|
||||
};
|
||||
protected:
|
||||
std::string m_name;
|
||||
std::string m_help;
|
||||
EFlags m_flags;
|
||||
EFlags m_oldFlags;
|
||||
bool m_wasDeserialized = false;
|
||||
bool m_unlocked = false;
|
||||
Delete _d;
|
||||
|
||||
virtual bool _fromString(std::string_view sv) = 0;
|
||||
public:
|
||||
CVar(std::string_view name, std::string_view help, EFlags flags);
|
||||
virtual ~CVar() = default;
|
||||
std::string name() const { return m_name; }
|
||||
typedef std::function<void(CVar*)> ListenerFunc;
|
||||
|
||||
using EType = DNACVAR::EType;
|
||||
using EFlags = DNACVAR::EFlags;
|
||||
|
||||
CVar(std::string_view name, std::string_view value, std::string_view help, EType type, EFlags flags, CVarManager& parent);
|
||||
CVar(std::string_view name, std::string_view value, std::string_view help, EFlags flags, CVarManager& parent);
|
||||
CVar(std::string_view name, float value, std::string_view help, EFlags flags, CVarManager& parent);
|
||||
CVar(std::string_view name, bool value, std::string_view help, EFlags flags, CVarManager& parent);
|
||||
CVar(std::string_view name, int value, std::string_view help, EFlags flags, CVarManager& parent);
|
||||
CVar(std::string_view name, const atVec4f& value, std::string_view help, EFlags flags, CVarManager& parent);
|
||||
|
||||
|
||||
std::string_view name() const { return m_name; }
|
||||
std::string_view rawHelp() const { return m_help; }
|
||||
std::string help() const;
|
||||
std::string rawHelp() const { return m_help; }
|
||||
virtual std::string toString() const=0;
|
||||
bool fromString(std::string_view v);
|
||||
virtual void deserialize(athena::io::YAMLDocReader& reader) = 0;
|
||||
virtual void serialize(athena::io::YAMLDocWriter& writer) const = 0;
|
||||
virtual bool hasDefaultValue() const = 0;
|
||||
virtual std::string defaultValueString() const = 0;
|
||||
std::string value() const { return m_value; }
|
||||
|
||||
atVec4f toVec4f(bool* isValid = nullptr) const;
|
||||
float toFloat(bool* isValid = nullptr) const;
|
||||
bool toBoolean(bool* isValid = nullptr) const;
|
||||
int toInteger(bool* isValid = nullptr) const;
|
||||
const std::wstring toWideLiteral(bool* isValid = nullptr) const;
|
||||
const std::string toLiteral(bool* isValid = nullptr) const;
|
||||
|
||||
bool fromVec4f(const atVec4f& val);
|
||||
bool fromFloat(float val);
|
||||
bool fromBoolean(bool val);
|
||||
bool fromInteger(int val);
|
||||
bool fromLiteral(std::string_view val);
|
||||
bool fromLiteral(std::wstring_view val);
|
||||
bool fromLiteralToType(std::string_view val, bool setDefault = false);
|
||||
bool fromLiteralToType(std::wstring_view val, bool setDefault = false);
|
||||
|
||||
bool isFloat() const { return m_type == EType::Float; }
|
||||
bool isBoolean() const { return m_type == EType::Boolean; }
|
||||
bool isInteger() const { return m_type == EType::Integer; }
|
||||
bool isLiteral() const { return m_type == EType::Literal; }
|
||||
bool isVec4f() const { return m_type == EType::Vec4f; }
|
||||
bool isModified() const;
|
||||
bool modificationRequiresRestart() const;
|
||||
bool isReadOnly() const;
|
||||
|
@ -57,36 +108,43 @@ public:
|
|||
bool isArchive() const;
|
||||
bool isInternalArchivable() const;
|
||||
bool wasDeserialized() const;
|
||||
bool hasDefaultValue() const;
|
||||
void clearModified();
|
||||
void setModified();
|
||||
|
||||
EType type() const { return m_type; }
|
||||
EFlags flags() const { return m_flags; }
|
||||
|
||||
/*!
|
||||
* \brief Unlocks the CVar for writing if it is ReadOnly.
|
||||
* <b>Handle with care!!!</b> if you use unlock(), make sure
|
||||
* you lock the cvar using lock()
|
||||
* \see lock
|
||||
*/
|
||||
void unlock();
|
||||
|
||||
/*!
|
||||
* \brief Locks the CVar to prevent writing if it is ReadOnly.
|
||||
* Unlike its partner function unlock, lock is harmless
|
||||
* \see unlock
|
||||
*/
|
||||
void lock();
|
||||
};
|
||||
ENABLE_BITWISE_ENUM(CVar::EFlags)
|
||||
|
||||
void addListener(ListenerFunc func) { m_listeners.push_back(func); }
|
||||
|
||||
template<typename T>
|
||||
class TCVar : public CVar
|
||||
{
|
||||
friend class CVarManager;
|
||||
protected:
|
||||
T& m_value;
|
||||
T m_defaultValue;
|
||||
bool _fromString(std::string_view sv);
|
||||
public:
|
||||
TCVar(T& value, std::string_view name, std::string_view help, EFlags flags);
|
||||
private:
|
||||
void dispatch();
|
||||
EType m_type;
|
||||
std::string m_help;
|
||||
std::string m_defaultValue;
|
||||
EFlags m_flags;
|
||||
EFlags m_oldFlags;
|
||||
bool m_unlocked = false;
|
||||
bool m_wasDeserialized = false;
|
||||
|
||||
virtual std::string toString() const;
|
||||
std::wstring toWideString() const;
|
||||
virtual void deserialize(athena::io::YAMLDocReader& reader);
|
||||
virtual void serialize(athena::io::YAMLDocWriter& writer) const;
|
||||
virtual bool hasDefaultValue() const;
|
||||
CVarManager& m_mgr;
|
||||
|
||||
T value() const;
|
||||
T defaultValue() const;
|
||||
std::string defaultValueString() const;
|
||||
std::vector<ListenerFunc> m_listeners;
|
||||
};
|
||||
|
||||
class CVarUnlocker
|
||||
|
@ -97,107 +155,6 @@ public:
|
|||
~CVarUnlocker() { if (m_cvar) m_cvar->lock(); }
|
||||
};
|
||||
|
||||
class Vec3fCVar : public CVar
|
||||
{
|
||||
friend class CVarManager;
|
||||
atVec3f& m_value;
|
||||
atVec3f m_defaultValue;
|
||||
bool _fromString(std::string_view v);
|
||||
public:
|
||||
Vec3fCVar(atVec3f& value, std::string_view name, std::string_view help, EFlags flags);
|
||||
|
||||
std::string toString() const;
|
||||
bool hasDefaultValue() const;
|
||||
void deserialize(athena::io::YAMLDocReader& reader);
|
||||
void serialize(athena::io::YAMLDocWriter& writer) const;
|
||||
atVec3f value() const { return m_value; }
|
||||
atVec3f defaultValue() const { return m_defaultValue; }
|
||||
|
||||
std::string defaultValueString() const;
|
||||
};
|
||||
|
||||
class Vec3dCVar : public CVar
|
||||
{
|
||||
friend class CVarManager;
|
||||
atVec3d& m_value;
|
||||
atVec3d m_defaultValue;
|
||||
bool _fromString(std::string_view v);
|
||||
public:
|
||||
Vec3dCVar(atVec3d& value, std::string_view name, std::string_view help, EFlags flags);
|
||||
|
||||
std::string toString() const;
|
||||
bool hasDefaultValue() const;
|
||||
void deserialize(athena::io::YAMLDocReader& reader);
|
||||
void serialize(athena::io::YAMLDocWriter& writer) const;
|
||||
atVec3d value() const { return m_value; }
|
||||
atVec3d defaultValue() const { return m_defaultValue; }
|
||||
std::string defaultValueString() const;
|
||||
};
|
||||
|
||||
class Vec4fCVar : public CVar
|
||||
{
|
||||
friend class CVarManager;
|
||||
atVec4f& m_value;
|
||||
atVec4f m_defaultValue;
|
||||
bool _fromString(std::string_view v);
|
||||
public:
|
||||
Vec4fCVar(atVec4f& value, std::string_view name, std::string_view help, EFlags flags);
|
||||
virtual ~Vec4fCVar() = default;
|
||||
|
||||
std::string toString() const;
|
||||
bool hasDefaultValue() const;
|
||||
void deserialize(athena::io::YAMLDocReader& reader);
|
||||
void serialize(athena::io::YAMLDocWriter& writer) const;
|
||||
atVec4f value() const { return m_value; }
|
||||
atVec4f defaultValue() const { return m_defaultValue; }
|
||||
std::string defaultValueString() const;
|
||||
};
|
||||
|
||||
class Vec4dCVar : public CVar
|
||||
{
|
||||
friend class CVarManager;
|
||||
atVec4d& m_value;
|
||||
atVec4d m_defaultValue;
|
||||
bool _fromString(std::string_view v);
|
||||
public:
|
||||
Vec4dCVar(atVec4d& value, std::string_view name, std::string_view help, EFlags flags);
|
||||
|
||||
std::string toString() const;
|
||||
bool hasDefaultValue() const;
|
||||
void deserialize(athena::io::YAMLDocReader& reader);
|
||||
void serialize(athena::io::YAMLDocWriter& writer) const;
|
||||
atVec4d value() const { return m_value; }
|
||||
atVec4d defaultValue() const { return m_defaultValue; }
|
||||
std::string defaultValueString() const;
|
||||
};
|
||||
|
||||
class StringCVar : public CVar
|
||||
{
|
||||
friend class CVarManager;
|
||||
std::string& m_value;
|
||||
std::string m_defaultValue;
|
||||
bool _fromString(std::string_view v);
|
||||
public:
|
||||
StringCVar(std::string& value, std::string_view name, std::string_view help, EFlags flags);
|
||||
|
||||
std::string toString() const;
|
||||
bool hasDefaultValue() const;
|
||||
void deserialize(athena::io::YAMLDocReader& reader);
|
||||
void serialize(athena::io::YAMLDocWriter& writer) const;
|
||||
const std::string& value() const { return m_value; }
|
||||
const std::string& defaultValue() const { return m_defaultValue; }
|
||||
std::string defaultValueString() const { return defaultValue(); }
|
||||
};
|
||||
|
||||
using BoolCVar = TCVar<bool>;
|
||||
using Int16CVar = TCVar<int16_t>;
|
||||
using Uint16CVar = TCVar<uint16_t>;
|
||||
using Int32CVar = TCVar<int32_t>;
|
||||
using Uint32CVar = TCVar<uint32_t>;
|
||||
using Int64CVar = TCVar<int64_t>;
|
||||
using Uint64CVar = TCVar<uint64_t>;
|
||||
using FloatCVar = TCVar<float>;
|
||||
using DoubleCVar = TCVar<double>;
|
||||
}
|
||||
#endif // CVAR_HPP
|
||||
|
||||
|
|
|
@ -12,75 +12,75 @@ namespace hecl
|
|||
using namespace std::literals;
|
||||
|
||||
#ifdef _WIN32
|
||||
#define DEFAULT_GRAPHICS_API "D3D11"
|
||||
#define DEFAULT_GRAPHICS_API "D3D11"sv
|
||||
#elif defined(__APPLE__)
|
||||
#define DEFAULT_GRAPHICS_API "Metal"
|
||||
#define DEFAULT_GRAPHICS_API "Metal"sv
|
||||
#else
|
||||
#define DEFAULT_GRAPHICS_API "OpenGL"
|
||||
#define DEFAULT_GRAPHICS_API "OpenGL"sv
|
||||
#endif
|
||||
|
||||
class CVarCommons
|
||||
{
|
||||
CVarManager& m_mgr;
|
||||
std::string m_graphicsApi = DEFAULT_GRAPHICS_API;
|
||||
uint32_t m_drawSamples = 1;
|
||||
uint32_t m_texAnisotropy = 1;
|
||||
bool m_deepColor = false;
|
||||
CVar* m_graphicsApi = nullptr;
|
||||
CVar* m_drawSamples = nullptr;
|
||||
CVar* m_texAnisotropy = nullptr;
|
||||
CVar* m_deepColor = nullptr;
|
||||
public:
|
||||
CVarCommons(CVarManager& manager) : m_mgr(manager)
|
||||
{
|
||||
m_mgr.findOrMakeCVar("graphicsApi"sv,
|
||||
m_graphicsApi = m_mgr.findOrMakeCVar("graphicsApi"sv,
|
||||
"API to use for rendering graphics"sv,
|
||||
m_graphicsApi, hecl::CVar::EFlags::System | hecl::CVar::EFlags::Archive | hecl::CVar::EFlags::ModifyRestart);
|
||||
m_mgr.findOrMakeCVar("drawSamples"sv,
|
||||
DEFAULT_GRAPHICS_API, hecl::CVar::EFlags::System | hecl::CVar::EFlags::Archive | hecl::CVar::EFlags::ModifyRestart);
|
||||
m_drawSamples = m_mgr.findOrMakeCVar("drawSamples"sv,
|
||||
"Number of MSAA samples to use for render targets"sv,
|
||||
m_drawSamples, hecl::CVar::EFlags::System | hecl::CVar::EFlags::Archive | hecl::CVar::EFlags::ModifyRestart);
|
||||
m_mgr.findOrMakeCVar("texAnisotropy"sv,
|
||||
1, hecl::CVar::EFlags::System | hecl::CVar::EFlags::Archive | hecl::CVar::EFlags::ModifyRestart);
|
||||
m_texAnisotropy = m_mgr.findOrMakeCVar("texAnisotropy"sv,
|
||||
"Number of anisotropic samples to use for sampling textures"sv,
|
||||
m_texAnisotropy, hecl::CVar::EFlags::System | hecl::CVar::EFlags::Archive | hecl::CVar::EFlags::ModifyRestart);
|
||||
m_mgr.findOrMakeCVar("deepColor"sv,
|
||||
1, hecl::CVar::EFlags::System | hecl::CVar::EFlags::Archive | hecl::CVar::EFlags::ModifyRestart);
|
||||
m_deepColor = m_mgr.findOrMakeCVar("deepColor"sv,
|
||||
"Allow framebuffer with color depth greater-then 24-bits"sv,
|
||||
m_deepColor, hecl::CVar::EFlags::System | hecl::CVar::EFlags::Archive | hecl::CVar::EFlags::ModifyRestart);
|
||||
false, hecl::CVar::EFlags::System | hecl::CVar::EFlags::Archive | hecl::CVar::EFlags::ModifyRestart);
|
||||
}
|
||||
|
||||
std::string getGraphicsApi() const
|
||||
{
|
||||
return m_graphicsApi;
|
||||
return m_graphicsApi->toLiteral();
|
||||
}
|
||||
|
||||
void setGraphicsApi(std::string_view api)
|
||||
{
|
||||
m_graphicsApi = api;
|
||||
m_graphicsApi->fromLiteral(api);
|
||||
}
|
||||
|
||||
uint32_t getSamples() const
|
||||
{
|
||||
return std::max(uint32_t(1), m_drawSamples);
|
||||
return std::max(uint32_t(1), uint32_t(m_drawSamples->toInteger()));
|
||||
}
|
||||
|
||||
void setSamples(uint32_t v)
|
||||
{
|
||||
m_drawSamples = std::max(uint32_t(1), v);
|
||||
m_drawSamples->fromInteger(std::max(uint32_t(1), v));
|
||||
}
|
||||
|
||||
uint32_t getAnisotropy() const
|
||||
{
|
||||
return std::max(uint32_t(1), m_texAnisotropy);
|
||||
return std::max(uint32_t(1), uint32_t(m_texAnisotropy->toInteger()));
|
||||
}
|
||||
|
||||
void setAnisotropy(uint32_t v)
|
||||
{
|
||||
m_texAnisotropy = std::max(uint32_t(1), v);
|
||||
m_texAnisotropy->fromInteger(std::max(uint32_t(1), v));
|
||||
}
|
||||
|
||||
bool getDeepColor() const
|
||||
{
|
||||
return m_deepColor;
|
||||
return m_deepColor->toBoolean();
|
||||
}
|
||||
|
||||
void setDeepColor(bool b)
|
||||
{
|
||||
m_deepColor = b;
|
||||
m_deepColor->fromBoolean(b);
|
||||
}
|
||||
|
||||
void serialize()
|
||||
|
|
|
@ -7,36 +7,31 @@
|
|||
|
||||
namespace hecl
|
||||
{
|
||||
|
||||
extern BoolCVar* com_developer;
|
||||
extern StringCVar* com_configfile;
|
||||
extern BoolCVar* com_enableCheats;
|
||||
|
||||
namespace Runtime
|
||||
{
|
||||
class FileStoreManager;
|
||||
}
|
||||
extern CVar* com_developer;
|
||||
extern CVar* com_configfile;
|
||||
extern CVar* com_enableCheats;
|
||||
class CVarManager final
|
||||
{
|
||||
CVar* _newCVar(CVar* cvar)
|
||||
using CVarContainer = DNACVAR::CVarContainer;
|
||||
template <typename T>
|
||||
CVar* _newCVar(std::string_view name, std::string_view help, const T& value, CVar::EFlags flags)
|
||||
{
|
||||
if (registerCVar(cvar))
|
||||
CVar* ret(new CVar(name, value, help, flags, *this));
|
||||
if (registerCVar(ret))
|
||||
{
|
||||
deserialize(cvar);
|
||||
return cvar;
|
||||
deserialize(ret);
|
||||
return ret;
|
||||
}
|
||||
delete cvar;
|
||||
delete ret;
|
||||
return nullptr;
|
||||
}
|
||||
template <typename T>
|
||||
CVar* _newCVar(std::string_view name, std::string_view help, T& value, CVar::EFlags flags)
|
||||
{ return _newCVar(new TCVar<T>(value, name, help, flags)); }
|
||||
|
||||
hecl::Runtime::FileStoreManager& m_store;
|
||||
std::string m_configFile = "config";
|
||||
bool m_useBinary;
|
||||
bool m_developerMode = false;
|
||||
bool m_enableCheats = false;
|
||||
static CVarManager* m_instance;
|
||||
public:
|
||||
CVarManager() = delete;
|
||||
|
@ -46,35 +41,16 @@ public:
|
|||
CVarManager(hecl::Runtime::FileStoreManager& store, bool useBinary = false);
|
||||
~CVarManager();
|
||||
|
||||
void update();
|
||||
CVar* newCVar(std::string_view name, std::string_view help, atVec3f& value, CVar::EFlags flags)
|
||||
{ return _newCVar(new Vec3fCVar(value, name, help, flags)); }
|
||||
CVar* newCVar(std::string_view name, std::string_view help, atVec3d& value, CVar::EFlags flags)
|
||||
{ return _newCVar(new Vec3dCVar(value, name, help, flags)); }
|
||||
CVar* newCVar(std::string_view name, std::string_view help, atVec4f& value, CVar::EFlags flags)
|
||||
{ return _newCVar(new Vec4fCVar(value, name, help, flags)); }
|
||||
CVar* newCVar(std::string_view name, std::string_view help, atVec4d& value, CVar::EFlags flags)
|
||||
{ return _newCVar(new Vec4dCVar(value, name, help, flags)); }
|
||||
CVar* newCVar(std::string_view name, std::string_view help, std::string& value, CVar::EFlags flags)
|
||||
{ return _newCVar(new StringCVar(value, name, help, flags)); }
|
||||
CVar* newCVar(std::string_view name, std::string_view help, bool& value, CVar::EFlags flags)
|
||||
CVar* newCVar(std::string_view name, std::string_view help, const atVec4f& value, CVar::EFlags flags)
|
||||
{ return _newCVar<atVec4f>(name, help, value, flags); }
|
||||
CVar* newCVar(std::string_view name, std::string_view help, std::string_view value, CVar::EFlags flags)
|
||||
{ return _newCVar<std::string_view>(name, help, value, flags); }
|
||||
CVar* newCVar(std::string_view name, std::string_view help, bool value, CVar::EFlags flags)
|
||||
{ return _newCVar<bool>(name, help, value, flags); }
|
||||
CVar* newCVar(std::string_view name, std::string_view help, float& value, CVar::EFlags flags)
|
||||
CVar* newCVar(std::string_view name, std::string_view help, float value, CVar::EFlags flags)
|
||||
{ return _newCVar<float>(name, help, value, flags); }
|
||||
CVar* newCVar(std::string_view name, std::string_view help, double& value, CVar::EFlags flags)
|
||||
{ return _newCVar<double>(name, help, value, flags); }
|
||||
CVar* newCVar(std::string_view name, std::string_view help, int16_t& value, CVar::EFlags flags)
|
||||
{ return _newCVar<int16_t>(name, help, value, flags); }
|
||||
CVar* newCVar(std::string_view name, std::string_view help, uint16_t& value, CVar::EFlags flags)
|
||||
{ return _newCVar<uint16_t>(name, help, value, flags); }
|
||||
CVar* newCVar(std::string_view name, std::string_view help, int32_t& value, CVar::EFlags flags)
|
||||
{ return _newCVar<int32_t>(name, help, value, flags); }
|
||||
CVar* newCVar(std::string_view name, std::string_view help, uint32_t& value, CVar::EFlags flags)
|
||||
{ return _newCVar<uint32_t>(name, help, value, flags); }
|
||||
CVar* newCVar(std::string_view name, std::string_view help, int64_t& value, CVar::EFlags flags)
|
||||
{ return _newCVar<int64_t>(name, help, value, flags); }
|
||||
CVar* newCVar(std::string_view name, std::string_view help, uint64_t& value, CVar::EFlags flags)
|
||||
{ return _newCVar<uint64_t>(name, help, value, flags); }
|
||||
CVar* newCVar(std::string_view name, std::string_view help, int value, CVar::EFlags flags)
|
||||
{ return _newCVar<int>(name, help, value, flags); }
|
||||
|
||||
bool registerCVar(CVar* cvar);
|
||||
|
||||
|
@ -100,8 +76,8 @@ public:
|
|||
void getCVar(class Console* con, const std::vector<std::string>& args);
|
||||
|
||||
|
||||
void setDeveloperMode(bool v, bool setDeserialized=false);
|
||||
bool restartRequired() const;
|
||||
void setDeveloperMode(bool v, bool setDeserialized = false);
|
||||
private:
|
||||
bool suppressDeveloper();
|
||||
void restoreDeveloper(bool oldDeveloper);
|
||||
|
|
|
@ -11,6 +11,7 @@
|
|||
namespace hecl
|
||||
{
|
||||
class CVarManager;
|
||||
class CVar;
|
||||
struct SConsoleCommand
|
||||
{
|
||||
std::string m_displayName;
|
||||
|
@ -72,8 +73,10 @@ private:
|
|||
bool m_overwrite : 1;
|
||||
bool m_cursorAtEnd : 1;
|
||||
State m_state = State::Closed;
|
||||
float m_conSpeed = 1.f;
|
||||
float m_conHeight = 0.5f;
|
||||
CVar* m_conSpeed;
|
||||
CVar* m_conHeight;
|
||||
float m_cachedConSpeed;
|
||||
float m_cachedConHeight;
|
||||
public:
|
||||
Console(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);
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
#include "hecl/hecl.hpp"
|
||||
#include "hecl/CVar.hpp"
|
||||
#include "hecl/CVarManager.hpp"
|
||||
|
||||
#include <athena/Utility.hpp>
|
||||
#include <algorithm>
|
||||
|
@ -7,40 +8,427 @@
|
|||
|
||||
namespace hecl
|
||||
{
|
||||
using namespace std::literals;
|
||||
extern BoolCVar* com_developer;
|
||||
extern BoolCVar* com_enableCheats;
|
||||
extern CVar* com_developer;
|
||||
extern CVar* com_enableCheats;
|
||||
|
||||
CVar::CVar(std::string_view name, std::string_view help, CVar::EFlags flags)
|
||||
: m_name(name)
|
||||
, m_help(help)
|
||||
, m_flags(flags)
|
||||
using namespace std::literals;
|
||||
|
||||
CVar::CVar(std::string_view name, std::string_view value, std::string_view help, EType type, EFlags flags, CVarManager& parent)
|
||||
: m_mgr(parent)
|
||||
{
|
||||
m_name = std::string(name);
|
||||
m_value = std::string(value);
|
||||
m_defaultValue = std::string(value);
|
||||
m_help = help;
|
||||
m_type = type;
|
||||
m_flags = flags;
|
||||
}
|
||||
|
||||
CVar::CVar(std::string_view name, std::string_view value, std::string_view help, CVar::EFlags flags, CVarManager& parent)
|
||||
: m_mgr(parent)
|
||||
{
|
||||
m_flags = flags;
|
||||
m_name = std::string(name);
|
||||
m_help = help;
|
||||
m_type = EType::Literal;
|
||||
|
||||
// Unlock the cvar for writing if readonly
|
||||
unlock();
|
||||
|
||||
fromLiteral(value);
|
||||
m_defaultValue = m_value;
|
||||
|
||||
// Lock the cvar
|
||||
lock();
|
||||
// Clear the modified flag, just incase lock didn't do it.
|
||||
m_flags = flags;
|
||||
}
|
||||
|
||||
CVar::CVar(std::string_view name, const atVec4f& value, std::string_view help, EFlags flags, CVarManager& parent)
|
||||
: m_mgr(parent)
|
||||
{
|
||||
m_name = std::string(name);
|
||||
m_help = help;
|
||||
m_type = EType::Vec4f;
|
||||
m_flags = flags;
|
||||
|
||||
// Unlock the cvar for writing if readonly
|
||||
unlock();
|
||||
|
||||
fromVec4f(value);
|
||||
m_defaultValue = m_value;
|
||||
|
||||
// Lock the cvar
|
||||
lock();
|
||||
// Clear the modified flag, just incase lock didn't do it.
|
||||
m_flags = flags;
|
||||
}
|
||||
|
||||
CVar::CVar(std::string_view name, float value, std::string_view help, EFlags flags, CVarManager& parent)
|
||||
: m_mgr(parent)
|
||||
{
|
||||
m_name = std::string(name);
|
||||
m_help = help;
|
||||
m_type = EType::Float;
|
||||
m_flags = flags;
|
||||
|
||||
// Unlock the cvar for writing if readonly
|
||||
unlock();
|
||||
|
||||
fromFloat(value);
|
||||
m_defaultValue = m_value;
|
||||
|
||||
// Lock the cvar
|
||||
lock();
|
||||
// Clear the modified flag, just incase lock didn't do it.
|
||||
m_flags = flags;
|
||||
}
|
||||
|
||||
CVar::CVar(std::string_view name, bool value, std::string_view help, CVar::EFlags flags, CVarManager& parent)
|
||||
: m_mgr(parent)
|
||||
{
|
||||
m_name = std::string(name);
|
||||
m_help = help;
|
||||
m_type = EType::Boolean;
|
||||
m_flags = flags;
|
||||
|
||||
// Unlock the cvar for writing if readonly
|
||||
unlock();
|
||||
|
||||
fromBoolean(value);
|
||||
m_defaultValue = m_value;
|
||||
|
||||
// Lock the cvar
|
||||
lock();
|
||||
// Clear the modified flag, just incase lock didn't do it.
|
||||
m_flags = flags;
|
||||
}
|
||||
|
||||
CVar::CVar(std::string_view name, int value, std::string_view help, CVar::EFlags flags, CVarManager& parent)
|
||||
: m_mgr(parent)
|
||||
{
|
||||
m_name = std::string(name);
|
||||
m_help = help;
|
||||
m_type = EType::Integer;
|
||||
m_flags = flags;
|
||||
|
||||
// Unlock the cvar for writing if readonly
|
||||
unlock();
|
||||
|
||||
fromInteger(value);
|
||||
m_defaultValue = m_value;
|
||||
|
||||
// Lock the cvar
|
||||
lock();
|
||||
// Clear the modified flag, just incase lock didn't do it.
|
||||
m_flags = flags;
|
||||
}
|
||||
|
||||
std::string CVar::help() const
|
||||
{
|
||||
return std::string(m_help + (hasDefaultValue() ? " (default: " + defaultValueString() : "") +
|
||||
(isReadOnly() ? " [ReadOnly]" : "")) + ")";
|
||||
return std::string(m_help + (m_defaultValue != std::string() ? "\ndefault: " + m_defaultValue : "") +
|
||||
(isReadOnly() ? "[ReadOnly]" : ""));
|
||||
}
|
||||
|
||||
bool CVar::fromString(std::string_view v)
|
||||
atVec4f CVar::toVec4f(bool* isValid) const
|
||||
{
|
||||
if (isCheat() && (com_developer && !com_developer->value() && !com_enableCheats->value()))
|
||||
if (m_type != EType::Vec4f)
|
||||
{
|
||||
if (isValid != nullptr)
|
||||
*isValid = false;
|
||||
|
||||
return atVec4f{};
|
||||
}
|
||||
|
||||
if (isValid != nullptr)
|
||||
*isValid = true;
|
||||
|
||||
atVec4f vec;
|
||||
std::sscanf(m_value.c_str(), "%f %f %f %f", &vec.vec[0], &vec.vec[1], &vec.vec[2], &vec.vec[3]);
|
||||
|
||||
return vec;
|
||||
}
|
||||
|
||||
float CVar::toFloat(bool* isValid) const
|
||||
{
|
||||
if (m_type != EType::Float)
|
||||
{
|
||||
if (isValid)
|
||||
*isValid = false;
|
||||
return 0.0f;
|
||||
}
|
||||
|
||||
return strtof(m_value.c_str(), nullptr);
|
||||
}
|
||||
|
||||
bool CVar::toBoolean(bool* isValid) const
|
||||
{
|
||||
if (m_type != EType::Boolean)
|
||||
{
|
||||
if (isValid)
|
||||
*isValid = false;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
// We don't want to modify the original value;
|
||||
std::string tmp = m_value;
|
||||
athena::utility::tolower(tmp);
|
||||
|
||||
if (!tmp.compare("yes") || !tmp.compare("true") || !tmp.compare("1"))
|
||||
{
|
||||
if (isValid)
|
||||
*isValid = true;
|
||||
return true;
|
||||
}
|
||||
else if (!tmp.compare("no") || !tmp.compare("false") || !tmp.compare("0"))
|
||||
{
|
||||
if (isValid)
|
||||
*isValid = true;
|
||||
return false;
|
||||
}
|
||||
|
||||
if (isValid)
|
||||
*isValid = false;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
int CVar::toInteger(bool* isValid) const
|
||||
{
|
||||
if (m_type != EType::Integer)
|
||||
{
|
||||
if (isValid)
|
||||
*isValid = false;
|
||||
return 0;
|
||||
}
|
||||
|
||||
return strtol(m_value.c_str(), nullptr, 0);
|
||||
}
|
||||
|
||||
const std::string CVar::toLiteral(bool* isValid) const
|
||||
{
|
||||
if (m_type != EType::Literal && (com_developer && com_developer->toBoolean()))
|
||||
{
|
||||
if (isValid != nullptr)
|
||||
*isValid = false;
|
||||
}
|
||||
else if (isValid != nullptr)
|
||||
*isValid = true;
|
||||
|
||||
// Even if it's not a literal, it's still safe to return
|
||||
return m_value;
|
||||
}
|
||||
|
||||
const std::wstring CVar::toWideLiteral(bool* isValid) const
|
||||
{
|
||||
if (m_type != EType::Literal && (com_developer && com_developer->toBoolean()))
|
||||
{
|
||||
if (isValid != nullptr)
|
||||
*isValid = false;
|
||||
}
|
||||
else if (isValid != nullptr)
|
||||
*isValid = true;
|
||||
|
||||
// Even if it's not a literal, it's still safe to return
|
||||
return hecl::UTF8ToWide(m_value);
|
||||
}
|
||||
|
||||
bool CVar::fromVec4f(const atVec4f& val)
|
||||
{
|
||||
if (isCheat() && (com_developer && !com_developer->toBoolean() && !com_enableCheats->toBoolean()))
|
||||
return false;
|
||||
else if (isCheat())
|
||||
return false;
|
||||
|
||||
if (isReadOnly() && (com_developer && !com_developer->value()))
|
||||
if (m_type != EType::Vec4f)
|
||||
return false;
|
||||
|
||||
bool ret = _fromString(v);
|
||||
if (ret)
|
||||
m_flags |= EFlags::Modified;
|
||||
return ret;
|
||||
if (isReadOnly() && (com_developer && !com_developer->toBoolean()))
|
||||
return false;
|
||||
|
||||
m_value.assign(hecl::Format("%f %f %f %f", val.vec[0], val.vec[1], val.vec[2], val.vec[3]));
|
||||
m_flags |= EFlags::Modified;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CVar::isModified() const { return int(m_flags & EFlags::Modified) != 0; }
|
||||
bool CVar::fromFloat(float val)
|
||||
{
|
||||
if (isCheat() && (com_developer && !com_developer->toBoolean() && !com_enableCheats->toBoolean()))
|
||||
return false;
|
||||
else if (isCheat())
|
||||
return false;
|
||||
|
||||
if (m_type != EType::Float)
|
||||
return false;
|
||||
|
||||
if (isReadOnly() && (com_developer && !com_developer->toBoolean()))
|
||||
return false;
|
||||
|
||||
m_value.assign(hecl::Format("%f", val));
|
||||
setModified();
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CVar::fromBoolean(bool val)
|
||||
{
|
||||
if (isCheat() && (com_developer && !com_developer->toBoolean() && !com_enableCheats->toBoolean()))
|
||||
return false;
|
||||
else if (isCheat())
|
||||
return false;
|
||||
|
||||
if (m_type != EType::Boolean)
|
||||
return false;
|
||||
|
||||
if (isReadOnly() && (com_developer && !com_developer->toBoolean()))
|
||||
return false;
|
||||
|
||||
if (val)
|
||||
m_value = "true"sv;
|
||||
else
|
||||
m_value = "false"sv;
|
||||
|
||||
setModified();
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CVar::fromInteger(int val)
|
||||
{
|
||||
if (isCheat() && (com_developer && !com_developer->toBoolean() && !com_enableCheats->toBoolean()))
|
||||
return false;
|
||||
else if (isCheat())
|
||||
return false;
|
||||
|
||||
if (m_type != EType::Integer)
|
||||
return false;
|
||||
|
||||
if (isReadOnly() && (com_developer && !com_developer->toBoolean()))
|
||||
return false;
|
||||
|
||||
m_value = hecl::Format("%i", val);
|
||||
setModified();
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CVar::fromLiteral(std::string_view val)
|
||||
{
|
||||
if (isCheat() && (com_developer && !com_developer->toBoolean() && !com_enableCheats->toBoolean()))
|
||||
return false;
|
||||
else if (isCheat())
|
||||
return false;
|
||||
|
||||
if (m_type != EType::Literal)
|
||||
return false;
|
||||
|
||||
if (isReadOnly() && (com_developer && !com_developer->toBoolean()))
|
||||
return false;
|
||||
|
||||
m_value.assign(val);
|
||||
setModified();
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CVar::fromLiteral(std::wstring_view val)
|
||||
{
|
||||
if (isCheat() && (com_developer && !com_developer->toBoolean() && !com_enableCheats->toBoolean()))
|
||||
return false;
|
||||
else if (isCheat())
|
||||
return false;
|
||||
|
||||
if (m_type != EType::Literal)
|
||||
return false;
|
||||
|
||||
if (isReadOnly() && (com_developer && !com_developer->toBoolean()))
|
||||
return false;
|
||||
|
||||
m_value.assign(hecl::WideToUTF8(val));
|
||||
setModified();
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CVar::fromLiteralToType(std::string_view val, bool setDefault)
|
||||
{
|
||||
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);
|
||||
}
|
||||
}
|
||||
if (setDefault)
|
||||
m_value = m_defaultValue;
|
||||
return false;
|
||||
}
|
||||
|
||||
bool CVar::fromLiteralToType(std::wstring_view val, bool setDefault)
|
||||
{
|
||||
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);
|
||||
}
|
||||
}
|
||||
if (setDefault)
|
||||
m_value = m_defaultValue;
|
||||
return false;
|
||||
}
|
||||
|
||||
bool CVar::isModified() const { return int(m_flags & EFlags::Modified) != 0;}
|
||||
bool CVar::modificationRequiresRestart() const { return int(m_flags & EFlags::ModifyRestart) != 0; }
|
||||
|
||||
bool CVar::isReadOnly() const { return int(m_flags & EFlags::ReadOnly) != 0; }
|
||||
|
@ -55,6 +443,8 @@ bool CVar::isInternalArchivable() const { return int(m_flags & EFlags::InternalA
|
|||
|
||||
bool CVar::wasDeserialized() const { return m_wasDeserialized; }
|
||||
|
||||
bool CVar::hasDefaultValue() const { return m_defaultValue == m_value; }
|
||||
|
||||
void CVar::clearModified()
|
||||
{
|
||||
if (!modificationRequiresRestart())
|
||||
|
@ -82,293 +472,10 @@ void CVar::lock()
|
|||
}
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
TCVar<T>::TCVar(T& value, std::string_view name, std::string_view description, EFlags flags)
|
||||
: CVar(name, description, flags)
|
||||
, m_value(value)
|
||||
, m_defaultValue(value)
|
||||
void CVar::dispatch()
|
||||
{
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
std::string TCVar<T>::toString() const
|
||||
{
|
||||
std::stringstream ss;
|
||||
ss << std::boolalpha << m_value;
|
||||
return ss.str();
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
std::wstring TCVar<T>::toWideString() const
|
||||
{
|
||||
return hecl::UTF8ToWide(toString());
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
bool TCVar<T>::_fromString(std::string_view v)
|
||||
{
|
||||
T tmp;
|
||||
std::stringstream ss;
|
||||
ss << std::boolalpha << v;
|
||||
ss >> tmp;
|
||||
if (ss.good())
|
||||
m_value = tmp;
|
||||
|
||||
return ss.good();
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
void TCVar<T>::deserialize(athena::io::YAMLDocReader &reader)
|
||||
{
|
||||
m_value = reader.readVal<T>(m_name.c_str());
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
void TCVar<T>::serialize(athena::io::YAMLDocWriter& writer) const
|
||||
{
|
||||
writer.writeVal(m_name.c_str(), m_value);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
bool TCVar<T>::hasDefaultValue() const
|
||||
{
|
||||
return m_value == m_defaultValue;
|
||||
}
|
||||
|
||||
|
||||
template<typename T>
|
||||
T TCVar<T>::value() const
|
||||
{
|
||||
return m_value;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
T TCVar<T>::defaultValue() const
|
||||
{
|
||||
return m_defaultValue;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
std::string TCVar<T>::defaultValueString() const
|
||||
{
|
||||
std::stringstream ss;
|
||||
ss << std::boolalpha << m_defaultValue;
|
||||
return ss.str();
|
||||
}
|
||||
|
||||
Vec3fCVar::Vec3fCVar(atVec3f &value, std::string_view name, std::string_view description, CVar::EFlags flags)
|
||||
: CVar(name, description, flags)
|
||||
, m_value(value)
|
||||
, m_defaultValue(value)
|
||||
{}
|
||||
|
||||
std::string Vec3fCVar::toString() const
|
||||
{
|
||||
return athena::utility::sprintf("%f %f %f", double(m_value.vec[0]), double(m_value.vec[1]), double(m_value.vec[2]));
|
||||
}
|
||||
|
||||
bool Vec3fCVar::_fromString(std::string_view v)
|
||||
{
|
||||
float x, y, z;
|
||||
if (std::sscanf(v.data(), "%f %f %f", &x, &y, &z) != 3)
|
||||
return false;
|
||||
m_value.vec[0] = x;
|
||||
m_value.vec[1] = y;
|
||||
m_value.vec[2] = y;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Vec3fCVar::hasDefaultValue() const
|
||||
{
|
||||
return !memcmp(&m_value.vec, &m_defaultValue.vec[0], sizeof(atVec3f));
|
||||
}
|
||||
|
||||
void Vec3fCVar::deserialize(athena::io::YAMLDocReader& reader)
|
||||
{
|
||||
m_value = reader.readVec3f(m_name.c_str());
|
||||
}
|
||||
|
||||
void Vec3fCVar::serialize(athena::io::YAMLDocWriter& writer) const
|
||||
{
|
||||
writer.writeVec3f(m_name.c_str(), m_value);
|
||||
}
|
||||
|
||||
std::string Vec3fCVar::defaultValueString() const
|
||||
{
|
||||
return athena::utility::sprintf("%f %f %f", double(m_defaultValue.vec[0]), double(m_defaultValue.vec[1]), double(m_defaultValue.vec[2]));
|
||||
}
|
||||
|
||||
Vec3dCVar::Vec3dCVar(atVec3d &value, std::string_view name, std::string_view description, CVar::EFlags flags)
|
||||
: CVar(name, description, flags)
|
||||
, m_value(value)
|
||||
, m_defaultValue(value)
|
||||
{}
|
||||
|
||||
std::string Vec3dCVar::toString() const
|
||||
{
|
||||
return athena::utility::sprintf("%lf %lf %lf", m_value.vec[0], m_value.vec[1], m_value.vec[2]);
|
||||
}
|
||||
|
||||
bool Vec3dCVar::_fromString(std::string_view v)
|
||||
{
|
||||
double x, y, z;
|
||||
if (std::sscanf(v.data(), "%lf %lf %lf", &x, &y, &z) != 3)
|
||||
return false;
|
||||
m_value.vec[0] = x;
|
||||
m_value.vec[1] = y;
|
||||
m_value.vec[2] = y;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Vec3dCVar::hasDefaultValue() const
|
||||
{
|
||||
return !memcmp(&m_value.vec, &m_defaultValue.vec[0], sizeof(atVec3d));
|
||||
}
|
||||
|
||||
void Vec3dCVar::deserialize(athena::io::YAMLDocReader& reader)
|
||||
{
|
||||
m_value = reader.readVec3d(m_name.c_str());
|
||||
}
|
||||
|
||||
void Vec3dCVar::serialize(athena::io::YAMLDocWriter& writer) const
|
||||
{
|
||||
writer.writeVec3d(m_name.c_str(), m_value);
|
||||
}
|
||||
|
||||
std::string Vec3dCVar::defaultValueString() const
|
||||
{
|
||||
return athena::utility::sprintf("%g %g %g", m_defaultValue.vec[0], m_defaultValue.vec[1], m_defaultValue.vec[2]);
|
||||
}
|
||||
|
||||
Vec4fCVar::Vec4fCVar(atVec4f &value, std::string_view name, std::string_view description, CVar::EFlags flags)
|
||||
: CVar(name, description, flags)
|
||||
, m_value(value)
|
||||
, m_defaultValue(value)
|
||||
{}
|
||||
|
||||
std::string Vec4fCVar::toString() const
|
||||
{
|
||||
return athena::utility::sprintf("%g %g %g %g", &m_value.vec[0], &m_value.vec[1], &m_value.vec[2], &m_value.vec[3]);
|
||||
}
|
||||
|
||||
bool Vec4fCVar::_fromString(std::string_view v)
|
||||
{
|
||||
float x, y, z, w;
|
||||
if (std::sscanf(v.data(), "%f %f %f %f", &x, &y, &z, &w) != 4)
|
||||
return false;
|
||||
m_value.vec[0] = x;
|
||||
m_value.vec[1] = y;
|
||||
m_value.vec[2] = y;
|
||||
m_value.vec[3] = w;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Vec4fCVar::hasDefaultValue() const
|
||||
{
|
||||
return !memcmp(&m_value.vec, &m_defaultValue.vec[0], sizeof(atVec4f));
|
||||
}
|
||||
|
||||
void Vec4fCVar::deserialize(athena::io::YAMLDocReader& reader)
|
||||
{
|
||||
m_value = reader.readVec4f(m_name.c_str());
|
||||
}
|
||||
|
||||
void Vec4fCVar::serialize(athena::io::YAMLDocWriter& writer) const
|
||||
{
|
||||
writer.writeVec4f(m_name.c_str(), m_value);
|
||||
}
|
||||
|
||||
std::string Vec4fCVar::defaultValueString() const
|
||||
{
|
||||
return athena::utility::sprintf("%f %f %f", &m_defaultValue.vec[0], &m_defaultValue.vec[1], &m_defaultValue.vec[2]);
|
||||
}
|
||||
|
||||
Vec4dCVar::Vec4dCVar(atVec4d &value, std::string_view name, std::string_view description, CVar::EFlags flags)
|
||||
: CVar(name, description, flags)
|
||||
, m_value(value)
|
||||
, m_defaultValue(value)
|
||||
{}
|
||||
|
||||
std::string Vec4dCVar::toString() const
|
||||
{
|
||||
return athena::utility::sprintf("%f %f %f %f", m_value.vec[0], m_value.vec[1], m_value.vec[2], m_value.vec[3]);
|
||||
}
|
||||
|
||||
bool Vec4dCVar::_fromString(std::string_view v)
|
||||
{
|
||||
double x, y, z, w;
|
||||
if (std::sscanf(v.data(), "%lf %lf %lf %lf", &x, &y, &z, &w) != 4)
|
||||
return false;
|
||||
m_value.vec[0] = x;
|
||||
m_value.vec[1] = y;
|
||||
m_value.vec[2] = y;
|
||||
m_value.vec[3] = w;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Vec4dCVar::hasDefaultValue() const
|
||||
{
|
||||
return !memcmp(&m_value.vec, &m_defaultValue.vec[0], sizeof(atVec4d));
|
||||
}
|
||||
|
||||
void Vec4dCVar::deserialize(athena::io::YAMLDocReader& reader)
|
||||
{
|
||||
m_value = reader.readVec4d(m_name.c_str());
|
||||
}
|
||||
|
||||
void Vec4dCVar::serialize(athena::io::YAMLDocWriter& writer) const
|
||||
{
|
||||
writer.writeVec4d(m_name.c_str(), m_value);
|
||||
}
|
||||
|
||||
std::string Vec4dCVar::defaultValueString() const
|
||||
{
|
||||
return athena::utility::sprintf("%g %g %g", m_defaultValue.vec[0], m_defaultValue.vec[1], m_defaultValue.vec[2]);
|
||||
}
|
||||
|
||||
StringCVar::StringCVar(std::string& value, std::string_view name, std::string_view help, CVar::EFlags flags)
|
||||
: CVar(name, help, flags)
|
||||
, m_value(value)
|
||||
, m_defaultValue(value)
|
||||
{
|
||||
}
|
||||
|
||||
std::string StringCVar::toString() const
|
||||
{
|
||||
return m_value;
|
||||
}
|
||||
|
||||
bool StringCVar::_fromString(std::string_view v)
|
||||
{
|
||||
m_value = v;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool StringCVar::hasDefaultValue() const
|
||||
{
|
||||
return m_value == m_defaultValue;
|
||||
}
|
||||
|
||||
void StringCVar::deserialize(athena::io::YAMLDocReader& reader)
|
||||
{
|
||||
m_value = reader.readString(m_name.c_str());
|
||||
}
|
||||
|
||||
void StringCVar::serialize(athena::io::YAMLDocWriter& writer) const
|
||||
{
|
||||
writer.writeString(m_name.c_str(), m_value.c_str());
|
||||
}
|
||||
|
||||
|
||||
template class TCVar<bool>;
|
||||
template class TCVar<int16_t>;
|
||||
template class TCVar<uint16_t>;
|
||||
template class TCVar<int32_t>;
|
||||
template class TCVar<uint32_t>;
|
||||
template class TCVar<int64_t>;
|
||||
template class TCVar<uint64_t>;
|
||||
template class TCVar<float>;
|
||||
template class TCVar<double>;
|
||||
|
||||
for (const ListenerFunc& listen : m_listeners)
|
||||
listen(this);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
#include "hecl/CVarManager.hpp"
|
||||
#include "hecl/CVar.hpp"
|
||||
#include "hecl/Console.hpp"
|
||||
#include <athena/FileWriter.hpp>
|
||||
#include <athena/Utility.hpp>
|
||||
|
@ -9,10 +8,9 @@
|
|||
namespace hecl
|
||||
{
|
||||
|
||||
BoolCVar* com_developer = nullptr;
|
||||
StringCVar* com_configfile = nullptr;
|
||||
BoolCVar* com_enableCheats = nullptr;
|
||||
|
||||
CVar* com_developer = nullptr;
|
||||
CVar* com_configfile = nullptr;
|
||||
CVar* com_enableCheats = nullptr;
|
||||
|
||||
CVarManager* CVarManager::m_instance = nullptr;
|
||||
|
||||
|
@ -22,24 +20,15 @@ CVarManager::CVarManager(hecl::Runtime::FileStoreManager& store, bool useBinary)
|
|||
m_useBinary(useBinary)
|
||||
{
|
||||
m_instance = this;
|
||||
com_configfile = dynamic_cast<StringCVar*>(findOrMakeCVar("config", "File to store configuration", m_configFile, CVar::EFlags::System));
|
||||
com_developer = dynamic_cast<BoolCVar*>(findOrMakeCVar("developer", "Enables developer mode", m_developerMode, (CVar::EFlags::System | CVar::EFlags::ReadOnly | CVar::EFlags::InternalArchivable)));
|
||||
com_enableCheats = dynamic_cast<BoolCVar*>(findOrMakeCVar("iamaweiner", "Enable cheats", m_enableCheats, (CVar::EFlags::System | CVar::EFlags::ReadOnly | CVar::EFlags::Hidden)));
|
||||
com_configfile = newCVar("config", "File to store configuration", std::string("config"), CVar::EFlags::System);
|
||||
com_developer = newCVar("developer", "Enables developer mode", false, (CVar::EFlags::System | CVar::EFlags::ReadOnly | CVar::EFlags::InternalArchivable));
|
||||
com_enableCheats = newCVar("iamaweiner", "Enable cheats", false, (CVar::EFlags::System | CVar::EFlags::ReadOnly | CVar::EFlags::Hidden));
|
||||
}
|
||||
|
||||
CVarManager::~CVarManager()
|
||||
{
|
||||
}
|
||||
|
||||
void CVarManager::update()
|
||||
{
|
||||
for (const std::pair<std::string, CVar*>& pair : m_cvars)
|
||||
if (pair.second->isModified())
|
||||
{
|
||||
pair.second->clearModified();
|
||||
}
|
||||
}
|
||||
|
||||
bool CVarManager::registerCVar(CVar* cvar)
|
||||
{
|
||||
std::string tmp(cvar->name());
|
||||
|
@ -86,53 +75,88 @@ void CVarManager::deserialize(CVar* cvar)
|
|||
if (!cvar || (!cvar->isArchive() && !cvar->isInternalArchivable()))
|
||||
return;
|
||||
|
||||
CVarContainer container;
|
||||
#if _WIN32
|
||||
hecl::SystemString filename = hecl::SystemString(m_store.getStoreRoot()) + _S('/') + hecl::UTF8ToWide(m_configFile);
|
||||
hecl::SystemString filename = hecl::SystemString(m_store.getStoreRoot()) + _S('/') + com_configfile->toWideLiteral();
|
||||
#else
|
||||
hecl::SystemString filename = hecl::SystemString(m_store.getStoreRoot()) + _S('/') + m_configFile;
|
||||
hecl::SystemString filename = hecl::SystemString(m_store.getStoreRoot()) + _S('/') + com_configfile->toLiteral();
|
||||
#endif
|
||||
hecl::Sstat st;
|
||||
|
||||
filename += _S(".yaml");
|
||||
if (hecl::Stat(filename.c_str(), &st) || !S_ISREG(st.st_mode))
|
||||
return;
|
||||
athena::io::FileReader reader(filename);
|
||||
if (reader.isOpen())
|
||||
if (m_useBinary)
|
||||
{
|
||||
athena::io::YAMLDocReader doc;
|
||||
doc.parse(&reader);
|
||||
if (doc.hasVal(cvar->name().c_str()))
|
||||
filename += _S(".bin");
|
||||
if (hecl::Stat(filename.c_str(), &st) || !S_ISREG(st.st_mode))
|
||||
return;
|
||||
athena::io::FileReader reader(filename);
|
||||
if (reader.isOpen())
|
||||
container.read(reader);
|
||||
}
|
||||
else
|
||||
{
|
||||
filename += _S(".yaml");
|
||||
if (hecl::Stat(filename.c_str(), &st) || !S_ISREG(st.st_mode))
|
||||
return;
|
||||
athena::io::FileReader reader(filename);
|
||||
if (reader.isOpen())
|
||||
container.fromYAMLStream(reader);
|
||||
}
|
||||
|
||||
|
||||
if (container.cvars.size() > 0)
|
||||
{
|
||||
auto serialized = std::find_if(container.cvars.begin(), container.cvars.end(), [&cvar](const DNACVAR::CVar& c) -> bool
|
||||
{ return c.m_name == cvar->name(); });
|
||||
|
||||
if (serialized != container.cvars.end())
|
||||
{
|
||||
cvar->unlock();
|
||||
cvar->deserialize(doc);
|
||||
cvar->m_wasDeserialized = true;;
|
||||
cvar->lock();
|
||||
DNACVAR::CVar& tmp = *serialized;
|
||||
|
||||
if (cvar->m_value != tmp.m_value)
|
||||
{
|
||||
cvar->unlock();
|
||||
cvar->fromLiteralToType(tmp.m_value, true);
|
||||
cvar->m_wasDeserialized = true;
|
||||
cvar->lock();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void CVarManager::serialize()
|
||||
{
|
||||
CVarContainer container;
|
||||
for (const std::pair<std::string, CVar*>& pair : m_cvars)
|
||||
if (pair.second->isArchive() || (pair.second->isInternalArchivable() && pair.second->wasDeserialized() && !pair.second->hasDefaultValue()))
|
||||
{
|
||||
CVar tmp = *pair.second;
|
||||
container.cvars.push_back(tmp);
|
||||
}
|
||||
|
||||
container.cvarCount = atUint32(container.cvars.size());
|
||||
|
||||
#if _WIN32
|
||||
hecl::SystemString filename = hecl::SystemString(m_store.getStoreRoot()) + _S('/') + hecl::UTF8ToWide(m_configFile);
|
||||
hecl::SystemString filename = hecl::SystemString(m_store.getStoreRoot()) + _S('/') + com_configfile->toWideLiteral();
|
||||
#else
|
||||
hecl::SystemString filename = hecl::SystemString(m_store.getStoreRoot()) + _S('/') + m_configFile;
|
||||
hecl::SystemString filename = hecl::SystemString(m_store.getStoreRoot()) + _S('/') + com_configfile->toLiteral();
|
||||
#endif
|
||||
|
||||
filename += _S(".yaml");
|
||||
athena::io::FileWriter writer(filename);
|
||||
if (writer.isOpen())
|
||||
if (m_useBinary)
|
||||
{
|
||||
athena::io::YAMLDocWriter doc(nullptr);
|
||||
for (const std::pair<std::string, CVar*>& pair : m_cvars)
|
||||
if (pair.second->isArchive() || (pair.second->isInternalArchivable() && pair.second->wasDeserialized() && !pair.second->hasDefaultValue()))
|
||||
pair.second->serialize(doc);
|
||||
doc.finish(&writer);
|
||||
filename += _S(".bin");
|
||||
athena::io::FileWriter writer(filename);
|
||||
if (writer.isOpen())
|
||||
container.write(writer);
|
||||
}
|
||||
else
|
||||
{
|
||||
filename += _S(".yaml");
|
||||
athena::io::FileWriter writer(filename);
|
||||
if (writer.isOpen())
|
||||
container.toYAMLStream(writer);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
CVarManager* CVarManager::instance()
|
||||
{
|
||||
return m_instance;
|
||||
|
@ -169,9 +193,8 @@ void CVarManager::setCVar(Console* con, const std::vector<std::string> &args)
|
|||
for (; it != args.end(); ++it)
|
||||
value += " " + *it;
|
||||
|
||||
if (!cv->fromString(value))
|
||||
con->report(Console::Level::Warning, "Unable to cvar '%s' to value '%s'", args[0].c_str(), value.c_str());
|
||||
|
||||
if (!cv->fromLiteralToType(value))
|
||||
con->report(Console::Level::Warning, "Unable to set cvar '%s' to value '%s'", args[0].c_str(), value.c_str());
|
||||
}
|
||||
|
||||
void CVarManager::getCVar(Console* con, const std::vector<std::string> &args)
|
||||
|
@ -191,7 +214,18 @@ void CVarManager::getCVar(Console* con, const std::vector<std::string> &args)
|
|||
}
|
||||
|
||||
const CVar* cv = m_cvars[cvName];
|
||||
con->report(Console::Level::Info, "'%s' = '%s'", cv->name().data(), cv->toString().c_str());
|
||||
con->report(Console::Level::Info, "'%s' = '%s'", cv->name().data(), cv->value().c_str());
|
||||
}
|
||||
|
||||
void CVarManager::setDeveloperMode(bool v, bool setDeserialized)
|
||||
{
|
||||
com_developer->unlock();
|
||||
com_developer->fromBoolean(v);
|
||||
if (setDeserialized)
|
||||
com_developer->m_wasDeserialized = true;
|
||||
com_developer->lock();
|
||||
com_developer->setModified();
|
||||
|
||||
}
|
||||
|
||||
bool CVarManager::restartRequired() const
|
||||
|
@ -205,27 +239,19 @@ bool CVarManager::restartRequired() const
|
|||
return false;
|
||||
}
|
||||
|
||||
void CVarManager::setDeveloperMode(bool v, bool setDeserialized)
|
||||
{
|
||||
com_developer->unlock();
|
||||
com_developer->m_value = v;
|
||||
if (setDeserialized)
|
||||
com_developer->m_wasDeserialized = true;
|
||||
com_developer->lock();
|
||||
com_developer->setModified();
|
||||
}
|
||||
|
||||
bool CVarManager::suppressDeveloper()
|
||||
{
|
||||
bool oldDeveloper = m_developerMode;
|
||||
m_developerMode = false;
|
||||
return oldDeveloper;
|
||||
bool oldDeveloper = com_developer->toBoolean();
|
||||
CVarUnlocker unlock(com_developer);
|
||||
com_developer->fromBoolean(false);
|
||||
|
||||
return oldDeveloper;
|
||||
}
|
||||
|
||||
void CVarManager::restoreDeveloper(bool oldDeveloper)
|
||||
{
|
||||
m_developerMode = oldDeveloper;
|
||||
CVarUnlocker unlock(com_developer);
|
||||
com_developer->fromBoolean(oldDeveloper);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -17,10 +17,11 @@ Console::Console(CVarManager* cvarMgr)
|
|||
registerCommand("listCVars", "Lists all available CVars", "", std::bind(&CVarManager::list, m_cvarMgr, std::placeholders::_1, std::placeholders::_2));
|
||||
registerCommand("setCVar", "Sets a given Console Variable to the specified value", "<cvar> <value>", std::bind(&CVarManager::setCVar, m_cvarMgr, std::placeholders::_1, std::placeholders::_2));
|
||||
registerCommand("getCVar", "Prints the value stored in the specified Console Variable", "<cvar>", std::bind(&CVarManager::getCVar, m_cvarMgr, std::placeholders::_1, std::placeholders::_2));
|
||||
m_cvarMgr->findOrMakeCVar("con_speed", "Speed at which the console opens and closes, calculated as pixels per second", m_conSpeed,
|
||||
m_conSpeed = cvarMgr->findOrMakeCVar("con_speed", "Speed at which the console opens and closes, calculated as pixels per second", 1.f,
|
||||
hecl::CVar::EFlags::System | hecl::CVar::EFlags::Archive);
|
||||
m_cvarMgr->findOrMakeCVar("con_height", "Maximum absolute height of the console, height is calculated from the top of the window, expects values ranged from [0.f,1.f]", m_conHeight,
|
||||
m_conHeight = cvarMgr->findOrMakeCVar("con_height", "Maximum absolute height of the console, height is calculated from the top of the window, expects values ranged from [0.f,1.f]", 0.5f,
|
||||
hecl::CVar::EFlags::System | hecl::CVar::EFlags::Archive);
|
||||
|
||||
}
|
||||
|
||||
void Console::registerCommand(std::string_view name, std::string_view helpText, std::string_view usage, const std::function<void(Console*, const std::vector<std::string> &)>&& func)
|
||||
|
@ -115,6 +116,18 @@ void Console::report(Level level, const char* fmt, ...)
|
|||
|
||||
void Console::proc()
|
||||
{
|
||||
if (m_conHeight->isModified())
|
||||
{
|
||||
m_cachedConHeight = m_conHeight->toFloat();
|
||||
m_conHeight->clearModified();
|
||||
}
|
||||
|
||||
if (m_conSpeed->isModified())
|
||||
{
|
||||
m_cachedConSpeed = m_conSpeed->toFloat();
|
||||
m_conSpeed->clearModified();
|
||||
}
|
||||
|
||||
if (m_state == State::Opened)
|
||||
{
|
||||
printf("\r%s ", m_commandString.c_str());
|
||||
|
@ -161,7 +174,7 @@ void Console::handleCharCode(unsigned long chr, boo::EModifierKey /*mod*/, bool
|
|||
m_commandString.insert(m_commandString.begin() + m_cursorPosition + 1, char(chr));
|
||||
}
|
||||
else
|
||||
m_commandString += char(chr);
|
||||
m_commandString += char(chr);
|
||||
|
||||
++m_cursorPosition;
|
||||
}
|
||||
|
@ -282,8 +295,8 @@ void Console::handleSpecialKeyDown(boo::ESpecialKey sp, boo::EModifierKey mod, b
|
|||
else
|
||||
m_cursorPosition++;
|
||||
|
||||
// m_showCursor = true;
|
||||
// m_cursorTime = 0;
|
||||
// m_showCursor = true;
|
||||
// m_cursorTime = 0;
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -373,7 +386,7 @@ void Console::dumpLog()
|
|||
{
|
||||
case Level::Info:
|
||||
printf("%s\n", l.first.c_str());
|
||||
break;
|
||||
break;
|
||||
case Level::Warning:
|
||||
printf("[Warning] %s\n", l.first.c_str());
|
||||
break;
|
||||
|
|
Loading…
Reference in New Issue