Skip to content

Commit

Permalink
Merge remote-tracking branch 'origin/pr/18882'
Browse files Browse the repository at this point in the history
* origin/pr/18882:
  Rebase fix
  Clarify comment
  Actually use the new functionality
  Much faster inventory
  Move tool subtype handling to load time
  Clean up
  Fix unwrap data not being cleared on game unload
  Drop template
  Move tool subtype handling to load time
  • Loading branch information
kevingranade committed Dec 7, 2016
2 parents cfc5765 + bcc83c6 commit e9ebb09
Show file tree
Hide file tree
Showing 4 changed files with 67 additions and 6 deletions.
29 changes: 29 additions & 0 deletions src/inventory.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -132,6 +132,7 @@ inventory inventory::operator+ (const item &rhs)
void inventory::unsort()
{
sorted = false;
binned = false;
}

bool stack_compare(const std::list<item> &lhs, const std::list<item> &rhs)
Expand All @@ -148,6 +149,7 @@ void inventory::sort()
void inventory::clear()
{
items.clear();
binned = false;
}

void inventory::add_stack(const std::list<item> newits)
Expand All @@ -167,6 +169,7 @@ void inventory::clone_stack (const std::list<item> &rhs)
newstack.push_back( rh );
}
items.push_back(newstack);
binned = false;
}

void inventory::push_back(std::list<item> newits)
Expand Down Expand Up @@ -243,6 +246,7 @@ char inventory::find_usable_cached_invlet(const std::string &item_type)

item &inventory::add_item(item newit, bool keep_invlet, bool assign_invlet)
{
binned = false;
bool reuse_cached_letter = false;

// Avoid letters that have been manually assigned to other things.
Expand Down Expand Up @@ -320,6 +324,7 @@ void inventory::restack(player *p)
return;
}

binned = false;
std::list<item> to_restack;
int idx = 0;
for (invstack::iterator iter = items.begin(); iter != items.end(); ++iter, ++idx) {
Expand Down Expand Up @@ -489,6 +494,7 @@ std::list<item> inventory::reduce_stack_internal(const Locator &locator, int qua
std::list<item> ret;
for (invstack::iterator iter = items.begin(); iter != items.end(); ++iter) {
if (item_matches_locator(iter->front(), locator, pos)) {
binned = false;
if(quantity >= (int)iter->size() || quantity < 0) {
ret = *iter;
items.erase(iter);
Expand Down Expand Up @@ -519,6 +525,7 @@ item inventory::remove_item(const item *it)
{
auto tmp = remove_items_with( [&it](const item& i) { return &i == it; }, 1 );
if( !tmp.empty() ) {
binned = false;
return tmp.front();
}
debugmsg("Tried to remove a item not in inventory (name: %s)", it->tname().c_str());
Expand All @@ -531,6 +538,7 @@ item inventory::remove_item_internal(const Locator &locator)
int pos = 0;
for (invstack::iterator iter = items.begin(); iter != items.end(); ++iter) {
if (item_matches_locator(iter->front(), locator, pos)) {
binned = false;
if (iter->size() > 1) {
std::list<item>::iterator stack_member = iter->begin();
char invlet = stack_member->invlet;
Expand Down Expand Up @@ -581,6 +589,7 @@ std::list<item> inventory::remove_randomly_by_volume( const units::volume &volum
chosen_item->invlet = result.back().invlet;
}
if( chosen_stack->empty() ) {
binned = false;
items.erase( chosen_stack );
}
}
Expand Down Expand Up @@ -708,6 +717,7 @@ std::list<item> inventory::use_amount(itype_id it, int _quantity)
}
}
if (iter->empty()) {
binned = false;
iter = items.erase(iter);
} else if (iter != items.end()) {
++iter;
Expand Down Expand Up @@ -949,3 +959,22 @@ std::set<char> inventory::allocated_invlets() const
}
return invlets;
}

const itype_bin &inventory::get_binned_items() const
{
if( binned ) {
return binned_items;
}

binned_items.clear();

// Hack warning
inventory *this_nonconst = const_cast<inventory *>( this );
this_nonconst->visit_items( [ this ]( item *e ) {
binned_items[ e->typeId() ].push_back( e );
return VisitResponse::NEXT;
} );

binned = true;
return binned_items;
}
16 changes: 16 additions & 0 deletions src/inventory.h
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
#include <utility>
#include <vector>
#include <functional>
#include <unordered_map>

class map;
class npc;
Expand All @@ -18,6 +19,7 @@ typedef std::list< std::list<item> > invstack;
typedef std::vector< std::list<item>* > invslice;
typedef std::vector< const std::list<item>* > const_invslice;
typedef std::vector< std::pair<std::list<item>*, int> > indexed_invslice;
typedef std::unordered_map< itype_id, std::list<const item *> > itype_bin;

class salvage_actor;

Expand Down Expand Up @@ -173,6 +175,12 @@ class inventory : public visitable<inventory>

std::set<char> allocated_invlets() const;

/**
* Returns visitable items binned by their itype.
* May not contain items that wouldn't be visited by @ref visitable methods.
*/
const itype_bin &get_binned_items() const;

private:
// For each item ID, store a set of "favorite" inventory letters.
std::map<std::string, std::vector<char> > invlet_cache;
Expand All @@ -186,6 +194,14 @@ class inventory : public visitable<inventory>

invstack items;
bool sorted;

mutable bool binned;
/**
* Items binned by their type.
* That is, item_bin["carrot"] is a list of pointers to all carrots in inventory.
* `mutable` because this is a pure cache that doesn't affect the contained items.
*/
mutable itype_bin binned_items;
};

#endif
2 changes: 2 additions & 0 deletions src/requirements.h
Original file line number Diff line number Diff line change
Expand Up @@ -240,6 +240,8 @@ struct requirement_data {
static void check_consistency( const std::vector< std::vector<T> > &vec,
const std::string &display_name );
template<typename T>
static void finalize( std::vector< std::vector<T> > &vec );
template<typename T>
static std::string print_missing_objs( const std::string &header,
const std::vector< std::vector<T> > &objs );
template<typename T>
Expand Down
26 changes: 20 additions & 6 deletions src/visitable.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -725,10 +725,17 @@ long visitable<T>::charges_of( const std::string &what, int limit ) const
template <>
long visitable<inventory>::charges_of( const std::string &what, int limit ) const
{
const auto &binned = static_cast<const inventory *>( this )->get_binned_items();
const auto iter = binned.find( what );
if( iter == binned.end() ) {
return 0;
}

long res = 0;
for( const auto &stack : static_cast<const inventory *>( this )->items ) {
res += stack.size() * charges_of_internal( stack.front(), what, limit );
for( const item *it : iter->second ) {
res += charges_of_internal( *it, what, limit );
}

return res;
}

Expand Down Expand Up @@ -779,11 +786,18 @@ int visitable<T>::amount_of( const std::string& what, bool pseudo, int limit ) c
template <>
int visitable<inventory>::amount_of( const std::string& what, bool pseudo, int limit ) const
{
int res = 0;
for( const auto &stack : static_cast<const inventory *>( this )->items ) {
res += stack.size() * stack.front().amount_of( what, pseudo, limit );
const auto &binned = static_cast<const inventory *>( this )->get_binned_items();
const auto iter = binned.find( what );
if( iter == binned.end() ) {
return 0;
}
return std::min( res, limit );

long res = 0;
for( const item *it : iter->second ) {
res += it->amount_of( what, pseudo, limit );
}

return res;
}

template <>
Expand Down

0 comments on commit e9ebb09

Please sign in to comment.