diff --git a/documentation/example.rst b/documentation/example.rst index 91e8d8a..c1f5ab2 100644 --- a/documentation/example.rst +++ b/documentation/example.rst @@ -4,9 +4,7 @@ Examples Mailbox Server -------------- -Serves a single PV name. -Any updates written (PUT) to this PV will be stored verbatim -and sent to any subscribers. +Latest version https://github.com/mdavidsaver/pvxs/blob/master/example/mailbox.cpp .. literalinclude:: ../example/mailbox.cpp :language: c++ diff --git a/example/mailbox.cpp b/example/mailbox.cpp index 7b2315e..73814d4 100644 --- a/example/mailbox.cpp +++ b/example/mailbox.cpp @@ -3,9 +3,16 @@ * pvxs is distributed subject to a Software License Agreement found * in file LICENSE that is included with this distribution. */ +/** + * Serves a single PV name. + * Any updates written (PUT) to this PV will be stored verbatim + * and sent to any subscribers. + */ #include +#include + #include #include #include @@ -21,12 +28,15 @@ int main(int argc, char* argv[]) } // Read $PVXS_LOG from process environment and update - // logging configuration. eg. PVXS_LOG=*=DEBUG makes - // a lot of noise. + // logging configuration. eg. + // export PVXS_LOG=*=DEBUG + // makes a lot of noise. logger_config_env(); - // Must provide a data type for the mailbox + // Must provide a data type for the mailbox. + // Use pre-canned definition of scalar with meta-data Value initial = nt::NTScalar{TypeCode::Float64}.create(); + // (optional) Provide an initial value initial["value"] = 42.0; initial["alarm.severity"] = 0; @@ -34,14 +44,48 @@ int main(int argc, char* argv[]) initial["alarm.message"] = ""; // Actually creating the mailbox PV. - // buildMailbox() includes a default PUT handler which simply + // buildMailbox() installs a default onPut() handler which // stores whatever a client sends (subject to our data type). server::SharedPV pv(server::SharedPV::buildMailbox()); + + // (optional) Replace the default PUT handler to do a range check + pv.onPut([](server::SharedPV& pv, + std::unique_ptr&& op, + Value&& top) + { + + // (optional) arbitrarily clip value to [-100.0, 100.0] + double val(top["value"].as()); + if(val<-100.0) + top["value"] = -100.0; + else if(val>100.0) + top["value"] = 100.0; + + // (optional) Provide a timestamp if the client has not (common) + Value ts(top["timeStamp"]); + if(!ts.isMarked(true, true)) { + // use current time + epicsTimeStamp now; + if(!epicsTimeGetCurrent(&now)) { + ts["secondsPastEpoch"] = now.secPastEpoch + POSIX_TIME_AT_EPICS_EPOCH; + ts["nanoseconds"] = now.nsec; + } + } + + // (optional) update the SharedPV cache and send + // a update to any subscribers + pv.post(std::move(top)); + + // Required. Inform client that PUT operation is complete. + op->reply(); + }); + // Associate a data type (and maybe initial value) with this PV pv.open(initial); // Build server which will server this PV - auto serv = server::Config::from_env() + // Configure using process environment. + server::Server serv = server::Config::from_env() .build() .addPV(argv[1], pv); @@ -49,9 +93,13 @@ int main(int argc, char* argv[]) // with any auto-address list expanded. std::cout<<"Effective config\n"<