diff --git a/SPID/include/FormData.h b/SPID/include/FormData.h index 558eb58..3d46c05 100644 --- a/SPID/include/FormData.h +++ b/SPID/include/FormData.h @@ -413,12 +413,15 @@ namespace Forms std::size_t GetSize() const; std::size_t GetLeveledSize() const; + std::size_t GetLookupCount() const; + RECORD::TYPE GetType() const; DataVec
& GetForms(bool a_onlyLevelEntries); DataVec& GetForms(); void LookupForms(RE::TESDataHandler* a_dataHandler, std::string_view a_type, INI::DataVec& a_INIDataVec); + void EmplaceForm(bool isValid, Form*, const IndexOrCount&, const FilterData&, const std::string& path); // Init formsWithLevels and formsNoLevels void FinishLookupForms(); @@ -428,6 +431,10 @@ namespace Forms DataVec forms{}; DataVec formsWithLevels{}; + /// Total number of entries that were matched to this Distributable, including invalid. + /// This counter is used for logging purposes. + std::size_t lookupCount{ 0 }; + void LookupForm(RE::TESDataHandler* a_dataHandler, INI::Data& rawForm); }; @@ -473,7 +480,7 @@ namespace Forms /// A raw form entry that needs to be looked up. /// A callback to be called with validated data after successful lookup. template - void LookupGenericForm(RE::TESDataHandler* const dataHandler, INI::Data& rawForm, std::function callback); + void LookupGenericForm(RE::TESDataHandler* const dataHandler, INI::Data& rawForm, std::function callback); } template @@ -503,6 +510,12 @@ std::size_t Forms::Distributables::GetLeveledSize() const return formsWithLevels.size(); } +template +std::size_t Forms::Distributables::GetLookupCount() const +{ + return lookupCount; +} + template RECORD::TYPE Forms::Distributables::GetType() const { @@ -525,15 +538,15 @@ Forms::DataVec& Forms::Distributables::GetForms(bool a_onlyLevelEntr } template -void Forms::Distributables::LookupForm(RE::TESDataHandler* a_dataHandler, INI::Data& rawForm) +void Forms::Distributables::LookupForm(RE::TESDataHandler* dataHandler, INI::Data& rawForm) { - Forms::LookupGenericForm(a_dataHandler, rawForm, [&](Form* form, auto& idxOrCount, auto& filters, std::string& path) { - forms.emplace_back(forms.size(), form, idxOrCount, filters, path); + Forms::LookupGenericForm(dataHandler, rawForm, [&](bool isValid, Form* form, const auto& idxOrCount, const auto& filters, const auto& path) { + EmplaceForm(isValid, form, idxOrCount, filters, path); }); } template -void Forms::Distributables::LookupForms(RE::TESDataHandler* a_dataHandler, std::string_view a_type, INI::DataVec& a_INIDataVec) +void Forms::Distributables::LookupForms(RE::TESDataHandler* dataHandler, std::string_view a_type, INI::DataVec& a_INIDataVec) { if (a_INIDataVec.empty()) { return; @@ -544,10 +557,19 @@ void Forms::Distributables::LookupForms(RE::TESDataHandler* a_dataHandler, forms.reserve(a_INIDataVec.size()); for (auto& rawForm : a_INIDataVec) { - LookupForm(a_dataHandler, rawForm); + LookupForm(dataHandler, rawForm); } } +template +void Forms::Distributables::EmplaceForm(bool isValid, Form* form, const IndexOrCount& idxOrCount, const FilterData& filters, const std::string& path) +{ + if (isValid) { + forms.emplace_back(forms.size(), form, idxOrCount, filters, path); + } + lookupCount++; +} + template void Forms::Distributables::FinishLookupForms() { @@ -572,7 +594,7 @@ void Forms::Distributables::FinishLookupForms() } template -void Forms::LookupGenericForm(RE::TESDataHandler* const dataHandler, INI::Data& rawForm, std::function callback) +void Forms::LookupGenericForm(RE::TESDataHandler* const dataHandler, INI::Data& rawForm, std::function callback) { auto& [formOrEditorID, strings, filterIDs, level, traits, idxOrCount, chance, path] = rawForm; @@ -588,10 +610,8 @@ void Forms::LookupGenericForm(RE::TESDataHandler* const dataHandler, INI::Data& validEntry = detail::formID_to_form(dataHandler, filterIDs.MATCH, filterForms.MATCH, path); } - if (validEntry) { - FilterData filters{ strings, filterForms, level, traits, chance }; - callback(form, idxOrCount, filters, path); - } + FilterData filters{ strings, filterForms, level, traits, chance }; + callback(validEntry, form, idxOrCount, filters, path); } } catch (const Lookup::UnknownFormIDException& e) { buffered_logger::error("\t[{}] [0x{:X}] ({}) FAIL - formID doesn't exist", e.path, e.formID, e.modName.value_or("")); diff --git a/SPID/src/LookupForms.cpp b/SPID/src/LookupForms.cpp index 994e7d0..bf64d33 100644 --- a/SPID/src/LookupForms.cpp +++ b/SPID/src/LookupForms.cpp @@ -18,23 +18,23 @@ bool LookupDistributables(RE::TESDataHandler* const dataHandler) for (auto& rawForm : genericForms) { // Add to appropriate list. (Note that type inferring doesn't recognize SleepOutfit or DeathItems) - LookupGenericForm(dataHandler, rawForm, [&](auto form, auto& idxOrCount, auto& filters, std::string& path) { + LookupGenericForm(dataHandler, rawForm, [&](bool isValid, auto form, const auto& idxOrCount, const auto& filters, const auto& path) { if (const auto keyword = form->As(); keyword) { - keywords.GetForms().emplace_back(keywords.GetSize(), keyword, idxOrCount, filters, path); + keywords.EmplaceForm(isValid, keyword, idxOrCount, filters, path); } else if (const auto spell = form->As(); spell) { - spells.GetForms().emplace_back(spells.GetSize(), spell, idxOrCount, filters, path); + spells.EmplaceForm(isValid, spell, idxOrCount, filters, path); } else if (const auto perk = form->As(); perk) { - perks.GetForms().emplace_back(perks.GetSize(), perk, idxOrCount, filters, path); + perks.EmplaceForm(isValid, perk, idxOrCount, filters, path); } else if (const auto shout = form->As(); shout) { - shouts.GetForms().emplace_back(shouts.GetSize(), shout, idxOrCount, filters, path); + shouts.EmplaceForm(isValid, shout, idxOrCount, filters, path); } else if (const auto item = form->As(); item) { - items.GetForms().emplace_back(items.GetSize(), item, idxOrCount, filters, path); + items.EmplaceForm(isValid, item, idxOrCount, filters, path); } else if (const auto outfit = form->As(); outfit) { - outfits.GetForms().emplace_back(outfits.GetSize(), outfit, idxOrCount, filters, path); + outfits.EmplaceForm(isValid, outfit, idxOrCount, filters, path); } else if (const auto faction = form->As(); faction) { - factions.GetForms().emplace_back(factions.GetSize(), faction, idxOrCount, filters, path); + factions.EmplaceForm(isValid, faction, idxOrCount, filters, path); } else if (const auto skin = form->As(); skin) { - skins.GetForms().emplace_back(skins.GetSize(), skin, idxOrCount, filters, path); + skins.EmplaceForm(isValid, skin, idxOrCount, filters, path); } else { auto type = form->GetFormType(); if (type == RE::FormType::Package || type == RE::FormType::FormList) { @@ -49,7 +49,7 @@ bool LookupDistributables(RE::TESDataHandler* const dataHandler) } else { packageIndex = std::get(idxOrCount); } - packages.GetForms().emplace_back(packages.GetSize(), form, packageIndex, filters, path); + packages.EmplaceForm(isValid, form, packageIndex, filters, path); } } }); @@ -78,12 +78,12 @@ void LogDistributablesLookup() ForEachDistributable([](Distributables& a_distributable) { const auto& recordName = RECORD::GetTypeName(a_distributable.GetType()); - const auto all = INI::configs[a_distributable.GetType()].size(); const auto added = a_distributable.GetSize(); + const auto all = a_distributable.GetLookupCount(); // Only log entries that are actually present in INIs. if (all > 0) { - logger::info("Registered {}/{} {}s:", added, all, recordName); + logger::info("Registered {}/{} {}s", added, all, recordName); } });