Project

General

Profile

v4 Destroyed Event

Added by Jeremy Brisko over 6 years ago

Hey Guys!

Great work with V4. I am currently working to upgrade a v3 project into v4. In this project there were many times it was nice to call a function when an object is destroyed to handle other parts of the application. In v4 it seems the destroyed event is gone, what is the preferred method for this scenario?

Thanks so much!


Replies (1)

RE: v4 Destroyed Event - Added by Roel Standaert over 6 years ago

The destroyed() signal was never documented, so we didn't consider it part of the public API. It was removed as a result. In any case, you have to be careful in the implementation of the slot when using destroyed(), since at that point the only part that remains is the WObject, since all of the destructors of derived classes have already run.

There's a few ways to deal with this: if you just want to prevent accidentally dereferencing a dangling pointer to the now-destroyed object, you can just use Wt::Core::observing_ptr.

Otherwise you could create derived classes of the objects you want to track the destruction of, and write a destructor. Another option I see, if you don't want to update too much code, is to create a generic wrapper that adds the destroyed() signal:

template<typename T>
class DestroyedSignalWrapper : public T {
public:
  template<typename ...Args>
  DestroyedSignalWrapper(Args&& ...args)
    : T(std::forward<Args>(args)...)
  { }

  ~DestroyedSignalWrapper()
  {
    destroyed()();
  }

  Wt::Signal<>& destroyed() { return destroyed_; }

private:
  Wt::Signal<> destroyed_;
};

Then, instead of constructing an object T, you can construct an object DestroyedSignalWrapper<T>, and use its destroyed() signal, e.g.:

auto button = std::make_unique<DestroyedSignalWrapper<Wt::WPushButton>>("Click me!");
button->destroyed().connect([]{
  std::cout << "Destroying button!\n";
});

So, to conclude, there isn't a preferred method, all three are valid:

  1. Use observing_ptr to check whether the target still exists (if that's all you need)
  2. Use derived classes that do the appropriate work upon destruction
  3. Use something like the wrapper I described above to add the destroyed() signal to anything

Regards,

Roel

    (1-1/1)