diff --git a/documentation/client.rst b/documentation/client.rst new file mode 100644 index 0000000..2321b24 --- /dev/null +++ b/documentation/client.rst @@ -0,0 +1,39 @@ +Client +====== + +`pvxs::client::Context` represents a PVA protocol client. :: + + #include + namespace pvxs { namespace client { ... } } + +Configuration +------------- + +The recommended starting point is creating new context configured from $PVA_* environment variables. +Use `pvxs::server::Config::from_env()` and then `pvxs::server::Config::build()`. + +EPICS_PVA_ADDR_LIST + A list of destination addresses to which UDP search messages will be sent. + May contain unicast and/or broadcast addresses. + +EPICS_PVA_AUTO_ADDR_LIST + If "YES" then all local broadcast addresses will be implicitly appended to $EPICS_PVA_ADDR_LIST + "YES" if unset. + +EPICS_PVA_BROADCAST_PORT + Default UDP port to which UDP searches will be sent. 5076 if unset. + +.. code-block:: c++ + + using namespace pvxs; + auto ctxt = client::Confiig::from_env().build(); + + +.. doxygenclass:: pvxs::client::Context + :members: + +As an alternative to `pvxs::server::Config::from_env()` +a Config may be created and filled in programatically. + +.. doxygenstruct:: pvxs::client::Config + :members: diff --git a/documentation/index.rst b/documentation/index.rst index 5865d2d..e9a5b9f 100644 --- a/documentation/index.rst +++ b/documentation/index.rst @@ -10,6 +10,7 @@ The canonical source can be found at https://github.com/mdavidsaver/pvxs :caption: Contents: value + client server util diff --git a/src/pvxs/client.h b/src/pvxs/client.h index 012b018..adf2de4 100644 --- a/src/pvxs/client.h +++ b/src/pvxs/client.h @@ -75,6 +75,14 @@ struct PVXS_API Subscription { virtual void cancel() =0; }; +/** An independent PVA protocol client instance + * + * Typically created with Config::build() + * + * @code + * Context ctxt(Config::from_env().build()); + * @endcode + */ class PVXS_API Context { public: struct Pvt; @@ -82,6 +90,7 @@ public: //! An empty/dummy Server constexpr Context() = default; //! Create/allocate, but do not start, a new server with the provided config. + //! Config::build() is a convienent shorthand. explicit Context(const Config &); ~Context(); @@ -93,6 +102,7 @@ public: Request request() const; + //! Options common to all operations template class CommonBuilder { protected: @@ -114,14 +124,28 @@ public: bool _get; public: GetBuilder(const std::shared_ptr& pvt, const std::string& name, bool get) :CommonBuilder{pvt,name}, _get(get) {} + //! Callback through which result Value will be delivered GetBuilder& result(decltype (_result)&& cb) { _result = std::move(cb); return *this; } + //! Initiate network operation. PVXS_API std::shared_ptr exec(); friend struct Context::Pvt; }; GetBuilder get(const std::string& name) { return GetBuilder{pvt, name, true}; } + /** Request type information from PV. + * Results in a Value with no marked fields. + * + * @code + * Context ctxt(...); + * auto op = ctxt.info("pv:name") + * .result([](Value&& prototype){ + * std::cout< { @@ -172,21 +196,24 @@ struct PVXS_API Config { std::vector addressList; //! UDP port to bind. Default is 5076. May be zero, cf. Server::config() to find allocated port. - unsigned short udp_port; + unsigned short udp_port = 5076; //! Whether to populate the beacon address list automatically. (recommended) - bool autoAddrList; + bool autoAddrList = true; //! Default configuration using process environment static Config from_env(); - //! Empty config - Config() :udp_port(5076), autoAddrList(true) {} - - //! Apply rules to translate current requested configuration - //! into one which can actually be loaded. - //! @post autoAddrList==false + /** Apply rules to translate current requested configuration + * into one which can actually be loaded based on current host network configuration. + * + * Explicit use of expand() is optional as the Context ctor expands any Config given. + * expand() is provided as a aid to help understand how Context::effective() is arrived at. + * + * @post autoAddrList==false + */ void expand(); + //! Create a new client Context using the current configuration. inline Context build() const { Context ret(*this);