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.

#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:

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::fromEnv()
        .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

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);

Note

SharedPV follows the Source rules for Threading and locking.

struct SharedPV

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 to subscribing clients).

A later call to close() will force disconnect all clients, and discard the data value and type. A further call to open() sets a new data value, which may be of a different data type.

The onPut() and onRPC() methods attach functors which will be called each time a Put or RPC operation is executed by a client.

Public Functions

void attach(std::unique_ptr<ChannelControl> &&op)

Attach this SharedPV with a new client channel. Not necessary when using StaticSource. eg. could call from Source::onCreate()

void onFirstConnect(std::function<void(SharedPV&)> &&fn)

Callback when the number of attach()d clients becomes non-zero.

void onLastDisconnect(std::function<void(SharedPV&)> &&fn)

Callback when the number of attach()d clients becomes zero.

void onPut(std::function<void(SharedPV&, std::unique_ptr<ExecOp>&&, Value&&)> &&fn)

Callback when a client executes a new Put operation.

void onRPC(std::function<void(SharedPV&, std::unique_ptr<ExecOp>&&, Value&&)> &&fn)

Callback when a client executes an RPC operation.

Note

RPC operations are allowed even when the SharedPV is not opened (isOpen()==false)

void open(const Value &initial)

Provide data type and initial value. Allows clients to begin connecting.

Parameters:

initial – Defines data type, and initial value

Pre:

!isOpen()

bool isOpen() const

Test whether open() has been called w/o matching close()

void close()

Reverse the effects of open() and force disconnect any remaining clients.

void post(const Value &val)

Update the internal data value, and dispatch subscription updates to any clients.

The value given as the argument must be created from the same TypeDef instance as the value given to open(). It is recommended that the same type is reused using by calling Value::cloneEmpty().

void fetch(Value &val) const

query the internal data value and update the provided Value.

Value fetch() const

Return a (shallow) copy of the internal data value.

Public Static Functions

static SharedPV buildMailbox()

Create a new SharedPV with a Put handler which post() s any client provided Value.

static SharedPV buildReadonly()

Create a new SharedPV with a Put handler which rejects any client provided Value.

struct StaticSource

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.

Public Functions

std::shared_ptr<Source> source() const

Fetch the Source interface, which may be used with Server::addSource()

void close()

call SharedPV::close() on all PVs

StaticSource &add(const std::string &name, const SharedPV &pv)

Add a new name through which a SharedPV may be addressed.

StaticSource &remove(const std::string &name)

Remove a single name.