Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. General and Desktop
  4. Merging multiple signals into one
Forum Updated to NodeBB v4.3 + New Features

Merging multiple signals into one

Scheduled Pinned Locked Moved Unsolved General and Desktop
7 Posts 4 Posters 1.2k Views 3 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • M Offline
    M Offline
    MajidKamali
    wrote on last edited by MajidKamali
    #1

    Hi. There is a device which I get multiple kinds of realtime data from it:

    class Device {
    signals:
      void param1Changed(Param1 p);
      void param2Changed(Param2 p);
      ...
    };
    

    Those Param1, Param2 etc. are independent values read from device.
    But sometimes I need to get multiple values at once and do a calculation:

    QObject *contextObject0 = new QObject;
    connect(d, Device::param1Changed, contextObject0, [=](Param1 p1) {
      QObject *contextObject1 = new QObject;
      connect(d, Device::param2Changed, contextObject1, [=](Param2 p2) {
        // do something with p1 and p2 values
        contextObject0->deleteLater();
        contextObject1->deleteLater();
      });
    });
    

    This can be even more cumbersome and clumsy when more than 2 parameters are needed and I should add another lambda inside the above one.

    Is there a generic solution to this? I mean setting multiple signals to it (in constructor, via setter, etc.), and get a unified signal which is emitted when all of them are emitted some time age (obviously with most recent values)
    Even a predefined and hardcoded signal signature is good enough for me, for now :-)

    Thanks

    A 1 Reply Last reply
    0
    • M MajidKamali

      Hi. There is a device which I get multiple kinds of realtime data from it:

      class Device {
      signals:
        void param1Changed(Param1 p);
        void param2Changed(Param2 p);
        ...
      };
      

      Those Param1, Param2 etc. are independent values read from device.
      But sometimes I need to get multiple values at once and do a calculation:

      QObject *contextObject0 = new QObject;
      connect(d, Device::param1Changed, contextObject0, [=](Param1 p1) {
        QObject *contextObject1 = new QObject;
        connect(d, Device::param2Changed, contextObject1, [=](Param2 p2) {
          // do something with p1 and p2 values
          contextObject0->deleteLater();
          contextObject1->deleteLater();
        });
      });
      

      This can be even more cumbersome and clumsy when more than 2 parameters are needed and I should add another lambda inside the above one.

      Is there a generic solution to this? I mean setting multiple signals to it (in constructor, via setter, etc.), and get a unified signal which is emitted when all of them are emitted some time age (obviously with most recent values)
      Even a predefined and hardcoded signal signature is good enough for me, for now :-)

      Thanks

      A Offline
      A Offline
      Anonymous_Banned275
      wrote on last edited by
      #2
      This post is deleted!
      1 Reply Last reply
      0
      • nageshN Offline
        nageshN Offline
        nagesh
        wrote on last edited by
        #3

        @MajidKamali Your way of calling connect statement is confusing/not correct, in the first connect statement Device::param1Changed lambda slot you are creating second connection Device::param2Changed.
        Which means you are doing multiple connection for each time the Device::param1Changed signal is emitted.

        One approach can be as follows,
        1)Have dirty bit flag for the data, indicating value changed.
        2)create the function which tracks the dirty bit flag for the data and emits the processing signal if both(param1 & Param2 dirty bit) are set.
        3)connect the param1changed/param2changed from device signal to the slot and store the data in the class. and set dirty bit flag for the data.
        call the dirtybit tracker function
        4)in the processing function after the processing reset the dirty bit

        1 Reply Last reply
        3
        • Kent-DorfmanK Offline
          Kent-DorfmanK Offline
          Kent-Dorfman
          wrote on last edited by
          #4

          I would argue that if it is truly a "device" you are reading from then you should NOT use a device class an associated signals from that class at all. Reason being is that you are making the interface way too specialized and specific.

          1 Reply Last reply
          0
          • M Offline
            M Offline
            MajidKamali
            wrote on last edited by MajidKamali
            #5

            @Kent-Dorfman You are right. Device class is actually an interface to a 'real' device class.
            @nagesh Oh I didn't noticed about multiple connections in lambda. Thanks. But I didn't understand your solution yet. By 1, you mean instead of emitting param1Change(Param p) signal, emit a param1Dirty() signal and save a dirty bit flag instead of real value? And then in 2, check for desired values (dirty bit flags) and emit a unified signal?

            nageshN 1 Reply Last reply
            0
            • M MajidKamali

              @Kent-Dorfman You are right. Device class is actually an interface to a 'real' device class.
              @nagesh Oh I didn't noticed about multiple connections in lambda. Thanks. But I didn't understand your solution yet. By 1, you mean instead of emitting param1Change(Param p) signal, emit a param1Dirty() signal and save a dirty bit flag instead of real value? And then in 2, check for desired values (dirty bit flags) and emit a unified signal?

              nageshN Offline
              nageshN Offline
              nagesh
              wrote on last edited by
              #6

              @MajidKamali
              some sample code snippet what I was proposing..

              //Intermediate storage of Data & state
              struct Data
              {
                  bool 	 isParam1Set=false;
                  Param1   param1;
                  bool 	 isParam2Set=false;
                  Param1   param2;
              };
              Data paramsData;
              
              connect(d, Device::param1Changed,this,[this](int param1){
                  paramsData.isParam1Set =true;
                  paramsData.param1 = param1;
                  this->paramTracker();
              });
              connect(d, Device::param1Changed,this,[this](int param2){
                  paramsData.isParam1Set =true;
                  paramsData.param2 = param2;
                  this->paramTracker();
              });
              
              void paramTracker()
              {
              	if( paramsData.bParam1Set && paramsData.bParam2Set )
              	{
              		emit paramsChanged(paramsData.param1, paramsData.param2);
              		paramsData.isParam1Set = false;
              		paramsData.isParam2Set = false;
              	}
              }
              
              1 Reply Last reply
              2
              • M Offline
                M Offline
                MajidKamali
                wrote on last edited by
                #7

                @nagesh Thanks that's very useful

                1 Reply Last reply
                0

                • Login

                • Login or register to search.
                • First post
                  Last post
                0
                • Categories
                • Recent
                • Tags
                • Popular
                • Users
                • Groups
                • Search
                • Get Qt Extensions
                • Unsolved