ksys/gdt: Add more flag utilities

This commit is contained in:
Léo Lam 2020-11-09 13:53:18 +01:00
parent b28ba7b3ad
commit f242ce69ee
No known key found for this signature in database
GPG Key ID: 0DF30F9081000741
3 changed files with 327 additions and 26 deletions

View File

@ -14,4 +14,163 @@ inline bool getBool(FlagHandle handle, bool debug = false) {
return value; return value;
} }
inline s32 getS32(FlagHandle handle, bool debug = false) {
s32 value{};
auto* mgr = Manager::instance();
if (mgr)
mgr->getS32(handle, &value, debug);
return value;
}
inline f32 getF32(FlagHandle handle, bool debug = false) {
f32 value{};
auto* mgr = Manager::instance();
if (mgr)
mgr->getF32(handle, &value, debug);
return value;
}
inline void getStr(FlagHandle handle, const char** value, bool debug = false) {
auto* mgr = Manager::instance();
if (mgr)
mgr->getStr(handle, value, debug);
}
inline void getStr64(FlagHandle handle, const char** value, bool debug = false) {
auto* mgr = Manager::instance();
if (mgr)
mgr->getStr64(handle, value, debug);
}
inline void getStr256(FlagHandle handle, const char** value, bool debug = false) {
auto* mgr = Manager::instance();
if (mgr)
mgr->getStr256(handle, value, debug);
}
inline void getVec2f(FlagHandle handle, sead::Vector2f* value, bool debug = false) {
auto* mgr = Manager::instance();
if (mgr)
mgr->getVec2f(handle, value, debug);
}
inline void getVec3f(FlagHandle handle, sead::Vector3f* value, bool debug = false) {
auto* mgr = Manager::instance();
if (mgr)
mgr->getVec3f(handle, value, debug);
}
inline void getVec4f(FlagHandle handle, sead::Vector4f* value, bool debug = false) {
auto* mgr = Manager::instance();
if (mgr)
mgr->getVec4f(handle, value, debug);
}
inline bool getBool(FlagHandle handle, s32 idx, bool debug = false) {
bool value{};
auto* mgr = Manager::instance();
if (mgr)
mgr->getBool(handle, &value, idx, debug);
return value;
}
inline s32 getS32(FlagHandle handle, s32 idx, bool debug = false) {
s32 value{};
auto* mgr = Manager::instance();
if (mgr)
mgr->getS32(handle, &value, idx, debug);
return value;
}
inline f32 getF32(FlagHandle handle, s32 idx, bool debug = false) {
f32 value{};
auto* mgr = Manager::instance();
if (mgr)
mgr->getF32(handle, &value, idx, debug);
return value;
}
inline void getStr(FlagHandle handle, const char** value, s32 idx, bool debug = false) {
auto* mgr = Manager::instance();
if (mgr)
mgr->getStr(handle, value, idx, debug);
}
inline void getStr64(FlagHandle handle, const char** value, s32 idx, bool debug = false) {
auto* mgr = Manager::instance();
if (mgr)
mgr->getStr64(handle, value, idx, debug);
}
inline void getStr256(FlagHandle handle, const char** value, s32 idx, bool debug = false) {
auto* mgr = Manager::instance();
if (mgr)
mgr->getStr256(handle, value, idx, debug);
}
inline void getVec2f(FlagHandle handle, sead::Vector2f* value, s32 idx, bool debug = false) {
auto* mgr = Manager::instance();
if (mgr)
mgr->getVec2f(handle, value, idx, debug);
}
inline void getVec3f(FlagHandle handle, sead::Vector3f* value, s32 idx, bool debug = false) {
auto* mgr = Manager::instance();
if (mgr)
mgr->getVec3f(handle, value, idx, debug);
}
inline void getVec4f(FlagHandle handle, sead::Vector4f* value, s32 idx, bool debug = false) {
auto* mgr = Manager::instance();
if (mgr)
mgr->getVec4f(handle, value, idx, debug);
}
#define GDT_SET_FLAG_(NAME, T) \
inline void NAME(T value, FlagHandle handle, bool debug = false) { \
auto* mgr = Manager::instance(); \
if (mgr) \
mgr->NAME(value, handle, debug); \
} \
inline void NAME(T value, FlagHandle handle, s32 sub_idx, bool debug = false) { \
auto* mgr = Manager::instance(); \
if (mgr) \
mgr->NAME(value, handle, debug, sub_idx); \
}
#define GDT_SET_FLAG_STR_(NAME, T) \
inline void NAME(T value, FlagHandle handle, bool debug = false) { \
auto* mgr = Manager::instance(); \
if (mgr) \
mgr->NAME(value.cstr(), handle, debug); \
} \
inline void NAME(T value, FlagHandle handle, s32 sub_idx, bool debug = false) { \
auto* mgr = Manager::instance(); \
if (mgr) \
mgr->NAME(value.cstr(), handle, debug, sub_idx); \
}
GDT_SET_FLAG_(setBool, bool)
GDT_SET_FLAG_(setS32, s32)
GDT_SET_FLAG_(setF32, f32)
GDT_SET_FLAG_STR_(setStr, const sead::SafeString&)
GDT_SET_FLAG_STR_(setStr64, const sead::SafeString&)
GDT_SET_FLAG_STR_(setStr256, const sead::SafeString&)
GDT_SET_FLAG_(setVec2f, const sead::Vector2f&)
GDT_SET_FLAG_(setVec3f, const sead::Vector3f&)
GDT_SET_FLAG_(setVec4f, const sead::Vector4f&)
#undef GDT_SET_FLAG_
#undef GDT_SET_FLAG_STR_
} // namespace ksys::gdt } // namespace ksys::gdt

