diff --git a/libs/main/core/piobject.cpp b/libs/main/core/piobject.cpp index b4a09568..a5b6b6c4 100644 --- a/libs/main/core/piobject.cpp +++ b/libs/main/core/piobject.cpp @@ -91,9 +91,11 @@ PIObject::~PIObject() { mutexObjects().lock(); objects().removeAll(this); mutexObjects().unlock(); - piDisconnect(this); + deleted(this); + piDisconnectAll(); } + PIMap PIObject::properties() const { PIMap ret; piForeachC (PropertyHash p, properties_) @@ -404,37 +406,38 @@ void PIObject::piDisconnect(PIObject * src, const PIString & sig) { } -void PIObject::piDisconnect(PIObject * src) { - src->deleted(src); - PIMutexLocker _ml(src->mutex_connect); - PIVector cv = src->connectors.toVector(); +void PIObject::piDisconnectAll() { + PIMutexLocker _ml(mutex_connect); + PIVector cv = connectors.toVector(); +// piCout << "disconnect connectors =" << connectors.size(); piForeach (PIObject * o, cv) { - //piCout << "disconnect"<< src->className()<< o->className(); - if (!o || (o == src)) continue; +// piCout << "disconnect"<< src << o; + if (!o || (o == this)) continue; if (!o->isPIObject()) continue; #if !defined(ANDROID) && !defined(MAC_OS) && !defined(FREERTOS) - PIMutexLocker _mld(o->mutex_connect, src != o); + PIMutexLocker _mld(o->mutex_connect, this != o); #endif PIVector<__Connection> & oc(o->connections); for (int i = 0; i < oc.size_s(); ++i) { if (oc[i].functor) continue; //piCout << " check" << (void*)(oc[i].dest_o) << "==" << (void*)(src); - if (oc[i].dest_o == src) { + if (oc[i].dest_o == this) { oc[i].destroy(); oc.remove(i); --i; } } } - piForeachC (PIObject::__Connection & c, src->connections) { +// piCout << "disconnect connections =" << connections.size(); + piForeachC (PIObject::__Connection & c, connections) { if (c.functor) continue; if (!c.dest_o) continue; if (!c.dest_o->isPIObject()) continue; - c.dest_o->connectors.remove(src); + c.dest_o->connectors.remove(this); } - for (int i = 0; i < src->connections.size_s(); ++i) - src->connections[i].destroy(); - src->connections.clear(); + for (int i = 0; i < connections.size_s(); ++i) + connections[i].destroy(); + connections.clear(); } diff --git a/libs/main/core/piobject.h b/libs/main/core/piobject.h index da47770e..cb19bcfa 100644 --- a/libs/main/core/piobject.h +++ b/libs/main/core/piobject.h @@ -160,10 +160,7 @@ public: //! Disconnect object "src" from all connections with event name "sig" static void piDisconnect(PIObject * src, const PIString & sig); - - //! Disconnect object "src" from all connections, i.e. all connections where object "src" is emitter - static void piDisconnect(PIObject * src); - + // / Raise events static void raiseEvent(PIObject * sender, const uint eventID) { for (int j = 0; j < sender->connections.size_s(); ++j) { @@ -488,6 +485,8 @@ private: PIVector<__MetaFunc> findEH(const PIString & name) const; __MetaFunc methodEH(const void * addr) const; void updateConnectors(); + void piDisconnectAll(); + void postQueuedEvent(const __QueuedEvent & e); void eventBegin() {in_event_cnt++;} void eventEnd () {in_event_cnt--;} diff --git a/tests/piobject/connect.cpp b/tests/piobject/connect.cpp index b254cdf8..95ce5a89 100644 --- a/tests/piobject/connect.cpp +++ b/tests/piobject/connect.cpp @@ -5,8 +5,13 @@ class Object : public PIObject { PIOBJECT(Object) - public: - Object() {x=0;} +public: + Object() { + x=0; +// CONNECTL(this, deleted, [](PIObject * o){ +// piCout << "deteted" << o; +// }); + } void test() {event_test();} void test_val() {event_val(x);} int getX() const {return x;} @@ -41,12 +46,15 @@ TEST(PiobjectConnections, CONNECT0) { b.test(); ASSERT_EQ(a.getX(), 0); ASSERT_EQ(b.getX(), 1); +// piCout << "================"; } TEST(PiobjectConnections, CONNECT0_DISCONNECT) { Object a; Object b; + a.setName("A"); + b.setName("B"); ASSERT_EQ(a.getX(), 0); ASSERT_EQ(b.getX(), 0); a.test(); @@ -64,7 +72,7 @@ TEST(PiobjectConnections, CONNECT0_DISCONNECT) { b.test(); ASSERT_EQ(a.getX(), 0); ASSERT_EQ(b.getX(), 1); - a.piDisconnect(&b); + PIObject::piDisconnect(&a, "event_test"); ASSERT_EQ(a.getX(), 0); ASSERT_EQ(b.getX(), 1); a.test(); @@ -73,6 +81,7 @@ TEST(PiobjectConnections, CONNECT0_DISCONNECT) { b.test(); ASSERT_EQ(a.getX(), 0); ASSERT_EQ(b.getX(), 1); +// piCout << "================"; } TEST(PiobjectConnections, CONNECTU) { @@ -95,6 +104,7 @@ TEST(PiobjectConnections, CONNECTU) { b.test(); ASSERT_EQ(a.getX(), 0); ASSERT_EQ(b.getX(), 1); +// piCout << "================"; } TEST(PiobjectConnections, CONNECTU_DISCONNECT) { @@ -117,7 +127,7 @@ TEST(PiobjectConnections, CONNECTU_DISCONNECT) { b.test(); ASSERT_EQ(a.getX(), 0); ASSERT_EQ(b.getX(), 1); - PIObject::piDisconnect(&a); + PIObject::piDisconnect(&a, "event_test"); ASSERT_EQ(a.getX(), 0); ASSERT_EQ(b.getX(), 1); a.test(); @@ -144,6 +154,7 @@ TEST(PiobjectConnections, CONNECTU_DISCONNECT) { a.test_val(); ASSERT_EQ(a.getX(), -1); ASSERT_EQ(b.getX(), 99); +// piCout << "================"; } @@ -169,6 +180,7 @@ TEST(PiobjectConnections, CONNECTL) { b.test(); ASSERT_EQ(a.getX(), 0); ASSERT_EQ(b.getX(), 7); +// piCout << "================"; } TEST(PiobjectConnections, CONNECTL_DISCONNECT) { @@ -196,12 +208,13 @@ TEST(PiobjectConnections, CONNECTL_DISCONNECT) { b.handler_test(); ASSERT_EQ(a.getX(), 0); ASSERT_EQ(b.getX(), 2); - PIObject::piDisconnect(&a); + PIObject::piDisconnect(&a, "event_test"); ASSERT_EQ(a.getX(), 0); ASSERT_EQ(b.getX(), 2); a.test(); ASSERT_EQ(a.getX(), 0); ASSERT_EQ(b.getX(), 2); +// piCout << "================"; } TEST(PiobjectConnections, CONNECTL_twice) { @@ -222,7 +235,7 @@ TEST(PiobjectConnections, CONNECTL_twice) { b.handler_val(0); ASSERT_EQ(a.getX(), 0); ASSERT_EQ(b.getX(), 0); - PIObject::piDisconnect(&a); + PIObject::piDisconnect(&a, "event_test"); a.test(); ASSERT_EQ(a.getX(), 0); ASSERT_EQ(b.getX(), 0); @@ -232,4 +245,73 @@ TEST(PiobjectConnections, CONNECTL_twice) { a.test(); ASSERT_EQ(a.getX(), 0); ASSERT_EQ(b.getX(), 1); +// piCout << "================"; +} + +TEST(PiobjectConnections, CONNECT_AFTER_DISCONNECT) { + Object a; + Object b; + CONNECTL(&a, event_test, [&b](){ + b.handler_test(); + }); + a.test(); + ASSERT_EQ(b.getX(), 1); + PIObject::piDisconnect(&a, "event_test"); + a.test(); + ASSERT_EQ(b.getX(), 1); + DISCONNECT1(void, int, &a, event_val, &b, handler_val); + CONNECT1(void, int, &a, event_val, &b, handler_val); + a.handler_val(8); + a.test_val(); + ASSERT_EQ(a.getX(), 8); + ASSERT_EQ(b.getX(), 8); +// piCout << "================"; +} + +TEST(PiobjectConnections, CONNECTL_WRONG_DISCONNECT) { + Object a; + Object b; + CONNECTL(&a, event_test, [&b](){ + b.handler_test(); + }); + a.test(); + ASSERT_EQ(b.getX(), 1); + PIObject::piDisconnect(&b, "event_test"); + a.test(); + ASSERT_EQ(b.getX(), 2); + PIObject::piDisconnect(&a, "event_test"); + a.test(); + ASSERT_EQ(b.getX(), 2); +// piCout << "================"; +} + +TEST(PiobjectConnections, CONNECT_WRONG_DISCONNECT) { + Object a; + Object b; + + CONNECT0(void, &a, event_test, &b, handler_test); + a.test(); + ASSERT_EQ(b.getX(), 1); + PIObject::piDisconnect(&b, "event_test"); + a.test(); + ASSERT_EQ(b.getX(), 2); + PIObject::piDisconnect(&a, "event_test"); + a.test(); + ASSERT_EQ(b.getX(), 2); +// piCout << "================"; +} + +TEST(PiobjectConnections, CONNECTU_WRONG_DISCONNECT) { + Object a; + Object b; + CONNECTU(&a, event_test, &b, handler_test); + a.test(); + ASSERT_EQ(b.getX(), 1); + PIObject::piDisconnect(&b, "event_test"); + a.test(); + ASSERT_EQ(b.getX(), 2); + PIObject::piDisconnect(&a, "event_test"); + a.test(); + ASSERT_EQ(b.getX(), 2); +// piCout << "================"; }