diff options
| author | Léo Lam <leo@leolam.fr> | 2021-04-11 14:31:55 +0200 |
|---|---|---|
| committer | Léo Lam <leo@leolam.fr> | 2021-04-11 15:54:21 +0200 |
| commit | 73637128659db7df2f332ea3d3285d07abf25f4f (patch) | |
| tree | d86c4f4d9cfe325f04e466f6e1850ec7d81571fe /src/KingSystem/Resource/resResourceASResource.cpp | |
| parent | 225ee27b41ae3e74cf0242108c6fc4df291c1987 (diff) | |
ksys/res: Finish implementing ASExtensions
Diffstat (limited to 'src/KingSystem/Resource/resResourceASResource.cpp')
| -rw-r--r-- | src/KingSystem/Resource/resResourceASResource.cpp | 101 |
1 files changed, 100 insertions, 1 deletions
diff --git a/src/KingSystem/Resource/resResourceASResource.cpp b/src/KingSystem/Resource/resResourceASResource.cpp index 0025bfe1..0112f3af 100644 --- a/src/KingSystem/Resource/resResourceASResource.cpp +++ b/src/KingSystem/Resource/resResourceASResource.cpp @@ -1,5 +1,9 @@ #include "KingSystem/Resource/resResourceASResource.h" +#include <container/seadSafeArray.h> +#include <optional> #include <prim/seadSafeString.h> +#include "KingSystem/ActorSystem/actASSetting.h" +#include "KingSystem/Resource/resResourceASSetting.h" namespace ksys::res { @@ -216,7 +220,13 @@ static ASParamParser* dummyASParserFactoryImpl_(sead::Heap*) { return nullptr; } -std::array<ASExtensions::Factory, ASParamParser::NumTypes> ASExtensions::sFactories{{ +namespace { +struct Factory { + const char* name; + ASParamParser* (*make)(sead::Heap* heap); +}; + +sead::SafeArray<Factory, ASParamParser::NumTypes> sASFactories{{ {"FrameCtrl", factoryImpl_<ASFrameCtrlParser>}, {"TriggerEvents", factoryImpl_<ASTriggerEventsParser>}, {"HoldEvents", factoryImpl_<ASHoldEventsParser>}, @@ -227,6 +237,7 @@ std::array<ASExtensions::Factory, ASParamParser::NumTypes> ASExtensions::sFactor {"BitIndex", factoryImpl_<ASBitIndexParser>}, {"BlenderBone", dummyASParserFactoryImpl_}, }}; +} // namespace ASExtensions::~ASExtensions() { for (auto*& parser : mParsers) { @@ -237,4 +248,92 @@ ASExtensions::~ASExtensions() { mParsers.freeBuffer(); } +bool ASExtensions::parse(const ASExtensions::ParseArgs& args) { + const auto Extend = agl::utl::getResParameterList(args.res_list, "Extend"); + if (!Extend) + return true; + + const auto num_extensions = Extend.getResParameterListNum(); + if (num_extensions == 0) + return true; + + if (!mParsers.tryAllocBuffer(num_extensions, args.heap)) + return false; + for (int i = 0, n = mParsers.size(); i < n; ++i) + mParsers(i) = nullptr; + + auto it = mParsers.begin(); + const auto end = mParsers.end(); + + ASParamParser::ParseArgs parse_args{}; + parse_args.list = &mList; + parse_args.heap = args.heap; + + auto res_it = Extend.listBegin(); + const auto res_end = Extend.listEnd(); + + for (; it != end && res_it != res_end; ++it, ++res_it) { + parse_args.res_list = res_it.getList(); + *it = makeParser(parse_args); + + constexpr int bone = int(ASParamParser::Type::BlenderBone); + if (*it == nullptr && parse_args.res_list.getParameterListNameHash() != + agl::utl::ParameterBase::calcHash(sASFactories[bone].name)) { + return false; + } + } + + args.list->addList(&mList, "Extend"); + return true; +} + +ASParamParser* ASExtensions::makeParser(const ASParamParser::ParseArgs& args) const { + const auto is_factory = [&args](int i) { + return args.res_list.getParameterListNameHash() == + agl::utl::ParameterBase::calcHash(sASFactories[i].name); + }; + + std::optional<int> type; + for (int i = 0; i < ASParamParser::NumTypes - 1; ++i) { + if (!is_factory(i)) + continue; + type = i; + break; + } + + if (!type.has_value() && is_factory(int(ASParamParser::Type::BlenderBone))) { + const auto obj = args.res_list.getResParameterObj(0); + if (obj.getNum() > 0) { + const sead::SafeString name = obj.getResParameter(0).getData<const char>(); + return act::ASSetting::instance()->getBoneParams(name); + } + } + + if (!type.has_value()) + return nullptr; + + const auto& factory = sASFactories[*type]; + + auto* parser = factory.make(args.heap); + if (!parser) + return nullptr; + + if (!parser->parse(args)) { + delete parser; + return nullptr; + } + + args.list->addList(&parser->getList(), factory.name); + return parser; +} + +ASParamParser* ASExtensions::getParser(ASParamParser::Type type) const { + for (int i = 0, n = mParsers.size(); i < n; ++i) { + auto* parser = mParsers[i]; + if (parser && parser->getType() == type) + return parser; + } + return nullptr; +} + } // namespace ksys::res |