View File

@ -215,6 +215,12 @@ public:
ref.get().NAME(value, idx); \ ref.get().NAME(value, idx); \
return true; \ return true; \
}); \ }); \
} \
void NAME(FlagHandle handle, T* value, s32 sub_idx, bool debug = false) { \
unwrapHandle<false>(handle, debug, [&](u32 idx, TriggerParamRef& ref) { \
ref.get().NAME(value, idx, sub_idx); \
return true; \
}); \
} }
GDT_GET_(getBool, bool) GDT_GET_(getBool, bool)
@ -230,6 +236,7 @@ public:
#undef GDT_GET_ #undef GDT_GET_
#define GDT_SET_(NAME, T) \ #define GDT_SET_(NAME, T) \
/* Setters (by handle) */ \
KSYS_ALWAYS_INLINE bool NAME(T value, FlagHandle handle, bool debug, bool force) { \ KSYS_ALWAYS_INLINE bool NAME(T value, FlagHandle handle, bool debug, bool force) { \
if (mBitFlags.isOn(BitFlag::_40000)) \ if (mBitFlags.isOn(BitFlag::_40000)) \
return false; \ return false; \
@ -242,7 +249,25 @@ public:
bool NAME##NoCheckForce(T value, FlagHandle handle) { \ bool NAME##NoCheckForce(T value, FlagHandle handle) { \
return NAME(value, handle, true, true); \ return NAME(value, handle, true, true); \
} \ } \
\ /* Setters for arrays (by handle) */ \
KSYS_ALWAYS_INLINE bool NAME(T value, FlagHandle handle, bool debug, bool force, \
s32 sub_idx) { \
if (mBitFlags.isOn(BitFlag::_40000)) \
return false; \
return unwrapHandle<true>(handle, debug, [&](u32 idx, TriggerParamRef& ref) { \
return ref.get().NAME(value, idx, sub_idx, force); \
}); \
} \
bool NAME(T value, FlagHandle handle, s32 sub_idx) { \
return NAME(value, handle, false, false, sub_idx); \
} \
bool NAME##NoCheck(T value, FlagHandle handle, s32 sub_idx) { \
return NAME(value, handle, true, false, sub_idx); \
} \
bool NAME##NoCheckForce(T value, FlagHandle handle, s32 sub_idx) { \
return NAME(value, handle, true, true, sub_idx); \
} \
/* Setters (by name) */ \
KSYS_ALWAYS_INLINE bool NAME(T value, const sead::SafeString& name, bool debug, bool force) { \ KSYS_ALWAYS_INLINE bool NAME(T value, const sead::SafeString& name, bool debug, bool force) { \
if (mBitFlags.isOn(BitFlag::_40000)) \ if (mBitFlags.isOn(BitFlag::_40000)) \
return false; \ return false; \
@ -257,6 +282,58 @@ public:
} \ } \
[[gnu::noinline]] bool NAME##NoCheckForce(T value, const sead::SafeString& name) { \ [[gnu::noinline]] bool NAME##NoCheckForce(T value, const sead::SafeString& name) { \
return NAME(value, name, true, true); \ return NAME(value, name, true, true); \
} \
/* Setters for arrays (by name) */ \
KSYS_ALWAYS_INLINE bool NAME(T value, const sead::SafeString& name, bool debug, bool force, \
s32 sub_idx) { \
if (mBitFlags.isOn(BitFlag::_40000)) \
return false; \
auto& ref = debug ? getParamBypassPerm() : getParam(); \
return ref.get().NAME(value, name, sub_idx, force); \
} \
[[gnu::noinline]] bool NAME(T value, const sead::SafeString& name, s32 sub_idx) { \
return NAME(value, name, false, false, sub_idx); \
} \
[[gnu::noinline]] bool NAME##NoCheck(T value, const sead::SafeString& name, s32 sub_idx) { \
return NAME(value, name, true, false, sub_idx); \
} \
[[gnu::noinline]] bool NAME##NoCheckForce(T value, const sead::SafeString& name, \
s32 sub_idx) { \
return NAME(value, name, true, true, sub_idx); \
} \
\
bool NAME(T value, FlagHandle handle, bool debug) { \
if (debug) { \
setBool(true, "IsChangedByDebug"); \
mBitFlags.set(BitFlag::_800); \
return NAME##NoCheckForce(value, handle); \
} \
return NAME(value, handle); \
} \
bool NAME(T value, const sead::SafeString& name, bool debug) { \
if (debug) { \
setBool(true, "IsChangedByDebug"); \
mBitFlags.set(BitFlag::_800); \
return NAME##NoCheckForce(value, name); \
} \
return NAME(value, name); \
} \
\
bool NAME(T value, FlagHandle handle, bool debug, s32 sub_idx) { \
if (debug) { \
setBool(true, "IsChangedByDebug"); \
mBitFlags.set(BitFlag::_800); \
return NAME##NoCheckForce(value, handle, sub_idx); \
} \
return NAME(value, handle, sub_idx); \
} \
bool NAME(T value, const sead::SafeString& name, bool debug, s32 sub_idx) { \
if (debug) { \
setBool(true, "IsChangedByDebug"); \
mBitFlags.set(BitFlag::_800); \
return NAME##NoCheckForce(value, name, sub_idx); \
} \
return NAME(value, name, sub_idx); \
} }
GDT_SET_(setBool, bool) GDT_SET_(setBool, bool)

