Revision control
Copy as Markdown
// Copyright (C) 2019 Ford Motor Company
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GFDL-1.3-no-invariants-only
/*!
\page remoteobjects-example-static-source
\title Example 1: Direct Connection using a Static Source
\brief Describes how the Qt Remote Objects establishes a direct connection using a static source.
\target qtro-example1
In this example, the source object is a simple binary switch that toggles its
state based on a timer. When the state changes, a signal is emitted by the
source which QtRO propagates to all replicas. Since the replicas have the same
properties, signals, and slots as were exposed from the source, any slots
connected to the replica's signal will be called when the replica receives that
signal. The client process then echoes back the received switch state to the
source by emitting its own signal which is connected to a slot on the replica.
\list 1
\li \b {Create a source object}
To create this \l Source object, first we create the definition file,
\c simpleswitch.rep. This file describes the properties and methods for the
object and is input to the Qt Remote Objects Compiler \l{repc}. This file only
defines interfaces that are necessary to expose to the \l{Replica}{Replicas}.
\c simpleswitch.rep
\snippet doc_src_simpleswitch.cpp simpleSwitch_rep
In \c simpleswitch.rep,
\list
\li \c currState holds the current state of the switch.
\li \c server_slot() allows us to interact with the source - it will be
connected to the \c echoSwitchState(bool newstate) signal.
\endlist
For repc to process this file, add the following line to your \c cmake file:
\snippet cmake-macros/CMakeLists.txt simpleSwitch_cmake_add_repc_source
If you're using \c qmake:
\snippet doc_src_simpleswitch.cpp simpleSwitch_repsource_example1
These instructions are only relevant for the Qt Remote Object module,
so you need to add it to your project as well. If you're using CMake,
add:
\snippet cmake-macros/CMakeLists.txt remote_objects_cmake
\snippet cmake-macros/CMakeLists.txt remote_objects_cmake_link
If you're using \c qmake:
\snippet doc_src_simpleswitch.cpp simpleSwitch_remoteobjectsadd_example1
repc creates the \c rep_SimpleSwitch_source.h header in the build directory
that you specify. For more information, see \l{Source}.
repc creates three helper classes for use with QtRO. For this example, we
use the basic: \c SimpleSwitchSimpleSource. It's an abstract class, defined in
\c rep_SimpleSwitch_source.h. We derive from it to define our SimpleSwitch
implementation class as shown below:
\c simpleswitch.h
\snippet doc_src_simpleswitch.cpp simpleSwitch_serverheader_example1
In \c simpleswitch.h,
\list
\li \c stateChangeTimer is a QTimer that is used to toggle the state of our
SimpleSwitch.
\li \c timeout_slot() is connected to \c stateChangeTimer's timeout() signal.
\li \c server_slot() -- which is called automatically on the source whenever
any replica calls their version of the slot -- outputs the received value.
\li \c currStateChanged(bool), defined in the \l{repc}-generated
\c rep_SimpleSwitch_source.h, is emitted whenever \c currState toggles.
In this example, we ignore the signal on the source side, and handle it
later on the replica side.
\endlist
The definition of our \c SimpleSwitch class is shown below:
\c simpleswitch.cpp
\snippet doc_src_simpleswitch.cpp simpleSwitch_serversource_example1
\li \b {Create a registry}
Because this example uses a direct connection between nodes, we can omit this
step.
\li \b {Create a host node}
The host node is created as shown below:
\snippet doc_src_simpleswitch.cpp simpleSwitch_serverhostnode_example1
\li \b {Host source object and remoting}
The following statements instantiate the \l {Source} object and pass it on to
the host to enable "remoting", which is the process of making an object visible
to the QtRO network:
\snippet doc_src_simpleswitch.cpp simpleSwitch_enableremoting_example1
The contents of \c main.cpp file that implements the steps described above are
as follows:
\c main.cpp
\snippet doc_src_simpleswitch.cpp simpleSwitch_servermaincpp_example1
Compile and run this source-side project. The output, without any replicas
created, should look as shown below with the switch state toggling between
\c true and \c false every two seconds.
\image DirectConnectServerOutput.png "Example 1: Server Output"
\endlist
The subsequent steps are for creating the replica side of the network, which in
this example gets the state of switch from the \l {Source} and echoes it back.
\section2 Replica Code
\list 1
\li \b {Use repc to add a replica to your project}
We use the same API definition file as we did on the source side,
\c SimpleSwitch.rep, to create a \l {Replica} header file using the \l {repc}.
If you're using \c cmake, include the following line in your client side
\c cmake file, specifying a \c .rep file input:
\snippet cmake-macros/CMakeLists.txt simpleSwitch_cmake_add_repc_replica
If you're using \c qmake, add the following line to your client side \c .pro
file:
\snippet doc_src_simpleswitch.cpp simpleSwitch_clientrep_example1
The \l {repc} tool generates a \c rep_SimpleSwitch_replica.h file in the build
directory. For more information, see \l{Replica}.
\li \b {Create a node to connect with the source's host node}
The following code instantiates the second node on the network and connects it
with the source host node:
\snippet doc_src_simpleswitch.cpp simpleSwitch_clientremotenode_example1
\li \b {Call the node's \l{QRemoteObjectNode::}{acquire()} to create a pointer
to a replica}
First, we instantiate a replica:
\snippet doc_src_simpleswitch.cpp simpleSwitch_clientacquirereplica_example1
\note \l{QRemoteObjectNode::}{acquire()} returns a pointer to the replica, but
doesn't manage its lifetime. This example shows the recommended process of
wrapping the returned pointer in a QSharedPointer or QScopedPointer to ensure
that the pointer is always deleted properly.
\c main.cpp implements the steps described above and instantiates our object:
\c main.cpp
\snippet doc_src_simpleswitch.cpp simpleSwitch_clientmain_example1
The complete declaration and definition for the \c Client class is as follows:
\c client.h
\snippet doc_src_simpleswitch.cpp simpleSwitch_clientheader_example1
\c client.cpp
\snippet doc_src_simpleswitch.cpp simpleSwitch_clientcpp_example1
Compiling and running this example together with the source-side example
generates the following output:
\image DirectConnectClientServerOutput.png "Direct Connect Server Client Communication output"
\endlist
*/