/** * Copyright - See the COPYRIGHT that is included with this distribution. * pvxs is distributed subject to a Software License Agreement found * in file LICENSE that is included with this distribution. */ #include #include #include #include #include #include #include #include namespace { using namespace pvxs; using namespace pvxs::server; DEFINE_LOGGER(app, "countdown"); auto def = nt::NTScalar{TypeCode::UInt32}.build(); struct CountdownSrc : public Source { const std::string name; pvxs::impl::evbase loop; CountdownSrc(const std::string& name) :name(name) ,loop("counter") {} virtual void onSearch(Search &search) override final { for(auto& op : search) { if(op.name()==name) { log_info_printf(app, "Claiming '%s'\n", op.name()); op.claim(); } else { log_debug_printf(app, "Ignoring '%s'\n", op.name()); } } } virtual void onCreate(std::unique_ptr &&op) override final { if(op->name()!=name) return; std::shared_ptr chan(std::move(op)); log_info_printf(app, "Create chan '%s'\n", chan->name().c_str()); chan->onSubscribe([this, chan](std::unique_ptr&& setup) { log_info_printf(app, "Create mon '%s'\n", chan->name().c_str()); std::shared_ptr op(setup->connect(def.create())); // unique_ptr becomes shared_ptr loop.later(1.0, std::bind(&CountdownSrc::tick, this, op, 5u)); }); // return a dummy value for info/get chan->onOp([](std::unique_ptr&& conn) { conn->connect(def.create()); conn->onGet([](std::unique_ptr&& op){ auto val = def.create(); val["value"] = 0u; op->reply(val); }); }); } virtual List onList() override final { auto names(std::make_shared>()); names->insert(name); return List{names}; } void tick(const std::shared_ptr& op, uint32_t count) { log_info_printf(app, "tick %u\n", unsigned(count)); auto val = def.create(); val["value"].from(count); { epicsTimeStamp now; epicsTimeGetCurrent(&now); val["value"] = count; val["timeStamp.secondsPastEpoch"] = now.secPastEpoch+POSIX_TIME_AT_EPICS_EPOCH; val["timeStamp.nanoseconds"] = now.nsec; } op->post(std::move(val)); if(count) loop.later(1.0, std::bind(&CountdownSrc::tick, this, op, count-1u)); else op->finish(); } }; } // namespace int main(int argc, char *argv[]) { int ret = 0; try { pvxs::logger_level_set(app.name, pvxs::Level::Info); pvxs::logger_config_env(); auto src = std::make_shared("countdown"); auto serv = Config::from_env() .build() .addSource("countdown", src); std::cout<<"Effective config\n"<