From 9ef060a2f277dd0c4b58486d98f329db503a8925 Mon Sep 17 00:00:00 2001
From: Michael Davidsaver
-class MonitorPlugin
-{
- virtual std::string const & getName() = 0;
- virtual bool causeMonitor(
- PVFieldPtr const &pvField,
- PVStructurePtr const &pvTop,
- MonitorElementPtr const &monitorElement) = 0;
- virtual void monitorDone(
- MonitorElementPtr const &monitorElement);
- virtual void startMonitoring();
- virtual void stopMonitoring();
- virtual void beginGroupPut();
- virtual void endGroupPut();
-};
-
-class MonitorPluginCreator
-{
- virtual MonitorPluginPtr create(
- FieldConstPtr const &field,
- StructureConstPtr const &top,
- PVStructurePtr const &pvFieldOptions) = 0;
- virtual std::string const & getName() = 0;
-}
-
-class MonitorPluginManager
-{
- static MonitorPluginManagerPtr get();
- bool addPlugin(
- std::string const &pluginName,
- MonitorPluginCreatorPtr const &creator);
- MonitorPluginCreatorPtr findPlugin(std::string const &pluginName);
- void showNames();
-};
-
-
-MonitorPlugin must be implemented by the plugin implementation. -It has methods:
-MonitorPluginCreator must also be implemented by the plugin implementation. -It is called for each field instance that has options of the from -[plugin=name...] where name is the name of the plugin. -Note that a plugin instance will belong to a single client. -It has methods:
-MonitorPluginManager has the methods:
-NOTE: -Should the method causeMonitor -have arguments pvField and pvTop -be defined so that they can not be modified. -This would be possible if the following was defined: -
-typedef std::tr1::shared_ptr<const PVField> PVFieldConstPtr; -typedef std::tr1::shared_ptr<const PVStructure> PVStructureConstPtr; --then the definition for causeMonitor could be: -
-virtual bool causeMonitor( - PVFieldConstPtr const &pvField, - PVStructureConstPtr const &pvTop, - MonitorElementPtr const &monitorElement) = 0; --But just adding these definitions is not sufficient. -In addition all methods defined in pvDataCPP must be checked. -In particular many of the methods in Convert must have -their arguments modified. -Big job. - -
This section describes an example plugin that:
-As an example assume that a channel provided by pvAccess has a top level structure -that represents a power supply.
--structure powerSupply - structure alarm - structure timeStamp - structure power - double value - structure alarm - structure display - structure voltage - double value - structure alarm - structure display - structure current - double value - structure alarm - structure display --
A pvAccess client wants to create a monitor on the powerSupply as follows: -The client wants a top level structure that looks like: -
-structure powerSupply - structure alarm - structure timeStamp - structure power - double value - structure voltage - double value - structure current - double value --In addition the client wants monitors to occur only when one of the monitored -fields changes value but not just because a put occured. -Also if only the timeStamp changes value then that should not cause a monitor. - -
The example monitor plugin implements the semantics the -client wants. It can be attached to any field via the following options: -
-[plugin=onChange,raiseMonitor=value] --This plugin will trigger a monitor for the field only if the field changes -value. In addition value equals false means do not raise a monitor -for changes to this field. -But if a change to another field does cause a monitor the change to this field -will be passed to the client. - -
-Assume that the client has already connected to the channel. -The client can then issue the commands:
-
-std::string request("field(alarm[plugin=onChange]");
-request += ",timeStamp[plugin=onChange,raiseMonitor=false]";
-request += ",power.value[plugin=onChange";
-request += ",voltage.value[plugin=onChange";
-request += ",current.value[plugin=onChange";
-
-PVStructurePtr pvRequest = createRequest->createRequest(request);
-
-MonitorPtr monitor = channel->createMonitor(monitorRequester,pvRequest);
-
-The header file to create the example has the definition:
-
-class ExampleMonitorPlugin{
-public:
- static void create();
-};
-
-The implementation is:
-
-class OnChangePlugin : public MonitorPlugin
-{
-public:
- virtual ~OnChangePlugin(){}
- OnChangePlugin() {}
- bool init(
- FieldConstPtr const &field,
- StructureConstPtr const &top,
- PVStructurePtr const &pvFieldOptions)
- {
- pvField = getPVDataCreate()->createPVField(field);
- raiseMonitor = true;
- if(pvFieldOptions!=NULL) {
- PVStringPtr pvString =
- pvFieldOptions->getSubField<PVString>("raiseMonitor");
- if(pvString!=NULL) {
- std::string value = pvString->get();
- if(value.compare("false")==0) raiseMonitor = false;
- }
- }
- return true;
- }
- virtual std::string &getName(){return pluginName;}
- virtual bool causeMonitor(
- PVFieldPtr const &pvNew,
- PVStructurePtr const &pvTop,
- MonitorElementPtr const &monitorElement)
- {
- bool isSame = convert->equals(pvNew,pvField);
- if(isSame) return false;
- convert->copy(pvNew,pvField);
- return raiseMonitor;
- }
-private:
- PVFieldPtr pvField;
- bool raiseMonitor;
-};
-class OnChangePluginCreator : public MonitorPluginCreator
-{
-public:
- virtual std::string &getName(){return pluginName;}
- virtual MonitorPluginPtr create(
- FieldConstPtr const &field,
- StructureConstPtr const &top,
- PVStructurePtr const &pvFieldOptions)
- {
- OnChangePluginPtr plugin(new OnChangePlugin());
- bool result = plugin->init(field,top,pvFieldOptions);
- if(!result) return MonitorPluginPtr();
- return plugin;
- }
-
-};
-
-void ExampleMonitorPlugin::create()
-{
- static OnChangePluginCreatorPtr plugin;
- static Mutex mutex;
- Lock xx(mutex);
- if(plugin==NULL) {
- plugin = OnChangePluginCreatorPtr(new OnChangePluginCreator());
- MonitorPluginManager::get()->addPlugin(pluginName,plugin);
- }
-}
-
-
-