/****************************************************************************
**
** Copyright (C) 2014 Ford Motor Company
** Contact: https://www.qt.io/licensing/
**
** This file is part of the QtRemoteObjects module of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL21$
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and The Qt Company. For licensing terms
** and conditions see http://www.qt.io/terms-conditions. For further
** information use the contact form at http://www.qt.io/contact-us.
**
** GNU Lesser General Public License Usage
** Alternatively, this file may be used under the terms of the GNU Lesser
** General Public License version 2.1 or version 3 as published by the Free
** Software Foundation and appearing in the file LICENSE.LGPLv21 and
** LICENSE.LGPLv3 included in the packaging of this file. Please review the
** following information to ensure the GNU Lesser General Public License
** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** As a special exception, The Qt Company gives you certain additional
** rights. These rights are described in The Qt Company LGPL Exception
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
** $QT_END_LICENSE$
**
****************************************************************************/
/*!
\page qtremoteobjects-replica.html
\title Qt Remote Objects Replica
\brief Describes how the remote object replica works as a proxy object.
\target Replica
\section1 Replica Objects

A remote object replica is a proxy object that has (approximately) the same API
as the \l {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 \l {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 \l {Remote Object Interaction}).

A compiled replica is a \l {QRemoteObjectReplica} based type, where the derived
class definition is automatically generated by the \l {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 \l
{QRemoteObjectNode::acquire} template function to create the Replica instance.

A \l {QRemoteObjectDynamicReplica} can be generated at runtime. To do so, you
call the non-templated version of \l {QRemoteObjectNode::acquire()}, passing in
as an argument the \l {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.

See \l {QRemoteObjectReplica} and \l {QRemoteObjectDynamicReplica}

\section1 Replica Initialization

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 \l {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).


\section1 Replica Ownership

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 \l {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 \l {QScopedPointer} or \l
{QSharedPointer} be used to help track a replica lifetime.
*/
