widelands-dev team mailing list archive
-
widelands-dev team
-
Mailing list archive
-
Message #08417
Re: [Merge] lp:~widelands-dev/widelands/notifications_shipwindow into lp:widelands
Review: Needs Fixing
> I want to remove the dependency from logic to wui,
that is a noble and excellent goal!
> and I think the Notification system is a good way of doing that.
I designed it with this idea in mind - to decouple user interface from logic.
I think the big problem in this change is the tracking of the open ship windows - I'd try getting rid of that by subscribing again for each ship window.
Diff comments:
>
> === modified file 'src/logic/map_objects/tribes/ship.cc'
> --- src/logic/map_objects/tribes/ship.cc 2016-09-07 09:30:49 +0000
> +++ src/logic/map_objects/tribes/ship.cc 2016-09-28 15:34:04 +0000
> @@ -926,8 +924,7 @@
> expedition_.reset(nullptr);
>
> // And finally update our ship window
> - if (upcast(InteractiveGameBase, igb, game.get_ibase()))
getting rid of game.get_ibase() would be a big win too!
> - refresh_window(*igb);
> + Notifications::publish(NoteShipWindow(*this, NoteShipWindow::Action::kRefresh));
> }
>
> /// Sinks the ship
>
> === modified file 'src/logic/map_objects/tribes/ship.h'
> --- src/logic/map_objects/tribes/ship.h 2016-09-07 09:30:49 +0000
> +++ src/logic/map_objects/tribes/ship.h 2016-09-28 15:34:04 +0000
> @@ -59,6 +54,19 @@
> }
> };
>
> +struct NoteShipWindow {
> + CAN_BE_SENT_AS_NOTE(NoteId::ShipWindow)
> +
> + Ship& ship;
I am unsure if this is save. It assumes that 'ship' is valid when this notification is processed - e.g. if the ship is deleting itself. I think the notification system does not queue up notifications, but runs them immediately - so it should be save. But could you doublecheck?
Also, can this be const ref? The observers should only query state, not change it.
> +
> + enum class Action { kRefresh, kRemove, kClosed };
> + const Action action;
> +
> + NoteShipWindow(Ship& init_ship, const Action& init_action)
> + : ship(init_ship), action(init_action) {
> + }
> +};
> +
> class ShipDescr : public BobDescr {
> public:
> ShipDescr(const std::string& init_descname, const LuaTable& t);
>
> === modified file 'src/wui/interactive_gamebase.cc'
> --- src/wui/interactive_gamebase.cc 2016-08-04 15:49:05 +0000
> +++ src/wui/interactive_gamebase.cc 2016-09-28 15:34:04 +0000
> @@ -63,6 +64,52 @@
> toggle_buildhelp_(INIT_BTN(
> "wui/menus/menu_toggle_buildhelp", "buildhelp", _("Show Building Spaces (on/off)"))) {
> toggle_buildhelp_.sigclicked.connect(boost::bind(&InteractiveGameBase::toggle_buildhelp, this));
> +
> + shipnotes_subscriber_ = Notifications::subscribe<Widelands::NoteShipWindow>(
Pull out into a OnNoteShipWindow member function? it reduces right drift and makes the constructor easier to read.
> + [this](const Widelands::NoteShipWindow& note) {
> + const Widelands::Serial serial = note.ship.serial();
> + switch (note.action) {
> + // The ship state has changed or the user requested a new window
> + case Widelands::NoteShipWindow::Action::kRefresh: {
> + bool is_refreshing = false;
> + Point pos(0, 0);
> + ShipWindow* shipwindow;
> + if (shipwindows_.count(serial) == 1) {
I think you do not require shipwindows_. Instead give each ShipWindow the serial of the ship it is watching and create a new NoteShipWindow observer there - it can then refresh itself if needed. It makes sense to pull the request for opening a ship window and for updating it into sparate messages for notification.
Alternatively, you can add boost::signal2 signals to the ship and signal that on changes - that is what we do in the UI for callbacks. I like the notifications approach better for now - until it proves to inefficient.
> + shipwindow = shipwindows_.at(serial);
> + if (shipwindow) {
> + is_refreshing = true;
> + pos = shipwindow->get_pos();
> + delete shipwindow;
> + shipwindow = nullptr;
> + }
> + }
> + shipwindow = new ShipWindow(*this, note.ship, is_refreshing);
> + shipwindows_.insert(std::pair<Widelands::Serial, ShipWindow*>(serial, shipwindow));
> + if (is_refreshing) {
> + shipwindow->set_pos(pos);
> + }
> +
> + } break;
> + // The ship has been removed
> + case Widelands::NoteShipWindow::Action::kRemove: {
> + if (shipwindows_.count(serial) == 1) {
> + ShipWindow* shipwindow = shipwindows_.at(serial);
> + if (shipwindow) {
> + delete shipwindow;
> + shipwindow = nullptr;
> + }
> + shipwindows_.erase(serial);
> + }
> +
> + } break;
> + // The user closed the window
> + case Widelands::NoteShipWindow::Action::kClosed: {
> + if (shipwindows_.count(serial) == 1) {
> + shipwindows_.erase(serial);
> + }
> + } break;
> + }
> + });
> }
>
> /// \return a pointer to the running \ref Game instance.
--
https://code.launchpad.net/~widelands-dev/widelands/notifications_shipwindow/+merge/307048
Your team Widelands Developers is subscribed to branch lp:~widelands-dev/widelands/notifications_shipwindow.
References