From b75c702dd302a297aaf4c1e6fd78ce138f8581ec Mon Sep 17 00:00:00 2001 From: ZhilkinSerg Date: Sat, 20 Apr 2019 16:52:59 +0300 Subject: [PATCH] Map cache invalidation --- src/activity_handlers.cpp | 2 ++ src/bionics.cpp | 2 ++ src/game.cpp | 62 ++++++++++++++++++++---------------- src/game.h | 4 +++ src/handle_action.cpp | 32 +++++++++---------- src/map.cpp | 5 +++ src/mapgen.cpp | 1 + src/mission_ui.cpp | 2 +- src/npctalk.cpp | 2 +- src/ranged.cpp | 1 + src/start_location.cpp | 1 + src/vehicle_use.cpp | 1 + tests/crafting_test.cpp | 1 + tests/map_helpers.cpp | 1 + tests/vehicle_drag.cpp | 1 + tests/vehicle_efficiency.cpp | 1 + tests/vehicle_power_test.cpp | 1 + tests/vision_test.cpp | 2 ++ 18 files changed, 76 insertions(+), 46 deletions(-) diff --git a/src/activity_handlers.cpp b/src/activity_handlers.cpp index f51c6a91d90d8..344ca0cf7a101 100644 --- a/src/activity_handlers.cpp +++ b/src/activity_handlers.cpp @@ -1954,6 +1954,7 @@ void activity_handlers::vehicle_finish( player_activity *act, player *p ) act->values.size() ); } else { if( vp ) { + g->invalidate_map_cache(); g->refresh_all(); // TODO: Z (and also where the activity is queued) // Or not, because the vehicle coordinates are dropped anyway @@ -2512,6 +2513,7 @@ void activity_handlers::meditate_finish( player_activity *act, player *p ) void activity_handlers::aim_do_turn( player_activity *act, player * ) { if( act->index == 0 ) { + g->invalidate_map_cache(); g->m.build_map_cache( g->get_levz() ); g->plfire(); } diff --git a/src/bionics.cpp b/src/bionics.cpp index 7128f3fbf5614..1a31ea21aad43 100644 --- a/src/bionics.cpp +++ b/src/bionics.cpp @@ -1039,6 +1039,7 @@ bool player::uninstall_bionic( const bionic_id &b_id, player &installer, bool au } bionics_uninstall_failure( installer, difficulty, success, adjusted_skill ); } + g->invalidate_map_cache(); g->refresh_all(); return true; } @@ -1133,6 +1134,7 @@ bool player::install_bionics( const itype &type, player &installer, bool autodoc } bionics_install_failure( installer, difficult, success, adjusted_skill ); } + g->invalidate_map_cache(); g->refresh_all(); return true; } diff --git a/src/game.cpp b/src/game.cpp index 229fecec9fea4..7be8913522765 100644 --- a/src/game.cpp +++ b/src/game.cpp @@ -524,7 +524,7 @@ void game::init_ui( const bool resized ) // Only refresh if we are in-game, otherwise all resources are not initialized // and this refresh will crash the game. if( resized && u.getID() != -1 ) { - refresh_all(); + g->refresh_all(); } } @@ -533,10 +533,10 @@ void game::toggle_fullscreen() #if !defined(TILES) fullscreen = !fullscreen; init_ui(); - refresh_all(); + g->refresh_all(); #else toggle_fullscreen_window(); - refresh_all(); + g->refresh_all(); #endif } @@ -548,7 +548,7 @@ void game::toggle_pixel_minimap() } pixel_minimap_option = !pixel_minimap_option; init_ui(); - refresh_all(); + g->refresh_all(); #endif // TILES } @@ -699,10 +699,12 @@ bool game::start_game() lev.y -= HALF_MAPSIZE; load_map( lev ); + g->invalidate_map_cache(); m.build_map_cache( get_levz() ); // Do this after the map cache has been built! start_loc.place_player( u ); // ...but then rebuild it, because we want visibility cache to avoid spawning monsters in sight + g->invalidate_map_cache(); m.build_map_cache( get_levz() ); // Start the overmap with out immediate neighborhood visible, this needs to be after place_player overmap_buffer.reveal( point( u.global_omt_location().x, u.global_omt_location().y ), @@ -1460,6 +1462,7 @@ bool game::do_turn() sounds::process_sounds(); // Update vision caches for monsters. If this turns out to be expensive, // consider a stripped down cache just for monsters. + g->invalidate_map_cache(); m.build_map_cache( get_levz(), true ); monmove(); if( calendar::once_every( 3_minutes ) ) { @@ -1922,13 +1925,12 @@ void game::handle_key_blocking_activity() cancel_activity_query( _( "Confirm:" ) ); } else if( action == "player_data" ) { u.disp_info(); - refresh_all(); } else if( action == "messages" ) { Messages::display_messages(); - refresh_all(); + g->refresh_all(); } else if( action == "help" ) { get_help().display_help(); - refresh_all(); + g->refresh_all(); } } } @@ -2923,7 +2925,7 @@ void game::debug() _( "Toggle NPC pathfinding on map" ), // 37 _( "Quit to Main Menu" ), // 38 } ); - refresh_all(); + g->refresh_all(); switch( action ) { case 0: debug_menu::wishitem( &u ); @@ -3354,7 +3356,8 @@ void game::debug() break; } catacurses::erase(); - refresh_all(); + g->invalidate_map_cache(); + g->refresh_all(); } void game::disp_kills() @@ -3411,7 +3414,7 @@ void game::disp_kills() } display_table( w, buffer.str(), 3, data ); - refresh_all(); + g->refresh_all(); } void game::disp_NPC_epilogues() @@ -3434,7 +3437,7 @@ void game::disp_NPC_epilogues() multipage( w, txt, "", 2 ); } - refresh_all(); + g->refresh_all(); } void game::disp_faction_ends() @@ -3533,7 +3536,7 @@ there was nothing left to fight for... just endless cities full of the dead." ) data.clear(); } - refresh_all(); + g->refresh_all(); } struct npc_dist_to_player { @@ -3596,6 +3599,7 @@ void game::draw() //temporary fix for updating visibility for minimap ter_view_z = ( u.pos() + u.view_offset ).z; + g->invalidate_map_cache(); m.build_map_cache( ter_view_z ); m.update_visibility_cache( ter_view_z ); @@ -5059,7 +5063,7 @@ void game::use_computer( const tripoint &p ) used->use(); - refresh_all(); + g->refresh_all(); } void game::resonance_cascade( const tripoint &p ) @@ -5695,7 +5699,7 @@ void game::use_item( int pos ) } } - refresh_all(); + g->refresh_all(); if( use_loc ) { update_lum( loc.clone(), false ); @@ -6214,7 +6218,7 @@ void game::peek() { const cata::optional p = choose_direction( _( "Peek where?" ), true ); if( !p ) { - refresh_all(); + g->refresh_all(); return; } @@ -7091,7 +7095,7 @@ void game::zones_manager() u.view_offset = stored_view_offset; pixel_minimap_option = stored_pm_opt; - refresh_all(); + g->refresh_all(); } void game::pre_print_all_tile_info( const tripoint &lp, const catacurses::window &w_info, @@ -7287,7 +7291,8 @@ look_around_result game::look_around( catacurses::window w_info, tripoint ¢e add_msg( m_debug, "levx: %d, levy: %d, levz :%d", get_levx(), get_levy(), center.z ); u.view_offset.z = center.z - u.posz(); - refresh_all(); + g->invalidate_map_cache(); + g->refresh_all(); if( select_zone && has_first_point ) { // is blinking blink = true; // Always draw blink symbols when moving cursor } @@ -7399,6 +7404,7 @@ look_around_result game::look_around( catacurses::window w_info, tripoint ¢e action != "throw_blind" ); if( m.has_zlevels() && center.z != old_levz ) { + g->invalidate_map_cache(); m.build_map_cache( old_levz ); u.view_offset.z = 0; } @@ -7643,7 +7649,7 @@ void game::reset_item_list_state( const catacurses::window &window, int height, xpos += shortcut_print( window, ypos, xpos, c_white, c_light_green, tokens[i] ) + gap_spaces; } - refresh_all(); + g->refresh_all(); } void game::list_items_monsters() @@ -7685,7 +7691,7 @@ void game::list_items_monsters() } } - refresh_all(); + g->refresh_all(); if( ret == game::vmenu_ret::FIRE ) { plfire( u.weapon ); } @@ -7773,7 +7779,7 @@ game::vmenu_ret game::list_items( const std::vector &item_list ) if( action == "COMPARE" ) { game_menus::inv::compare( u, active_pos ); reset = true; - refresh_all(); + g->refresh_all(); } else if( action == "FILTER" ) { draw_item_filter_rules( w_item_info, 0, iInfoHeight - 1, item_filter_type::FILTER ); string_input_popup() @@ -8543,7 +8549,7 @@ bool game::get_liquid_target( item &liquid, item *const source, const int radius const std::string liqstr = string_format( _( "Pour %s where?" ), liquid_name ); - refresh_all(); + g->refresh_all(); const cata::optional target_pos_ = choose_adjacent( liqstr ); if( !target_pos_ ) { return; @@ -8571,7 +8577,7 @@ bool game::get_liquid_target( item &liquid, item *const source, const int radius } menu.query(); - refresh_all(); + g->refresh_all(); if( menu.ret < 0 || static_cast( menu.ret ) >= actions.size() ) { add_msg( _( "Never mind." ) ); // Explicitly canceled all options (container, drink, pour). @@ -8707,7 +8713,7 @@ void game::drop() void game::drop_in_direction() { if( const cata::optional pnt = choose_adjacent( _( "Drop where?" ) ) ) { - refresh_all(); + g->refresh_all(); u.drop( game_menus::inv::multidrop( u ), *pnt ); } } @@ -8721,7 +8727,7 @@ void game::plthrow( int pos, const cata::optional &blind_throw_from_po if( pos == INT_MIN ) { pos = inv_for_all( _( "Throw item" ), _( "You don't have any items to throw." ) ); - refresh_all(); + g->refresh_all(); } if( pos == INT_MIN ) { @@ -8948,7 +8954,7 @@ bool game::plfire() args.ammo = gun->ammo_data(); u.set_targeting_data( args ); - refresh_all(); + g->refresh_all(); } } @@ -9615,7 +9621,7 @@ void game::reload( item_location &loc, bool prompt, bool empty ) u.activity.targets.push_back( std::move( opt.ammo ) ); } - refresh_all(); + g->refresh_all(); } @@ -11672,7 +11678,8 @@ void game::vertical_move( int movez, bool force ) } } - refresh_all(); + g->invalidate_map_cache(); + g->refresh_all(); // Upon force movement, traps can not be avoided. m.creature_on_trap( u, !force ); } @@ -11948,6 +11955,7 @@ point game::update_map( int &x, int &y ) load_npcs(); // Make sure map cache is consistent since it may have shifted. + g->invalidate_map_cache(); m.build_map_cache( get_levz() ); // Spawn monsters if appropriate diff --git a/src/game.h b/src/game.h index e8ce75e583b6e..5a026546dfc68 100644 --- a/src/game.h +++ b/src/game.h @@ -572,6 +572,10 @@ class game int assign_npc_id(); Creature *is_hostile_nearby(); Creature *is_hostile_very_close(); + bool is_map_cache_valid = false; + inline void invalidate_map_cache() { + g->is_map_cache_valid = false; + } void refresh_all(); // Handles shifting coordinates transparently when moving between submaps. // Helper to make calling with a player pointer less verbose. diff --git a/src/handle_action.cpp b/src/handle_action.cpp index ff39cda2ce718..d276dacda548e 100644 --- a/src/handle_action.cpp +++ b/src/handle_action.cpp @@ -1725,16 +1725,16 @@ bool game::handle_action() break; case ACTION_BIONICS: u.power_bionics(); - refresh_all(); + g->refresh_all(); break; case ACTION_MUTATIONS: u.power_mutations(); - refresh_all(); + g->refresh_all(); break; case ACTION_SORT_ARMOR: u.sort_armor(); - refresh_all(); + g->refresh_all(); break; case ACTION_WAIT: @@ -1770,6 +1770,7 @@ bool game::handle_action() add_msg( m_info, _( "You can't disassemble items while driving." ) ); } else { u.disassemble(); + g->invalidate_map_cache(); refresh_all(); } break; @@ -1861,7 +1862,7 @@ bool game::handle_action() uquit = QUIT_SUICIDE; } } - refresh_all(); + g->refresh_all(); break; case ACTION_SAVE: @@ -1871,7 +1872,7 @@ bool game::handle_action() uquit = QUIT_SAVED; } } - refresh_all(); + g->refresh_all(); break; case ACTION_QUICKSAVE: @@ -1884,7 +1885,6 @@ bool game::handle_action() case ACTION_PL_INFO: u.disp_info(); - refresh_all(); break; case ACTION_MAP: @@ -1911,53 +1911,52 @@ bool game::handle_action() case ACTION_FACTIONS: new_faction_manager_ptr->display(); - refresh_all(); break; case ACTION_MORALE: u.disp_morale(); - refresh_all(); + g->refresh_all(); break; case ACTION_MESSAGES: Messages::display_messages(); - refresh_all(); + g->refresh_all(); break; case ACTION_HELP: get_help().display_help(); - refresh_all(); + g->refresh_all(); break; case ACTION_KEYBINDINGS: ctxt.display_menu(); - refresh_all(); + g->refresh_all(); break; case ACTION_OPTIONS: get_options().show( true ); - refresh_all(); g->init_ui( true ); break; + case ACTION_AUTOPICKUP: get_auto_pickup().show(); - refresh_all(); + g->refresh_all(); break; case ACTION_SAFEMODE: get_safemode().show(); - refresh_all(); + g->refresh_all(); break; case ACTION_COLOR: all_colors.show_gui(); - refresh_all(); + g->refresh_all(); break; case ACTION_WORLD_MODS: world_generator->show_active_world_mods( world_generator->active_world->active_mod_order ); - refresh_all(); + g->refresh_all(); break; case ACTION_DEBUG: @@ -1965,7 +1964,6 @@ bool game::handle_action() break; //don't do anything when sharing and not debugger } debug(); - refresh_all(); break; case ACTION_TOGGLE_FULLSCREEN: diff --git a/src/map.cpp b/src/map.cpp index 5cbb0b61df852..3188dfa38d27f 100644 --- a/src/map.cpp +++ b/src/map.cpp @@ -7612,6 +7612,11 @@ void map::build_floor_caches() void map::build_map_cache( const int zlev, bool skip_lightmap ) { + if( g->is_map_cache_valid ) { + return; + } + g->is_map_cache_valid = true; + const int minz = zlevels ? -OVERMAP_DEPTH : zlev; const int maxz = zlevels ? OVERMAP_HEIGHT : zlev; for( int z = minz; z <= maxz; z++ ) { diff --git a/src/mapgen.cpp b/src/mapgen.cpp index 622f2b050d290..5ed0cf909a72b 100644 --- a/src/mapgen.cpp +++ b/src/mapgen.cpp @@ -8647,6 +8647,7 @@ bool update_mapgen_function_json::update_map( const tripoint &omt_pos, int offse update_map.save(); g->load_npcs(); + g->invalidate_map_cache(); g->refresh_all(); return true; } diff --git a/src/mission_ui.cpp b/src/mission_ui.cpp index 40d6d6a45ef02..fc16bab8ef8ad 100644 --- a/src/mission_ui.cpp +++ b/src/mission_ui.cpp @@ -192,5 +192,5 @@ void game::list_missions() } } - refresh_all(); + g->refresh_all(); } diff --git a/src/npctalk.cpp b/src/npctalk.cpp index ff135526c79dc..8ff69cecb6f2b 100644 --- a/src/npctalk.cpp +++ b/src/npctalk.cpp @@ -274,7 +274,7 @@ void game::chat() } u.moves -= 100; - refresh_all(); + g->refresh_all(); } void npc::handle_sound( int priority, const std::string &description, int heard_volume, diff --git a/src/ranged.cpp b/src/ranged.cpp index d6d51c0fef0aa..481e159f03a36 100644 --- a/src/ranged.cpp +++ b/src/ranged.cpp @@ -1401,6 +1401,7 @@ std::vector target_handler::target_ui( player &pc, target_mode mode, // We need to do a bunch of redrawing and cache updates since we're // looking at a different z-level. + g->invalidate_map_cache(); g->refresh_all(); } diff --git a/src/start_location.cpp b/src/start_location.cpp index 02477faae36fd..8dbdd6776fc6e 100644 --- a/src/start_location.cpp +++ b/src/start_location.cpp @@ -299,6 +299,7 @@ void start_location::place_player( player &u ) const u.setx( HALF_MAPSIZE_X ); u.sety( HALF_MAPSIZE_Y ); u.setz( g->get_levz() ); + g->invalidate_map_cache(); m.build_map_cache( m.get_abs_sub().z ); const bool must_be_inside = flags().count( "ALLOW_OUTSIDE" ) == 0; ///\EFFECT_STR allows player to start behind less-bashable furniture and terrain diff --git a/src/vehicle_use.cpp b/src/vehicle_use.cpp index 6f2769b927b34..edc609d554721 100644 --- a/src/vehicle_use.cpp +++ b/src/vehicle_use.cpp @@ -1355,6 +1355,7 @@ void vehicle::use_bike_rack( int part ) success = try_to_rack_nearby_vehicle( racks_parts ); } if( success ) { + g->invalidate_map_cache(); g->refresh_all(); } } diff --git a/tests/crafting_test.cpp b/tests/crafting_test.cpp index 97b5ff9d54395..c292fde7e99da 100644 --- a/tests/crafting_test.cpp +++ b/tests/crafting_test.cpp @@ -397,6 +397,7 @@ static void set_time( int time ) g->reset_light_level(); int z = g->u.posz(); g->m.update_visibility_cache( z ); + g->invalidate_map_cache(); g->m.build_map_cache( z ); } diff --git a/tests/map_helpers.cpp b/tests/map_helpers.cpp index 2d4c9ebed3fc8..f8d0b0ef6320e 100644 --- a/tests/map_helpers.cpp +++ b/tests/map_helpers.cpp @@ -18,6 +18,7 @@ void wipe_map_terrain() for( wrapped_vehicle &veh : g->m.get_vehicles() ) { g->m.destroy_vehicle( veh.v ); } + g->invalidate_map_cache(); g->m.build_map_cache( 0, true ); } diff --git a/tests/vehicle_drag.cpp b/tests/vehicle_drag.cpp index e82fa51dce318..55dceda4d9cb8 100644 --- a/tests/vehicle_drag.cpp +++ b/tests/vehicle_drag.cpp @@ -48,6 +48,7 @@ void clear_game_drag( const ter_id &terrain ) g->m.destroy_vehicle( veh.v ); } + g->invalidate_map_cache(); g->m.build_map_cache( 0, true ); // hard force a rebuild of caches g->m.shift( 0, 1 ); diff --git a/tests/vehicle_efficiency.cpp b/tests/vehicle_efficiency.cpp index c7a092047341e..a2fc2972f4da6 100644 --- a/tests/vehicle_efficiency.cpp +++ b/tests/vehicle_efficiency.cpp @@ -45,6 +45,7 @@ void clear_game( const ter_id &terrain ) g->m.destroy_vehicle( veh.v ); } + g->invalidate_map_cache(); g->m.build_map_cache( 0, true ); } diff --git a/tests/vehicle_power_test.cpp b/tests/vehicle_power_test.cpp index 761e168fcc7a9..f9b682fab3253 100644 --- a/tests/vehicle_power_test.cpp +++ b/tests/vehicle_power_test.cpp @@ -23,6 +23,7 @@ TEST_CASE( "vehicle_power" ) g->m.i_clear( p ); } + g->invalidate_map_cache(); g->m.build_map_cache( 0, true ); const tripoint test_origin( 15, 15, 0 ); diff --git a/tests/vision_test.cpp b/tests/vision_test.cpp index 06141819c441b..95d96f6fba3b2 100644 --- a/tests/vision_test.cpp +++ b/tests/vision_test.cpp @@ -108,8 +108,10 @@ void full_map_test( const std::vector &setup, // they might, for example, have poor nightvision due to having just been // in daylight) g->m.update_visibility_cache( origin.z ); + g->invalidate_map_cache(); g->m.build_map_cache( origin.z ); g->m.update_visibility_cache( origin.z ); + g->invalidate_map_cache(); g->m.build_map_cache( origin.z ); const level_cache &cache = g->m.access_cache( origin.z );