From 701171dafdcbf7fb0bb088bd03c1f3f192804833 Mon Sep 17 00:00:00 2001 From: FeepingCreature Date: Thu, 21 Nov 2019 00:43:41 +0100 Subject: [PATCH 1/4] replace std::weak_ptr with weak_ptr_fast, std::shared_ptr with shared_ptr_fast std::weak_ptr/std::shared_ptr forces atomic access despite the fact cdda is singlethreaded. --- src/activity_handlers.cpp | 6 ++-- src/basecamp.h | 3 +- src/character.cpp | 2 +- src/character.h | 3 +- src/clzones.cpp | 12 +++---- src/clzones.h | 9 +++--- src/creature_tracker.cpp | 28 ++++++++-------- src/creature_tracker.h | 23 ++++++++------ src/debug_menu.cpp | 2 +- src/faction.cpp | 2 +- src/faction_camp.cpp | 4 +-- src/game.cpp | 67 ++++++++++++++++++++------------------- src/game.h | 31 ++++++++++-------- src/iuse.cpp | 6 ++-- src/iuse_actor.cpp | 2 +- src/map.cpp | 4 +-- src/mapgen.cpp | 24 +++++++------- src/mapgen.h | 7 ++-- src/memory_fast.h | 25 +++++++++++++++ src/mission_companion.cpp | 2 +- src/mission_companion.h | 3 +- src/monmove.cpp | 8 ++--- src/mutation.h | 2 +- src/mutation_data.cpp | 12 ++++--- src/npc.h | 9 +++--- src/npcmove.cpp | 20 ++++++------ src/npctalk_funcs.cpp | 2 +- src/overmap.cpp | 14 ++++---- src/overmap.h | 13 ++++---- src/overmap_ui.cpp | 2 +- src/overmapbuffer.cpp | 28 ++++++++-------- src/overmapbuffer.h | 17 +++++----- src/player.h | 5 +-- src/player_activity.h | 3 +- src/regional_settings.h | 3 +- src/savegame.cpp | 4 +-- src/savegame_json.cpp | 4 +-- src/suffer.cpp | 6 ++-- src/vehicle_group.cpp | 6 ++-- src/vehicle_group.h | 4 +-- tests/npc_test.cpp | 3 +- 41 files changed, 242 insertions(+), 188 deletions(-) create mode 100644 src/memory_fast.h diff --git a/src/activity_handlers.cpp b/src/activity_handlers.cpp index 0bcc670e7c2e3..4a12352ed6188 100644 --- a/src/activity_handlers.cpp +++ b/src/activity_handlers.cpp @@ -2957,7 +2957,7 @@ void activity_handlers::find_mount_do_turn( player_activity *act, player *p ) if( p->can_mount( *mon ) ) { act->set_to_null(); guy.revert_after_activity(); - guy.chosen_mount = std::weak_ptr(); + guy.chosen_mount = weak_ptr_fast(); p->mount_creature( *mon ); } else { act->set_to_null(); @@ -4055,7 +4055,7 @@ void activity_handlers::robot_control_do_turn( player_activity *act, player *p ) act->set_to_null(); return; } - const std::shared_ptr z = act->monsters[0].lock(); + const shared_ptr_fast z = act->monsters[0].lock(); if( !z || !iuse::robotcontrol_can_target( p, *z ) ) { p->add_msg_if_player( _( "Target lost. IFF override failed." ) ); @@ -4075,7 +4075,7 @@ void activity_handlers::robot_control_finish( player_activity *act, player *p ) return; } - std::shared_ptr z = act->monsters[0].lock(); + shared_ptr_fast z = act->monsters[0].lock(); act->monsters.clear(); if( !z || !iuse::robotcontrol_can_target( p, *z ) ) { diff --git a/src/basecamp.h b/src/basecamp.h index e0860bfcfcbce..024a8d091d806 100644 --- a/src/basecamp.h +++ b/src/basecamp.h @@ -14,6 +14,7 @@ #include "optional.h" #include "point.h" #include "translations.h" +#include "memory_fast.h" class JsonIn; class JsonOut; @@ -36,7 +37,7 @@ struct expansion_data { }; -using npc_ptr = std::shared_ptr; +using npc_ptr = shared_ptr_fast; using comp_list = std::vector; using Group_tag = std::string; using itype_id = std::string; diff --git a/src/character.cpp b/src/character.cpp index 635c2fca938cd..486ebd96fb170 100644 --- a/src/character.cpp +++ b/src/character.cpp @@ -546,7 +546,7 @@ player_activity Character::get_destination_activity() const void Character::mount_creature( monster &z ) { tripoint pnt = z.pos(); - std::shared_ptr mons = g->shared_from( z ); + shared_ptr_fast mons = g->shared_from( z ); if( mons == nullptr ) { add_msg( m_debug, "mount_creature(): monster not found in critter_tracker" ); return; diff --git a/src/character.h b/src/character.h index 413c76773f8aa..15ff814eb1974 100644 --- a/src/character.h +++ b/src/character.h @@ -41,6 +41,7 @@ #include "weighted_list.h" #include "point.h" #include "magic_enchantment.h" +#include "memory_fast.h" struct pathfinding_settings; class item_location; @@ -1254,7 +1255,7 @@ class Character : public Creature, public visitable /** Returns the intensity of the specified addiction */ int addiction_level( add_type type ) const; - std::shared_ptr mounted_creature; + shared_ptr_fast mounted_creature; // for loading NPC mounts int mounted_creature_id; // for vehicle work diff --git a/src/clzones.cpp b/src/clzones.cpp index 3ccb1ff499ecc..4a034e483d141 100644 --- a/src/clzones.cpp +++ b/src/clzones.cpp @@ -135,17 +135,17 @@ void zone_type::load( JsonObject &jo, const std::string & ) optional( jo, was_loaded, "description", desc_, "" ); } -std::shared_ptr zone_options::create( const zone_type_id &type ) +shared_ptr_fast zone_options::create( const zone_type_id &type ) { if( type == zone_type_id( "FARM_PLOT" ) ) { - return std::make_shared(); + return make_shared_fast(); } else if( type == zone_type_id( "CONSTRUCTION_BLUEPRINT" ) ) { - return std::make_shared(); + return make_shared_fast(); } else if( type == zone_type_id( "LOOT_CUSTOM" ) ) { - return std::make_shared(); + return make_shared_fast(); } - return std::make_shared(); + return make_shared_fast(); } bool zone_options::is_valid( const zone_type_id &type, const zone_options &options ) @@ -907,7 +907,7 @@ void zone_manager::create_vehicle_loot_zone( vehicle &vehicle, const point &moun void zone_manager::add( const std::string &name, const zone_type_id &type, const faction_id &fac, const bool invert, const bool enabled, const tripoint &start, - const tripoint &end, std::shared_ptr options ) + const tripoint &end, shared_ptr_fast options ) { zone_data new_zone = zone_data( name, type, fac, invert, enabled, start, end, options ); //the start is a vehicle tile with cargo space diff --git a/src/clzones.h b/src/clzones.h index 12965094d8866..12cf82555e63f 100644 --- a/src/clzones.h +++ b/src/clzones.h @@ -17,6 +17,7 @@ #include "point.h" #include "string_id.h" #include "type_id.h" +#include "memory_fast.h" class JsonIn; class JsonOut; @@ -62,7 +63,7 @@ class zone_options virtual ~zone_options() = default; /* create valid instance for zone type */ - static std::shared_ptr create( const zone_type_id &type ); + static shared_ptr_fast create( const zone_type_id &type ); /* checks if options is correct base / derived class for zone type */ static bool is_valid( const zone_type_id &type, const zone_options &options ); @@ -237,7 +238,7 @@ class zone_data bool is_vehicle; tripoint start; tripoint end; - std::shared_ptr options; + shared_ptr_fast options; public: zone_data() { @@ -253,7 +254,7 @@ class zone_data zone_data( const std::string &_name, const zone_type_id &_type, const faction_id &_faction, bool _invert, const bool _enabled, const tripoint &_start, const tripoint &_end, - std::shared_ptr _options = nullptr ) { + shared_ptr_fast _options = nullptr ) { name = _name; type = _type; faction = _faction; @@ -377,7 +378,7 @@ class zone_manager void add( const std::string &name, const zone_type_id &type, const faction_id &faction, bool invert, bool enabled, const tripoint &start, const tripoint &end, - std::shared_ptr options = nullptr ); + shared_ptr_fast options = nullptr ); const zone_data *get_zone_at( const tripoint &where, const zone_type_id &type ) const; void create_vehicle_loot_zone( class vehicle &vehicle, const point &mount_point, zone_data &new_zone ); diff --git a/src/creature_tracker.cpp b/src/creature_tracker.cpp index f964738034e95..9abe26b6337fb 100644 --- a/src/creature_tracker.cpp +++ b/src/creature_tracker.cpp @@ -18,11 +18,11 @@ Creature_tracker::Creature_tracker() = default; Creature_tracker::~Creature_tracker() = default; -std::shared_ptr Creature_tracker::find( const tripoint &pos ) const +shared_ptr_fast Creature_tracker::find( const tripoint &pos ) const { const auto iter = monsters_by_location.find( pos ); if( iter != monsters_by_location.end() ) { - const std::shared_ptr &mon_ptr = iter->second; + const shared_ptr_fast &mon_ptr = iter->second; if( !mon_ptr->is_dead() ) { return mon_ptr; } @@ -33,7 +33,7 @@ std::shared_ptr Creature_tracker::find( const tripoint &pos ) const int Creature_tracker::temporary_id( const monster &critter ) const { const auto iter = std::find_if( monsters_list.begin(), monsters_list.end(), - [&]( const std::shared_ptr &ptr ) { + [&]( const shared_ptr_fast &ptr ) { return ptr.get() == &critter; } ); if( iter == monsters_list.end() ) { @@ -42,7 +42,7 @@ int Creature_tracker::temporary_id( const monster &critter ) const return iter - monsters_list.begin(); } -std::shared_ptr Creature_tracker::from_temporary_id( const int id ) +shared_ptr_fast Creature_tracker::from_temporary_id( const int id ) { if( static_cast( id ) < monsters_list.size() ) { return monsters_list[id]; @@ -51,7 +51,7 @@ std::shared_ptr Creature_tracker::from_temporary_id( const int id ) } } -bool Creature_tracker::add( std::shared_ptr critter_ptr ) +bool Creature_tracker::add( shared_ptr_fast critter_ptr ) { assert( critter_ptr ); monster &critter = *critter_ptr; @@ -65,7 +65,7 @@ bool Creature_tracker::add( std::shared_ptr critter_ptr ) return false; } - if( const std::shared_ptr existing_mon_ptr = find( critter.pos() ) ) { + if( const shared_ptr_fast existing_mon_ptr = find( critter.pos() ) ) { // We can spawn stuff on hallucinations, but we need to kill them first if( existing_mon_ptr->is_hallucination() ) { existing_mon_ptr->die( nullptr ); @@ -89,7 +89,7 @@ bool Creature_tracker::add( std::shared_ptr critter_ptr ) return true; } -void Creature_tracker::add_to_faction_map( std::shared_ptr critter_ptr ) +void Creature_tracker::add_to_faction_map( shared_ptr_fast critter_ptr ) { assert( critter_ptr ); monster &critter = *critter_ptr; @@ -117,7 +117,7 @@ bool Creature_tracker::update_pos( const monster &critter, const tripoint &new_p return true; } - if( const std::shared_ptr new_critter_ptr = find( new_pos ) ) { + if( const shared_ptr_fast new_critter_ptr = find( new_pos ) ) { auto &othermon = *new_critter_ptr; if( othermon.is_hallucination() ) { othermon.die( nullptr ); @@ -130,7 +130,7 @@ bool Creature_tracker::update_pos( const monster &critter, const tripoint &new_p } const auto iter = std::find_if( monsters_list.begin(), monsters_list.end(), - [&]( const std::shared_ptr &ptr ) { + [&]( const shared_ptr_fast &ptr ) { return ptr.get() == &critter; } ); if( iter != monsters_list.end() ) { @@ -172,7 +172,7 @@ void Creature_tracker::remove_from_location_map( const monster &critter ) void Creature_tracker::remove( const monster &critter ) { const auto iter = std::find_if( monsters_list.begin(), monsters_list.end(), - [&]( const std::shared_ptr &ptr ) { + [&]( const shared_ptr_fast &ptr ) { return ptr.get() == &critter; } ); if( iter == monsters_list.end() ) { @@ -206,7 +206,7 @@ void Creature_tracker::rebuild_cache() { monsters_by_location.clear(); monster_faction_map_.clear(); - for( const std::shared_ptr &mon_ptr : monsters_list ) { + for( const shared_ptr_fast &mon_ptr : monsters_list ) { monsters_by_location[mon_ptr->pos()] = mon_ptr; add_to_faction_map( mon_ptr ); } @@ -223,13 +223,13 @@ void Creature_tracker::swap_positions( monster &first, monster &second ) const auto second_iter = monsters_by_location.find( second.pos() ); // implied: first_iter != second_iter - std::shared_ptr first_ptr; + shared_ptr_fast first_ptr; if( first_iter != monsters_by_location.end() ) { first_ptr = first_iter->second; monsters_by_location.erase( first_iter ); } - std::shared_ptr second_ptr; + shared_ptr_fast second_ptr; if( second_iter != monsters_by_location.end() ) { second_ptr = second_iter->second; monsters_by_location.erase( second_iter ); @@ -257,7 +257,7 @@ bool Creature_tracker::kill_marked_for_death() // Copy the list so we can iterate the copy safely *and* add new monsters from within monster::die // This happens for example with blob monsters (they split into two smaller monsters). const auto copy = monsters_list; - for( const std::shared_ptr &mon_ptr : copy ) { + for( const shared_ptr_fast &mon_ptr : copy ) { assert( mon_ptr ); monster &critter = *mon_ptr; if( !critter.is_dead() ) { diff --git a/src/creature_tracker.h b/src/creature_tracker.h index e11a762ac5365..38b2879ebd297 100644 --- a/src/creature_tracker.h +++ b/src/creature_tracker.h @@ -10,6 +10,7 @@ #include "point.h" #include "type_id.h" +#include "memory_fast.h" class monster; class JsonIn; @@ -18,24 +19,26 @@ class JsonOut; class Creature_tracker { private: - void add_to_faction_map( std::shared_ptr critter ); + + void add_to_faction_map( shared_ptr_fast critter ); class weak_ptr_comparator { public: - bool operator()( const std::weak_ptr &lhs, const std::weak_ptr &rhs ) const { + bool operator()( const weak_ptr_fast &lhs, + const weak_ptr_fast &rhs ) const { return lhs.lock().get() < rhs.lock().get(); } }; - std::unordered_map, weak_ptr_comparator>> + std::unordered_map, weak_ptr_comparator>> monster_faction_map_; /** * Creatures that get removed via @ref remove are stored here until the end of the turn. * This keeps the objects valid and they can still be accessed instead of causing UB. */ - std::vector> removed_; + std::vector> removed_; public: Creature_tracker(); @@ -45,7 +48,7 @@ class Creature_tracker * If there is no monster, it returns a `nullptr`. * Dead monsters are ignored and not returned. */ - std::shared_ptr find( const tripoint &pos ) const; + shared_ptr_fast find( const tripoint &pos ) const; /** * Returns a temporary id of the given monster (which must exist in the tracker). * The id is valid until monsters are added or removed from the tracker. @@ -54,14 +57,14 @@ class Creature_tracker * return a nullptr if the given id is not valid.) */ int temporary_id( const monster &critter ) const; - std::shared_ptr from_temporary_id( int id ); + shared_ptr_fast from_temporary_id( int id ); /** * Adds the given monster to the tracker. @p critter must not be null. * If the operation succeeded, the monster pointer is now managed by this tracker. * @return Whether the operation was successful. It may fail if there is already * another monster at the location of the new monster. */ - bool add( std::shared_ptr critter ); + bool add( shared_ptr_fast critter ); size_t size() const; /** Updates the position of the given monster to the given point. Returns whether the operation * was successful. */ @@ -77,7 +80,7 @@ class Creature_tracker /** Removes dead monsters from. Their pointers are invalidated. */ void remove_dead(); - const std::vector> &get_monsters_list() const { + const std::vector> &get_monsters_list() const { return monsters_list; } @@ -89,8 +92,8 @@ class Creature_tracker } private: - std::vector> monsters_list; - std::unordered_map> monsters_by_location; + std::vector> monsters_list; + std::unordered_map> monsters_by_location; /** Remove the monsters entry in @ref monsters_by_location */ void remove_from_location_map( const monster &critter ); }; diff --git a/src/debug_menu.cpp b/src/debug_menu.cpp index 24e9d0005e45c..8d838f5fb4c4f 100644 --- a/src/debug_menu.cpp +++ b/src/debug_menu.cpp @@ -1070,7 +1070,7 @@ void debug() break; case DEBUG_SPAWN_NPC: { - std::shared_ptr temp = std::make_shared(); + shared_ptr_fast temp = make_shared_fast(); temp->normalize(); temp->randomize(); temp->spawn_at_precise( { g->get_levx(), g->get_levy() }, u.pos() + point( -4, -4 ) ); diff --git a/src/faction.cpp b/src/faction.cpp index 7568e52c2c7d2..e53d4d1dc8c23 100644 --- a/src/faction.cpp +++ b/src/faction.cpp @@ -668,7 +668,7 @@ void faction_manager::display() const // create a list of NPCs, visible and the ones on overmapbuffer std::vector followers; for( auto &elem : g->get_follower_list() ) { - std::shared_ptr npc_to_get = overmap_buffer.find_npc( elem ); + shared_ptr_fast npc_to_get = overmap_buffer.find_npc( elem ); if( !npc_to_get ) { continue; } diff --git a/src/faction_camp.cpp b/src/faction_camp.cpp index 27a9d5ce39f47..00e0f1e1b92bc 100644 --- a/src/faction_camp.cpp +++ b/src/faction_camp.cpp @@ -1669,7 +1669,7 @@ void basecamp::start_menial_labor() popup( _( "You don't have enough food stored to feed your companion." ) ); return; } - std::shared_ptr comp = talk_function::companion_choose(); + shared_ptr_fast comp = talk_function::companion_choose(); if( comp == nullptr ) { return; } @@ -2546,7 +2546,7 @@ void basecamp::recruit_return( const std::string &task, int score ) //Success of finding an NPC to recruit, based on survival/tracking int skill = comp->get_skill_level( skill_survival ); if( rng( 1, 20 ) + skill > 17 ) { - recruit = std::make_shared(); + recruit = make_shared_fast(); recruit->normalize(); recruit->randomize(); popup( _( "%s encountered %s…" ), comp->name, recruit->name ); diff --git a/src/game.cpp b/src/game.cpp index 1bbd0377b2d10..699dcad4e8bbb 100644 --- a/src/game.cpp +++ b/src/game.cpp @@ -868,11 +868,11 @@ void game::load_npcs() { const int radius = HALF_MAPSIZE - 1; // uses submap coordinates - std::vector> just_added; + std::vector> just_added; for( const auto &temp : overmap_buffer.get_npcs_near_player( radius ) ) { const character_id &id = temp->getID(); const auto found = std::find_if( active_npc.begin(), active_npc.end(), - [id]( const std::shared_ptr &n ) { + [id]( const shared_ptr_fast &n ) { return n->getID() == id; } ); if( found != active_npc.end() ) { @@ -952,7 +952,7 @@ void game::create_starting_npcs() return; //There is already an NPC in this starting location } - std::shared_ptr tmp = std::make_shared(); + shared_ptr_fast tmp = make_shared_fast(); tmp->normalize(); tmp->randomize( one_in( 2 ) ? NC_DOCTOR : NC_NONE ); tmp->spawn_at_precise( { get_levx(), get_levy() }, u.pos() - point_south_east ); @@ -2815,7 +2815,7 @@ bool game::load_packs( const std::string &msg, const std::vector &packs, void game::reset_npc_dispositions() { for( auto elem : follower_ids ) { - std::shared_ptr npc_to_get = overmap_buffer.find_npc( elem ); + shared_ptr_fast npc_to_get = overmap_buffer.find_npc( elem ); if( !npc_to_get ) { continue; } @@ -3026,7 +3026,7 @@ void game::disp_NPC_epilogues() epilogue epi; // TODO: This search needs to be expanded to all NPCs for( auto elem : follower_ids ) { - std::shared_ptr npc_to_get = overmap_buffer.find_npc( elem ); + shared_ptr_fast npc_to_get = overmap_buffer.find_npc( elem ); if( !npc_to_get ) { continue; } @@ -3144,7 +3144,8 @@ struct npc_dist_to_player { const tripoint ppos; npc_dist_to_player() : ppos( g->u.global_omt_location() ) { } // Operator overload required to leverage sort API. - bool operator()( const std::shared_ptr &a, const std::shared_ptr &b ) const { + bool operator()( const shared_ptr_fast &a, + const shared_ptr_fast &b ) const { const tripoint apos = a->global_omt_location(); const tripoint bpos = b->global_omt_location(); return square_dist( ppos.xy(), apos.xy() ) < @@ -3165,7 +3166,7 @@ void game::disp_NPCs() // NOLINTNEXTLINE(cata-use-named-point-constants) mvwprintz( w, point( 0, 1 ), c_white, _( "Your local position: %d, %d, %d" ), lpos.x, lpos.y, lpos.z ); - std::vector> npcs = overmap_buffer.get_npcs_near_player( 100 ); + std::vector> npcs = overmap_buffer.get_npcs_near_player( 100 ); std::sort( npcs.begin(), npcs.end(), npc_dist_to_player() ); size_t i; for( i = 0; i < 20 && i < npcs.size(); i++ ) { @@ -4584,7 +4585,7 @@ void game::use_computer( const tripoint &p ) template T *game::critter_at( const tripoint &p, bool allow_hallucination ) { - if( const std::shared_ptr mon_ptr = critter_tracker->find( p ) ) { + if( const shared_ptr_fast mon_ptr = critter_tracker->find( p ) ) { if( !allow_hallucination && mon_ptr->is_hallucination() ) { return nullptr; } @@ -4628,9 +4629,9 @@ template Character *game::critter_at( const tripoint &, bool ); template const Creature *game::critter_at( const tripoint &, bool ) const; template -std::shared_ptr game::shared_from( const T &critter ) +shared_ptr_fast game::shared_from( const T &critter ) { - if( const std::shared_ptr mon_ptr = critter_tracker->find( critter.pos() ) ) { + if( const shared_ptr_fast mon_ptr = critter_tracker->find( critter.pos() ) ) { return std::dynamic_pointer_cast( mon_ptr ); } if( static_cast( &critter ) == static_cast( &u ) ) { @@ -4645,12 +4646,12 @@ std::shared_ptr game::shared_from( const T &critter ) return nullptr; } -template std::shared_ptr game::shared_from( const Creature & ); -template std::shared_ptr game::shared_from( const Character & ); -template std::shared_ptr game::shared_from( const player & ); -template std::shared_ptr game::shared_from( const avatar & ); -template std::shared_ptr game::shared_from( const monster & ); -template std::shared_ptr game::shared_from( const npc & ); +template shared_ptr_fast game::shared_from( const Creature & ); +template shared_ptr_fast game::shared_from( const Character & ); +template shared_ptr_fast game::shared_from( const player & ); +template shared_ptr_fast game::shared_from( const avatar & ); +template shared_ptr_fast game::shared_from( const monster & ); +template shared_ptr_fast game::shared_from( const npc & ); template T *game::critter_by_id( const character_id id ) @@ -4697,7 +4698,7 @@ monster *game::place_critter_at( const mtype_id &id, const tripoint &p ) return place_critter_around( id, p, 0 ); } -monster *game::place_critter_at( const std::shared_ptr mon, const tripoint &p ) +monster *game::place_critter_at( const shared_ptr_fast mon, const tripoint &p ) { return place_critter_around( mon, p, 0 ); } @@ -4708,10 +4709,11 @@ monster *game::place_critter_around( const mtype_id &id, const tripoint ¢er, if( id.is_null() ) { return nullptr; } - return place_critter_around( std::make_shared( id ), center, radius ); + return place_critter_around( make_shared_fast( id ), center, radius ); } -monster *game::place_critter_around( const std::shared_ptr mon, const tripoint ¢er, +monster *game::place_critter_around( const shared_ptr_fast mon, + const tripoint ¢er, const int radius ) { cata::optional where; @@ -4738,10 +4740,10 @@ monster *game::place_critter_within( const mtype_id &id, const tripoint_range &r if( id.is_null() ) { return nullptr; } - return place_critter_within( std::make_shared( id ), range ); + return place_critter_within( make_shared_fast( id ), range ); } -monster *game::place_critter_within( const std::shared_ptr mon, +monster *game::place_critter_within( const shared_ptr_fast mon, const tripoint_range &range ) { const cata::optional where = choose_where_to_place_monster( *this, *mon, range ); @@ -4781,7 +4783,7 @@ void game::clear_zombies() bool game::spawn_hallucination( const tripoint &p ) { if( one_in( 100 ) ) { - std::shared_ptr tmp = std::make_shared(); + shared_ptr_fast tmp = make_shared_fast(); tmp->normalize(); tmp->randomize( NC_HALLU ); tmp->spawn_at_precise( { get_levx(), get_levy() }, p ); @@ -4795,7 +4797,7 @@ bool game::spawn_hallucination( const tripoint &p ) } const mtype_id &mt = MonsterGenerator::generator().get_valid_hallucination(); - const std::shared_ptr phantasm = std::make_shared( mt ); + const shared_ptr_fast phantasm = make_shared_fast( mt ); phantasm->hallucination = true; phantasm->spawn( p ); @@ -4905,7 +4907,8 @@ bool game::revive_corpse( const tripoint &p, item &it ) debugmsg( "Tried to revive a non-corpse." ); return false; } - std::shared_ptr newmon_ptr = std::make_shared( it.get_mtype()->id ); + shared_ptr_fast newmon_ptr = make_shared_fast + ( it.get_mtype()->id ); monster &critter = *newmon_ptr; critter.init_from_item( it ); if( critter.get_hp() < 1 ) { @@ -4973,7 +4976,7 @@ void game::save_cyborg( item *cyborg, const tripoint &couch_pos, player &install m.i_rem( couch_pos, cyborg ); const string_id npc_cyborg( "cyborg_rescued" ); - std::shared_ptr tmp = std::make_shared(); + shared_ptr_fast tmp = make_shared_fast(); tmp->normalize(); tmp->load_npc_template( npc_cyborg ); tmp->spawn_at_precise( { get_levx(), get_levy() }, couch_pos ); @@ -10368,12 +10371,12 @@ void game::vertical_move( int movez, bool force ) // Save all monsters that can reach the stairs, remove them from the tracker, // then despawn the remaining monsters. Because it's a vertical shift, all // monsters are out of the bounds of the map and will despawn. - std::shared_ptr stored_mount; + shared_ptr_fast stored_mount; if( u.is_mounted() && !m.has_zlevels() ) { // Store a *copy* of the mount, so we can remove the original monster instance // from the tracker before the map shifts. // Map shifting would otherwise just despawn the mount and would later respawn it. - stored_mount = std::make_shared( *u.mounted_creature ); + stored_mount = make_shared_fast( *u.mounted_creature ); critter_tracker->remove( *u.mounted_creature ); } if( !m.has_zlevels() ) { @@ -10402,11 +10405,11 @@ void game::vertical_move( int movez, bool force ) shift_monsters( tripoint( 0, 0, movez ) ); } - std::vector> npcs_to_bring; + std::vector> npcs_to_bring; std::vector monsters_following; if( !m.has_zlevels() && abs( movez ) == 1 ) { std::copy_if( active_npc.begin(), active_npc.end(), back_inserter( npcs_to_bring ), - [this]( const std::shared_ptr &np ) { + [this]( const shared_ptr_fast &np ) { return np->is_walking_with() && !np->is_mounted() && !np->in_sleep_state() && rl_dist( np->pos(), u.pos() ) < 2; } ); @@ -10876,7 +10879,7 @@ void game::replace_stair_monsters() for( auto &elem : coming_to_stairs ) { elem.staircount = 0; const tripoint pnt( elem.pos().xy(), get_levz() ); - place_critter_around( std::make_shared( elem ), pnt, 10 ); + place_critter_around( make_shared_fast( elem ), pnt, 10 ); } coming_to_stairs.clear(); @@ -10983,7 +10986,7 @@ void game::update_stair_monsters() if( is_empty( dest ) ) { critter.spawn( dest ); critter.staircount = 0; - place_critter_at( std::make_shared( critter ), dest ); + place_critter_at( make_shared_fast( critter ), dest ); if( u.sees( dest ) ) { if( !from_below ) { add_msg( m_warning, _( "The %1$s comes down the %2$s!" ), @@ -11174,7 +11177,7 @@ void game::perhaps_add_random_npc() } counter += 1; } - std::shared_ptr tmp = std::make_shared(); + shared_ptr_fast tmp = make_shared_fast(); tmp->normalize(); tmp->randomize(); std::string new_fac_id = "solo_"; diff --git a/src/game.h b/src/game.h index 78128a7be54ba..fc76d0d798cdb 100644 --- a/src/game.h +++ b/src/game.h @@ -30,6 +30,7 @@ #include "monster.h" #include "weather.h" #include "point.h" +#include "memory_fast.h" class item; @@ -267,7 +268,7 @@ class game * the @ref critter_tracker nor in @ref active_npc nor is it @ref u). */ template - std::shared_ptr shared_from( const T &critter ); + shared_ptr_fast shared_from( const T &critter ); /** * Adds critters to the reality bubble, creating them if necessary. @@ -294,11 +295,13 @@ class game */ /** @{ */ monster *place_critter_at( const mtype_id &id, const tripoint &p ); - monster *place_critter_at( std::shared_ptr mon, const tripoint &p ); + monster *place_critter_at( shared_ptr_fast mon, const tripoint &p ); monster *place_critter_around( const mtype_id &id, const tripoint ¢er, int radius ); - monster *place_critter_around( std::shared_ptr mon, const tripoint ¢er, int radius ); + monster *place_critter_around( shared_ptr_fast mon, const tripoint ¢er, + int radius ); monster *place_critter_within( const mtype_id &id, const tripoint_range &range ); - monster *place_critter_within( std::shared_ptr mon, const tripoint_range &range ); + monster *place_critter_within( shared_ptr_fast mon, + const tripoint_range &range ); /** @} */ /** * Returns the approximate number of creatures in the reality bubble. @@ -324,19 +327,19 @@ class game class non_dead_range { public: - std::vector> items; + std::vector> items; class iterator { private: bool valid(); public: - std::vector> &items; - typename std::vector>::iterator iter; - std::shared_ptr current; + std::vector> &items; + typename std::vector>::iterator iter; + shared_ptr_fast current; - iterator( std::vector> &i, - const typename std::vector>::iterator t ) : items( i ), iter( t ) { + iterator( std::vector> &i, + const typename std::vector>::iterator t ) : items( i ), iter( t ) { while( iter != items.end() && !valid() ) { ++iter; } @@ -383,7 +386,7 @@ class game class Creature_range : public non_dead_range { private: - std::shared_ptr u; + shared_ptr_fast u; public: Creature_range( game &g ); @@ -1001,7 +1004,7 @@ class game int mostseen; // # of mons seen last turn; if this increases, set safe_mode to SAFE_MODE_STOP private: - std::shared_ptr u_shared_ptr; + shared_ptr_fast u_shared_ptr; catacurses::window w_terrain_ptr; catacurses::window w_minimap_ptr; @@ -1010,11 +1013,11 @@ class game std::string list_item_upvote; std::string list_item_downvote; - std::vector> new_seen_mon; + std::vector> new_seen_mon; bool safe_mode_warning_logged; bool bVMonsterLookFire; character_id next_npc_id; - std::list> active_npc; + std::list> active_npc; int next_mission_id; std::set follower_ids; // Keep track of follower NPC IDs int moves_since_last_save; diff --git a/src/iuse.cpp b/src/iuse.cpp index 64b9468476a75..102be6a8508f3 100644 --- a/src/iuse.cpp +++ b/src/iuse.cpp @@ -6128,7 +6128,7 @@ int iuse::robotcontrol( player *p, item *it, bool, const tripoint & ) uilist pick_robot; pick_robot.text = _( "Choose an endpoint to hack." ); // Build a list of all unfriendly robots in range. - std::vector< std::shared_ptr< monster> > mons; // TODO: change into vector + std::vector< shared_ptr_fast< monster> > mons; // TODO: change into vector std::vector< tripoint > locations; int entry_num = 0; for( const monster &candidate : g->all_monsters() ) { @@ -6157,7 +6157,7 @@ int iuse::robotcontrol( player *p, item *it, bool, const tripoint & ) return it->type->charges_to_use(); } const size_t mondex = pick_robot.ret; - std::shared_ptr< monster > z = mons[mondex]; + shared_ptr_fast< monster > z = mons[mondex]; p->add_msg_if_player( _( "You start reprogramming the %s into an ally." ), z->name() ); /** @EFFECT_INT speeds up hacking preperation */ @@ -9213,7 +9213,7 @@ int iuse::capture_monster_veh( player *p, item *it, bool, const tripoint &pos ) bool item::release_monster( const tripoint &target, const int radius ) { - std::shared_ptr new_monster = std::make_shared(); + shared_ptr_fast new_monster = make_shared_fast(); try { ::deserialize( *new_monster, get_var( "contained_json", "" ) ); } catch( const std::exception &e ) { diff --git a/src/iuse_actor.cpp b/src/iuse_actor.cpp index 9941a85ef5451..63c2204da565b 100644 --- a/src/iuse_actor.cpp +++ b/src/iuse_actor.cpp @@ -783,7 +783,7 @@ void place_monster_iuse::load( JsonObject &obj ) int place_monster_iuse::use( player &p, item &it, bool, const tripoint & ) const { - std::shared_ptr newmon_ptr = std::make_shared( mtypeid ); + shared_ptr_fast newmon_ptr = make_shared_fast( mtypeid ); monster &newmon = *newmon_ptr; newmon.init_from_item( it ); if( place_randomly ) { diff --git a/src/map.cpp b/src/map.cpp index b4b3ec88389fd..11f5e80e59142 100644 --- a/src/map.cpp +++ b/src/map.cpp @@ -7543,7 +7543,7 @@ void map::spawn_monsters_submap_group( const tripoint &gp, mongroup &group, bool tmp.wander_pos.x, tmp.wander_pos.y, tmp.wander_pos.z ); } - monster *const placed = g->place_critter_at( std::make_shared( tmp ), p ); + monster *const placed = g->place_critter_at( make_shared_fast( tmp ), p ); if( placed ) { placed->on_load(); } @@ -7587,7 +7587,7 @@ void map::spawn_monsters_submap( const tripoint &gp, bool ignore_sight ) }; const auto place_it = [&]( const tripoint & p ) { - monster *const placed = g->place_critter_at( std::make_shared( tmp ), p ); + monster *const placed = g->place_critter_at( make_shared_fast( tmp ), p ); if( placed ) { placed->on_load(); } diff --git a/src/mapgen.cpp b/src/mapgen.cpp index 3ceae2a25f1b6..dc212cf9a7f2e 100644 --- a/src/mapgen.cpp +++ b/src/mapgen.cpp @@ -1758,7 +1758,8 @@ bool jmapgen_objects::check_bounds( const jmapgen_place place, JsonObject &jso ) return common_check_bounds( place.x, place.y, mapgensize, jso ); } -void jmapgen_objects::add( const jmapgen_place &place, std::shared_ptr piece ) +void jmapgen_objects::add( const jmapgen_place &place, + shared_ptr_fast piece ) { objects.emplace_back( place, piece ); } @@ -1773,7 +1774,7 @@ void jmapgen_objects::load_objects( JsonArray parray ) where.offset( m_offset ); if( check_bounds( where, jsi ) ) { - add( where, std::make_shared( jsi ) ); + add( where, make_shared_fast( jsi ) ); } else { jsi.allow_omitted_members(); } @@ -1793,7 +1794,7 @@ void jmapgen_objects::load_objects( JsonArray parray ) continue; } - auto loot = std::make_shared( jsi ); + auto loot = make_shared_fast( jsi ); auto rate = get_option( "ITEM_SPAWNRATE" ); if( where.repeat.valmax != 1 ) { @@ -1822,7 +1823,7 @@ void jmapgen_objects::load_objects( JsonObject &jsi, const std::string &member_n template void load_place_mapings( JsonObject jobj, mapgen_palette::placing_map::mapped_type &vect ) { - vect.push_back( std::make_shared( jobj ) ); + vect.push_back( make_shared_fast( jobj ) ); } /* @@ -1857,7 +1858,7 @@ void load_place_mapings_string( JsonObject &pjo, const std::string &key, { if( pjo.has_string( key ) ) { try { - vect.push_back( std::make_shared( pjo.get_string( key ) ) ); + vect.push_back( make_shared_fast( pjo.get_string( key ) ) ); } catch( const std::runtime_error &err ) { // Using the json object here adds nice formatting and context information pjo.throw_error( err.what(), key ); @@ -1869,7 +1870,7 @@ void load_place_mapings_string( JsonObject &pjo, const std::string &key, while( jarr.has_more() ) { if( jarr.test_string() ) { try { - vect.push_back( std::make_shared( jarr.next_string() ) ); + vect.push_back( make_shared_fast( jarr.next_string() ) ); } catch( const std::runtime_error &err ) { // Using the json object here adds nice formatting and context information jarr.throw_error( err.what() ); @@ -1892,7 +1893,7 @@ void load_place_mapings_alternatively( JsonObject &pjo, const std::string &key, if( !pjo.has_array( key ) ) { load_place_mapings_string( pjo, key, vect ); } else { - auto alter = std::make_shared< jmapgen_alternativly >(); + auto alter = make_shared_fast< jmapgen_alternativly >(); JsonArray jarr = pjo.get_array( key ); while( jarr.has_more() ) { if( jarr.test_string() ) { @@ -6363,7 +6364,7 @@ character_id map::place_npc( const point &p, const string_id &type if( !force && !get_option( "STATIC_NPC" ) ) { return character_id(); //Do not generate an npc. } - std::shared_ptr temp = std::make_shared(); + shared_ptr_fast temp = make_shared_fast(); temp->normalize(); temp->load_npc_template( type ); temp->spawn_at_precise( { abs_sub.xy() }, { p, abs_sub.z } ); @@ -6700,8 +6701,9 @@ void map::rotate( int turns, const bool setpos_safe ) // TODO: This radius can be smaller - how small? const int radius = HALF_MAPSIZE + 3; // uses submap coordinates - const std::vector> npcs = overmap_buffer.get_npcs_near( abs_sub, radius ); - for( const std::shared_ptr &i : npcs ) { + const std::vector> npcs = overmap_buffer.get_npcs_near( abs_sub, + radius ); + for( const shared_ptr_fast &i : npcs ) { npc &np = *i; const tripoint sq = np.global_square_location(); const point local_sq = getlocal( sq ).xy(); @@ -6737,7 +6739,7 @@ void map::rotate( int turns, const bool setpos_safe ) // OK, this is ugly: we remove the NPC from the whole map // Then we place it back from scratch // It could be rewritten to utilize the fact that rotation shouldn't cross overmaps - std::shared_ptr npc_ptr = overmap_buffer.remove_npc( np.getID() ); + shared_ptr_fast npc_ptr = overmap_buffer.remove_npc( np.getID() ); np.spawn_at_precise( { abs_sub.xy() }, { new_pos, abs_sub.z } ); overmap_buffer.insert_npc( npc_ptr ); } diff --git a/src/mapgen.h b/src/mapgen.h index 8bf9cf02d24f6..f87251c9e4eea 100644 --- a/src/mapgen.h +++ b/src/mapgen.h @@ -11,6 +11,7 @@ #include "regional_settings.h" #include "type_id.h" +#include "memory_fast.h" class time_point; struct point; @@ -189,7 +190,7 @@ class mapgen_palette * similar to objects, but it uses key to get the actual position where to place things * out of the json "bitmap" (which is used to paint the terrain/furniture). */ - using placing_map = std::map< int, std::vector< std::shared_ptr > >; + using placing_map = std::map< int, std::vector< shared_ptr_fast > >; std::map format_terrain; std::map format_furniture; @@ -235,7 +236,7 @@ struct jmapgen_objects { bool check_bounds( jmapgen_place place, JsonObject &jso ); - void add( const jmapgen_place &place, std::shared_ptr piece ); + void add( const jmapgen_place &place, shared_ptr_fast piece ); /** * PieceType must be inheriting from jmapgen_piece. It must have constructor that accepts a @@ -267,7 +268,7 @@ struct jmapgen_objects { /** * Combination of where to place something and what to place. */ - using jmapgen_obj = std::pair >; + using jmapgen_obj = std::pair >; std::vector objects; point m_offset; point mapgensize; diff --git a/src/memory_fast.h b/src/memory_fast.h new file mode 100644 index 0000000000000..f1b2a32022044 --- /dev/null +++ b/src/memory_fast.h @@ -0,0 +1,25 @@ +#pragma once +#ifndef SINGLETHREADED_PTRS_H +#define SINGLETHREADED_PTRS_H + +#include + +#if __GLIBCXX__ +template using shared_ptr_fast = std::__shared_ptr; +template using weak_ptr_fast = std::__weak_ptr; +template shared_ptr_fast make_shared_fast( + Args &&... args ) +{ + return std::__make_shared( args... ); +} +#else +template using shared_ptr_fast = std::shared_ptr; +template using weak_ptr_fast = std::weak_ptr; +template shared_ptr_fast make_shared_fast( + Args &&... args ) +{ + return std::make_shared( args... ); +} +#endif + +#endif diff --git a/src/mission_companion.cpp b/src/mission_companion.cpp index 09b7713ff762b..1b3d19abcd9bd 100644 --- a/src/mission_companion.cpp +++ b/src/mission_companion.cpp @@ -910,7 +910,7 @@ int talk_function::combat_score( const std::vector< monster * > &group ) npc_ptr talk_function::temp_npc( const string_id &type ) { - npc_ptr temp = std::make_shared(); + npc_ptr temp = make_shared_fast(); temp->normalize(); temp->load_npc_template( type ); return temp; diff --git a/src/mission_companion.h b/src/mission_companion.h index 15ef33566c1ce..10eb937a49455 100644 --- a/src/mission_companion.h +++ b/src/mission_companion.h @@ -11,6 +11,7 @@ #include "optional.h" #include "point.h" #include "type_id.h" +#include "memory_fast.h" class npc; class item; @@ -21,7 +22,7 @@ template class string_id; class monster; -using npc_ptr = std::shared_ptr; +using npc_ptr = shared_ptr_fast; using comp_list = std::vector; struct mission_entry { diff --git a/src/monmove.cpp b/src/monmove.cpp index 2d4a9ce1187b3..ea705372ec1d1 100644 --- a/src/monmove.cpp +++ b/src/monmove.cpp @@ -410,8 +410,8 @@ void monster::plan() continue; } - for( const std::weak_ptr &weak : fac.second ) { - const std::shared_ptr shared = weak.lock(); + for( const weak_ptr_fast &weak : fac.second ) { + const shared_ptr_fast shared = weak.lock(); if( !shared ) { continue; } @@ -442,8 +442,8 @@ void monster::plan() } swarms = swarms && target == nullptr; // Only swarm if we have no target if( group_morale || swarms ) { - for( const std::weak_ptr &weak : myfaction_iter->second ) { - const std::shared_ptr shared = weak.lock(); + for( const weak_ptr_fast &weak : myfaction_iter->second ) { + const shared_ptr_fast shared = weak.lock(); if( !shared ) { continue; } diff --git a/src/mutation.h b/src/mutation.h index b30fc8b7d4e6e..f85d25bb8f8a7 100644 --- a/src/mutation.h +++ b/src/mutation.h @@ -363,7 +363,7 @@ struct mutation_branch { * Get the trait group object specified by the given ID, or null if no * such group exists. */ - static std::shared_ptr get_group( const trait_group::Trait_group_tag &gid ); + static shared_ptr_fast get_group( const trait_group::Trait_group_tag &gid ); /** * Return the idents of all trait groups that are known. diff --git a/src/mutation_data.cpp b/src/mutation_data.cpp index e615551c8c4ba..81fac0300a9b9 100644 --- a/src/mutation_data.cpp +++ b/src/mutation_data.cpp @@ -16,7 +16,8 @@ #include "translations.h" #include "generic_factory.h" -using TraitGroupMap = std::map>; +using TraitGroupMap = + std::map>; using TraitSet = std::set; using trait_reader = auto_flags_reader; @@ -564,7 +565,7 @@ void mutation_branch::reset_all() trait_blacklist.clear(); trait_groups.clear(); trait_groups.emplace( trait_group::Trait_group_tag( "EMPTY_GROUP" ), - std::make_shared( 100 ) ); + make_shared_fast( 100 ) ); } std::vector dream::messages() const @@ -640,8 +641,8 @@ static Trait_group &make_group_or_throw( const trait_group::Trait_group_tag &gid { // NOTE: If the gid is already in the map, emplace will just return an iterator to it auto found = ( is_collection - ? trait_groups.emplace( gid, std::make_shared( 100 ) ) - : trait_groups.emplace( gid, std::make_shared( 100 ) ) ).first; + ? trait_groups.emplace( gid, make_shared_fast( 100 ) ) + : trait_groups.emplace( gid, make_shared_fast( 100 ) ) ).first; // Evidently, making the collection/distribution separation better has made the code for this check worse. if( is_collection ) { if( dynamic_cast( found->second.get() ) ) { @@ -774,7 +775,8 @@ void mutation_branch::add_entry( Trait_group &tg, JsonObject &obj ) tg.add_entry( std::move( ptr ) ); } -std::shared_ptr mutation_branch::get_group( const trait_group::Trait_group_tag &gid ) +shared_ptr_fast mutation_branch::get_group( const + trait_group::Trait_group_tag &gid ) { auto found = trait_groups.find( gid ); return found != trait_groups.end() ? found->second : nullptr; diff --git a/src/npc.h b/src/npc.h index 630de395151fa..5e6d718def08d 100644 --- a/src/npc.h +++ b/src/npc.h @@ -33,6 +33,7 @@ #include "int_id.h" #include "item.h" #include "point.h" +#include "memory_fast.h" namespace auto_pickup { @@ -513,9 +514,9 @@ struct npc_short_term_cache { float total_danger; float danger_assessment; // Use weak_ptr to avoid circular references between Creatures - std::weak_ptr target; + weak_ptr_fast target; // target is hostile, ally is for aiding actions - std::weak_ptr ally; + weak_ptr_fast ally; healing_options can_heal; // map of positions / type / volume of suspicious sounds std::vector sound_alerts; @@ -528,7 +529,7 @@ struct npc_short_term_cache { double my_weapon_value; // Use weak_ptr to avoid circular references between Creatures - std::vector> friends; + std::vector> friends; std::vector dangerous_explosives; std::map threat_map; @@ -772,7 +773,7 @@ class npc : public player } void load_npc_template( const string_id &ident ); void npc_dismount(); - std::weak_ptr chosen_mount; + weak_ptr_fast chosen_mount; // Generating our stats, etc. void randomize( const npc_class_id &type = npc_class_id::NULL_ID() ); void randomize_from_faction( faction *fac ); diff --git a/src/npcmove.cpp b/src/npcmove.cpp index f816a89c4c454..969e986916a8a 100644 --- a/src/npcmove.cpp +++ b/src/npcmove.cpp @@ -413,7 +413,7 @@ void npc::assess_danger() def_radius = std::max( 6, max_range ); } // find our Character friends and enemies - std::vector> hostile_guys; + std::vector> hostile_guys; for( const npc &guy : g->all_npcs() ) { if( &guy == this || !guy.is_active() ) { continue; @@ -468,7 +468,7 @@ void npc::assess_danger() // don't ignore monsters that are too close or too close to an ally bool is_too_close = dist <= def_radius; const auto test_too_close = [critter, def_radius, - &is_too_close]( const std::weak_ptr &guy ) { + &is_too_close]( const weak_ptr_fast &guy ) { // Bit of a dirty hack - sometimes shared_from, returns nullptr or bad weak_ptr for // friendly NPC when the NPC is riding a creature - I dont know why. // so this skips the bad weak_ptrs, but this doesnt functionally change the AI Priority @@ -515,7 +515,7 @@ void npc::assess_danger() return 0.0f; } bool is_too_close = dist <= def_radius; - for( const std::weak_ptr guy : ai_cache.friends ) { + for( const weak_ptr_fast guy : ai_cache.friends ) { is_too_close |= too_close( foe.pos(), guy.lock().get()->pos(), def_radius ); if( is_too_close ) { break; @@ -537,14 +537,14 @@ void npc::assess_danger() return foe_threat; }; - for( const std::weak_ptr &guy : hostile_guys ) { + for( const weak_ptr_fast &guy : hostile_guys ) { player *foe = dynamic_cast( guy.lock().get() ); if( foe && foe->is_npc() ) { assessment += handle_hostile( *foe, evaluate_enemy( *foe ), "bandit", "kill_npc" ); } } - for( const std::weak_ptr &guy : ai_cache.friends ) { + for( const weak_ptr_fast &guy : ai_cache.friends ) { player *ally = dynamic_cast( guy.lock().get() ); if( !( ally && ally->is_npc() ) ) { continue; @@ -637,8 +637,8 @@ void npc::regen_ai_cache() } float old_assessment = ai_cache.danger_assessment; ai_cache.friends.clear(); - ai_cache.target = std::shared_ptr(); - ai_cache.ally = std::shared_ptr(); + ai_cache.target = shared_ptr_fast(); + ai_cache.ally = shared_ptr_fast(); ai_cache.can_heal.clear_all(); ai_cache.danger = 0.0f; ai_cache.total_danger = 0.0f; @@ -2041,7 +2041,7 @@ bool npc::wont_hit_friend( const tripoint &tar, const item &it, bool throwing ) int safe_angle = 30; for( const auto &fr : ai_cache.friends ) { - const std::shared_ptr ally_p = fr.lock(); + const shared_ptr_fast ally_p = fr.lock(); if( !ally_p ) { continue; } @@ -2415,7 +2415,7 @@ void npc::avoid_friendly_fire() // Calculate center of weight of friends and move away from that tripoint center; for( const auto &fr : ai_cache.friends ) { - if( std::shared_ptr fr_p = fr.lock() ) { + if( shared_ptr_fast fr_p = fr.lock() ) { center += fr_p->pos(); } } @@ -2661,7 +2661,7 @@ void npc::find_item() } std::vector followers; for( auto &elem : g->get_follower_list() ) { - std::shared_ptr npc_to_get = overmap_buffer.find_npc( elem ); + shared_ptr_fast npc_to_get = overmap_buffer.find_npc( elem ); if( !npc_to_get ) { continue; } diff --git a/src/npctalk_funcs.cpp b/src/npctalk_funcs.cpp index e3136ff93aa07..eaf4d0d125bea 100644 --- a/src/npctalk_funcs.cpp +++ b/src/npctalk_funcs.cpp @@ -989,7 +989,7 @@ void talk_function::set_npc_pickup( npc &p ) void talk_function::npc_die( npc &p ) { p.die( nullptr ); - const std::shared_ptr guy = overmap_buffer.find_npc( p.getID() ); + const shared_ptr_fast guy = overmap_buffer.find_npc( p.getID() ); if( guy && !guy->is_dead() ) { guy->marked_for_death = true; } diff --git a/src/overmap.cpp b/src/overmap.cpp index 907764215d081..3a10d07729ff3 100644 --- a/src/overmap.cpp +++ b/src/overmap.cpp @@ -1217,15 +1217,16 @@ bool overmap::monster_check( const std::pair &candidate ) con } ) != matching_range.second; } -void overmap::insert_npc( std::shared_ptr who ) +void overmap::insert_npc( shared_ptr_fast who ) { npcs.push_back( who ); g->set_npcs_dirty(); } -std::shared_ptr overmap::erase_npc( const character_id id ) +shared_ptr_fast overmap::erase_npc( const character_id id ) { - const auto iter = std::find_if( npcs.begin(), npcs.end(), [id]( const std::shared_ptr &n ) { + const auto iter = std::find_if( npcs.begin(), + npcs.end(), [id]( const shared_ptr_fast &n ) { return n->getID() == id; } ); if( iter == npcs.end() ) { @@ -1237,10 +1238,11 @@ std::shared_ptr overmap::erase_npc( const character_id id ) return ptr; } -std::vector> overmap::get_npcs( const std::function +std::vector> overmap::get_npcs( const + std::function &predicate ) const { - std::vector> result; + std::vector> result; for( const auto &g : npcs ) { if( predicate( *g ) ) { result.push_back( g ); @@ -4370,7 +4372,7 @@ void overmap::for_each_npc( const std::function &callback ) } } -std::shared_ptr overmap::find_npc( const character_id id ) const +shared_ptr_fast overmap::find_npc( const character_id id ) const { for( const auto &guy : npcs ) { if( guy->getID() == id ) { diff --git a/src/overmap.h b/src/overmap.h index d77e5bb4c52ff..dc24f202110b3 100644 --- a/src/overmap.h +++ b/src/overmap.h @@ -310,25 +310,26 @@ class overmap std::map, std::vector> connections_out; cata::optional find_camp( const point &p ); /// Adds the npc to the contained list of npcs ( @ref npcs ). - void insert_npc( std::shared_ptr who ); + void insert_npc( shared_ptr_fast who ); /// Removes the npc and returns it ( or returns nullptr if not found ). - std::shared_ptr erase_npc( character_id id ); + shared_ptr_fast erase_npc( character_id id ); void for_each_npc( const std::function &callback ); void for_each_npc( const std::function &callback ) const; - std::shared_ptr find_npc( character_id id ) const; + shared_ptr_fast find_npc( character_id id ) const; - const std::vector> &get_npcs() const { + const std::vector> &get_npcs() const { return npcs; } - std::vector> get_npcs( const std::function &predicate ) + std::vector> get_npcs( const std::function + &predicate ) const; private: friend class overmapbuffer; - std::vector> npcs; + std::vector> npcs; bool nullbool = false; point loc = point_zero; diff --git a/src/overmap_ui.cpp b/src/overmap_ui.cpp index 17c82e3b852ff..b63cb704f66c0 100644 --- a/src/overmap_ui.cpp +++ b/src/overmap_ui.cpp @@ -563,7 +563,7 @@ void draw( const catacurses::window &w, const catacurses::window &wbar, const tr } std::vector followers; for( auto &elem : g->get_follower_list() ) { - std::shared_ptr npc_to_get = overmap_buffer.find_npc( elem ); + shared_ptr_fast npc_to_get = overmap_buffer.find_npc( elem ); if( !npc_to_get ) { continue; } diff --git a/src/overmapbuffer.cpp b/src/overmapbuffer.cpp index 6bb7dcca90fe5..dacec7dbe35be 100644 --- a/src/overmapbuffer.cpp +++ b/src/overmapbuffer.cpp @@ -992,7 +992,7 @@ tripoint overmapbuffer::find_random( const tripoint &origin, const std::string & return find_random( origin, params ); } -std::shared_ptr overmapbuffer::find_npc( character_id id ) +shared_ptr_fast overmapbuffer::find_npc( character_id id ) { for( auto &it : overmaps ) { if( auto p = it.second->find_npc( id ) ) { @@ -1012,7 +1012,7 @@ cata::optional overmapbuffer::find_camp( const point &p ) return cata::nullopt; } -void overmapbuffer::insert_npc( const std::shared_ptr &who ) +void overmapbuffer::insert_npc( const shared_ptr_fast &who ) { assert( who ); const tripoint npc_omt_pos = who->global_omt_location(); @@ -1020,7 +1020,7 @@ void overmapbuffer::insert_npc( const std::shared_ptr &who ) get( npc_om_pos ).insert_npc( who ); } -std::shared_ptr overmapbuffer::remove_npc( const character_id &id ) +shared_ptr_fast overmapbuffer::remove_npc( const character_id &id ) { for( auto &it : overmaps ) { if( const auto p = it.second->erase_npc( id ) ) { @@ -1031,7 +1031,7 @@ std::shared_ptr overmapbuffer::remove_npc( const character_id &id ) return nullptr; } -std::vector> overmapbuffer::get_npcs_near_player( int radius ) +std::vector> overmapbuffer::get_npcs_near_player( int radius ) { tripoint plpos = g->u.global_omt_location(); // get_npcs_near needs submap coordinates @@ -1078,9 +1078,9 @@ std::vector overmapbuffer::get_overmaps_near( const point &p, const i return get_overmaps_near( tripoint( p, 0 ), radius ); } -std::vector> overmapbuffer::get_companion_mission_npcs() +std::vector> overmapbuffer::get_companion_mission_npcs() { - std::vector> available; + std::vector> available; // TODO: this is an arbitrary radius, replace with something sane. for( const auto &guy : get_npcs_near_player( 100 ) ) { if( guy->has_companion_mission() ) { @@ -1091,9 +1091,10 @@ std::vector> overmapbuffer::get_companion_mission_npcs() } // If z == INT_MIN, allow all z-levels -std::vector> overmapbuffer::get_npcs_near( const tripoint &p, int radius ) +std::vector> overmapbuffer::get_npcs_near( const tripoint &p, + int radius ) { - std::vector> result; + std::vector> result; for( auto &it : get_overmaps_near( p, radius ) ) { auto temp = it->get_npcs( [&]( const npc & guy ) { // Global position of NPC, in submap coordinates @@ -1109,10 +1110,10 @@ std::vector> overmapbuffer::get_npcs_near( const tripoint & } // If z == INT_MIN, allow all z-levels -std::vector> overmapbuffer::get_npcs_near_omt( const tripoint &p, +std::vector> overmapbuffer::get_npcs_near_omt( const tripoint &p, int radius ) { - std::vector> result; + std::vector> result; for( auto &it : get_overmaps_near( omt_to_sm_copy( p.xy() ), radius ) ) { auto temp = it->get_npcs( [&]( const npc & guy ) { // Global position of NPC, in submap coordinates @@ -1191,9 +1192,9 @@ std::vector overmapbuffer::get_camps_near( const tripoint &locat return result; } -std::vector> overmapbuffer::get_overmap_npcs() +std::vector> overmapbuffer::get_overmap_npcs() { - std::vector> result; + std::vector> result; for( auto &om : overmaps ) { const overmap &overmap = *om.second; for( auto &guy : overmap.npcs ) { @@ -1332,7 +1333,8 @@ void overmapbuffer::spawn_monster( const tripoint &p ) // The monster position must be local to the main map when added to the game const tripoint local = tripoint( g->m.getlocal( ms ), p.z ); assert( g->m.inbounds( local ) ); - monster *const placed = g->place_critter_at( std::make_shared( this_monster ), local ); + monster *const placed = g->place_critter_at( make_shared_fast( this_monster ), + local ); if( placed ) { placed->on_load(); } diff --git a/src/overmapbuffer.h b/src/overmapbuffer.h index 15b494f184397..3eab56ca7b52d 100644 --- a/src/overmapbuffer.h +++ b/src/overmapbuffer.h @@ -18,6 +18,7 @@ #include "type_id.h" #include "point.h" #include "string_id.h" +#include "memory_fast.h" class character_id; struct mongroup; @@ -221,44 +222,44 @@ class overmapbuffer * specific submap. */ - std::vector> get_npcs_near( const tripoint &p, int radius ); + std::vector> get_npcs_near( const tripoint &p, int radius ); /** * Get all (currently loaded!) npcs that have a companion * mission set. */ - std::vector> get_companion_mission_npcs(); + std::vector> get_companion_mission_npcs(); /** * Uses overmap terrain coordinates, this also means radius is * in overmap terrain. * A radius of 0 returns all npcs that are on that specific * overmap terrain tile. */ - std::vector> get_npcs_near_omt( const tripoint &p, int radius ); + std::vector> get_npcs_near_omt( const tripoint &p, int radius ); /** * Same as @ref get_npcs_near(int,int,int,int) but uses * player position as center. */ - std::vector> get_npcs_near_player( int radius ); + std::vector> get_npcs_near_player( int radius ); /** * Find the npc with the given ID. * Returns NULL if the npc could not be found. * Searches all loaded overmaps. */ - std::shared_ptr find_npc( character_id id ); + shared_ptr_fast find_npc( character_id id ); /** * Get all NPCs active on the overmap */ - std::vector> get_overmap_npcs(); + std::vector> get_overmap_npcs(); /** * Find npc by id and if found, erase it from the npc list * and return it ( or return nullptr if not found ). */ - std::shared_ptr remove_npc( const character_id &id ); + shared_ptr_fast remove_npc( const character_id &id ); /** * Adds the npc to an overmap ( based on the npcs current location ) * and stores it there. The overmap takes ownership of the pointer. */ - void insert_npc( const std::shared_ptr &who ); + void insert_npc( const shared_ptr_fast &who ); /** * Find all places with the specific overmap terrain type. diff --git a/src/player.h b/src/player.h index 947cfda438b47..e6fba9127abc6 100644 --- a/src/player.h +++ b/src/player.h @@ -39,6 +39,7 @@ #include "monster.h" #include "craft_command.h" #include "point.h" +#include "memory_fast.h" class basecamp; class effect; @@ -1159,7 +1160,7 @@ class player : public Character start_location_id start_location; double recoil = MAX_RECOIL; - std::weak_ptr last_target; + weak_ptr_fast last_target; cata::optional last_target_pos; // Save favorite ammo location item_location ammo_location; @@ -1345,7 +1346,7 @@ class player : public Character private: /** smart pointer to targeting data stored for aiming the player's weapon across turns. */ - std::shared_ptr tdata; + shared_ptr_fast tdata; protected: diff --git a/src/player_activity.h b/src/player_activity.h index 767363522dbca..9c6ad33aaefe1 100644 --- a/src/player_activity.h +++ b/src/player_activity.h @@ -14,6 +14,7 @@ #include "item_location.h" #include "point.h" #include "string_id.h" +#include "memory_fast.h" class avatar; class player; @@ -47,7 +48,7 @@ class player_activity std::vector str_values; std::vector coords; std::unordered_set coord_set; - std::vector> monsters; + std::vector> monsters; tripoint placement; /** If true, the activity will be auto-resumed next time the player attempts * an identical activity. This value is set dynamically. diff --git a/src/regional_settings.h b/src/regional_settings.h index d3804845eeab5..9277e15f7fce6 100644 --- a/src/regional_settings.h +++ b/src/regional_settings.h @@ -17,6 +17,7 @@ #include "int_id.h" #include "string_id.h" #include "type_id.h" +#include "memory_fast.h" class JsonObject; @@ -223,7 +224,7 @@ struct regional_settings { oter_str_id default_oter; // 'field' double river_scale; weighted_int_list default_groundcover; // ie, 'grass_or_dirt' - std::shared_ptr> default_groundcover_str; + shared_ptr_fast> default_groundcover_str; city_settings city_spec; // put what where in a city of what kind groundcover_extra field_coverage; diff --git a/src/savegame.cpp b/src/savegame.cpp index c57e1bbede964..708b80d07bd87 100644 --- a/src/savegame.cpp +++ b/src/savegame.cpp @@ -1067,7 +1067,7 @@ void overmap::unserialize( std::istream &fin ) } else if( name == "npcs" ) { jsin.start_array(); while( !jsin.end_array() ) { - std::shared_ptr new_npc = std::make_shared(); + shared_ptr_fast new_npc = make_shared_fast(); new_npc->deserialize( jsin ); if( !new_npc->get_fac_id().str().empty() ) { new_npc->set_fac( new_npc->get_fac_id() ); @@ -1712,7 +1712,7 @@ void Creature_tracker::deserialize( JsonIn &jsin ) jsin.start_array(); while( !jsin.end_array() ) { // @todo would be nice if monster had a constructor using JsonIn or similar, so this could be one statement. - std::shared_ptr mptr = std::make_shared(); + shared_ptr_fast mptr = make_shared_fast(); jsin.read( *mptr ); add( mptr ); } diff --git a/src/savegame_json.cpp b/src/savegame_json.cpp index cefc5759e462f..7939cb3b7f205 100644 --- a/src/savegame_json.cpp +++ b/src/savegame_json.cpp @@ -113,7 +113,7 @@ static const std::array obj_type_name = { { "OBJECT_NO }; // TODO: investigate serializing other members of the Creature class hierarchy -static void serialize( const std::weak_ptr &obj, JsonOut &jsout ) +static void serialize( const weak_ptr_fast &obj, JsonOut &jsout ) { if( const auto monster_ptr = obj.lock() ) { jsout.start_object(); @@ -129,7 +129,7 @@ static void serialize( const std::weak_ptr &obj, JsonOut &jsout ) } } -static void deserialize( std::weak_ptr &obj, JsonIn &jsin ) +static void deserialize( weak_ptr_fast &obj, JsonIn &jsin ) { JsonObject data = jsin.get_object(); tripoint temp_pos; diff --git a/src/suffer.cpp b/src/suffer.cpp index 4515032f678e1..da93b8e207961 100644 --- a/src/suffer.cpp +++ b/src/suffer.cpp @@ -548,7 +548,7 @@ void Character::suffer_from_schizophrenia() } // Follower turns hostile if( one_turn_in( 4_hours ) ) { - std::vector> followers = overmap_buffer.get_npcs_near_player( 12 ); + std::vector> followers = overmap_buffer.get_npcs_near_player( 12 ); std::string who_gets_angry = name; if( !followers.empty() ) { @@ -608,13 +608,13 @@ void Character::suffer_from_schizophrenia() // Weapon is concerned for player if bleeding // Weapon is concerned for itself if damaged // Otherwise random chit-chat - std::vector> mons = g->all_monsters().items; + std::vector> mons = g->all_monsters().items; std::string i_talk_w; bool does_talk = false; if( !mons.empty() && one_turn_in( 12_minutes ) ) { std::vector seen_mons; - for( std::weak_ptr &n : mons ) { + for( weak_ptr_fast &n : mons ) { if( sees( *n.lock() ) ) { seen_mons.emplace_back( n.lock()->get_name() ); } diff --git a/src/vehicle_group.cpp b/src/vehicle_group.cpp index a18c42d6ba72c..3415a82a75352 100644 --- a/src/vehicle_group.cpp +++ b/src/vehicle_group.cpp @@ -180,13 +180,13 @@ void VehicleSpawn::load( JsonObject &jo ) if( type.has_object( "vehicle_json" ) ) { JsonObject vjo = type.get_object( "vehicle_json" ); - spawn.add( type.get_float( "weight" ), std::make_shared( vjo ) ); + spawn.add( type.get_float( "weight" ), make_shared_fast( vjo ) ); } else if( type.has_string( "vehicle_function" ) ) { if( builtin_functions.count( type.get_string( "vehicle_function" ) ) == 0 ) { type.throw_error( "load_vehicle_spawn: unable to find builtin function", "vehicle_function" ); } - spawn.add( type.get_float( "weight" ), std::make_shared + spawn.add( type.get_float( "weight" ), make_shared_fast ( builtin_functions[type.get_string( "vehicle_function" )] ) ); } else { type.throw_error( "load_vehicle_spawn: missing required vehicle_json (object) or vehicle_function (string)." ); @@ -201,7 +201,7 @@ void VehicleSpawn::reset() void VehicleSpawn::apply( map &m, const std::string &terrain_name ) const { - const std::shared_ptr *func = types.pick(); + const shared_ptr_fast *func = types.pick(); if( func == nullptr ) { debugmsg( "unable to find valid function for vehicle spawn" ); } else { diff --git a/src/vehicle_group.h b/src/vehicle_group.h index 29808f41732ca..c6f62b7c60c53 100644 --- a/src/vehicle_group.h +++ b/src/vehicle_group.h @@ -160,7 +160,7 @@ class VehicleSpawn public: VehicleSpawn() = default; - void add( const double &weight, const std::shared_ptr &func ) { + void add( const double &weight, const shared_ptr_fast &func ) { types.add( func, weight ); } @@ -183,7 +183,7 @@ class VehicleSpawn static void reset(); private: - weighted_float_list> types; + weighted_float_list> types; using FunctionMap = std::unordered_map; static FunctionMap builtin_functions; diff --git a/tests/npc_test.cpp b/tests/npc_test.cpp index 07e3ae4cd84e7..2b4d53105576a 100644 --- a/tests/npc_test.cpp +++ b/tests/npc_test.cpp @@ -28,6 +28,7 @@ #include "string_id.h" #include "type_id.h" #include "point.h" +#include "memory_fast.h" class Creature; @@ -351,7 +352,7 @@ TEST_CASE( "npc-movement" ) if( type == 'A' || type == 'R' || type == 'W' || type == 'M' || type == 'B' || type == 'C' ) { - std::shared_ptr guy = std::make_shared(); + shared_ptr_fast guy = make_shared_fast(); do { guy->normalize(); guy->randomize(); From e4f685d18173a063881b68a4240c78ad0cefa836 Mon Sep 17 00:00:00 2001 From: FeepingCreature Date: Thu, 21 Nov 2019 00:44:46 +0100 Subject: [PATCH 2/4] inline rl_dist(), trig_dist(), square_dist() --- src/line.cpp | 39 --------------------------------------- src/line.h | 45 ++++++++++++++++++++++++++++++++++++++------- 2 files changed, 38 insertions(+), 46 deletions(-) diff --git a/src/line.cpp b/src/line.cpp index a7f14b64ec8b1..8d120ac336bed 100644 --- a/src/line.cpp +++ b/src/line.cpp @@ -14,8 +14,6 @@ #include "output.h" #include "enums.h" -extern bool trigdist; - void bresenham( const point &p1, const point &p2, int t, const std::function &interact ) { @@ -230,43 +228,6 @@ std::vector line_to( const tripoint &loc1, const tripoint &loc2, int return line; } -float trig_dist( const point &loc1, const point &loc2 ) -{ - return trig_dist( tripoint( loc1, 0 ), tripoint( loc2, 0 ) ); -} - -float trig_dist( const tripoint &loc1, const tripoint &loc2 ) -{ - return sqrt( static_cast( ( loc1.x - loc2.x ) * ( loc1.x - loc2.x ) ) + - ( ( loc1.y - loc2.y ) * ( loc1.y - loc2.y ) ) + - ( ( loc1.z - loc2.z ) * ( loc1.z - loc2.z ) ) ); -} - -int square_dist( const point &loc1, const point &loc2 ) -{ - const point d = abs( loc1 - loc2 ); - return std::max( d.x, d.y ); -} - -int square_dist( const tripoint &loc1, const tripoint &loc2 ) -{ - const tripoint d = abs( loc1 - loc2 ); - return std::max( { d.x, d.y, d.z } ); -} - -int rl_dist( const point &a, const point &b ) -{ - return rl_dist( tripoint( a, 0 ), tripoint( b, 0 ) ); -} - -int rl_dist( const tripoint &loc1, const tripoint &loc2 ) -{ - if( trigdist ) { - return trig_dist( loc1, loc2 ); - } - return square_dist( loc1, loc2 ); -} - float rl_dist_exact( const tripoint &loc1, const tripoint &loc2 ) { if( trigdist ) { diff --git a/src/line.h b/src/line.h index 5b52fd599b4cc..d20bb102b3f3d 100644 --- a/src/line.h +++ b/src/line.h @@ -6,6 +6,7 @@ #include #include #include +#include #include "math_defines.h" #include "point.h" @@ -109,14 +110,44 @@ std::vector line_to( const point &p1, const point &p2, int t = 0 ); // t and t2 decide which Bresenham line is used. std::vector line_to( const tripoint &loc1, const tripoint &loc2, int t = 0, int t2 = 0 ); // sqrt(dX^2 + dY^2) -float trig_dist( const point &loc1, const point &loc2 ); -float trig_dist( const tripoint &loc1, const tripoint &loc2 ); -// Roguelike distance; minimum of dX and dY -int square_dist( const point &loc1, const point &loc2 ); -int square_dist( const tripoint &loc1, const tripoint &loc2 ); + +extern bool trigdist; + +inline float trig_dist( const tripoint &loc1, const tripoint &loc2 ) +{ + return sqrt( static_cast( ( loc1.x - loc2.x ) * ( loc1.x - loc2.x ) ) + + ( ( loc1.y - loc2.y ) * ( loc1.y - loc2.y ) ) + + ( ( loc1.z - loc2.z ) * ( loc1.z - loc2.z ) ) ); +} +inline float trig_dist( const point &loc1, const point &loc2 ) +{ + return trig_dist( tripoint( loc1, 0 ), tripoint( loc2, 0 ) ); +} + +// Roguelike distance; maximum of dX and dY +inline int square_dist( const tripoint &loc1, const tripoint &loc2 ) +{ + const tripoint d = abs( loc1 - loc2 ); + return std::max( { d.x, d.y, d.z } ); +} +inline int square_dist( const point &loc1, const point &loc2 ) +{ + const point d = abs( loc1 - loc2 ); + return std::max( d.x, d.y ); +} + // Choose between the above two according to the "circular distances" option -int rl_dist( const point &a, const point &b ); -int rl_dist( const tripoint &loc1, const tripoint &loc2 ); +inline int rl_dist( const tripoint &loc1, const tripoint &loc2 ) +{ + if( trigdist ) { + return trig_dist( loc1, loc2 ); + } + return square_dist( loc1, loc2 ); +} +inline int rl_dist( const point &a, const point &b ) +{ + return rl_dist( tripoint( a, 0 ), tripoint( b, 0 ) ); +} float rl_dist_exact( const tripoint &loc1, const tripoint &loc2 ); // Sum of distance in both axes int manhattan_dist( const point &loc1, const point &loc2 ); From 44100442cee0a425f3c609559db4a129ced54c51 Mon Sep 17 00:00:00 2001 From: FeepingCreature Date: Thu, 21 Nov 2019 00:45:38 +0100 Subject: [PATCH 3/4] line.h: add rl_dist_fast, which allows to skip the sqrt so we can do the length checks in monster::rate_target() and compute the sqrt when we know it's necessary. --- src/line.h | 56 +++++++++++++++++++++++++++++++++++++++++++++++++ src/monmove.cpp | 6 +++--- 2 files changed, 59 insertions(+), 3 deletions(-) diff --git a/src/line.h b/src/line.h index d20bb102b3f3d..43f4b1377a733 100644 --- a/src/line.h +++ b/src/line.h @@ -148,6 +148,62 @@ inline int rl_dist( const point &a, const point &b ) { return rl_dist( tripoint( a, 0 ), tripoint( b, 0 ) ); } + +/** + * Helper type for the return value of dist_fast(). + * + * This lets us delay the sqrt() call of trigdist until the actual length is needed. + */ +struct FastDistanceApproximation { + private: + int value; + public: + inline FastDistanceApproximation( int value ) : value( value ) { } + template + inline bool operator<=( const T &rhs ) const { + if( trigdist ) { + return value <= rhs * rhs; + } + return value <= rhs; + } + template + inline bool operator>=( const T &rhs ) const { + if( trigdist ) { + return value >= rhs * rhs; + } + return value >= rhs; + } + inline operator int() const { + if( trigdist ) { + return sqrt( value ); + } + return value; + } +}; + +inline FastDistanceApproximation trig_dist_fast( const tripoint &loc1, const tripoint &loc2 ) +{ + return ( loc1.x - loc2.x ) * ( loc1.x - loc2.x ) + + ( loc1.y - loc2.y ) * ( loc1.y - loc2.y ) + + ( loc1.z - loc2.z ) * ( loc1.z - loc2.z ); +} +inline FastDistanceApproximation square_dist_fast( const tripoint &loc1, const tripoint &loc2 ) +{ + const tripoint d = abs( loc1 - loc2 ); + return std::max( { d.x, d.y, d.z } ); +} +inline FastDistanceApproximation rl_dist_fast( const tripoint &loc1, const tripoint &loc2 ) +{ + if( trigdist ) { + return trig_dist_fast( loc1, loc2 ); + } + return square_dist_fast( loc1, loc2 ); +} +inline FastDistanceApproximation rl_dist_fast( const point &a, const point &b ) +{ + return rl_dist_fast( tripoint( a, 0 ), tripoint( b, 0 ) ); +} + float rl_dist_exact( const tripoint &loc1, const tripoint &loc2 ); // Sum of distance in both axes int manhattan_dist( const point &loc1, const point &loc2 ); diff --git a/src/monmove.cpp b/src/monmove.cpp index ea705372ec1d1..4319ce9e222cb 100644 --- a/src/monmove.cpp +++ b/src/monmove.cpp @@ -251,7 +251,7 @@ void monster::wander_to( const tripoint &p, int f ) float monster::rate_target( Creature &c, float best, bool smart ) const { - const int d = rl_dist( pos(), c.pos() ); + const auto d = rl_dist_fast( pos(), c.pos() ); if( d <= 0 ) { return INT_MAX; } @@ -266,7 +266,7 @@ float monster::rate_target( Creature &c, float best, bool smart ) const } if( !smart ) { - return d; + return int( d ); } float power = c.power_rating(); @@ -277,7 +277,7 @@ float monster::rate_target( Creature &c, float best, bool smart ) const } if( power > 0 ) { - return d / power; + return int( d ) / power; } return INT_MAX; From d23f10963c532a71641a1f817c133f567ce14c6c Mon Sep 17 00:00:00 2001 From: FeepingCreature Date: Thu, 21 Nov 2019 07:23:59 +0100 Subject: [PATCH 4/4] fix clang-tidy warning: remove redundant smartptr get() --- src/activity_handlers.cpp | 2 +- src/npcmove.cpp | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/activity_handlers.cpp b/src/activity_handlers.cpp index 4a12352ed6188..402ebffd6a85b 100644 --- a/src/activity_handlers.cpp +++ b/src/activity_handlers.cpp @@ -2965,7 +2965,7 @@ void activity_handlers::find_mount_do_turn( player_activity *act, player *p ) return; } } else { - const std::vector route = route_adjacent( *p, guy.chosen_mount.lock().get()->pos() ); + const std::vector route = route_adjacent( *p, guy.chosen_mount.lock()->pos() ); if( route.empty() ) { act->set_to_null(); guy.revert_after_activity(); diff --git a/src/npcmove.cpp b/src/npcmove.cpp index 969e986916a8a..d5b04503bdb63 100644 --- a/src/npcmove.cpp +++ b/src/npcmove.cpp @@ -475,7 +475,7 @@ void npc::assess_danger() // because the horse the NPC is riding is still in the ai_cache.friends vector, // so either one would count as a friendly for this purpose. if( guy.lock() ) { - is_too_close |= too_close( critter.pos(), guy.lock().get()->pos(), def_radius ); + is_too_close |= too_close( critter.pos(), guy.lock()->pos(), def_radius ); } return is_too_close; }; @@ -516,7 +516,7 @@ void npc::assess_danger() } bool is_too_close = dist <= def_radius; for( const weak_ptr_fast guy : ai_cache.friends ) { - is_too_close |= too_close( foe.pos(), guy.lock().get()->pos(), def_radius ); + is_too_close |= too_close( foe.pos(), guy.lock()->pos(), def_radius ); if( is_too_close ) { break; }