View File

@ -6,6 +6,58 @@ import typing as tp
import oead import oead
class FlagTypeInfo(tp.NamedTuple):
def get_getter_fn_name(self) -> str:
return self.getter_fn_name
def get_handle_getter_fn_name(self) -> str:
s = self.getter_fn_name
if self.is_value_array():
s += "Array"
s += "Handle"
return s
def get_setter_fn_name(self) -> str:
return "s" + self.getter_fn_name[1:]
def is_value_inline(self) -> bool:
return self.arg_type in ("bool", "s32", "f32")
def is_value_array(self) -> bool:
return self.arg_type.endswith("_array_data")
def get_setter_arg_type(self) -> str:
if self.arg_type == "const char*":
return "sead::SafeString"
return self.arg_type
getter_fn_name: str
arg_type: str
flag_type_info = {
"bool_data": FlagTypeInfo("getBool", "bool"),
"s32_data": FlagTypeInfo("getS32", "s32"),
"f32_data": FlagTypeInfo("getF32", "f32"),
"string_data": FlagTypeInfo("getStr", "char const*"),
"string64_data": FlagTypeInfo("getStr64", "char const*"),
"string256_data": FlagTypeInfo("getStr256", "char const*"),
"vector2f_data": FlagTypeInfo("getVec2f", "sead::Vector2f"),
"vector3f_data": FlagTypeInfo("getVec3f", "sead::Vector3f"),
"vector4f_data": FlagTypeInfo("getVec4f", "sead::Vector4f"),
"bool_array_data": FlagTypeInfo("getBool", "bool"),
"s32_array_data": FlagTypeInfo("getS32", "s32"),
"f32_array_data": FlagTypeInfo("getF32", "f32"),
"string_array_data": FlagTypeInfo("getStr", "char const*"),
"string64_array_data": FlagTypeInfo("getStr64", "char const*"),
"string256_array_data": FlagTypeInfo("getStr256", "char const*"),
"vector2f_array_data": FlagTypeInfo("getVec2f", "sead::Vector2f"),
"vector3f_array_data": FlagTypeInfo("getVec3f", "sead::Vector3f"),
"vector4f_array_data": FlagTypeInfo("getVec4f", "sead::Vector4f"),
}
def add_development_remnant_flags(flags: tp.Dict[str, str]): def add_development_remnant_flags(flags: tp.Dict[str, str]):
_flags = { _flags = {
"AoC_DragonFireChallengeRing_Advent": "bool_data", "AoC_DragonFireChallengeRing_Advent": "bool_data",
@ -116,7 +168,42 @@ void initCommonFlags();
for i, name in enumerate(exe_flag_list): for i, name in enumerate(exe_flag_list):
chunk_idx: int = i // FLAGS_PER_CHUNK chunk_idx: int = i // FLAGS_PER_CHUNK
f.write(f"inline FlagHandle& flag_{name}() {{ return detail::sCommonFlags{chunk_idx}.flag_{name}; }}\n") f.write(f"inline FlagHandle& flag_{name}() {{ return detail::sCommonFlags{chunk_idx}.flag_{name}; }}\n")
pass
f.write("""\
// clang-format on
} // namespace ksys::gdt
""")
with (src_gdt / "gdtCommonFlagsUtils.h").open("w") as f:
f.write("""\
#pragma once
// DO NOT EDIT. This file is automatically generated.
#include "KingSystem/GameData/gdtCommonFlags.h"
#include "KingSystem/GameData/gdtFlagUtils.h"
namespace ksys::gdt {
// clang-format off
""")
for i, name in enumerate(exe_flag_list):
info = flag_type_info[flag_types[name]]
if info.is_value_inline():
f.write(
f"inline {info.arg_type} getFlag_{name}(bool debug = false) {{ return {info.get_getter_fn_name()}(flag_{name}(), debug); }}\n")
else:
f.write(
f"inline void getFlag_{name}({info.arg_type}* value, bool debug = false) {{ {info.get_getter_fn_name()}(flag_{name}(), value, debug); }}\n")
for i, name in enumerate(exe_flag_list):
info = flag_type_info[flag_types[name]]
f.write(
f"inline void setFlag_{name}({info.get_setter_arg_type()} const& value, bool debug = false) {{ "
f"{info.get_setter_fn_name()}(value, flag_{name}(), debug); }}\n")
f.write("""\ f.write("""\
@ -126,29 +213,6 @@ void initCommonFlags();
""") """)
# Generate the implementation. # Generate the implementation.
fn_names = {
"bool_data": "getBoolHandle",
"s32_data": "getS32Handle",
"f32_data": "getF32Handle",
"string_data": "getStrHandle",
"string64_data": "getStr64Handle",
"string256_data": "getStr256Handle",
"vector2f_data": "getVec2fHandle",
"vector3f_data": "getVec3fHandle",
"vector4f_data": "getVec4fHandle",
"bool_array_data": "getBoolArrayHandle",
"s32_array_data": "getS32ArrayHandle",
"f32_array_data": "getF32ArrayHandle",
"string_array_data": "getStrArrayHandle",
"string64_array_data": "getStr64ArrayHandle",
"string256_array_data": "getStr256ArrayHandle",
"vector2f_array_data": "getVec2fArrayHandle",
"vector3f_array_data": "getVec3fArrayHandle",
"vector4f_array_data": "getVec4fArrayHandle",
}
with (src_gdt / "gdtCommonFlags.cpp").open("w") as f: with (src_gdt / "gdtCommonFlags.cpp").open("w") as f:
f.write("""\ f.write("""\
// DO NOT EDIT. This file is automatically generated. // DO NOT EDIT. This file is automatically generated.
@ -180,7 +244,8 @@ void initCommonFlags_() {
""") """)
for flag_name in exe_flag_list: for flag_name in exe_flag_list:
f.write(f" flag_{flag_name}() = mgr->{fn_names[flag_types[flag_name]]}(\"{flag_name}\");\n") info = flag_type_info[flag_types[flag_name]]
f.write(f" flag_{flag_name}() = mgr->{info.get_handle_getter_fn_name()}(\"{flag_name}\");\n")
f.write("""\ f.write("""\