Skip to content

Commit

Permalink
cache holsters per loaded save
Browse files Browse the repository at this point in the history
 - Second search with `d:` in crafting menu takes ~5 seconds instead of ~20 seconds
  • Loading branch information
Brambor committed Jan 5, 2025
1 parent 58db8be commit ca5c6db
Show file tree
Hide file tree
Showing 3 changed files with 34 additions and 9 deletions.
10 changes: 1 addition & 9 deletions src/item.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5994,15 +5994,7 @@ void item::final_info( std::vector<iteminfo> &info, const iteminfo_query *parts,
}

// does the item fit in any holsters?
std::vector<const itype *> holsters = Item_factory::find( [this]( const itype & e ) {
if( !e.can_use( "holster" ) ) {
return false;
}
const holster_actor *ptr = dynamic_cast<const holster_actor *>
( e.get_use( "holster" )->get_actor_ptr() );
const item holster_item( &e );
return ptr->can_holster( holster_item, *this ) && !item_is_blacklisted( holster_item.typeId() );
} );
std::vector<const itype *> holsters = item_controller->find_holster_for( *type );

if( !holsters.empty() && parts->test( iteminfo_parts::DESCRIPTION_HOLSTERS ) ) {
insert_separation_line( info );
Expand Down
22 changes: 22 additions & 0 deletions src/item_factory.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4832,6 +4832,7 @@ void Item_factory::reset()
void Item_factory::clear()
{
m_template_groups.clear();
type_contained_in_holsters.clear();

iuse_function_list.clear();

Expand Down Expand Up @@ -5469,6 +5470,27 @@ std::vector<const itype *> Item_factory::find( const std::function<bool( const i
return res;
}

const std::vector<const itype *> &Item_factory::find_holster_for( const itype &it )
{
const itype_id iid = it.get_id();
if( type_contained_in_holsters.count( iid ) > 0 ) {
return type_contained_in_holsters.at( iid );
}
const item itm( &it );

type_contained_in_holsters[iid] = Item_factory::find( [&itm]( const itype & e ) {
if( !e.can_use( "holster" ) ) {
return false;
}
const holster_actor *ptr = dynamic_cast<const holster_actor *>
( e.get_use( "holster" )->get_actor_ptr() );
const item holster_item( &e );
return ptr->can_holster( holster_item, itm );
} );

return type_contained_in_holsters[iid];
}

std::list<itype_id> Item_factory::subtype_replacement( const itype_id &base ) const
{
std::list<itype_id> ret;
Expand Down
11 changes: 11 additions & 0 deletions src/item_factory.h
Original file line number Diff line number Diff line change
Expand Up @@ -266,6 +266,14 @@ class Item_factory

/** Find all item templates (both static and runtime) matching UnaryPredicate function */
static std::vector<const itype *> find( const std::function<bool( const itype & )> &func );
/**
* Find all holsters for itype. Uses type_contained_in_holsters cache, so it's much faster
* than constructing the result on the fly.
*
* This internally constructs an empty item from the itype. It should not be used as replacement
* for item::can_holster (for non-empty items). Ignores blacklist too.
*/
const std::vector<const itype *> &find_holster_for( const itype & );

std::list<itype_id> subtype_replacement( const itype_id & ) const;

Expand All @@ -285,6 +293,9 @@ class Item_factory
std::unordered_map<itype_id, ammotype> migrated_ammo;
std::unordered_map<itype_id, itype_id> migrated_magazines;

// cache for holsters
std::unordered_map<itype_id, std::vector<const itype *>> type_contained_in_holsters;

/** Checks that ammo is listed in ammunition_type::name().
* At least one instance of this ammo type should be defined.
* If any of checks fails, prints a message to the msg stream.
Expand Down

0 comments on commit ca5c6db

Please sign in to comment.