On Thu, Aug 6, 2015 at 4:20 PM, Nick Stokes <randomaccessiterator@gmail.com> wrote:


On Thu, Aug 6, 2015 at 4:10 PM, Michael Powell <mwpowellhtx@gmail.com> wrote:

On Thu, Aug 6, 2015 at 4:01 PM, Nick Stokes
<randomaccessiterator@gmail.com> wrote:

I'm not sure what you're shooting for. 


Again, is my "broader picture" example useful in anyway? 

perhaps, the short "use-case" example I provided was misleading: 


> // in use
> for( ComboSlot& cs : sig() )  {
>    cs.method1(3);
>    cs.method2(3.14);
> }
>


This gives the false impression that I am calling both methods in order.  That is very misleading indeed, sorry.  Here is perhaps a more clarifying use case:



struct EventGenerator {

      void event1( int i )  {
               // want to launch all listeners of event1
      }

      void event2( double d) {
               // want to launch all listeners of event2
      }
};


One implementation is to define two separate signals for each even and manage their slots independently:


struct EventGenerator {
      typedef signal< void(int) >  sig1_t;
      typedef signal< void(double) >  sig2_t;

      void event1( int i )  {
        sig1(i);
      }

      void event2( double d) {
           sig2(d);
      }

      void connect( std::shared_ptr<ComboSlot>& e ) {
           sig1.connect( sig1_t::slot_type( &ComboSlot::method1, e.get(), _1 ).track(e) );
           sig2.connect( sig2_t::slot_type( &ComboSlot::method2, e.get(), _1 ).track(e) );
      }
private:
     sig1_t sig1;
     sig2_t sig2;
};


The invariant that signals must be connected together to a same underlying event handler is satisfied. But this implementation quickly gets out of hand as number of events increase.

Another alternative would be: 

struct EventGenerator {
      typedef signal< ComboSlot&(),  RangeCombiner > sig_t;

      void event1( int i )  {
           for( ComboSlot& cs : sig() ) { 
               cs.method1(i);  
               // also imagine, i can do arbitrary things there. e.g. break loop what not
           } 
      }

      void event2( double d) {
           for( ComboSlot& cs : sig() ) { 
               cs.method2(d);
           } 
      }

     void connect( std::shared_ptr<ComboSlot>& e ) {
           ComboSlot* cs = e.get();
           sig.connect( sig_t::slot_type( [cs](){ return cs;} ).track(e) );
           // done - number of events don't matter
      }
private: 
    sig_t sig;
};


hopefully this clarifies the use case. 

Thanks
Nick