Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Optimize allocation patterns in item and elsewhere #70423

Merged
merged 12 commits into from
Jan 6, 2024
26 changes: 18 additions & 8 deletions src/catacharset.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -415,21 +415,31 @@ std::u32string utf8_to_utf32( const std::string_view str )
std::vector<std::string> utf8_display_split( const std::string &s )
akrieger marked this conversation as resolved.
Show resolved Hide resolved
{
std::vector<std::string> result;
std::string current_glyph;
std::vector<std::string_view> parts;
utf8_display_split_into( s, parts );
result.reserve( parts.size() );
for( std::string_view part : parts ) {
result.emplace_back( part );
}
return result;
}

void utf8_display_split_into( const std::string &s, std::vector<std::string_view> &result )
{
const char *pos = s.c_str();
const char *glyph_begin = pos;
const char *glyph_end = pos;
int len = s.length();
while( len > 0 ) {
const char *old_pos = pos;
const uint32_t ch = UTF8_getch( &pos, &len );
const int width = mk_wcwidth( ch );
if( width > 0 && !current_glyph.empty() ) {
result.push_back( current_glyph );
current_glyph.clear();
if( width > 0 && glyph_begin != glyph_end ) {
result.emplace_back( glyph_begin, std::distance( glyph_begin, glyph_end ) );
glyph_begin = glyph_end;
}
current_glyph += std::string( old_pos, pos );
glyph_end = pos;
}
result.push_back( current_glyph );
return result;
result.emplace_back( glyph_begin, std::distance( glyph_begin, glyph_end ) );
}

int center_text_pos( const char *text, int start_pos, int end_pos )
Expand Down
1 change: 1 addition & 0 deletions src/catacharset.h
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@ std::u32string utf8_to_utf32( std::string_view str );
// Split the given string into displayed characters. Each element of the returned vector
// contains one 'regular' codepoint and all subsequent combining characters.
std::vector<std::string> utf8_display_split( const std::string & );
void utf8_display_split_into( const std::string &, std::vector<std::string_view> & );

/**
* UTF8-Wrapper over std::string.
Expand Down
36 changes: 18 additions & 18 deletions src/field.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -124,8 +124,8 @@ field_entry *field::find_field( const field_type_id &field_type_to_find, const b
if( !_displayed_field_type ) {
return nullptr;
}
const auto it = _field_type_list.find( field_type_to_find );
if( it != _field_type_list.end() && ( !alive_only || it->second.is_field_alive() ) ) {
const auto it = _field_type_list->find( field_type_to_find );
if( it != _field_type_list->end() && ( !alive_only || it->second.is_field_alive() ) ) {
akrieger marked this conversation as resolved.
Show resolved Hide resolved
return &it->second;
}
return nullptr;
Expand All @@ -137,8 +137,8 @@ const field_entry *field::find_field( const field_type_id &field_type_to_find,
if( !_displayed_field_type ) {
return nullptr;
}
const auto it = _field_type_list.find( field_type_to_find );
if( it != _field_type_list.end() && ( !alive_only || it->second.is_field_alive() ) ) {
const auto it = _field_type_list->find( field_type_to_find );
if( it != _field_type_list->end() && ( !alive_only || it->second.is_field_alive() ) ) {
return &it->second;
}
return nullptr;
Expand All @@ -159,8 +159,8 @@ bool field::add_field( const field_type_id &field_type_to_add, const int new_int
if( !field_type_to_add ) {
return false;
}
auto it = _field_type_list.find( field_type_to_add );
if( it != _field_type_list.end() ) {
auto it = _field_type_list->find( field_type_to_add );
if( it != _field_type_list->end() ) {
//Already exists, but lets update it. This is tentative.
int prev_intensity = it->second.get_field_intensity();
if( !it->second.is_field_alive() ) {
Expand All @@ -180,8 +180,8 @@ bool field::add_field( const field_type_id &field_type_to_add, const int new_int

bool field::remove_field( const field_type_id &field_to_remove )
{
const auto it = _field_type_list.find( field_to_remove );
if( it == _field_type_list.end() ) {
const auto it = _field_type_list->find( field_to_remove );
if( it == _field_type_list->end() ) {
return false;
}
remove_field( it );
Expand All @@ -190,9 +190,9 @@ bool field::remove_field( const field_type_id &field_to_remove )

void field::remove_field( std::map<field_type_id, field_entry>::iterator const it )
{
_field_type_list.erase( it );
_field_type_list->erase( it );
_displayed_field_type = fd_null;
for( auto &fld : _field_type_list ) {
for( auto &fld : *_field_type_list ) {
if( !_displayed_field_type || fld.first.obj().priority >= _displayed_field_type.obj().priority ) {
_displayed_field_type = fld.first;
}
Expand All @@ -201,7 +201,7 @@ void field::remove_field( std::map<field_type_id, field_entry>::iterator const i

void field::clear()
{
_field_type_list.clear();
_field_type_list->clear();
_displayed_field_type = fd_null;
}

Expand All @@ -211,27 +211,27 @@ Returns the number of fields existing on the current tile.
*/
unsigned int field::field_count() const
{
return _field_type_list.size();
return _field_type_list->size();
}

std::map<field_type_id, field_entry>::iterator field::begin()
{
return _field_type_list.begin();
return _field_type_list->begin();
}

std::map<field_type_id, field_entry>::const_iterator field::begin() const
{
return _field_type_list.begin();
return _field_type_list->begin();
}

std::map<field_type_id, field_entry>::iterator field::end()
{
return _field_type_list.end();
return _field_type_list->end();
}

std::map<field_type_id, field_entry>::const_iterator field::end() const
{
return _field_type_list.end();
return _field_type_list->end();
}

/*
Expand All @@ -250,14 +250,14 @@ description_affix field::displayed_description_affix() const

int field::displayed_intensity() const
{
auto it = _field_type_list.find( _displayed_field_type );
auto it = _field_type_list->find( _displayed_field_type );
return it->second.get_field_intensity();
}

int field::total_move_cost() const
{
int current_cost = 0;
for( const auto &fld : _field_type_list ) {
for( const auto &fld : *_field_type_list ) {
current_cost += fld.second.get_intensity_level().move_cost;
}
return current_cost;
Expand Down
3 changes: 2 additions & 1 deletion src/field.h
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
#include <vector>

#include "calendar.h"
#include "cata_lazy.h"
#include "color.h"
#include "enums.h"
#include "field_type.h"
Expand Down Expand Up @@ -180,7 +181,7 @@ class field

private:
// A pointer lookup table of all field effects on the current tile.
std::map<field_type_id, field_entry> _field_type_list;
lazy<std::map<field_type_id, field_entry>> _field_type_list;
//_displayed_field_type currently is equal to the last field added to the square. You can modify this behavior in the class functions if you wish.
field_type_id _displayed_field_type;
};
Expand Down
9 changes: 5 additions & 4 deletions src/item.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -415,7 +415,7 @@ item::item( const itype_id &id, time_point turn, solitary_tag tag )

safe_reference<item> item::get_safe_reference()
{
return anchor.reference_to( this );
return anchor->reference_to( this );
}

static const item *get_most_rotten_component( const item &craft )
Expand Down Expand Up @@ -587,10 +587,10 @@ item::item( const recipe *rec, int qty, item &component )
}

item::item( const item & ) = default;
item::item( item && ) noexcept( map_is_noexcept ) = default;
item::item( item && ) noexcept = default;
item::~item() = default;
item &item::operator=( const item & ) = default;
item &item::operator=( item && ) noexcept( list_is_noexcept ) = default;
item &item::operator=( item && ) noexcept = default;

item item::make_corpse( const mtype_id &mt, time_point turn, const std::string &name,
const int upgrade_time )
Expand Down Expand Up @@ -1489,7 +1489,8 @@ bool item::stacks_with( const item &rhs, bool check_components, bool combine_liq
// Guns that differ only by dirt/shot_counter can still stack,
// but other item_vars such as label/note will prevent stacking
const std::vector<std::string> ignore_keys = { "dirt", "shot_counter", "spawn_location_omt" };
if( map_without_keys( item_vars, ignore_keys ) != map_without_keys( rhs.item_vars, ignore_keys ) ) {
if( map_without_keys( *item_vars, ignore_keys ) != map_without_keys( *rhs.item_vars,
ignore_keys ) ) {
return false;
}
const std::string omt_loc_var = "spawn_location_omt";
Expand Down
17 changes: 9 additions & 8 deletions src/item.h
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
#include <vector>

#include "calendar.h"
#include "cata_lazy.h"
#include "cata_utility.h"
#include "compatibility.h"
#include "enums.h"
Expand Down Expand Up @@ -192,9 +193,9 @@ class item : public visitable

item();

item( item && ) noexcept( map_is_noexcept );
item( item && ) noexcept;
item( const item & );
item &operator=( item && ) noexcept( list_is_noexcept );
item &operator=( item && ) noexcept;
item &operator=( const item & );

explicit item( const itype_id &id, time_point turn = calendar::turn, int qty = -1 );
Expand Down Expand Up @@ -2995,21 +2996,21 @@ class item : public visitable
const itype *type;
item_components components;
/** What faults (if any) currently apply to this item */
std::set<fault_id> faults;
cata::heap<std::set<fault_id>> faults;

private:
item_contents contents;
/** `true` if item has any of the flags that require processing in item::process_internal.
* This flag is reset to `true` if item tags are changed.
*/
bool requires_tags_processing = true;
FlagsSetType item_tags; // generic item specific flags
FlagsSetType inherited_tags_cache;
safe_reference_anchor anchor;
std::map<std::string, std::string> item_vars;
cata::heap<FlagsSetType> item_tags; // generic item specific flags
cata::heap<FlagsSetType> inherited_tags_cache;
lazy<safe_reference_anchor> anchor;
cata::heap<std::map<std::string, std::string>> item_vars;
const mtype *corpse = nullptr;
std::string corpse_name; // Name of the late lamented
std::set<matec_id> techniques; // item specific techniques
cata::heap<std::set<matec_id>> techniques; // item specific techniques

// Select a random variant from the possibilities
// Intended to be called when no explicit variant is set
Expand Down
3 changes: 2 additions & 1 deletion src/item_components.h
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
#include <vector>

#include "type_id.h"
#include "value_ptr.h"

class item;
class JsonOut;
Expand All @@ -18,7 +19,7 @@ class ret_val;
class item_components
{
private:
std::map<itype_id, std::vector<item>> comps;
cata::heap<std::map<itype_id, std::vector<item>>> comps;
using comp_iterator = std::map<itype_id, std::vector<item>>::iterator;
using const_comp_iterator = std::map<itype_id, std::vector<item>>::const_iterator;

Expand Down
Loading
Loading