Skip to content

Commit

Permalink
Merge pull request #70423 from akrieger/itemizing_item_optimizing
Browse files Browse the repository at this point in the history
Optimize allocation patterns in item and elsewhere
  • Loading branch information
Maleclypse authored Jan 6, 2024
2 parents a368c90 + 211e1f0 commit 8c5e33d
Show file tree
Hide file tree
Showing 10 changed files with 347 additions and 170 deletions.
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 )
{
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() ) ) {
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 @@ -413,7 +413,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 @@ -585,10 +585,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 @@ -1487,7 +1487,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

0 comments on commit 8c5e33d

Please sign in to comment.