A remote object replica is a proxy object that has (approximately) the same API as the Source QObject it is replicating. There are a few additional properties and signals to make it possible to detect when the Replica is initialized or if it loses the connectivity to the Source object. There are a few other differences: a constant property on the source cannot be constant on the replica. The value will not be known at the time the replica is instantiated, it will only be known once the replica is initialized (see Remote Object Interaction).
A compiled replica is a QRemoteObjectReplica based type, where the derived class definition is automatically generated by the repc compiler. Only a header file is generated (and using the REPC_REPLICA macro in your .pro file can make generation part of the build process), but it is a complete type. There is no public constructor, you need to use the QRemoteObjectNode::acquire template function to create the Replica instance.
A QRemoteObjectDynamicReplica can be generated at runtime. To do so, you call the non-templated version of QRemoteObjectNode::acquire(), passing in as an argument the Source name (a QString). Dynamic replicas are a bit more verbose to use from C++, but do not require compilation and can be used easily in QML or (potentially) exposed to scripting languages such as Python. Dynamic replicas do not support initial property values, and do not support introspection until they have been initialized.
An important difference between these two ways of creating replicas is the behavior before the replica is initialized. Since a Dynamic replica only gets a metaObject after initialization, it basically has no API before initialization. No properties, and no Signals to connect slots to. Due to the compile-time creation of the metaObject for compiled replicas, their API is available when the replica is instantiated. You can even provide default values for Properties in the template file, which will be used until the replica is initialized with current values from the Source.
A host node will share the list of sources it hosts and every other node that connects to it. It will send updates when sources are added or removed from the list. In this way, a connected node will always know what sources it can attach to. Changes to a specific Source are only propagated to nodes that have a replica of that source. This avoids unnecessary network traffic.
When a node acquires a replica for a known source, the replica node sends a request for that source to the host node. Upon receipt of this request, the host will create a reply packet with the current values of all properties of the source. If the requested replica is dynamic, it will include the API definition for the source. The replica node will be included in the list of connections that receive changes to that source from then on.
If a replica is instantiated but the node is not connected to the node that hosts the requested source (or that object lives in a host node process, but sharing/remoting has not been enabled for the QObject), the Replica will still be created, it will just remain uninitialized.
If, at a later time, the replica node gets notified that the requested source is available from a connected node, it will at that point request the source and start the initialization process.
If the connection to a host node is lost, the replica will transition to the invalid state. It will attempt to reconnect and will re-initialize if the connection is restored (this making sure all Properties are current).
The acquire methods return a pointer to the replica QObject instantiated by the node. The node has no way of knowing the intended lifetime of the replica, so it is the responsibility of the calling program to delete the replica when it is no longer needed.
You can instantiate multiple copies of the same replica (this may be necessary in QML for instance). All replicas of the same source from a single node will share a private data member which handles the network communication. This means multiple instances of a Replica do not introduce additional network traffic, although there will be some additional processing overhead. Failing to delete replicas will prevent the reference count on this private object to be invalid, and cause unnecessary network communication until the calling process exits. For this reason, it is recommended that QScopedPointer or QSharedPointer be used to help track a replica lifetime.
As part of the free Business evaluation, we offer a free welcome call for companies, to talk about your requirements, and how the Felgo SDK & Services can help you. Just sign up and schedule your call.
Sign up now to start your free Business evaluation: