mirror of
https://github.com/open-goal/jak-project
synced 2026-09-10 04:22:13 -04:00
[decomp] fisher and FIN.DGO (finalboss) level (#899)
* decomp `fisher`, `robotboss`, `light-eco`, `green-eco-lurker`, `sage-finalboss`, `robotboss-weapon`, `robotboss-misc` * fixes * add files * add `:states` list to `deftype` and fix files * test state forward decl's on a few more types * also the refs * add light-eco * whatever
This commit is contained in:
@@ -246,6 +246,21 @@ std::string Type::common_type_info_diff(const Type& other) const {
|
||||
}
|
||||
}
|
||||
}
|
||||
if (m_states != other.m_states) {
|
||||
if (m_states.size() != other.m_states.size()) {
|
||||
result += fmt::format("Number of additional states {} vs. {}\n", m_states.size(),
|
||||
other.m_states.size());
|
||||
}
|
||||
|
||||
for (size_t i = 0; i < std::min(m_states.size(), other.m_states.size()); i++) {
|
||||
if (m_states.at(i) != other.m_states.at(i)) {
|
||||
result +=
|
||||
fmt::format("State {} ({}/{}):\n", i, m_states.at(i).name, other.m_states.at(i).name);
|
||||
result += m_states.at(i).diff(other.m_states.at(i));
|
||||
result += "\n";
|
||||
}
|
||||
}
|
||||
}
|
||||
if (m_new_method_info != other.m_new_method_info) {
|
||||
result += m_new_method_info.diff(other.m_new_method_info);
|
||||
}
|
||||
@@ -381,6 +396,27 @@ std::string Type::print_method_info() const {
|
||||
return result;
|
||||
}
|
||||
|
||||
const StateInfo& Type::add_state(const StateInfo& info) {
|
||||
m_states.push_back(info);
|
||||
return m_states.back();
|
||||
}
|
||||
|
||||
bool StateInfo::operator==(const StateInfo& other) const {
|
||||
return name == other.name && type == other.type;
|
||||
}
|
||||
|
||||
std::string StateInfo::diff(const StateInfo& other) const {
|
||||
std::string result;
|
||||
if (name != other.name) {
|
||||
result += fmt::format("name: {} vs. {}\n", name, other.name);
|
||||
}
|
||||
|
||||
if (type != other.type) {
|
||||
result += fmt::format("type: {} vs. {}\n", type.print(), other.type.print());
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
std::string Type::incompatible_diff(const Type& other) const {
|
||||
return fmt::format("diff is not implemented between {} and {}\n", typeid((*this)).name(),
|
||||
typeid(other).name());
|
||||
@@ -1067,4 +1103,4 @@ std::string EnumType::diff_impl(const Type& other_) const {
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -27,6 +27,15 @@ struct MethodInfo {
|
||||
std::string diff(const MethodInfo& other) const;
|
||||
};
|
||||
|
||||
struct StateInfo {
|
||||
std::string name;
|
||||
TypeSpec type;
|
||||
|
||||
bool operator==(const StateInfo& other) const;
|
||||
bool operator!=(const StateInfo& other) const { return !((*this) == other); }
|
||||
std::string diff(const StateInfo& other) const;
|
||||
};
|
||||
|
||||
/*!
|
||||
* Parent class of all Types.
|
||||
*/
|
||||
@@ -80,12 +89,14 @@ class Type {
|
||||
const MethodInfo& add_method(const MethodInfo& info);
|
||||
const MethodInfo& add_new_method(const MethodInfo& info);
|
||||
std::string print_method_info() const;
|
||||
const StateInfo& add_state(const StateInfo& info);
|
||||
|
||||
void disallow_in_runtime() { m_allow_in_runtime = false; }
|
||||
|
||||
virtual ~Type() = default;
|
||||
|
||||
const std::vector<MethodInfo>& get_methods_defined_for_type() const { return m_methods; }
|
||||
const std::vector<StateInfo>& get_states_declared_for_type() const { return m_states; }
|
||||
|
||||
const MethodInfo* get_new_method_defined_for_type() const {
|
||||
if (m_new_method_info_defined) {
|
||||
@@ -105,6 +116,7 @@ class Type {
|
||||
std::string incompatible_diff(const Type& other) const;
|
||||
|
||||
std::vector<MethodInfo> m_methods;
|
||||
std::vector<StateInfo> m_states;
|
||||
MethodInfo m_new_method_info;
|
||||
bool m_new_method_info_defined = false;
|
||||
|
||||
|
||||
@@ -1692,6 +1692,26 @@ std::string TypeSystem::generate_deftype_footer(const Type* type) const {
|
||||
result.append(")\n ");
|
||||
}
|
||||
|
||||
std::string states_string;
|
||||
for (auto& info : type->get_states_declared_for_type()) {
|
||||
if (info.type.arg_count() > 1) {
|
||||
states_string.append(fmt::format(" ({}", info.name));
|
||||
for (size_t i = 0; i < info.type.arg_count() - 1; i++) {
|
||||
states_string.push_back(' ');
|
||||
states_string.append(info.type.get_arg(i).print());
|
||||
}
|
||||
states_string.append(")\n");
|
||||
} else {
|
||||
states_string.append(fmt::format(" {}\n", info.name));
|
||||
}
|
||||
}
|
||||
|
||||
if (!states_string.empty()) {
|
||||
result.append("(:states\n");
|
||||
result.append(states_string);
|
||||
result.append(" )\n ");
|
||||
}
|
||||
|
||||
result.append(")\n");
|
||||
return result;
|
||||
}
|
||||
|
||||
@@ -243,6 +243,34 @@ void declare_method(Type* type, TypeSystem* type_system, const goos::Object& def
|
||||
});
|
||||
}
|
||||
|
||||
void declare_state(Type* type, TypeSystem* type_system, const goos::Object& def) {
|
||||
for_each_in_list(def, [&](const goos::Object& _obj) {
|
||||
auto obj = &_obj;
|
||||
if (obj->is_list()) {
|
||||
// (name ,@args)
|
||||
auto state_name = symbol_string(car(obj));
|
||||
auto args = cdr(obj);
|
||||
|
||||
TypeSpec state_typespec("state");
|
||||
|
||||
for_each_in_list(*args, [&](const goos::Object& o) {
|
||||
state_typespec.add_arg(parse_typespec(type_system, o));
|
||||
});
|
||||
state_typespec.add_arg(TypeSpec(type->get_name()));
|
||||
|
||||
type->add_state({state_name, state_typespec});
|
||||
} else {
|
||||
// name
|
||||
auto state_name = symbol_string(*obj);
|
||||
|
||||
TypeSpec state_typespec("state");
|
||||
state_typespec.add_arg(TypeSpec(type->get_name()));
|
||||
|
||||
type->add_state({state_name, state_typespec});
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
struct StructureDefResult {
|
||||
TypeFlags flags;
|
||||
bool generate_runtime_type = true;
|
||||
@@ -274,8 +302,11 @@ StructureDefResult parse_structure_def(StructureType* type,
|
||||
auto& first = car(opt_list);
|
||||
opt_list = cdr(opt_list);
|
||||
|
||||
if (symbol_string(first) == ":methods") {
|
||||
auto list_name = symbol_string(first);
|
||||
if (list_name == ":methods") {
|
||||
declare_method(type, ts, *opt_list);
|
||||
} else if (list_name == ":states") {
|
||||
declare_state(type, ts, *opt_list);
|
||||
} else {
|
||||
throw std::runtime_error("Invalid option list in field specification: " +
|
||||
car(rest).print());
|
||||
|
||||
Reference in New Issue
Block a user