feat(signal): added signal holder to automatically disconnect signals + instance AncestryChanged
This commit is contained in:
parent
0acc2d8857
commit
3b60b3b0ec
4 changed files with 41 additions and 0 deletions
|
@ -72,6 +72,19 @@ void CSignalConnection::Call(std::vector<Data::Variant> args) {
|
|||
|
||||
//
|
||||
|
||||
SignalConnectionHolder::SignalConnectionHolder() : heldConnection() {}
|
||||
SignalConnectionHolder::SignalConnectionHolder(std::shared_ptr<SignalConnection> connection) : heldConnection(connection) {}
|
||||
SignalConnectionHolder::SignalConnectionHolder(Data::SignalConnectionRef other) : heldConnection(other) {}
|
||||
|
||||
SignalConnectionHolder::~SignalConnectionHolder() {
|
||||
// printf("Prediscon!\n");
|
||||
// if (!heldConnection.expired()) printf("Disconnected!\n");
|
||||
if (!heldConnection.expired())
|
||||
heldConnection.lock()->Disconnect();
|
||||
}
|
||||
|
||||
//
|
||||
|
||||
SignalConnectionRef Signal::Connect(std::function<void(std::vector<Data::Variant>)> callback) {
|
||||
auto conn = std::dynamic_pointer_cast<SignalConnection>(std::make_shared<CSignalConnection>(callback, weak_from_this()));
|
||||
connections.push_back(conn);
|
||||
|
@ -96,6 +109,8 @@ SignalConnectionRef Signal::Once(lua_State* state) {
|
|||
return SignalConnectionRef(conn);
|
||||
}
|
||||
|
||||
//
|
||||
|
||||
int __waitingThreads = 0;
|
||||
int Signal::Wait(lua_State* thread) {
|
||||
// If the table hasn't been constructed yet, make it
|
||||
|
|
|
@ -56,6 +56,27 @@ public:
|
|||
~LuaSignalConnection();
|
||||
};
|
||||
|
||||
// Holds a signal connection such that when the holder is deleted (either via its parent object being deleted, or being overwritten),
|
||||
// the connection is disconnected. Useful to prevent lingering connections that no longer contain valid objects
|
||||
class SignalConnectionHolder {
|
||||
std::weak_ptr<SignalConnection> heldConnection;
|
||||
public:
|
||||
SignalConnectionHolder();
|
||||
SignalConnectionHolder(std::shared_ptr<SignalConnection>);
|
||||
SignalConnectionHolder(Data::SignalConnectionRef other);
|
||||
~SignalConnectionHolder();
|
||||
|
||||
// Prevent SignalConnectionHolder being accidentally copied, making it useless
|
||||
// https://stackoverflow.com/a/10473009/16255372
|
||||
SignalConnectionHolder(const SignalConnectionHolder&) = delete;
|
||||
SignalConnectionHolder& operator=(const SignalConnectionHolder&) = delete;
|
||||
SignalConnectionHolder(SignalConnectionHolder&&) = default;
|
||||
SignalConnectionHolder& operator=(SignalConnectionHolder&&) = default;
|
||||
|
||||
inline bool Connected() { return !heldConnection.expired() && heldConnection.lock()->Connected(); }
|
||||
inline void Disconnect() { if (!heldConnection.expired()) heldConnection.lock()->Disconnect(); }
|
||||
};
|
||||
|
||||
class Signal : public std::enable_shared_from_this<Signal> {
|
||||
std::vector<std::shared_ptr<SignalConnection>> connections;
|
||||
std::vector<std::shared_ptr<SignalConnection>> onceConnections;
|
||||
|
|
|
@ -96,6 +96,7 @@ void Instance::updateAncestry(std::optional<std::shared_ptr<Instance>> updatedCh
|
|||
}
|
||||
|
||||
OnAncestryChanged(updatedChild, newParent);
|
||||
AncestryChanged->Fire({updatedChild.has_value() ? Data::InstanceRef(updatedChild.value()) : Data::InstanceRef(), newParent.has_value() ? Data::InstanceRef(newParent.value()) : Data::InstanceRef()});
|
||||
|
||||
// Old workspace used to exist, and workspaces differ
|
||||
if (!oldWorkspace.expired() && oldWorkspace != _workspace) {
|
||||
|
|
|
@ -11,6 +11,7 @@
|
|||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include "datatypes/signal.h"
|
||||
#include "error/instance.h"
|
||||
#include "error/result.h"
|
||||
#include "member.h"
|
||||
|
@ -93,6 +94,9 @@ public:
|
|||
const static InstanceType TYPE;
|
||||
std::string name;
|
||||
|
||||
// Signals
|
||||
SignalSource AncestryChanged;
|
||||
|
||||
// Instance is abstract, so it should not implement GetClass directly
|
||||
virtual const InstanceType* GetClass() = 0;
|
||||
bool SetParent(std::optional<std::shared_ptr<Instance>> newParent);
|
||||
|
|
Loading…
Add table
Reference in a new issue