doc sharedpv

This commit is contained in:
Michael Davidsaver
2020-02-04 14:37:33 -08:00
parent dadb622a59
commit 3129c2de75
3 changed files with 118 additions and 2 deletions
+1
View File
@@ -11,6 +11,7 @@ This module is under active development and is only suitable for experimental us
nt
typedef
server
sharedpv
source
util
+77
View File
@@ -0,0 +1,77 @@
SharedPV and StaticSource
-------------------------
A SharedPV is a single data value which may be accessed by multiple clients through a Server.
It is "shared" in the sense that all clients are manipulating a single variable.
.. code-block:: c++
#include <pvxs/sharedpv.h>
namespace pvxs { namespace server { ... } }
Each SharedPV instance has (after open() ) an associated data structure
which is later manipulated with post().
A simple usage is:
.. code-block:: c++
using namespace pvxs;
auto initial = nt::NTScalar{TypeCode::Float64}.create();
initial["value"] = 42.0;
auto src(server::StaticSource::build());
auto pv(server::SharedPV::buildMailbox());
pv.open(initial);
src.add(argv[1], pv);
auto serv = server::Server::Config::from_env()
.build()
.addSource("box", src.source());
serv.run();
In this context "mailbox" refers to the default onPut() handler, which simply post()s whatever
the client sends.
An example of a SharedPV with a custom Put handler
.. code-block:: c++
auto pv(server::SharedPV::buildMailbox());
pv.opPut([](server::SharedPV& pv,
std::unique_ptr<server::ExecOp>&& op,
Value&& top)
{
// We decide that .value will be present with .open()
auto val = top["value"];
// is client trying to change .value ?
if(val.isMarked(true, true)) {
auto val = top["value"].as<double>();
// clip to range [0, 10]
top["value"] = std::max(0.0, std::min(val, 10.0));
}
// update and send to subscribers
pv.post(std::move(top));
// notify client of success (or call op->error() if not)
op->reply();
});
auto initial = nt::NTScalar{TypeCode::Float64}.create();
initial["value"] = 42.0;
auto src(server::StaticSource::build());
pv.open(initial);
.. doxygenstruct:: pvxs::server::SharedPV
:members:
.. doxygenstruct:: pvxs::server::StaticSource
:members:
+40 -2
View File
@@ -21,28 +21,58 @@ struct ChannelControl;
struct ExecOp;
struct Source;
/** A SharedPV is a single data value which may be accessed by multiple clients through a Server.
*
* On creation a SharedPV has no associated data structure, or data type.
* This is set by calling open() to provide a data type, and initial data values.
* Subsequent calls to post() will update this data structure (and send notifications
* so subscribing clients).
*
* A later call to close() will force disconnect all clients, and discard the data value and type
* in preperation for a later call to open() to set a new data value, which may be of a different type.
*
* The onPut() and onRPC() methods attach functors which will be called each time a Put or RPC
* operation is executed by a client.
*/
struct PVXS_API SharedPV
{
//! Create a new SharedPV with a Put handler which post() s any client provided Value.
static SharedPV buildMailbox();
//! Create a new SharedPV with a Put handler which rejects any client provided Value.
static SharedPV buildReadonly();
~SharedPV();
inline explicit operator bool() const { return !!impl; }
// call from Source::onCreate()
//! Attach this SharedPV with a new client channel.
//! Not necessary when using StaticSource.
//! eg. could call from Source::onCreate()
void attach(std::unique_ptr<ChannelControl>&& op);
//! Callback when the number of attach()d clients becomes non-zero.
void onFirstConnect(std::function<void()>&& fn);
//! Callback when the number of attach()d clients becomes zero.
void onLastDisconnect(std::function<void()>&& fn);
//! Callback when a client executes a new Put operation.
void onPut(std::function<void(SharedPV&, std::unique_ptr<ExecOp>&&, Value&&)>&& fn);
//! Callback when a client executes an RPC operation.
//! @note RPC operations are allowed event when @code !isOpen() @endcode
void onRPC(std::function<void(SharedPV&, std::unique_ptr<ExecOp>&&, Value&&)>&& fn);
void open(const Value& prototype);
/** Provide data type and initial value. Allows clients to begin connecting.
* @pre !isOpen()
* @param initial Defines data type, and initial value
*/
void open(const Value& initial);
//! Test whether open() has been called w/o matching close()
bool isOpen() const;
//! Reverse the effects of open() and force disconnect any remaining clients.
void close();
//! Update the internal data value, and dispatch subscription updates to any clients.
void post(Value&& val);
//! query the internal data value.
void fetch(Value& val);
struct Impl;
@@ -50,6 +80,11 @@ private:
std::shared_ptr<Impl> impl;
};
/** Allow clients to find (through a Server) SharedPV instances by name.
*
* A single PV name may only be added once to a StaticSource.
* However, a single SharedPV may be added multiple times with different PV names.
*/
struct PVXS_API StaticSource
{
static StaticSource build();
@@ -58,9 +93,12 @@ struct PVXS_API StaticSource
inline explicit operator bool() const { return !!impl; }
//! Fetch the Source interface, which may be used with Server::addSource()
std::shared_ptr<Source> source() const;
//! Add a new name through which a SharedPV may be addressed.
StaticSource& add(const std::string& name, const SharedPV& pv);
//! Remove a single name
StaticSource& remove(const std::string& name);
struct Impl;