0

I am using Boost Signals2 in one of our project.In this I want automatic connection management,for this I am testing Boost Signals2 tracking but I am not getting slot invoked. After I run following code , slots are not called . Environment: VS 2010,windows 7,boost 1.54

    #include <stdio.h>
    #include <iostream>
    #include <string>
    #include <boost/bind.hpp>
    #include <boost/enable_shared_from_this.hpp>
    #include <boost/signals2/signal.hpp>
    #include <boost/shared_ptr.hpp>


    typedef boost::signals2::signal<void ()>  signal_test;
    using namespace boost;

    class SubjectTest
    {

    public:
        void Connect(const signal_test::slot_type &subscriber)
        {
            m_Signal.connect(subscriber);
            std::cout << "No of connections : " << m_Signal.num_slots() << std::endl;
        }
        void Notify()
        {
            m_Signal();
        }
    private:
        signal_test m_Signal;
    };

    class Listner 
    {
    public:
        Listner(){}
        ~Listner(){}
        Listner(std::string name)
        :m_name(name)
        {
        }
        void GotSignal()
        {
            std::cout << m_name <<  std::endl;
        }
        void ConnectWithTracking(SubjectTest *s)
        {
            shared_ptr<Listner> l = new Listner();
            s->Connect(signal_test::slot_type(&Listner::GotSignal,l.get()).track(l));

        }
        void ConnectNormal(SubjectTest *s)
        {
            s->Connect(bind(&Listner::GotSignal,this));

        }

    private:
        std::string m_name;
        shared_ptr<Listner> l;
    };

    void main()
    {
        Listner l2("First"); 
        SubjectTest sub;

        try
        {
        l2.ConnectWithTracking(&sub);
        //l2.ConnectNormal(&sub);
        sub.Notify();

        {
            Listner l3("Second"); 

            l3.ConnectWithTracking(&sub);
            //l3.ConnectNormal(&sub);
            sub.Notify();
        }

        sub.Notify();
        }
        catch(std::exception ex)
        {
            std::cout << ex.what() << std::endl;
        }

        std::cout << "Finish" <<std::endl;
    }

Updated : *Working now*

    #include <stdio.h>
    #include <iostream>
    #include <string>
    #include <boost/bind.hpp>
    #include <boost/enable_shared_from_this.hpp>
    #include <boost/signals2/signal.hpp>
    #include <boost/shared_ptr.hpp>


    typedef boost::signals2::signal<void ()>  signal_test;
    using namespace boost;

    class SubjectTest
    {

    public:
        void Connect(const signal_test::slot_type &subscriber)
        {
            m_Signal.connect(subscriber);
            std::cout << "No of connections : " << m_Signal.num_slots() << std::endl;
        }
        void Notify()
        {
            m_Signal();
        }
    private:
        signal_test m_Signal;
    };

    class Listner : public boost::enable_shared_from_this<Listner>
    {
    public:
        Listner(){}
        ~Listner(){}
        Listner(std::string name)
        :m_name(name)
        {
        }
        void GotSignal()
        {
            std::cout << m_name <<  std::endl;
        }
        void ConnectWithTracking(SubjectTest *s)
        {
            s->Connect(signal_test::slot_type(&Listner::GotSignal,shared_from_this().get()).track(shared_from_this()));
        }
        void ConnectNormal(SubjectTest *s)
        {
            s->Connect(bind(&Listner::GotSignal,this));
        }

    private:
        std::string m_name;

    };

    void main()
    {
        shared_ptr<Listner> l2(new Listner("First")); 

        SubjectTest sub;

        try
        {
        l2->ConnectWithTracking(&sub);

        sub.Notify();

        {
            shared_ptr<Listner> l3(new Listner("Second")); 

            l3->ConnectWithTracking(&sub);
            //l3.ConnectNormal(&sub);
            sub.Notify();
        }

        sub.Notify();
        }
        catch(std::exception ex)
        {
            std::cout << ex.what() << std::endl;
        }

        std::cout << "Finish" <<std::endl;
    }

Now this is complete example of Signal2 Automatic Connection Management

Rushikesh
  • 21
  • 1
  • 3

1 Answers1

0
{
  shared_ptr<Listner> l(new Listner());
  s->Connect(signal_test::slot_type(&Listner::GotSignal,l.get()).track(l));
}

In the above lines l pointee gets destroyed at the closing } - meaning that the slot you just connected got expired.

The whole point of tracking is to pass to track() a shared_ptr (or weak_ptr), which is bound (or tightly related) to the slot itself. It doesn't make sense to pass a shared_ptr whose lifespan is unrelated to that of the slot itself.

Igor R.
  • 14,716
  • 2
  • 49
  • 83
  • Can you suggest ,where exactly I should create shared pointer? – Rushikesh Feb 27 '14 at 08:11
  • @Rushikesh You should change the design: inherit `Listener` from `enable_shared_from_this`, use `new` to instantiate it, and manage the instances by means of `shared_ptr`s only. Then you'll be able to track its lifespan passing `shared_from_this()` to `track()` function. – Igor R. Feb 27 '14 at 10:17
  • Thanks , updated solution. If wrong then please comment – Rushikesh Feb 27 '14 at 12:04
  • @Rushikesh , it's ok now. Note that you don't have to call `shared_form_this().get()`, putting `this` is enough. Besides, I guess you realize that `ConnectNormal` is unsafe, due to lack of tracking. – Igor R. Feb 27 '14 at 12:24
  • yes , ConnectNormal was used to just to check signals working . – Rushikesh Feb 27 '14 at 14:28