diff --git a/src/client/pv/pvAccess.h b/src/client/pv/pvAccess.h index 9e670ba..9463b8f 100644 --- a/src/client/pv/pvAccess.h +++ b/src/client/pv/pvAccess.h @@ -1245,6 +1245,10 @@ public: return add(fact, replace) ? fact : typename Factory::shared_pointer(); } + typedef ChannelProvider::shared_pointer (*factoryfn_t)(const std::tr1::shared_ptr&); + + ChannelProviderFactory::shared_pointer add(const std::string& name, factoryfn_t, bool replace=true); + //! Attempt to remove a factory with the given name. Return Factory which was removed, or NULL if not found. ChannelProviderFactory::shared_pointer remove(const std::string& name); diff --git a/src/factory/ChannelAccessFactory.cpp b/src/factory/ChannelAccessFactory.cpp index f510fb8..3762c20 100644 --- a/src/factory/ChannelAccessFactory.cpp +++ b/src/factory/ChannelAccessFactory.cpp @@ -78,6 +78,44 @@ bool ChannelProviderRegistry::add(const ChannelProviderFactory::shared_pointer& return true; } +namespace { +struct FunctionFactory : public ChannelProviderFactory { + const std::string pname; + epics::pvData::Mutex sharedM; + ChannelProvider::weak_pointer shared; + const ChannelProviderRegistry::factoryfn_t fn; + + FunctionFactory(const std::string& name, ChannelProviderRegistry::factoryfn_t fn) + :pname(name), fn(fn) + {} + virtual ~FunctionFactory() {} + virtual std::string getFactoryName() { return pname; } + + virtual ChannelProvider::shared_pointer sharedInstance() + { + epics::pvData::Lock L(sharedM); + ChannelProvider::shared_pointer ret(shared.lock()); + if(!ret) { + ret = fn(std::tr1::shared_ptr()); + shared = ret; + } + return ret; + } + + virtual ChannelProvider::shared_pointer newInstance(const std::tr1::shared_ptr& conf) + { + return fn(conf); + } + +}; +}//namespace + +ChannelProviderFactory::shared_pointer ChannelProviderRegistry::add(const std::string& name, factoryfn_t fn, bool replace) +{ + ChannelProviderFactory::shared_pointer F(new FunctionFactory(name, fn)); + return add(F, replace) ? F : ChannelProviderFactory::shared_pointer(); +} + ChannelProviderFactory::shared_pointer ChannelProviderRegistry::remove(const std::string& name) { Lock G(mutex);