|
@@ -3,16 +3,20 @@
|
|
|
#include <Windows.h>
|
|
#include <Windows.h>
|
|
|
|
|
|
|
|
#include <algorithm>
|
|
#include <algorithm>
|
|
|
|
|
+#include <new>
|
|
|
#include <span>
|
|
#include <span>
|
|
|
|
|
|
|
|
#include "../../../../core/ui/busy/busy.h"
|
|
#include "../../../../core/ui/busy/busy.h"
|
|
|
#include "../../abilities/ability_bucket_catalog.h"
|
|
#include "../../abilities/ability_bucket_catalog.h"
|
|
|
#include "../../cache/internal.h"
|
|
#include "../../cache/internal.h"
|
|
|
#include "../../cache/records/validation.h"
|
|
#include "../../cache/records/validation.h"
|
|
|
|
|
+#include "../../collectibles/collectible_catalog.h"
|
|
|
#include "../../constants/investment_constant_catalog.h"
|
|
#include "../../constants/investment_constant_catalog.h"
|
|
|
#include "../../hash_names/hash_name_catalog.h"
|
|
#include "../../hash_names/hash_name_catalog.h"
|
|
|
#include "../../inventory/buckets/inventory_bucket_catalog.h"
|
|
#include "../../inventory/buckets/inventory_bucket_catalog.h"
|
|
|
#include "../../items/details/item_detail_catalog.h"
|
|
#include "../../items/details/item_detail_catalog.h"
|
|
|
|
|
+#include "../../items/socket_plugs/socket_plug_catalog.h"
|
|
|
|
|
+#include "../../material_requirements/material_requirement_catalog.h"
|
|
|
#include "../../progressions/progression_catalog.h"
|
|
#include "../../progressions/progression_catalog.h"
|
|
|
#include "../../runtime.h"
|
|
#include "../../runtime.h"
|
|
|
#include "../../scenarios/scenario_catalog.h"
|
|
#include "../../scenarios/scenario_catalog.h"
|
|
@@ -26,6 +30,15 @@ namespace {
|
|
|
|
|
|
|
|
Context g_context;
|
|
Context g_context;
|
|
|
|
|
|
|
|
|
|
+/** Lazily allocates one bounded cache-snapshot bank and exposes all rows on success. */
|
|
|
|
|
+template <typename Value, std::size_t Capacity>
|
|
|
|
|
+[[nodiscard]] std::span<Value> ensure_scratch(std::unique_ptr<Value[]>& storage) noexcept {
|
|
|
|
|
+ if (!storage) {
|
|
|
|
|
+ storage.reset(new (std::nothrow) Value[Capacity]);
|
|
|
|
|
+ }
|
|
|
|
|
+ return {storage.get(), storage ? Capacity : 0};
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
/** @param value Published runtime constants. @return The packed header form. */
|
|
/** @param value Published runtime constants. @return The packed header form. */
|
|
|
[[nodiscard]] cache::records::InvestmentConstants
|
|
[[nodiscard]] cache::records::InvestmentConstants
|
|
|
to_record(const constants::InvestmentConstants& value) noexcept {
|
|
to_record(const constants::InvestmentConstants& value) noexcept {
|
|
@@ -47,7 +60,16 @@ to_record(const constants::InvestmentConstants& value) noexcept {
|
|
|
*scratch.constants = to_record(constants::snapshot());
|
|
*scratch.constants = to_record(constants::snapshot());
|
|
|
return content::snapshot(scratch.named, counts.named)
|
|
return content::snapshot(scratch.named, counts.named)
|
|
|
&& items::snapshot(scratch.items, counts.items)
|
|
&& items::snapshot(scratch.items, counts.items)
|
|
|
|
|
+ && collectibles::snapshot(scratch.collectibles, counts.collectibles)
|
|
|
|
|
+ && material_requirements::snapshot(scratch.materialRequirementSets,
|
|
|
|
|
+ counts.materialRequirementSets)
|
|
|
&& items::details::snapshot(scratch.itemDetails, counts.itemDetails)
|
|
&& items::details::snapshot(scratch.itemDetails, counts.itemDetails)
|
|
|
|
|
+ && items::socket_plugs::snapshot(scratch.socketPlugRules,
|
|
|
|
|
+ counts.socketPlugRules,
|
|
|
|
|
+ scratch.socketPlugPools,
|
|
|
|
|
+ counts.socketPlugPools,
|
|
|
|
|
+ scratch.socketPlugMembers,
|
|
|
|
|
+ counts.socketPlugMembers)
|
|
|
&& inventory::buckets::snapshot(scratch.inventoryBuckets, counts.inventoryBuckets)
|
|
&& inventory::buckets::snapshot(scratch.inventoryBuckets, counts.inventoryBuckets)
|
|
|
&& socket_entry_lists::snapshot(scratch.socketEntryLists, counts.socketEntryLists)
|
|
&& socket_entry_lists::snapshot(scratch.socketEntryLists, counts.socketEntryLists)
|
|
|
&& socket_entry_lists::snapshot_entry_tables(scratch.socketEntryTables,
|
|
&& socket_entry_lists::snapshot_entry_tables(scratch.socketEntryTables,
|
|
@@ -73,28 +95,85 @@ Context& context() noexcept {
|
|
|
bool all_domains_ready() noexcept {
|
|
bool all_domains_ready() noexcept {
|
|
|
constants::InvestmentConstants published{};
|
|
constants::InvestmentConstants published{};
|
|
|
return runtime::named::ready() && item_definitions_ready() && configured_item_details_ready()
|
|
return runtime::named::ready() && item_definitions_ready() && configured_item_details_ready()
|
|
|
- && inventory_bucket_descriptors_ready() && socket_entry_lists_ready()
|
|
|
|
|
- && ability_buckets_ready() && progression_definitions_ready() && scenario_layouts_ready()
|
|
|
|
|
- && spawn_sets_ready() && hash_names_ready() && constants::find(published);
|
|
|
|
|
|
|
+ && collectible_definitions_ready() && socket_plug_rules_ready()
|
|
|
|
|
+ && material_requirement_sets_ready() && inventory_bucket_descriptors_ready()
|
|
|
|
|
+ && socket_entry_lists_ready() && ability_buckets_ready()
|
|
|
|
|
+ && progression_definitions_ready() && scenario_layouts_ready() && spawn_sets_ready()
|
|
|
|
|
+ && hash_names_ready() && constants::find(published);
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
/** Gives mutable views over every fixed snapshot buffer. */
|
|
/** Gives mutable views over every fixed snapshot buffer. */
|
|
|
cache::records::MutableDomains scratch_domains(Context& state) noexcept {
|
|
cache::records::MutableDomains scratch_domains(Context& state) noexcept {
|
|
|
|
|
+ const auto named = ensure_scratch<content::Definition, content::kDefinitionCatalogCapacity>(
|
|
|
|
|
+ state.namedScratch);
|
|
|
|
|
+ const auto items =
|
|
|
|
|
+ ensure_scratch<build_data::items::Definition, build_data::items::kDefinitionCapacity>(
|
|
|
|
|
+ state.itemScratch);
|
|
|
|
|
+ const auto collectibles =
|
|
|
|
|
+ ensure_scratch<build_data::collectibles::Definition,
|
|
|
|
|
+ build_data::collectibles::kDefinitionCapacity>(state.collectibleScratch);
|
|
|
|
|
+ const auto materialRequirementSets = ensure_scratch<material_requirements::Definition,
|
|
|
|
|
+ material_requirements::kDefinitionCapacity>(
|
|
|
|
|
+ state.materialRequirementSetScratch);
|
|
|
|
|
+ const auto itemDetails =
|
|
|
|
|
+ ensure_scratch<build_data::items::details::Definition,
|
|
|
|
|
+ build_data::items::details::kDefinitionCapacity>(state.itemDetailScratch);
|
|
|
|
|
+ const auto socketPlugRules =
|
|
|
|
|
+ ensure_scratch<build_data::items::socket_plugs::Rule,
|
|
|
|
|
+ build_data::items::socket_plugs::kRuleCapacity>(state.socketPlugRuleScratch);
|
|
|
|
|
+ const auto socketPlugPools =
|
|
|
|
|
+ ensure_scratch<build_data::items::socket_plugs::Pool,
|
|
|
|
|
+ build_data::items::socket_plugs::kPoolCapacity>(state.socketPlugPoolScratch);
|
|
|
|
|
+ const auto socketPlugMembers = ensure_scratch<build_data::items::socket_plugs::Member,
|
|
|
|
|
+ build_data::items::socket_plugs::kMemberCapacity>(
|
|
|
|
|
+ state.socketPlugMemberScratch);
|
|
|
|
|
+ const auto inventoryBuckets =
|
|
|
|
|
+ ensure_scratch<inventory::buckets::Descriptor, inventory::buckets::kDescriptorCapacity>(
|
|
|
|
|
+ state.inventoryBucketScratch);
|
|
|
|
|
+ const auto socketEntryLists =
|
|
|
|
|
+ ensure_scratch<socket_entry_lists::Definition, socket_entry_lists::kDefinitionCapacity>(
|
|
|
|
|
+ state.socketEntryListScratch);
|
|
|
|
|
+ const auto socketEntryTables =
|
|
|
|
|
+ ensure_scratch<socket_entry_lists::EntryTable, socket_entry_lists::kEntryTableCapacity>(
|
|
|
|
|
+ state.socketEntryTableScratch);
|
|
|
|
|
+ const auto abilityBuckets =
|
|
|
|
|
+ ensure_scratch<abilities::Definition, abilities::kDefinitionCapacity>(
|
|
|
|
|
+ state.abilityBucketScratch);
|
|
|
|
|
+ const auto progressions =
|
|
|
|
|
+ ensure_scratch<progressions::Definition, progressions::kDefinitionCapacity>(
|
|
|
|
|
+ state.progressionScratch);
|
|
|
|
|
+ const auto scenarios = ensure_scratch<scenarios::Definition, scenarios::kDefinitionCapacity>(
|
|
|
|
|
+ state.scenarioScratch);
|
|
|
|
|
+ const auto rosterGroups =
|
|
|
|
|
+ ensure_scratch<scenarios::RosterGroup, scenarios::kRosterGroupCapacity>(
|
|
|
|
|
+ state.rosterGroupScratch);
|
|
|
|
|
+ const auto spawnStems =
|
|
|
|
|
+ ensure_scratch<spawn_sets::Stem, spawn_sets::kStemCapacity>(state.spawnStemScratch);
|
|
|
|
|
+ const auto spawnNameHashes =
|
|
|
|
|
+ ensure_scratch<spawn_sets::NameHash, spawn_sets::kNameHashCapacity>(
|
|
|
|
|
+ state.spawnNameHashScratch);
|
|
|
|
|
+ const auto hashNames =
|
|
|
|
|
+ ensure_scratch<hash_names::Name, hash_names::kNameCapacity>(state.hashNameScratch);
|
|
|
return {
|
|
return {
|
|
|
&state.constantsScratch,
|
|
&state.constantsScratch,
|
|
|
- state.namedScratch,
|
|
|
|
|
- state.itemScratch,
|
|
|
|
|
- state.itemDetailScratch,
|
|
|
|
|
- state.inventoryBucketScratch,
|
|
|
|
|
- state.socketEntryListScratch,
|
|
|
|
|
- state.socketEntryTableScratch,
|
|
|
|
|
- state.abilityBucketScratch,
|
|
|
|
|
- state.progressionScratch,
|
|
|
|
|
- state.scenarioScratch,
|
|
|
|
|
- state.rosterGroupScratch,
|
|
|
|
|
- state.spawnStemScratch,
|
|
|
|
|
- state.spawnNameHashScratch,
|
|
|
|
|
- state.hashNameScratch,
|
|
|
|
|
|
|
+ named,
|
|
|
|
|
+ items,
|
|
|
|
|
+ collectibles,
|
|
|
|
|
+ materialRequirementSets,
|
|
|
|
|
+ itemDetails,
|
|
|
|
|
+ socketPlugRules,
|
|
|
|
|
+ socketPlugPools,
|
|
|
|
|
+ socketPlugMembers,
|
|
|
|
|
+ inventoryBuckets,
|
|
|
|
|
+ socketEntryLists,
|
|
|
|
|
+ socketEntryTables,
|
|
|
|
|
+ abilityBuckets,
|
|
|
|
|
+ progressions,
|
|
|
|
|
+ scenarios,
|
|
|
|
|
+ rosterGroups,
|
|
|
|
|
+ spawnStems,
|
|
|
|
|
+ spawnNameHashes,
|
|
|
|
|
+ hashNames,
|
|
|
};
|
|
};
|
|
|
}
|
|
}
|
|
|
|
|
|
|
@@ -103,7 +182,20 @@ void clear_locked(Context& state) noexcept {
|
|
|
const cache::records::MutableDomains scratch = scratch_domains(state);
|
|
const cache::records::MutableDomains scratch = scratch_domains(state);
|
|
|
std::fill(scratch.named.begin(), scratch.named.end(), content::Definition{});
|
|
std::fill(scratch.named.begin(), scratch.named.end(), content::Definition{});
|
|
|
std::fill(scratch.items.begin(), scratch.items.end(), items::Definition{});
|
|
std::fill(scratch.items.begin(), scratch.items.end(), items::Definition{});
|
|
|
|
|
+ std::fill(scratch.collectibles.begin(), scratch.collectibles.end(), collectibles::Definition{});
|
|
|
|
|
+ std::fill(scratch.materialRequirementSets.begin(),
|
|
|
|
|
+ scratch.materialRequirementSets.end(),
|
|
|
|
|
+ material_requirements::Definition{});
|
|
|
std::fill(scratch.itemDetails.begin(), scratch.itemDetails.end(), items::details::Definition{});
|
|
std::fill(scratch.itemDetails.begin(), scratch.itemDetails.end(), items::details::Definition{});
|
|
|
|
|
+ std::fill(scratch.socketPlugRules.begin(),
|
|
|
|
|
+ scratch.socketPlugRules.end(),
|
|
|
|
|
+ items::socket_plugs::Rule{});
|
|
|
|
|
+ std::fill(scratch.socketPlugPools.begin(),
|
|
|
|
|
+ scratch.socketPlugPools.end(),
|
|
|
|
|
+ items::socket_plugs::Pool{});
|
|
|
|
|
+ std::fill(scratch.socketPlugMembers.begin(),
|
|
|
|
|
+ scratch.socketPlugMembers.end(),
|
|
|
|
|
+ items::socket_plugs::Member{});
|
|
|
std::fill(scratch.inventoryBuckets.begin(),
|
|
std::fill(scratch.inventoryBuckets.begin(),
|
|
|
scratch.inventoryBuckets.end(),
|
|
scratch.inventoryBuckets.end(),
|
|
|
inventory::buckets::Descriptor{});
|
|
inventory::buckets::Descriptor{});
|
|
@@ -134,21 +226,43 @@ void clear_locked(Context& state) noexcept {
|
|
|
/** Gives read-only views over the used rows of one canonical snapshot. */
|
|
/** Gives read-only views over the used rows of one canonical snapshot. */
|
|
|
cache::records::Domains occupied_domains(Context& state,
|
|
cache::records::Domains occupied_domains(Context& state,
|
|
|
const cache::records::DomainCounts& counts) noexcept {
|
|
const cache::records::DomainCounts& counts) noexcept {
|
|
|
|
|
+ const std::span<const items::details::Definition> itemDetails{state.itemDetailScratch.get(),
|
|
|
|
|
+ counts.itemDetails};
|
|
|
|
|
+ const std::span<const items::socket_plugs::Rule> socketPlugRules{
|
|
|
|
|
+ state.socketPlugRuleScratch.get(), counts.socketPlugRules};
|
|
|
|
|
+ const std::span<const items::socket_plugs::Pool> socketPlugPools{
|
|
|
|
|
+ state.socketPlugPoolScratch.get(), counts.socketPlugPools};
|
|
|
|
|
+ const std::span<const items::socket_plugs::Member> socketPlugMembers{
|
|
|
|
|
+ state.socketPlugMemberScratch.get(), counts.socketPlugMembers};
|
|
|
return {
|
|
return {
|
|
|
state.constantsScratch,
|
|
state.constantsScratch,
|
|
|
- std::span(state.namedScratch).first(counts.named),
|
|
|
|
|
- std::span(state.itemScratch).first(counts.items),
|
|
|
|
|
- std::span(state.itemDetailScratch).first(counts.itemDetails),
|
|
|
|
|
- std::span(state.inventoryBucketScratch).first(counts.inventoryBuckets),
|
|
|
|
|
- std::span(state.socketEntryListScratch).first(counts.socketEntryLists),
|
|
|
|
|
- std::span(state.socketEntryTableScratch).first(counts.socketEntryTables),
|
|
|
|
|
- std::span(state.abilityBucketScratch).first(counts.abilityBuckets),
|
|
|
|
|
- std::span(state.progressionScratch).first(counts.progressions),
|
|
|
|
|
- std::span(state.scenarioScratch).first(counts.scenarios),
|
|
|
|
|
- std::span(state.rosterGroupScratch).first(counts.rosterGroups),
|
|
|
|
|
- std::span(state.spawnStemScratch).first(counts.spawnStems),
|
|
|
|
|
- std::span(state.spawnNameHashScratch).first(counts.spawnNameHashes),
|
|
|
|
|
- std::span(state.hashNameScratch).first(counts.hashNames),
|
|
|
|
|
|
|
+ std::span<const content::Definition>{state.namedScratch.get(), counts.named},
|
|
|
|
|
+ std::span<const build_data::items::Definition>{state.itemScratch.get(), counts.items},
|
|
|
|
|
+ std::span<const build_data::collectibles::Definition>{state.collectibleScratch.get(),
|
|
|
|
|
+ counts.collectibles},
|
|
|
|
|
+ std::span<const material_requirements::Definition>{
|
|
|
|
|
+ state.materialRequirementSetScratch.get(), counts.materialRequirementSets},
|
|
|
|
|
+ itemDetails,
|
|
|
|
|
+ socketPlugRules,
|
|
|
|
|
+ socketPlugPools,
|
|
|
|
|
+ socketPlugMembers,
|
|
|
|
|
+ std::span<const inventory::buckets::Descriptor>{state.inventoryBucketScratch.get(),
|
|
|
|
|
+ counts.inventoryBuckets},
|
|
|
|
|
+ std::span<const socket_entry_lists::Definition>{state.socketEntryListScratch.get(),
|
|
|
|
|
+ counts.socketEntryLists},
|
|
|
|
|
+ std::span<const socket_entry_lists::EntryTable>{state.socketEntryTableScratch.get(),
|
|
|
|
|
+ counts.socketEntryTables},
|
|
|
|
|
+ std::span<const abilities::Definition>{state.abilityBucketScratch.get(),
|
|
|
|
|
+ counts.abilityBuckets},
|
|
|
|
|
+ std::span<const progressions::Definition>{state.progressionScratch.get(),
|
|
|
|
|
+ counts.progressions},
|
|
|
|
|
+ std::span<const scenarios::Definition>{state.scenarioScratch.get(), counts.scenarios},
|
|
|
|
|
+ std::span<const scenarios::RosterGroup>{state.rosterGroupScratch.get(),
|
|
|
|
|
+ counts.rosterGroups},
|
|
|
|
|
+ std::span<const spawn_sets::Stem>{state.spawnStemScratch.get(), counts.spawnStems},
|
|
|
|
|
+ std::span<const spawn_sets::NameHash>{state.spawnNameHashScratch.get(),
|
|
|
|
|
+ counts.spawnNameHashes},
|
|
|
|
|
+ std::span<const hash_names::Name>{state.hashNameScratch.get(), counts.hashNames},
|
|
|
};
|
|
};
|
|
|
}
|
|
}
|
|
|
|
|
|