Qt World Summit: Register Today!

Avoiding circular dependency with signals/slots

  • My application is made up of multiple, dynamically created "Node" widgets. In addition, there is a single "ProtocolManager" object, a pointer to which is stored in each "Node" object. The "ProtocolManager" object handles the creation, management, and processing of a TCP socket which communicates with a target system. "Node" objects call parameterized "ProtocolManager" methods to send commands to the target, the idea being that all communication happens via a single socket.

    This all works fine, although I now need to process responses from the target system and return the received data to the correct "Node" object which is identified by a unique ID. I could make a forward declaration inside "ProtocolManager" to "Node", pass a list of "Node" object pointers, and then transfer the data to the correct object. However, I'd like to avoid circular dependencies if possible.

    Alternatively, I could connect all "Nodes" to a signal which passes the data and the "Node" ID. Each object could then decide whether the data is relevant and ignore if not. With potentially dozens of "Nodes", this could be particularly inefficient.

    Is there perhaps a way to dynamically create a signal and connect it to the slot of one, and only one "Node", so data is only sent to the object for which it was intended?

    Any other ideas to get around this problem would be great! Thanks

  • Lifetime Qt Champion

    Hi and welcome to devnet,

    You could take a look at QNetworkAccessManager, your architecture description makes it look like a usefully inspiration.

  • @SGaist Thanks for your response. Could you elaborate please? I'm not sure how QNetworkAccessManager might solve my problem.

  • Two ways:
    1, same signals are sent to all nodes. These signals, however, have embedded Node id info in them. Parse them and ignore the signals which are not related. Simple protocol thing.
    2. send different signals to different nodes.
    I will go with the first one.

  • @JoeCFD 1. is what I proposed in the question, but worried that it would be inefficient.
    Not sure how 2. would work as the "Nodes" are generated dynamically, unless there's also a way to dynamically create signals? Thanks

  • @ECEC Parsing is very fast in GUI design. No worry about the efficiency. It is good enough to do it with unique ids or object names.

  • Lifetime Qt Champion

    @ECEC said in Avoiding circular dependency with signals/slots:

    @SGaist Thanks for your response. Could you elaborate please? I'm not sure how QNetworkAccessManager might solve my problem.

    I meant from an architecture point of view.

    With QNAM you can either connect your QNAM directly and manage things with it concerning the replies or you use the QNetworkReply returned by the operation you want to execute and use its signals and slots.

  • @SGaist Could you please illustrate with an example in the context of my application? Not sure I'm understanding how implementing something similar would work in practice.

  • Lifetime Qt Champion

    Your ProtocolManager could return something similar to a reply that could then be connected by the Node to a lambda or a slot to do further processing of the answer.

    Therefor, your ProtocolManager would not have to care about the Node objects.

  • @SGaist Ahhh, I think I see what you mean. So when the Nodes make a command request to the ProtocolManager, it returns a pointer to some sort of Reply object which the ProtocolManager populates when data for that Node is available. The Reply object then emits a signal which connects to a slot in Node. As requests are made frequently (10/sec) and the responses are short, I wonder whether it might make sense to have just one Reply object per Node instead of generating a new one per command request. What do you think, and is the above what you had in mind? Cheers

  • Lifetime Qt Champion

    Yes that's that.

    I would first get it to work and then benchmark the simple implementation. If you see performance issue then start optimizing.

  • @SGaist As the responses are so short, is there a risk that data is received and the Reply signal is emitted before the Reply object has been returned to the Node and connected? Is there a way to prevent this from happening?

  • Lifetime Qt Champion

    If you queue the request, it should not.

    As already suggested, you should take a look at the implementation of QNAM. You make a request, get a reply object and there's no "speed" issue with it.

Log in to reply