Did you update FleetWnd.cpp properly? There's no "m_system_changed_connection" in the file I linked just above, though several were removed from previous versions. Maybe refresh your browser, in case it's caching the old version?
Anyway, here's the diff:
Code:
Index: FleetWnd.h
===================================================================
--- FleetWnd.h (revision 2027)
+++ FleetWnd.h (working copy)
@@ -14,11 +14,7 @@
class Ship;
class System;
class UniverseObject;
-namespace GG {
- class TextControl;
-}
-
class FleetDetailWnd : public CUIWnd
{
public:
@@ -45,6 +41,8 @@
private:
std::string TitleText() const;
+ boost::signals::connection m_panel_empty_connection;
+
FleetDetailPanel* m_fleet_panel;
};
@@ -114,16 +112,15 @@
int m_current_fleet;
std::map<Fleet*, FleetDetailWnd*> m_open_fleet_detail_wnds;
- std::map<FleetDetailWnd*, boost::signals::connection> m_open_fleet_detail_wnd_connections;
+ std::multimap<FleetDetailWnd*, boost::signals::connection> m_open_fleet_detail_wnd_connections;
+ std::set<boost::signals::connection> m_misc_connections;
+
FleetsListBox* m_fleets_lb;
FleetDataPanel* m_new_fleet_drop_target;
FleetDetailPanel* m_fleet_detail_panel;
- boost::signals::connection m_lb_delete_connection;
- boost::signals::connection m_system_changed_connection;
- std::vector<boost::signals::connection> m_misc_connections;
-
+
static GG::Pt s_last_position; ///< the latest position to which any FleetWnd has been moved. This is used to keep the place of the fleet window in single-fleetwindow mode.
};
Index: FleetWnd.cpp
===================================================================
--- FleetWnd.cpp (revision 2027)
+++ FleetWnd.cpp (working copy)
@@ -38,7 +38,8 @@
};
FleetDataPanel(int w, int h, const Fleet* fleet, int empire = -1, int system_id = -1, double x = 0.0, double y = 0.0);
-
+ ~FleetDataPanel();
+
bool Selected() const;
virtual void Render();
@@ -58,6 +59,9 @@
const int m_system_id;
const double m_x;
const double m_y;
+
+ boost::signals::connection m_fleet_connection;
+
GG::StaticGraphic* m_fleet_icon;
GG::TextControl* m_fleet_name_text;
StatisticIcon* m_num_ships_stat;
@@ -105,11 +109,18 @@
m_ship_strength_stat = new StatisticIcon(h, SHIP_NAME_HT, STAT_ICON_WD, h - SHIP_NAME_HT - 1, (ClientUI::ArtDir() / "icons" / "combatstrength.png").native_file_string(),
ClientUI::TextColor(), 0, 0, true, false);
AttachChild(m_ship_strength_stat);
- GG::Connect(m_ship->StateChangedSignal, &ShipDataPanel::Refresh, this);
+ Logger().errorStream() << "ShipDataPanel::ShipDataPanel() connection ship " << m_ship->ID() << " StateChangedSignal to this->Refresh(). this: " << this;
+ m_ship_connection = GG::Connect(m_ship->StateChangedSignal, &ShipDataPanel::Refresh, this);
Refresh();
}
+ ~ShipDataPanel()
+ {
+ Logger().errorStream() << "ShipDataPanel::~ShipDataPanel() DISconnection ship " << m_ship->ID() << " StateChangedSignal. this: " << this;
+ m_ship_connection.disconnect();
+ }
+
virtual void Render()
{
const GG::Clr& unselected_color = GG::CLR_GRAY;
@@ -160,8 +171,7 @@
design_name = "Scout";
}
m_ship_icon = new GG::StaticGraphic(ICON_OFFSET, ICON_OFFSET, SHIP_ICON_SZ, SHIP_ICON_SZ,
- ClientUI::GetTexture(ClientUI::ArtDir() / "icons" / (design_name + ".png")),
- GG::GR_FITGRAPHIC);
+ /*ClientUI::ShipIcon(design_name)*/ ClientUI::GetTexture(ClientUI::ArtDir() / "icons" / (design_name + ".png")), GG::GR_FITGRAPHIC);
AttachChild(m_ship_icon);
}
@@ -207,6 +217,7 @@
StatisticIcon* m_damage_stat;
GG::StaticGraphic* m_colonizer_icon;
bool m_selected;
+ boost::signals::connection m_ship_connection;
};
struct FleetRow : public GG::ListBox::Row
@@ -308,11 +319,16 @@
ClientUI::TextColor(), 0, 0, true, false);
AttachChild(m_num_ships_stat);
AttachChild(m_fleet_strength_stat);
- GG::Connect(m_fleet->StateChangedSignal, &FleetDataPanel::Refresh, this);
+ m_fleet_connection = GG::Connect(m_fleet->StateChangedSignal, &FleetDataPanel::Refresh, this);
}
Refresh();
}
+
+FleetDataPanel::~FleetDataPanel()
+{
+ m_fleet_connection.disconnect();
+}
bool FleetDataPanel::Selected() const
{
@@ -371,6 +387,7 @@
}
}
if (wnds.front()->DragDropDataType() == SHIP_DROP_TYPE_STRING) {
+ Logger().errorStream() << "FleetDataPanel::AcceptDrops. Signaling NewFleetFromShipsSignal(" << ships[0]->Name() << ", ...)";
NewFleetFromShipsSignal(ships[0], ship_ids);
}
wnds.clear();
@@ -423,7 +440,7 @@
} else {
design_name = "Scout";
}
- icon = ClientUI::GetTexture(ClientUI::ArtDir() / "icons" / (design_name + ".png"));
+ icon = ClientUI::ShipIcon(design_name);
}
} else { // the "new fleet" data panel
icon = ClientUI::GetTexture(ClientUI::ArtDir() / "icons" / "newfleet.png");
@@ -495,6 +512,7 @@
{
public:
FleetDetailPanel(Fleet* fleet, bool read_only, Uint32 flags = 0); ///< ctor
+ ~FleetDetailPanel();
Fleet* GetFleet() const {return m_fleet;} ///< returns the currently-displayed fleet (may be 0)
@@ -516,6 +534,8 @@
Fleet* m_fleet;
const bool m_read_only;
boost::signals::connection m_fleet_connection;
+ std::set<boost::signals::connection>
+ m_misc_connections;
GG::TextControl* m_destination_text;
ShipsListBox* m_ships_lb;
@@ -717,6 +737,11 @@
m_ships_lb(0),
m_ship_status_text(0)
{
+ if (fleet)
+ Logger().errorStream() << "FleetDetailPanel::FleetDetailPanel(...) fleet: " << fleet->ID() << " this: " << this;
+ else
+ Logger().errorStream() << "FleetDetailPanel::FleetDetailPanel(...) fleet: (null) this: " << this;
+
SetText("FleetDetailPanel");
EnableChildClipping(true);
@@ -735,12 +760,25 @@
m_destination_text->SetMinSize(false);
m_ship_status_text->SetMinSize(false);
- SetFleet(fleet);
+ if (fleet) SetFleet(fleet);
Init();
- GG::Connect(GetUniverse().UniverseObjectDeleteSignal, &FleetDetailPanel::UniverseObjectDeleted, this);
+ m_misc_connections.insert(GG::Connect(GetUniverse().UniverseObjectDeleteSignal, &FleetDetailPanel::UniverseObjectDeleted, this));
+ Logger().errorStream() << "FleetDetailPanel::FleetDetailPanel(...) done";
}
+FleetDetailPanel::~FleetDetailPanel()
+{
+ if (m_fleet) {
+ Logger().errorStream() << "FleetDetailPanel::~FleetDetailPanel() DISconnecting StateChangedSignal() for fleet " << m_fleet->ID() << " to FleetDetailPanel::Refresh : " << this;
+ m_fleet_connection.disconnect();
+ }
+ while (!m_misc_connections.empty()) {
+ m_misc_connections.begin()->disconnect();
+ m_misc_connections.erase(m_misc_connections.begin());
+ }
+}
+
int FleetDetailPanel::GetShipIDOfListRow(int row_idx) const
{
return dynamic_cast<ShipRow&>(m_ships_lb->GetRow(row_idx)).ShipID();
@@ -748,26 +786,47 @@
void FleetDetailPanel::SetFleet(Fleet* fleet)
{
+ if (fleet)
+ Logger().errorStream() << "FleetDetailPanel::SetFleet() fleet id: " << fleet->ID() << " this: " << this;
+ else
+ Logger().errorStream() << "FleetDetailPanel::SetFleet() fleet id (null), this: " << this;
+
Fleet* old_fleet = m_fleet;
- if (fleet != old_fleet)
+
+ if (old_fleet && old_fleet != fleet) {
+ Logger().errorStream() << "FleetDetailPanel::SetFleet() DISconnecting StateChangedSignal() for fleet " << m_fleet->ID();
m_fleet_connection.disconnect();
+ } else {
+ Logger().errorStream() << "FleetDetailPanel::SetFleet() did not disconnect StateChangedSignal because old fleet is: " << old_fleet;
+ }
+
+ Logger().errorStream() << "blanking destination text and status text";
*m_destination_text << "";
*m_ship_status_text << "";
+ Logger().errorStream() << "clearing ships listbox";
m_ships_lb->Clear();
+ Logger().errorStream() << "setting fleet of lixbox";
m_ships_lb->SetFleet(fleet);
- if ((m_fleet = fleet)) {
+
+ m_fleet = fleet;
+
+ if (m_fleet) {
+ Logger().errorStream() << "have a new fleet, so ... hmm";
Universe& universe = GetUniverse();
+
if (m_fleet->NumShips()) {
- for (Fleet::const_iterator it = m_fleet->begin(); it != m_fleet->end(); ++it) {
+ for (Fleet::const_iterator it = m_fleet->begin(); it != m_fleet->end(); ++it)
m_ships_lb->Insert(new ShipRow(universe.Object<Ship>(*it)));
- }
+
} else {
PanelEmptySignal(m_fleet);
- return; // return immediately, since the signal above may invalidate this
+ return; // return immediately, since PanelEmptySignal may invalidate this pointer
}
+
*m_destination_text << DestinationText();
- if (fleet != old_fleet) {
- m_fleet_connection.disconnect();
+
+ if (old_fleet != fleet) {
+ Logger().errorStream() << "FleetDetailPanel::SetFleet() connecting StateChangedSignal() for fleet " << m_fleet->ID() << " to FleetDetailPanel::Refresh : " << this;
m_fleet_connection = GG::Connect(m_fleet->StateChangedSignal, &FleetDetailPanel::Refresh, this);
}
}
@@ -791,13 +850,14 @@
GetLayout()->SetRowStretch(1, 1.0);
GetLayout()->SetMinimumRowHeight(2, ClientUI::Pts() + 4);
- GG::Connect(m_ships_lb->SelChangedSignal, &FleetDetailPanel::ShipSelectionChanged, this);
- GG::Connect(m_ships_lb->BrowsedSignal, &FleetDetailPanel::ShipBrowsed, this);
- GG::Connect(m_ships_lb->RightClickedSignal, &FleetDetailPanel::ShipRightClicked, this);
+ m_misc_connections.insert(GG::Connect(m_ships_lb->SelChangedSignal, &FleetDetailPanel::ShipSelectionChanged, this));
+ m_misc_connections.insert(GG::Connect(m_ships_lb->BrowsedSignal, &FleetDetailPanel::ShipBrowsed, this));
+ m_misc_connections.insert(GG::Connect(m_ships_lb->RightClickedSignal, &FleetDetailPanel::ShipRightClicked, this));
}
void FleetDetailPanel::Refresh()
{
+ Logger().errorStream() << "FleetDetailPanel::Refresh() : this:" << this;
SetFleet(m_fleet);
}
@@ -902,11 +962,13 @@
SetMaxSize(GG::Pt(Width(), MaxSize().y));
SetText(TitleText());
EnableChildClipping(false);
- GG::Connect(m_fleet_panel->PanelEmptySignal, PanelEmptySignal);
+ m_panel_empty_connection = GG::Connect(m_fleet_panel->PanelEmptySignal, PanelEmptySignal);
}
FleetDetailWnd::~FleetDetailWnd()
{
+ Logger().errorStream() << "FleetDetailWnd::~FleetDetailWnd() : this: " << this;
+ m_panel_empty_connection.disconnect();
ClosingSignal(m_fleet_panel->GetFleet());
}
@@ -977,23 +1039,40 @@
EnableChildClipping(false);
Init(fleets, selected_fleet);
- GG::Connect(GetUniverse().UniverseObjectDeleteSignal, &FleetWnd::UniverseObjectDeleted, this);
+ m_misc_connections.insert(GG::Connect(GetUniverse().UniverseObjectDeleteSignal, &FleetWnd::UniverseObjectDeleted, this));
if (const System* system = fleets.back()->GetSystem())
- m_system_changed_connection = Connect(system->StateChangedSignal, &FleetWnd::SystemChangedSlot, this);
+ m_misc_connections.insert(Connect(system->StateChangedSignal, &FleetWnd::SystemChangedSlot, this));
SetMaxSize(GG::Pt(Width(), MaxSize().y));
}
FleetWnd::~FleetWnd()
{
+ // disconnect all signals connect to the FleetWnd itself
+ while (!m_misc_connections.empty()) {
+ m_misc_connections.begin()->disconnect();
+ m_misc_connections.erase(m_misc_connections.begin());
+ }
+ // disconnect all signals attached to FleetDetailWnds
+ while (!m_open_fleet_detail_wnd_connections.empty()) {
+ m_open_fleet_detail_wnd_connections.begin()->second.disconnect();
+ m_open_fleet_detail_wnd_connections.erase(m_open_fleet_detail_wnd_connections.begin());
+ }
+ //std::multimap<FleetDetailWnd*, boost::signals::connection>::iterator sig_it = m_open_fleet_detail_wnd_connections.begin();
+ //while (sig_it != m_open_fleet_detail_wnd_connections.end()) {
+ // sig_it->second.disconnect();
+ // m_open_fleet_detail_wnd_connections.erase(sig_it);
+ // sig_it = m_open_fleet_detail_wnd_connections.begin();
+ //}
+
ClientUI::GetClientUI()->GetMapWnd()->SetProjectedFleetMovement(0, std::list<System*>());
}
void FleetWnd::CloseClicked()
{
s_last_position = UpperLeft();
- m_lb_delete_connection.disconnect();
+
for (std::map<Fleet*, FleetDetailWnd*>::iterator it = m_open_fleet_detail_wnds.begin(); it != m_open_fleet_detail_wnds.end(); ++it) {
delete it->second;
}
@@ -1031,13 +1110,13 @@
}
GetLayout()->SetBorderMargin(7);
- GG::Connect(m_fleet_detail_panel->PanelEmptySignal, &FleetWnd::DeleteFleet, this);
- GG::Connect(m_fleets_lb->SelChangedSignal, &FleetWnd::FleetSelectionChanged, this);
- GG::Connect(m_fleets_lb->RightClickedSignal, &FleetWnd::FleetRightClicked, this);
- GG::Connect(m_fleets_lb->DoubleClickedSignal, &FleetWnd::FleetDoubleClicked, this);
- m_lb_delete_connection = GG::Connect(m_fleets_lb->ErasedSignal, &FleetWnd::FleetDeleted, this);
+ m_misc_connections.insert(GG::Connect(m_fleet_detail_panel->PanelEmptySignal, &FleetWnd::DeleteFleet, this));
+ m_misc_connections.insert(GG::Connect(m_fleets_lb->SelChangedSignal, &FleetWnd::FleetSelectionChanged, this));
+ m_misc_connections.insert(GG::Connect(m_fleets_lb->RightClickedSignal, &FleetWnd::FleetRightClicked, this));
+ m_misc_connections.insert(GG::Connect(m_fleets_lb->DoubleClickedSignal, &FleetWnd::FleetDoubleClicked, this));
+ m_misc_connections.insert(GG::Connect(m_fleets_lb->ErasedSignal, &FleetWnd::FleetDeleted, this));
if (!m_read_only)
- GG::Connect(m_new_fleet_drop_target->NewFleetFromShipsSignal, &FleetWnd::CreateNewFleetFromDrops, this);
+ m_misc_connections.insert(GG::Connect(m_new_fleet_drop_target->NewFleetFromShipsSignal, &FleetWnd::CreateNewFleetFromDrops, this));
SetText(TitleText());
@@ -1155,17 +1234,20 @@
int num_open_windows = m_open_fleet_detail_wnds.size();
GG::Pt window_posn(std::max(0, 25 + LowerRight().x + num_open_windows * 25), std::max(0, UpperLeft().y + num_open_windows * 25));
if (!m_open_fleet_detail_wnds[row_fleet]) {
- FleetDetailWnd* fleet_wnd = new FleetDetailWnd(window_posn.x, window_posn.y, row_fleet, m_read_only);
- m_open_fleet_detail_wnds[row_fleet] = fleet_wnd;
- if (GG::GUI::GetGUI()->AppWidth() < fleet_wnd->LowerRight().x)
- window_posn.x = GG::GUI::GetGUI()->AppWidth() - fleet_wnd->Width();
- if (GG::GUI::GetGUI()->AppHeight() < fleet_wnd->LowerRight().y)
- window_posn.y = GG::GUI::GetGUI()->AppHeight() - fleet_wnd->Height();
- fleet_wnd->MoveTo(window_posn);
- m_open_fleet_detail_wnd_connections[fleet_wnd] =
- GG::Connect(fleet_wnd->ClosingSignal, &FleetWnd::FleetDetailWndClosing, this);
- GG::Connect(fleet_wnd->PanelEmptySignal, &FleetWnd::DeleteFleet, this);
- GG::GUI::GetGUI()->Register(fleet_wnd);
+ FleetDetailWnd* fleet_detail_wnd = new FleetDetailWnd(window_posn.x, window_posn.y, row_fleet, m_read_only);
+ m_open_fleet_detail_wnds[row_fleet] = fleet_detail_wnd;
+ if (GG::GUI::GetGUI()->AppWidth() < fleet_detail_wnd->LowerRight().x)
+ window_posn.x = GG::GUI::GetGUI()->AppWidth() - fleet_detail_wnd->Width();
+ if (GG::GUI::GetGUI()->AppHeight() < fleet_detail_wnd->LowerRight().y)
+ window_posn.y = GG::GUI::GetGUI()->AppHeight() - fleet_detail_wnd->Height();
+ fleet_detail_wnd->MoveTo(window_posn);
+
+ m_open_fleet_detail_wnd_connections.insert(std::pair<FleetDetailWnd*, boost::signals::connection>(
+ fleet_detail_wnd, GG::Connect(fleet_detail_wnd->ClosingSignal, &FleetWnd::FleetDetailWndClosing, this)));
+ m_open_fleet_detail_wnd_connections.insert(std::pair<FleetDetailWnd*, boost::signals::connection>(
+ fleet_detail_wnd, GG::Connect(fleet_detail_wnd->PanelEmptySignal, &FleetWnd::DeleteFleet, this)));
+
+ GG::GUI::GetGUI()->Register(fleet_detail_wnd);
}
}
@@ -1206,9 +1288,19 @@
std::map<Fleet*, FleetDetailWnd*>::iterator it = m_open_fleet_detail_wnds.find(fleet);
if (it != m_open_fleet_detail_wnds.end()) {
- m_open_fleet_detail_wnd_connections[it->second].disconnect();
+
+ // disconnect all signals attached to this FleetDetailWnd
+ // find first signal...
+ std::multimap<FleetDetailWnd*, boost::signals::connection>::iterator sig_it = m_open_fleet_detail_wnd_connections.find(it->second);
+ while (sig_it != m_open_fleet_detail_wnd_connections.end()) {
+ // disconnect and remove from map
+ sig_it->second.disconnect();
+ m_open_fleet_detail_wnd_connections.erase(sig_it);
+ // find next signal, if present, until all signals disconnected and removed
+ sig_it = m_open_fleet_detail_wnd_connections.find(it->second);
+ }
+
delete it->second;
- m_open_fleet_detail_wnd_connections.erase(it->second);
m_open_fleet_detail_wnds.erase(it);
}
NotShowingFleetSignal(fleet);
@@ -1223,6 +1315,10 @@
void FleetWnd::CreateNewFleetFromDrops(Ship* first_ship, const std::vector<int>& ship_ids)
{
+ Logger().errorStream() << "FleetWnd::CreateNewFleetFromDrops. ship ids: ";
+ for (std::vector<int>::const_iterator it = ship_ids.begin(); it != ship_ids.end(); ++it)
+ Logger().errorStream() << ".. " << *it;
+
Fleet* some_fleet = FleetInRow(0);
// special case: disallow creating a new fleet from a ship when there is exactly 1 fleet containing exactly 1 ship
@@ -1250,10 +1346,11 @@
Fleet* new_fleet = 0;
if (system) {
+ Logger().errorStream() << "FleetWnd::CreateNewFleetFromDrops: Issuing NewFleetOrder at system with id: " << system->ID();
HumanClientApp::GetApp()->Orders().IssueOrder(new NewFleetOrder(empire_id, fleet_name, new_fleet_id, system->ID(), ship_ids));
System::ObjectVec fleets = system->FindObjectsInOrbit(-1, StationaryFleetVisitor(empire_id));
for (unsigned int i = 0; i < fleets.size(); ++i) {
- if (fleets[i]->Name() == fleet_name) {
+ if (fleets[i]->ID() == new_fleet_id) {
new_fleet = universe_object_cast<Fleet*>(fleets[i]);
break;
}
@@ -1284,10 +1381,15 @@
for (std::map<Fleet*, FleetDetailWnd*>::iterator it = m_open_fleet_detail_wnds.begin(); it != m_open_fleet_detail_wnds.end(); ++it) {
if (it->first == fleet) {
- m_open_fleet_detail_wnd_connections[it->second].disconnect();
- delete it->second;
- m_open_fleet_detail_wnd_connections.erase(it->second);
+ FleetDetailWnd* fleet_detail_wnd = it->second;
+ std::multimap<FleetDetailWnd*, boost::signals::connection>::iterator sig_it = m_open_fleet_detail_wnd_connections.find(fleet_detail_wnd);
+ while (sig_it != m_open_fleet_detail_wnd_connections.end()) {
+ sig_it->second.disconnect();
+ m_open_fleet_detail_wnd_connections.erase(sig_it);
+ sig_it = m_open_fleet_detail_wnd_connections.find(fleet_detail_wnd);
+ }
m_open_fleet_detail_wnds.erase(it);
+ delete fleet_detail_wnd;
break;
}
}