// ------------------------------------------------------------------------------------------------ void Signal::DisconnectFunc(Function & func) { // Don't attempt to search anything if there's no head if (m_Head == nullptr) { return; } const SQHash hash = Slot{NullObject(), func}.mFuncHash; // Walk down the chain and remove the matching nodes for (Slot * node = m_Head, * next = nullptr; node != nullptr; node = next) { // Grab the next node upfront next = node->mNext; // Is this our node? if (node->mFuncHash == hash) { // Is this the head? if (node == m_Head) { m_Head = next; // Move the head to the next one } // Detach it from the chain node->Detach(); // Delete the node instance delete node; } } }
// ------------------------------------------------------------------------------------------------ void Signal::Tail(Object & env, Function & func) { // Don't attempt to search anything if there's no head if (m_Head == nullptr) { m_Head = new Slot(env, func, nullptr); // We're done here return; } const Slot slot{env, func}; // Don't attempt to search anything if there's only one element if (m_Head->mNext == nullptr) { // Is it already inserted? if (*m_Head != slot) { m_Head->mNext = new Slot(env, func, nullptr); // Link with the head m_Head->mNext->mPrev = m_Head; } // We're done here return; } // Grab the head node Slot * node = m_Head, * prev = nullptr; // Walk down the chain and find a matching node for (; node != nullptr; prev = node, node = node->mNext) { if (*node == slot) { break; // Found it } } // Have we found anything? if (node == nullptr) { // Create the slot now node = new Slot(env, func, nullptr); } else { // Walk down the chain until the end while (prev->mNext != nullptr) { prev = prev->mNext; } // Finally, detach the node from it's current position node->Detach(); } // Knowing 'prev' points to last element node->AttachPrev(prev); }
int main(int argc, char* argv[]) { Classe myClass; Slot<int, float> slot; //declaring a slot that holds functions and functors which receive 2 parameters, an int and a float Signal<int, float> signal; //declares a signal compatible with the previous slot slot.Attach(&myClass, &Classe::miMethod); //adds to the slot a member method of myClass slot.Attach(&myFloat); //adds to the slot.Attach(&Classe::StaticMethod); //adds a static method to the slot signal.Connect(&slot); //connects the signal and the slot, so that firing the signal will also fire all the elements connected to the slot signal(2, 3); //fires the signal, which will fire the three elements connected to the slot slot.Detach(&myFloat); //detaches the function from the slot signal(2, 4); //now, firing the signal will only fire two elements of the slot slot.Detach(&myClass, &Classe::miMethod); //detaches the member of myClass signal(2, 5); //fires the only one element of the slot slot.Detach(&myClass, &Classe::miMethod2); //tryies to detach an element that is not present in the slot. Nothing happens signal(2, 6); slot.Detach(&Classe::StaticMethod); //detaches the last element of the signal signal(2, 7); //slot empty, nothing is fired //signal and slot for members with empty parameter list Signal<> empParamSignal; Slot<> empParamSlot; empParamSlot.Attach(&empty); empParamSignal.Connect(&empParamSlot); empParamSignal(); return 0; }