#pragma once // PFC weakRef class // Create weak references to objects that automatically become invalidated upon destruction of the object // Note that this is NOT thread safe and meant for single thread usage. If you require thread safety, provide your own means, such as mutexlocking of weakRef::get() and the destruction of your objects. #include // std::shared_ptr namespace pfc { typedef std::shared_ptr weakRefKillSwitch_t; template class weakRef { typedef weakRef self_t; public: static self_t _make(target_t * target, weakRefKillSwitch_t ks) { self_t ret; ret.m_target = target; ret.m_ks = ks; return ret; } bool isValid() const { return m_ks && !*m_ks; } target_t * get() const { if (!isValid()) return nullptr; return m_target; } target_t * operator() () const { return get(); } private: target_t * m_target = nullptr; weakRefKillSwitch_t m_ks; }; template class weakRefTarget { public: weakRefTarget() {} typedef weakRef weakRef_t; weakRef weakRef() { PFC_ASSERT(!*m_ks); class_t * ptr = static_cast(this); return weakRef_t::_make(ptr, m_ks); } // Optional: explicitly invalidates all weak references to this object. Called implicitly by the destructor, but you can do it yourself earlier. void weakRefShutdown() { *m_ks = true; } ~weakRefTarget() { weakRefShutdown(); } // Optional: obtain a reference to the killswitch if you wish to use it directly weakRefKillSwitch_t weakRefKS() const { return m_ks; } private: std::shared_ptr m_ks = std::make_shared(false); weakRefTarget(const weakRefTarget &) = delete; void operator=(const weakRefTarget &) = delete; }; }