diff options
author | Michael Brasser <mbrasser@ford.com> | 2018-09-19 16:03:59 -0500 |
---|---|---|
committer | Michael Brasser <michael.brasser@live.com> | 2018-10-01 22:17:04 +0000 |
commit | c27f6f7cba7cda4ce6b8acf78d9151a174e8c8f8 (patch) | |
tree | 6a74ac04fec297c222ec813fb3df5de7855554c1 | |
parent | 833c58dacdb20511f0e7912f631f6c2a4f5412d5 (diff) |
Documentation clarifications
Change-Id: I6b34593c208d803e284fe5239f2eb1b0a873a2ee
Reviewed-by: Brett Stottlemyer <bstottle@ford.com>
7 files changed, 123 insertions, 79 deletions
diff --git a/src/remoteobjects/doc/src/remoteobjects-nodes.qdoc b/src/remoteobjects/doc/src/remoteobjects-nodes.qdoc index 0b66748..65778a9 100644 --- a/src/remoteobjects/doc/src/remoteobjects-nodes.qdoc +++ b/src/remoteobjects/doc/src/remoteobjects-nodes.qdoc @@ -30,18 +30,18 @@ \brief Describes how Qt Remote Objects Nodes pass data between nodes. \section1 Nodes -QRemoteObjectNodes (let's shorten the name to Node for now) are what enables -the passing of information between processes. All of the QtRO functionality is +QRemoteObjectNodes (Nodes) are what enable +the passing of information between processes. All QtRO functionality is enabled by a small number of distinct packets passing the necessary data between nodes. Each process that participates in QtRO's IPC will instantiate a Node-based type (QRemoteObjectNode, QRemoteObjectHost, or QRemoteObjectRegistryHost). The -latter types of Nodes provide additional functionality. Both QRemoteObjectHost +host types of Nodes provide additional functionality. Both QRemoteObjectHost and QRemoteObjectRegistryHost support the \l {QRemoteObjectHostBase::}{enableRemoting()} (and the corresponding \l {QRemoteObjectHostBase::}{disableRemoting()}) methods, which are the key methods to expose \l Source objects to the network. In order -to use the \l Registry functionality, there should be one QRemoteObjectRegistryHost +to use the \l Registry functionality, there should be a QRemoteObjectRegistryHost on the network. All other nodes can then pass the RegistryHost's URL to the Node's \e registryAddress constructor parameter, or pass the URL to the \l {QRemoteObjectNode::}{setRegistryUrl()} @@ -49,7 +49,7 @@ method. QtRO works as a peer-to-peer network. That is, in order to \l {QRemoteObjectNode::acquire()}{acquire()} a valid \l {Replica}, the \l -{Replica} node needs a connection to the node that hosts its \l {Source}. A +{Replica}'s node needs a connection to the node that hosts its \l {Source}. A host node is a node that allows other nodes to connect to it, which is accomplished by giving hosts unique addresses (the address is provided to the QRemoteObjectHost constructor or set by the setHostUrl method). The node that a @@ -61,9 +61,9 @@ in order to initialize the \l {Replica} and keep it up to date. Host Nodes use custom URLs to simplify connections. While the list will likely be extended, QtRO currently supports two types of connections. A "tcp" connection (using the standard tcp/ip protocol) supports connections between -devices as well as between processes on the same device. The 2nd option is a -"local" connection - which can have less overhead, depending on the underlying -OS features - but does not support connectivity between devices. +devices as well as between processes on the same device. A "local" connection +(which can have less overhead, depending on the underlying OS features) only supports +connections between processes on the same device. When using a local connection, a unique name must be used. For tcp connections, a unique address and port number combination much be used. @@ -76,7 +76,7 @@ simplify the connection process for a network with multiple Host Nodes. Connection types are summarized in the following table. \table 90% \header \li URL \li Host Node \li Connecting Node - \row \li \l {QUrl}("local:replica") \li \l {QLocalServer}("replica") \li \l {QLocalSocket}("replica") + \row \li \l {QUrl}("local:service") \li \l {QLocalServer}("service") \li \l {QLocalSocket}("service") \row \li \l {QUrl}("tcp://192.168.1.1:9999") \li \l {QTcpServer}("192.168.1.1",9999) \li \l {QTcpSocket}("192.168.1.1",9999) \endtable diff --git a/src/remoteobjects/doc/src/remoteobjects-overview.qdoc b/src/remoteobjects/doc/src/remoteobjects-overview.qdoc index 113eada..75cb5f4 100644 --- a/src/remoteobjects/doc/src/remoteobjects-overview.qdoc +++ b/src/remoteobjects/doc/src/remoteobjects-overview.qdoc @@ -71,8 +71,8 @@ signal to alert you if the connection is lost. Objects shared over QtRO use the links (conduits) between nodes for all communication. If you intend to share a QObject, you must create a \e {host node} with a URL other nodes can connect to. You can also use the QtRO \l -{Registry} to facilitate connections, but your node’s sharing \l {Source} -{sources} still need to be a Host Node. Each shared object is given a name +{Registry} to facilitate connections, but your nodes sharing \l {Source} +{sources} still need to be Host nodes. Each shared object is given a name (a QString), used for identifying it on the QtRO network. See the \l {Qt Remote Objects} {Overview} for a more detailed description, or @@ -166,10 +166,10 @@ Above, our SimpleSwitch, \li \c timeout_slot() is connected to the timeout() signal of \c stateChangeTimer, - \li \c server_slot(), which is called on the source (automatically - via QtRO) whenever any replica calls their version of the slot, + \li \c server_slot() -- which is called on the source (automatically + via QtRO) whenever any replica calls their version of the slot -- outputs the received value, and - \li \c currStateChanged(bool) signal, defined in \l {repc}-generated + \li \c currStateChanged(bool), defined in \l {repc}-generated \c rep_SimpleSwitch_source.h, is emitted whenever currState toggles. In this example, we ignore the signal on the source side, and handle it later on the replica side. @@ -276,10 +276,9 @@ generates the following output: A dynamic replica is initially created as a "bare" QObject - that is, it has no properties, signals or slots. QtRO returns the API for the object during initialization (after the connection to the source is made), thus the API is -added to the object at runtime. Dynamic replicas are good when a replica is -intended to be used in QML. +added to the object at runtime. -There are no changes to source side as a dynamic \l Replica only impacts +There are no changes to the source side as a dynamic \l Replica only impacts how the requestor node acquires the replica. The source-side code shown in \l {qtro-example1}{Example 1} will be used. @@ -317,8 +316,8 @@ to \l {qtro-example1}{Example 1}. \target qtro-example3 \section1 Example 3: Remote Nodes using a Registry -This example will illustrate the use of \l {Registry} for building the node -topology. For only two nodes, the benefits of using the Registry are minimal. +This example will illustrate the use of a \l {Registry} for building the node +topology. For only two nodes, the benefits of using a registry are minimal. With a registry, instead of using a QUrl to create a direct connection between two nodes, you use a different QUrl to point both the host and replica nodes to the registry. As the network grows, using a registry means that all nodes only @@ -336,7 +335,7 @@ node is created and connected to the \l {Registry}: \section2 Replica Code -Requestor object used for this example is the dynamic replica client +The requestor object used for this example is the dynamic replica client discussed in \l {qtro-example2}{Example 2}. The only modification is in \c main.cpp: a \l {Registry} node is created diff --git a/src/remoteobjects/doc/src/remoteobjects-registry.qdoc b/src/remoteobjects/doc/src/remoteobjects-registry.qdoc index 39d6d48..c122da0 100644 --- a/src/remoteobjects/doc/src/remoteobjects-registry.qdoc +++ b/src/remoteobjects/doc/src/remoteobjects-registry.qdoc @@ -35,7 +35,7 @@ When you \l {QRemoteObjectNode::acquire()} a replica, the node URL is not passed as an argument. This means you do not need to specify the host node, but it does require you to have some other means of connecting to that host. Without the -registry, it is necessary to manually call \l {QRemoteObjectNode::connect()}, +registry, it is necessary to manually call \l {QRemoteObjectNode::connectToNode()}, from each node, to every host node that has \l {Source} objects it should replicate. This is fine for small or static networks, but does not scale. diff --git a/src/remoteobjects/doc/src/remoteobjects-repc.qdoc b/src/remoteobjects/doc/src/remoteobjects-repc.qdoc index 7580151..bb47b90 100644 --- a/src/remoteobjects/doc/src/remoteobjects-repc.qdoc +++ b/src/remoteobjects/doc/src/remoteobjects-repc.qdoc @@ -46,13 +46,13 @@ files are processed by repc, repc generates both \l {Source} and \l {Replica} header files. - The Qt Remote Objects module also includes qmake macros (\l REPC_SOURCE, \l - REPC_REPLICA) that can be added to your project file to automatically run + The Qt Remote Objects module also includes qmake variables (\l REPC_SOURCE, \l + REPC_REPLICA, and \l REPC_MERGED) that can be added to your project file to automatically run repc, and add the resulting files to the list of files processed by \l{moc}{Meta Object Compiler} during the build process, making use of Qt Remote Objects in your projects simple. - While Qt Remote Objects supports sharing QObjects over the network (using + While Qt Remote Objects supports sharing any QObject over the network (using enableRemoting on the Source side and acquireDynamic on the Replica side), there are a couple of advantages to letting repc define your objects. First of all, while \l {QRemoteObjectDynamicReplica} {DynamicReplicas} are @@ -63,7 +63,7 @@ format supports default values, which can be handy if you are unable to ensure the Source is available when the Replica is instantiated. - See the documentation \l {Source} {Sources here} for information on using + See the documentation \l {Source} {here} for information on using the generated files in your code. Here we will focus on the repc format and options. @@ -92,7 +92,7 @@ Q_PROPERTY elements are created by using the PROP keyword in the rep file. The syntax is the \c PROP keyword followed by the definition enclosed - in quotes, where the definition is the type, the name, and (optionally) a + in parentheses, where the definition is the type, the name, and (optionally) a default value or attributes. \code PROP(bool simpleBool) // boolean named simpleBool @@ -118,7 +118,7 @@ More information about creating custom types can be found \l {Creating Custom Qt Types} {here}. - By default, properties will have getters and a "push" Slot defined, as well + By default, properties will have getters and a "push" slot defined, as well as a notify signal emitted when the value is changed. Qt Remote Objects requires the notify signal on the Source object to trigger sending updates to the attached Replicas. In earlier versions of QtRO, properties defaulted @@ -161,11 +161,11 @@ // sets the myVal to something else (race // condition) // Rather than use QSignalSpy, the event-driven practice would be to connect the - // myValChanged notify signal to a Slot that responds to the changes. + // myValChanged notify signal to a slot that responds to the changes. \endcode QtRO now defaults to READPUSH, which provides an automatically generated - Slot for requesting a property change. + slot for requesting a property change. \code // In .rep file, defaults to READPUSH PROP(bool myVal) // No setMyVal(int myVal) on Replica, has @@ -193,7 +193,7 @@ You can also use the \c CONSTANT, \c READONLY, \c PERSISTED, \c READWRITE, \c READPUSH, or \c SOURCEONLYSETTER keywords in the PROP declaration, which - affects how this is implemented. READPUSH is the default value if no value + affects how the property is implemented. READPUSH is the default value if no value used. \code @@ -205,13 +205,13 @@ Q_PROPERTY declared as CONSTANT on the SOURCE side. However, replicas cannot know the correct value until they are initialized, which means the property value has to be allowed to change during initialization. For - READONLY, the Source will have neither a setter nor a push slot, and the + READONLY, the source will have neither a setter nor a push slot, and the replica side will not have a push slot generated. Adding the PERSISTED trait to a PROP will have the PROP use the \l QRemoteObjectAbstractPersistedStore instance set on a Node (if any) to save/restore PROP values. Another nuanced value is SOURCEONLYSETTER, which provides another way of - specifying asymmetric behavior, where the Source (specifically the helper + specifying asymmetric behavior, where the \l Source (specifically the helper class, \l SimpleSource) will have a public getter and setter for the property, but it will be ReadOnly (with a notify signal) on the \l Replica side. Thus the property can be fully controlled from the \l Source side, @@ -341,15 +341,55 @@ instance, use #include or #define directives that support the logic or datatypes needed. - The repc tool currently only everything from the "#" symbol to the + The repc tool currently ignores everything from the "#" symbol to the end-of-line and adds that to the generated files. So multi-line #if/#else/#endif statements and multi-line macros are not supported. - \section1 Project file macros + \section1 qmake variables \section2 REPC_REPLICA - ... + + Specifies the names of all rep files in the project that should be used to generate + replica header files. + + For example: + \code + REPC_REPLICA = media.rep \ + location.rep + \endcode + + The generated file(s) will be of the form \c {rep_<replica file base>_replica.h}. + \section2 REPC_SOURCE - ... - \section2 QOBJECT_REPLICA - ... + + Specifies the names of all rep files in the project that should be used to generate + source header files. + + For example: + \code + REPC_SOURCE = media.rep \ + location.rep + \endcode + + The generated file(s) will be of the form \c {rep_<replica file base>_source.h}. + + \section2 REPC_MERGED + + Specifies the names of all rep files in the project that should be used to generate + combined (source and replica) header files. + + For example: + \code + REPC_MERGED = media.rep \ + location.rep + + The generated file(s) will be of the form \c {rep_<replica file base>_merged.h}. + + \note Typically sources and replicas live in separate processes or devices, so this variable + is not commonly used. + \endcode + + \section 2 QOBJECT_REP + + Specifies the names of existing QObject header files that should be used to generate corresponding + .rep files. */ diff --git a/src/remoteobjects/doc/src/remoteobjects-replica.qdoc b/src/remoteobjects/doc/src/remoteobjects-replica.qdoc index 1c1cfca..4ed144b 100644 --- a/src/remoteobjects/doc/src/remoteobjects-replica.qdoc +++ b/src/remoteobjects/doc/src/remoteobjects-replica.qdoc @@ -27,14 +27,14 @@ /*! \page qtremoteobjects-replica.html \title Qt Remote Objects Replica -\brief Describes how the remote object replica works as a proxy object. +\brief Describes how the remote object replica works as a surrogate object. \target Replica \section1 Replica Objects -A remote object replica is a proxy object that has (approximately) the same API +A remote object replica is a surrogate 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 +initialized or if it loses its connection 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 @@ -42,57 +42,56 @@ replica is instantiated, it will only be known once the replica is initialized 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. +header file is generated (using the REPC_REPLICA variable in your .pro file +will 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. +call \l {QRemoteObjectNode::acquireDynamic()}, passing in +the \l {Source} name (a QString) as an argument. Dynamic replicas are a bit +more verbose to use from C++, but do not require compilation. 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 +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. +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. +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 +A host node will share the list of sources it hosts with 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 +When a node acquires a replica for a known source, it 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 +definition for the source. The replica's 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 +If a replica is instantiated but its 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. +be created, but will remain uninitialized. -If, at a later time, the replica node gets notified that the requested source is +If, at a later time, the replica's 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). +connection is restored (this making sure all properties are current). \section1 Replica Ownership @@ -102,13 +101,13 @@ 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 +You can instantiate multiple copies of the same replica. 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 +delete replicas will prevent the reference count on this private object from reaching 0, +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. +{QSharedPointer} be used to help track replica lifetime. */ diff --git a/src/remoteobjects/doc/src/remoteobjects-source.qdoc b/src/remoteobjects/doc/src/remoteobjects-source.qdoc index 926a8dd..fd97027 100644 --- a/src/remoteobjects/doc/src/remoteobjects-source.qdoc +++ b/src/remoteobjects/doc/src/remoteobjects-source.qdoc @@ -42,13 +42,11 @@ If you already have a fully defined QObject, it can become a Source simply by passing it to \l {QRemoteObjectHostBase::enableRemoting()}. This lets other processes/devices create a \l {Replica} of the object to interact with (see \l {Remote Object Interaction}). You can then instantiate \l {QRemoteObjectDynamicReplica}s -of your object, or use the \l {QOBJECT_REPLICA} macro in your project file, -which will use \l {repc} to create a header file describing the Replica for -use in that process/on that device (and provides compile-time checks). +of your object. Letting \l {repc} generate a \l {Source} header file for your project (using -the \l {REPC_SOURCE} macro) provides three options of implementing the desired -API. If your class name was Foo, the options would be the following (and see \l +the \l {REPC_SOURCE} variable) provides three options for implementing the desired +API. If your class name was Foo, the options would be the following (see \l {The rep file format} for help in creating a rep file) \list @@ -62,25 +60,24 @@ There is a <Type>SimpleSource class defined in the header, which provides basic getter/setter methods for each property and implements data members of the correct property type in the header. Here "<Type>" represents the class name from the .rep file, so if your class is of type "MyType" in the .rep file, -there will be a MyTypeSimpleSource class declared in the produced header file. +there will be a MyTypeSimpleSource class declared in the generated header file. This is a fast way to get started using the API. To use this class, you need to inherit from this class and implement any defined slots (which are pure virtual in the generated header file). Whatever logic is needed to manage the -exposed properties and define when Signals need to be emitted would be added to -the overriding class as well. +exposed properties and emit signals would be added to +the inheriting class as well. \target TypeSource If you need to hide the implementation details, you can use the <Type>Source -class instead, which is the 2nd class declared in the same resulting header +class instead, which is the 2nd class declared in the header file. This class definition does not provide data members, and makes the getter/setter functions pure virtual as well. You have more flexibility in how -you implement the class, although you need to write more code. This defines the -API for both the source and replica side from a single .rep template file. +you implement the class, although you need to write more code. \target TypeAPI Finally, there is the <Type>SourceAPI class generated in the header. This is a templated class, for use specifically by the templated version of \l -{QRemoteObjectHostBase::enableRemoting()} function overload, which allows you to +{QRemoteObjectHostBase::enableRemoting()}, which allows you to use any QObject that supports the desired API as the source. You will get compile-time warnings if the class does not provide the correct API, and using this class allows you to hide or convert properties or signal/slot parameters. @@ -104,10 +101,12 @@ types, or a static name() function for the SourceAPI type). If you pass your own QObject type to \l {QRemoteObjectHostBase::enableRemoting()}, the name will be determined using the following logic: \list + \li A name can optionally be passed to \l {QRemoteObjectHostBase::enableRemoting()}. + If provided, that name will be used. \li If the object or any of its ancestors has Q_CLASSINFO of type - "RemoteObject Type" defined, the provided name will be used. + "RemoteObject Type" defined, the defined type name will be used. \li Otherwise, the QObject's objectName (if set) will be - used. \li If neither is available, the call to - \l {QRemoteObjectHostBase::enableRemoting()} will fail, returning False. + used. \li If none of the above are available, the call to + \l {QRemoteObjectHostBase::enableRemoting()} will fail, returning false. \endlist */ diff --git a/src/remoteobjects/doc/src/remoteobjects-troubleshooting.qdoc b/src/remoteobjects/doc/src/remoteobjects-troubleshooting.qdoc index ee25957..db5b8d9 100644 --- a/src/remoteobjects/doc/src/remoteobjects-troubleshooting.qdoc +++ b/src/remoteobjects/doc/src/remoteobjects-troubleshooting.qdoc @@ -29,5 +29,12 @@ \title Troubleshooting Qt Remote Objects \section1 Troubleshooting -//! TODO +QtRO includes a number of internal logging categories that can be used for further debugging: + +\code +qt.remoteobjects +qt.remoteobjects.io +qt.remoteobjects.models +\endcode + */ |