widelands-dev team mailing list archive
-
widelands-dev team
-
Mailing list archive
-
Message #10829
[Merge] lp:~widelands-dev/widelands/kill_edge_overlay into lp:widelands
SirVer has proposed merging lp:~widelands-dev/widelands/kill_edge_overlay into lp:widelands.
Commit message:
Remove the ill named EdgeOverlayManager.
It only dealt with road previews while in road building mode. This data is now
passed into the GameRenderer directly instead of being side loaded through
egbase.iabase.
- Replace Coords::ordering_functor through operator<.
- Fixed some warnings in ai headers that were disturbing while working.
Requested reviews:
Widelands Developers (widelands-dev)
For more details, see:
https://code.launchpad.net/~widelands-dev/widelands/kill_edge_overlay/+merge/328947
--
Your team Widelands Developers is requested to review the proposed merge of lp:~widelands-dev/widelands/kill_edge_overlay into lp:widelands.
=== modified file 'src/ai/ai_help_structs.h'
--- src/ai/ai_help_structs.h 2017-07-30 15:35:36 +0000
+++ src/ai/ai_help_structs.h 2017-08-12 06:54:09 +0000
@@ -609,7 +609,7 @@
uint32_t get_int();
uint16_t get_id() {
return id;
- };
+ }
private:
std::bitset<kFNeuronBitSize> core;
@@ -622,7 +622,7 @@
void set_expantion_type(ExpansionMode);
ExpansionMode get_expansion_type() {
return type;
- };
+ }
private:
ExpansionMode type;
@@ -654,14 +654,14 @@
uint16_t new_neuron_id() {
++next_neuron_id;
return next_neuron_id - 1;
- };
+ }
void reset_neuron_id() {
next_neuron_id = 0;
}
uint16_t new_bi_neuron_id() {
++next_bi_neuron_id;
return next_bi_neuron_id - 1;
- };
+ }
void reset_bi_neuron_id() {
next_bi_neuron_id = 0;
}
=== modified file 'src/graphic/CMakeLists.txt'
--- src/graphic/CMakeLists.txt 2017-05-21 18:17:14 +0000
+++ src/graphic/CMakeLists.txt 2017-08-12 06:54:09 +0000
@@ -183,7 +183,6 @@
graphic_terrain_programs
logic
wui
- wui_edge_overlay_manager
wui_field_overlay_manager
wui_mapview_pixelfunctions
)
=== modified file 'src/graphic/game_renderer.cc'
--- src/graphic/game_renderer.cc 2017-06-08 16:11:05 +0000
+++ src/graphic/game_renderer.cc 2017-08-12 06:54:09 +0000
@@ -29,7 +29,6 @@
#include "logic/editor_game_base.h"
#include "logic/map_objects/world/world.h"
#include "logic/player.h"
-#include "wui/edge_overlay_manager.h"
#include "wui/field_overlay_manager.h"
#include "wui/interactive_base.h"
#include "wui/mapviewpixelconstants.h"
@@ -100,12 +99,12 @@
void draw_objects_for_visible_field(const EditorGameBase& egbase,
const FieldsToDraw::Field& field,
const float zoom,
- const TextToDraw draw_text,
+ const TextToDraw text_to_draw,
const Player* player,
RenderTarget* dst) {
BaseImmovable* const imm = field.fcoords.field->get_immovable();
if (imm != nullptr && imm->get_positions(egbase).front() == field.fcoords) {
- TextToDraw draw_text_for_this_immovable = draw_text;
+ TextToDraw draw_text_for_this_immovable = text_to_draw;
const Player* owner = imm->get_owner();
if (player != nullptr && owner != nullptr && !player->see_all() &&
player->is_hostile(*owner)) {
@@ -117,7 +116,7 @@
egbase.get_gametime(), draw_text_for_this_immovable, field.rendertarget_pixel, zoom, dst);
}
for (Bob* bob = field.fcoords.field->get_first_bob(); bob; bob = bob->get_next_bob()) {
- TextToDraw draw_text_for_this_bob = draw_text;
+ TextToDraw draw_text_for_this_bob = text_to_draw;
const Player* owner = bob->get_owner();
if (player != nullptr && owner != nullptr && !player->see_all() &&
player->is_hostile(*owner)) {
@@ -209,7 +208,7 @@
const float zoom,
const FieldsToDraw& fields_to_draw,
const Player* player,
- const TextToDraw draw_text,
+ const TextToDraw text_to_draw,
RenderTarget* dst) {
std::vector<FieldOverlayManager::OverlayInfo> overlay_info;
for (size_t current_index = 0; current_index < fields_to_draw.size(); ++current_index) {
@@ -239,7 +238,7 @@
}
if (1 < field.vision) { // Render stuff that belongs to the node.
- draw_objects_for_visible_field(egbase, field, zoom, draw_text, player, dst);
+ draw_objects_for_visible_field(egbase, field, zoom, text_to_draw, player, dst);
} else if (field.vision == 1) {
// We never show census or statistics for objects in the fog.
assert(player != nullptr);
@@ -313,23 +312,23 @@
const Vector2f& viewpoint,
const float zoom,
const Widelands::Player& player,
- const TextToDraw draw_text,
+ const Overlays& overlays,
RenderTarget* dst) {
- draw(egbase, viewpoint, zoom, draw_text, &player, dst);
+ draw(egbase, viewpoint, zoom, overlays, &player, dst);
}
void GameRenderer::rendermap(const Widelands::EditorGameBase& egbase,
const Vector2f& viewpoint,
const float zoom,
- const TextToDraw draw_text,
+ const Overlays& overlays,
RenderTarget* dst) {
- draw(egbase, viewpoint, zoom, draw_text, nullptr, dst);
+ draw(egbase, viewpoint, zoom, overlays, nullptr, dst);
}
void GameRenderer::draw(const EditorGameBase& egbase,
const Vector2f& viewpoint,
const float zoom,
- const TextToDraw draw_text,
+ const Overlays& overlays,
const Player* player,
RenderTarget* dst) {
assert(viewpoint.x >= 0); // divisions involving negative numbers are bad
@@ -367,7 +366,6 @@
const int surface_height = surface->height();
Map& map = egbase.map();
- const EdgeOverlayManager& edge_overlay_manager = egbase.get_ibase()->edge_overlay_manager();
const uint32_t gametime = egbase.get_gametime();
const float scale = 1.f / zoom;
@@ -423,7 +421,11 @@
f.is_border = pf.border;
}
}
- f.roads |= edge_overlay_manager.get_overlay(f.fcoords);
+
+ const auto it = overlays.road_building_preview.find(f.fcoords);
+ if (it != overlays.road_building_preview.end()) {
+ f.roads |= it->second;
+ }
}
}
@@ -451,5 +453,5 @@
i.program_id = RenderQueue::Program::kTerrainRoad;
RenderQueue::instance().enqueue(i);
- draw_objects(egbase, scale, fields_to_draw_, player, draw_text, dst);
+ draw_objects(egbase, scale, fields_to_draw_, player, overlays.text_to_draw, dst);
}
=== modified file 'src/graphic/game_renderer.h'
--- src/graphic/game_renderer.h 2017-01-25 18:55:59 +0000
+++ src/graphic/game_renderer.h 2017-08-12 06:54:09 +0000
@@ -21,6 +21,7 @@
#define WL_GRAPHIC_GAME_RENDERER_H
#include <memory>
+#include <map>
#include "base/macros.h"
#include "base/vector.h"
@@ -37,6 +38,11 @@
// Renders the MapView on screen.
class GameRenderer {
public:
+ struct Overlays {
+ TextToDraw text_to_draw;
+ std::map<Widelands::Coords, uint8_t> road_building_preview;
+ };
+
GameRenderer();
~GameRenderer();
@@ -47,7 +53,7 @@
const Vector2f& viewpoint,
float scale,
const Widelands::Player& player,
- TextToDraw draw_text,
+ const Overlays& overlays,
RenderTarget* dst);
// Renders the map from an omniscient perspective. This is used
@@ -55,7 +61,7 @@
void rendermap(const Widelands::EditorGameBase& egbase,
const Vector2f& viewpoint,
float scale,
- TextToDraw draw_text,
+ const Overlays& overlays,
RenderTarget* dst);
private:
@@ -64,7 +70,7 @@
void draw(const Widelands::EditorGameBase& egbase,
const Vector2f& viewpoint,
float scale,
- TextToDraw draw_text,
+ const Overlays& overlays,
const Widelands::Player* player,
RenderTarget* dst);
=== modified file 'src/logic/map.cc'
--- src/logic/map.cc 2017-01-30 14:40:12 +0000
+++ src/logic/map.cc 2017-08-12 06:54:09 +0000
@@ -1967,11 +1967,11 @@
bool Map::allows_seafaring() {
Map::PortSpacesSet port_spaces = get_port_spaces();
std::vector<Coords> portdocks;
- std::set<Coords, Coords::OrderingFunctor> swim_coords;
+ std::set<Coords> swim_coords;
for (const Coords& c : port_spaces) {
std::queue<Coords> q_positions;
- std::set<Coords, Coords::OrderingFunctor> visited_positions;
+ std::set<Coords> visited_positions;
FCoords fc = get_fcoords(c);
portdocks = find_portdock(fc);
=== modified file 'src/logic/map.h'
--- src/logic/map.h 2017-01-25 18:55:59 +0000
+++ src/logic/map.h 2017-08-12 06:54:09 +0000
@@ -146,7 +146,7 @@
friend struct MapElementalPacket;
friend struct WidelandsMapLoader;
- using PortSpacesSet = std::set<Coords, Coords::OrderingFunctor>;
+ using PortSpacesSet = std::set<Coords>;
using Objectives = std::map<std::string, std::unique_ptr<Objective>>;
using SuggestedTeam = std::vector<PlayerNumber>; // Players in a team
using SuggestedTeamLineup =
=== modified file 'src/logic/map_objects/checkstep.h'
--- src/logic/map_objects/checkstep.h 2017-01-25 18:55:59 +0000
+++ src/logic/map_objects/checkstep.h 2017-08-12 06:54:09 +0000
@@ -183,11 +183,10 @@
bool reachable_dest(Map&, FCoords dest) const;
private:
- // It is OK to use Coords::OrderingFunctor because the ordering of the set
- // does not matter, as long as it is system independent (for parallel
- // simulation).
+ // The ordering of the set does not matter, as long as it is system
+ // independent (for parallel simulation).
// The only thing that matters is whether a location is in the set.
- std::set<Coords, Coords::OrderingFunctor> allowed_locations_;
+ std::set<Coords> allowed_locations_;
};
}
=== modified file 'src/logic/widelands_geometry.h'
--- src/logic/widelands_geometry.h 2017-01-25 18:55:59 +0000
+++ src/logic/widelands_geometry.h 2017-08-12 06:54:09 +0000
@@ -54,15 +54,12 @@
bool operator==(const Coords& other) const;
bool operator!=(const Coords& other) const;
+ bool operator<(const Coords& other) const {
+ return std::forward_as_tuple(y, x) < std::forward_as_tuple(other.y, other.x);
+ }
+
operator bool() const;
- // Ordering functor for use with std:: containers.
- struct OrderingFunctor {
- bool operator()(const Coords& a, const Coords& b) const {
- return std::forward_as_tuple(a.y, a.x) < std::forward_as_tuple(b.y, b.x);
- }
- };
-
// Move the coords to the 'new_origin'.
void reorigin(Coords new_origin, const Extent& extent);
=== modified file 'src/wui/CMakeLists.txt'
--- src/wui/CMakeLists.txt 2017-05-14 14:40:24 +0000
+++ src/wui/CMakeLists.txt 2017-08-12 06:54:09 +0000
@@ -49,15 +49,6 @@
)
-wl_library(wui_edge_overlay_manager
- SRCS
- edge_overlay_manager.cc
- edge_overlay_manager.h
- DEPENDS
- base_macros
- logic_widelands_geometry
-)
-
wl_library(wui_mapview_pixelfunctions
SRCS
mapviewpixelconstants.h
@@ -273,7 +264,6 @@
ui_basic
wui_chat_ui
wui_economy_options
- wui_edge_overlay_manager
wui_field_overlay_manager
wui_mapview
wui_mapview_pixelfunctions
=== removed file 'src/wui/edge_overlay_manager.cc'
--- src/wui/edge_overlay_manager.cc 2017-01-25 18:55:59 +0000
+++ src/wui/edge_overlay_manager.cc 1970-01-01 00:00:00 +0000
@@ -1,62 +0,0 @@
-/*
- * Copyright (C) 2006-2017 by the Widelands Development Team
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- *
- */
-
-#include "wui/edge_overlay_manager.h"
-
-EdgeOverlayManager::EdgeOverlayManager() : current_overlay_id_(0) {
-}
-
-EdgeOverlayManager::OverlayId EdgeOverlayManager::next_overlay_id() {
- ++current_overlay_id_;
- return current_overlay_id_;
-}
-
-void EdgeOverlayManager::register_overlay(Widelands::Coords const c,
- uint8_t const where,
- OverlayId const overlay_id) {
- const RegisteredRoadOverlays overlay = {overlay_id, where};
- RegisteredRoadOverlaysMap::iterator it = overlays_.find(c);
- if (it == overlays_.end())
- overlays_.insert(std::pair<const Widelands::Coords, RegisteredRoadOverlays>(c, overlay));
- else
- it->second = overlay;
-}
-
-void EdgeOverlayManager::remove_overlay(const Widelands::Coords c) {
- const RegisteredRoadOverlaysMap::iterator it = overlays_.find(c);
- if (it != overlays_.end())
- overlays_.erase(it);
-}
-
-void EdgeOverlayManager::remove_overlay(OverlayId const overlay_id) {
- RegisteredRoadOverlaysMap::iterator it = overlays_.begin();
- const RegisteredRoadOverlaysMap::const_iterator end = overlays_.end();
- while (it != end)
- if (it->second.overlay_id == overlay_id)
- overlays_.erase(it++); // Necessary!
- else
- ++it;
-}
-
-uint8_t EdgeOverlayManager::get_overlay(const Widelands::Coords c) const {
- RegisteredRoadOverlaysMap::const_iterator const it = overlays_.find(c);
- if (it != overlays_.end())
- return it->second.where;
- return 0;
-}
=== removed file 'src/wui/edge_overlay_manager.h'
--- src/wui/edge_overlay_manager.h 2017-01-25 18:55:59 +0000
+++ src/wui/edge_overlay_manager.h 1970-01-01 00:00:00 +0000
@@ -1,62 +0,0 @@
-/*
- * Copyright (C) 2006-2017 by the Widelands Development Team
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- *
- */
-
-#ifndef WL_WUI_EDGE_OVERLAY_MANAGER_H
-#define WL_WUI_EDGE_OVERLAY_MANAGER_H
-
-#include <map>
-
-#include "base/macros.h"
-#include "logic/widelands_geometry.h"
-
-// Similar to FieldOverlayManager, this class cares for overlays that are drawn
-// onto the edges of triangles.
-class EdgeOverlayManager {
-public:
- // A unique id identifying a registered overlay.
- using OverlayId = uint32_t;
-
- EdgeOverlayManager();
-
- /// Get a unique, unused job id.
- OverlayId next_overlay_id();
-
- // When a road overlay information is requested the same data as for a
- // field is returned (a uint8_t which needs to be ANDed).
- void register_overlay(Widelands::Coords, uint8_t where, OverlayId overlay_id = 0);
- void remove_overlay(Widelands::Coords);
- void remove_overlay(OverlayId overlay_id);
- uint8_t get_overlay(Widelands::Coords c) const;
-
-private:
- struct RegisteredRoadOverlays {
- OverlayId overlay_id;
- uint8_t where;
- };
-
- using RegisteredRoadOverlaysMap =
- std::map<const Widelands::Coords, RegisteredRoadOverlays, Widelands::Coords::OrderingFunctor>;
-
- OverlayId current_overlay_id_;
- RegisteredRoadOverlaysMap overlays_;
-
- DISALLOW_COPY_AND_ASSIGN(EdgeOverlayManager);
-};
-
-#endif // end of include guard: WL_WUI_EDGE_OVERLAY_MANAGER_H
=== modified file 'src/wui/field_overlay_manager.h'
--- src/wui/field_overlay_manager.h 2017-05-13 11:25:24 +0000
+++ src/wui/field_overlay_manager.h 2017-08-12 06:54:09 +0000
@@ -122,9 +122,7 @@
int level;
};
- using RegisteredOverlaysMap = std::multimap<const Widelands::Coords,
- RegisteredOverlays,
- Widelands::Coords::OrderingFunctor>;
+ using RegisteredOverlaysMap = std::multimap<const Widelands::Coords, RegisteredOverlays>;
// Returns the index into buildhelp_infos_ for the correct fieldcaps for
// 'fc' according to the current 'callback_'.
=== modified file 'src/wui/interactive_base.cc'
--- src/wui/interactive_base.cc 2017-07-24 20:35:46 +0000
+++ src/wui/interactive_base.cc 2017-08-12 06:54:09 +0000
@@ -45,7 +45,6 @@
#include "logic/player.h"
#include "profile/profile.h"
#include "scripting/lua_interface.h"
-#include "wui/edge_overlay_manager.h"
#include "wui/field_overlay_manager.h"
#include "wui/game_chat_menu.h"
#include "wui/game_debug_ui.h"
@@ -85,7 +84,6 @@
toolbar_(this, 0, 0, UI::Box::Horizontal),
m(new InteractiveBaseInternals(new QuickNavigation(this))),
field_overlay_manager_(new FieldOverlayManager()),
- edge_overlay_manager_(new EdgeOverlayManager()),
egbase_(the_egbase),
#ifndef NDEBUG // not in releases
display_flags_(dfDebug),
@@ -95,7 +93,6 @@
lastframe_(SDL_GetTicks()),
frametime_(0),
avg_usframetime_(0),
- jobid_(0),
road_buildhelp_overlay_jobid_(0),
buildroad_(nullptr),
road_build_player_(0),
@@ -680,12 +677,11 @@
*/
void InteractiveBase::roadb_add_overlay() {
assert(buildroad_);
+ assert(road_building_preview_.empty());
Map& map = egbase().map();
// preview of the road
- assert(!jobid_);
- jobid_ = field_overlay_manager_->next_overlay_id();
const CoordPath::StepVector::size_type nr_steps = buildroad_->get_nsteps();
for (CoordPath::StepVector::size_type idx = 0; idx < nr_steps; ++idx) {
Widelands::Direction dir = (*buildroad_)[idx];
@@ -695,12 +691,8 @@
map.get_neighbour(c, dir, &c);
dir = Widelands::get_reverse_dir(dir);
}
-
int32_t const shift = 2 * (dir - Widelands::WALK_E);
-
- uint8_t set_to = edge_overlay_manager_->get_overlay(c);
- set_to |= Widelands::RoadType::kNormal << shift;
- edge_overlay_manager_->register_overlay(c, set_to, jobid_);
+ road_building_preview_[c] |= (Widelands::RoadType::kNormal << shift);
}
// build hints
@@ -762,11 +754,7 @@
void InteractiveBase::roadb_remove_overlay() {
assert(buildroad_);
- // preview of the road
- if (jobid_) {
- edge_overlay_manager_->remove_overlay(jobid_);
- }
- jobid_ = 0;
+ road_building_preview_.clear();
// build hints
if (road_buildhelp_overlay_jobid_) {
=== modified file 'src/wui/interactive_base.h'
--- src/wui/interactive_base.h 2017-06-27 18:10:20 +0000
+++ src/wui/interactive_base.h 2017-08-12 06:54:09 +0000
@@ -20,6 +20,7 @@
#ifndef WL_WUI_INTERACTIVE_BASE_H
#define WL_WUI_INTERACTIVE_BASE_H
+#include <map>
#include <memory>
#include <SDL_keycode.h>
@@ -36,7 +37,6 @@
#include "ui_basic/unique_window.h"
#include "wui/chatoverlay.h"
#include "wui/debugconsole.h"
-#include "wui/edge_overlay_manager.h"
#include "wui/field_overlay_manager.h"
#include "wui/mapview.h"
#include "wui/minimap.h"
@@ -158,10 +158,6 @@
return field_overlay_manager_.get();
}
- const EdgeOverlayManager& edge_overlay_manager() const {
- return *edge_overlay_manager_;
- }
-
void toggle_minimap();
void toggle_buildhelp();
@@ -171,6 +167,10 @@
// Sets the landmark for the keyboard 'key' to 'point'
void set_landmark(size_t key, const MapView::View& view);
+ const std::map<Widelands::Coords, uint8_t>& road_building_preview() const {
+ return road_building_preview_;
+ }
+
protected:
/// Adds a toolbar button to the toolbar
/// \param image_basename: File path for button image starting from 'images' and without
@@ -242,7 +242,11 @@
std::unique_ptr<InteractiveBaseInternals> m;
std::unique_ptr<FieldOverlayManager> field_overlay_manager_;
- std::unique_ptr<EdgeOverlayManager> edge_overlay_manager_;
+
+ // The roads that are displayed while a road is being build. They are not
+ // yet logically in the game, but need to be displayed for the user as
+ // visual guide. The data type is the same as for Field::road.
+ std::map<Widelands::Coords, uint8_t> road_building_preview_;
std::unique_ptr<Notifications::Subscriber<GraphicResolutionChanged>>
graphic_resolution_changed_subscriber_;
@@ -253,7 +257,6 @@
uint32_t frametime_; // in millseconds
uint32_t avg_usframetime_; // in microseconds!
- EdgeOverlayManager::OverlayId jobid_;
FieldOverlayManager::OverlayId road_buildhelp_overlay_jobid_;
Widelands::CoordPath* buildroad_; // path for the new road
Widelands::PlayerNumber road_build_player_;
=== modified file 'src/wui/interactive_gamebase.h'
--- src/wui/interactive_gamebase.h 2017-02-28 16:00:20 +0000
+++ src/wui/interactive_gamebase.h 2017-08-12 06:54:09 +0000
@@ -54,6 +54,7 @@
Section& global_s,
PlayerType pt = NONE,
bool multiplayer = false);
+ ~InteractiveGameBase() override {}
Widelands::Game* get_game() const;
Widelands::Game& game() const;
=== modified file 'src/wui/mapview.cc'
--- src/wui/mapview.cc 2017-05-13 18:48:26 +0000
+++ src/wui/mapview.cc 2017-08-12 06:54:09 +0000
@@ -392,21 +392,23 @@
return;
}
- TextToDraw draw_text = TextToDraw::kNone;
+ TextToDraw text_to_draw = TextToDraw::kNone;
auto display_flags = intbase().get_display_flags();
if (display_flags & InteractiveBase::dfShowCensus) {
- draw_text = draw_text | TextToDraw::kCensus;
+ text_to_draw = text_to_draw | TextToDraw::kCensus;
}
if (display_flags & InteractiveBase::dfShowStatistics) {
- draw_text = draw_text | TextToDraw::kStatistics;
+ text_to_draw = text_to_draw | TextToDraw::kStatistics;
}
if (upcast(InteractivePlayer const, interactive_player, &intbase())) {
+ const GameRenderer::Overlays overlays{text_to_draw, interactive_player->road_building_preview()};
renderer_->rendermap(
- egbase, view_.viewpoint, view_.zoom, interactive_player->player(), draw_text, &dst);
+ egbase, view_.viewpoint, view_.zoom, interactive_player->player(), overlays, &dst);
} else {
+ const GameRenderer::Overlays overlays{static_cast<TextToDraw>(text_to_draw), {}};
renderer_->rendermap(
- egbase, view_.viewpoint, view_.zoom, static_cast<TextToDraw>(draw_text), &dst);
+ egbase, view_.viewpoint, view_.zoom, overlays, &dst);
}
}
Follow ups