ChannelManager Class
(ServerIO::ChannelManager)The ChannelManager class can be used to synchronize ICDPChannel classes between User/Worker thread and CDPProcess where the CDP class (like CDPSignal, CDPProperty) for channel implementation is created. More...
Header: | #include <IO/ServerIO/ChannelManager.h> |
Public Functions
ChannelManager(CDPComponent *server) | |
virtual | ~ChannelManager() |
ICDPChannel * | AllocateNewCDPChannel(XMLElementEx *pXML, double &dSize, int moduleNo, int groupNo, bool bInputChannel) |
void | DeregisterCDPChannel(ICDPChannel *channel) |
virtual void | Destroy() |
std::list<ICDPChannel *> | GetChannelList() |
int | GetInputSyncGroupId() const |
int | GetOutputSyncGroupId() const |
ICDPChannel * | HandleCDPChannelElement(XMLElementEx *pEx) |
ICDPChannel * | HasChannel(const std::string &shortName) |
void | RegisterCDPChannel(ICDPChannel *channel) |
void | SetSyncGroupId(bool bInputChannel, ICDPChannel *pChannel) |
void | SynchronizeValuesIn() |
void | SynchronizeValuesOut() |
Static Public Members
ICDPChannel * | NewICDPChannel(XMLElementEx *pXML, double &dSize, int moduleNo, int groupNo, bool bInputChannel) |
Detailed Description
The ChannelManager class can be used to synchronize ICDPChannel classes between User/Worker thread and CDPProcess where the CDP class (like CDPSignal, CDPProperty) for channel implementation is created.
The ChannelManager is typically added to an IOServer like this: Include header:
#include <IO/ServerIO/ChannelManager.h>
Add ChannelManager:
ServerIO::ChannelManager* m_pChannelManager;
In the IOServer constructor, initialize the ChannelManager:
CustomIO::CustomIO() : m_pChannelManager(new ServerIO::ChannelManager(this)) { }
Make sure to delete it in the destructor...
CustomIO::~CustomIO() { delete m_pChannelManager; }
..and override Destroy to free its resources:
CustomIO::Destroy() { IOServer::Destroy(); m_pChannelManager->Destroy(); }
In your library, add a CDPChannel Table like this:
- Add a CDPModel -> AggregateBaseModel
- In the Elements table, rename AggregateBaseModel to CDPChannel
- Set the {CDPChannel} AcceptsBase column value to CDPSignalChannel<> to accept CDPSignalChannel models.
- Build the library to apply the changes; a table named CDPChannel should now appear in your model.
Extend HandleXMLElement() to auto-generate and register the channels in the ChannelManager when they are read from the configuration CDPChannel table:
bool CustomIO::HandleXMLElement(XMLElementEx *pEx) { // Handle creation of objects that have an XML configuration in the component configuration file if (pEx->GetName()=="CDPChannel") { double dataSize; ServerIO::ICDPChannel* pChannel = ServerIO::ChannelManager::NewICDPChannel(pEx,dataSize,0,0,0); if (pChannel==nullptr) { CDPMessage("Suspending %s: Failed creating CDPChannel for Name=%s.\n",ShortName(), pEx->GetAttributeValue("Name").c_str()); this->Suspend(); return false; } pChannel->SetNodeOwner(this); std::string channelName = pEx->GetAttributeValue("Name").c_str(); pChannel->Create(channelName.c_str(),this); pChannel->SetChannelParameters(pEx->GetAttributeValue("Input"),0,0,pEx->GetAttributeValue("Nr")); pChannel->Configure(pEx); m_pChannelManager->RegisterCDPChannel(pChannel); return true; // don't call HandleXMLElement() for children of CDPChannel-element } ...
To expose the channels in Online mode, override FillNodeChildren():
void CustomIO::FillNodeChildren(CDP::StudioAPI::NodeStream &serializer) const { ... for (auto channel: m_pChannelManager->GetChannelList()) serializer << AdoptedChild(channel); }
Update the IOServer::ProtocolImplementation() to update the channels before sending them and after receiving them:
void CustomIO::ProtocolImplementation() { m_pChannelManager->SynchronizeValuesIn(); // Send the updated signals... ... // Receive the signals from the device, then do: m_pChannelManager->SynchronizeValuesOut(); }
See also IOServer and ServerIO::IChannel.
Member Function Documentation
ChannelManager::ChannelManager(CDPComponent *server)
ChannelManager constructor that takes in the IOServer pointer the channel manager is used in.
server should contain IOServer pointer that is used as parent of CDPSignalChannels when locking MemberAccess mutex.
[virtual]
ChannelManager::~ChannelManager()
Destructor that deletes all Channels that are left in ChannelManager at the point of it's destruction.
ICDPChannel *ChannelManager::AllocateNewCDPChannel(XMLElementEx *pXML, double &dSize, int moduleNo, int groupNo, bool bInputChannel)
Allocates a new CDPSignal channel or other ICDPChannel implementing channel. Models supported are "CDPSignal", "CDPSignalChannel", "CDPProperty", "CDPPropertyChannel", "ComponentState" or "ComponentStateChannel". Create and Configure are called on the created channel instance.
pXML pointer to XMLElement which must contain one of the supported Models and other configuration.
dSize will return the created channel's datasize (1/8 for bool, channel's GetDataSize() for other types).
moduleNo is set as parameter of the Channel instance if applicable.
groupNo is set as parameter of the Channel instance if applicable.
bInputChannel holds the direction of CDP primiteve in the channel. Input expects valus from CDP, output provides them.
Returns a pointer to ICDPChannel if successful, otherwise nullptr is returned.
void ChannelManager::DeregisterCDPChannel(ICDPChannel *channel)
Removes a channel from manager. Removed channels need to be deleted manually.
channel holds the channel-pointer to be removed.
[virtual]
void ChannelManager::Destroy()
Destroys all channels in m_channels.
std::list<ICDPChannel *> ChannelManager::GetChannelList()
Returns the list of all channel pointers in ChannelManager, updated by RegisterCDPChannel/DeregisterCDPChannel. This method should not be used for frequent iteration needs in IOServers.
int ChannelManager::GetInputSyncGroupId() const
Returns sync Id for the channels to be synchronised in by CDP.
int ChannelManager::GetOutputSyncGroupId() const
Returns sync Id for the channels to be synchronised out by CDP.
ICDPChannel *ChannelManager::HandleCDPChannelElement(XMLElementEx *pEx)
Will call AllocateNewCDPChannel() and RegisterCDPChannel() based on contents of pEx. pEx is a pointer to XMLElement containing configuration, must at least contain "CDPChannel" and "Model".
Returns a pointer to ICDPChannel if successful, otherwise nullptr is returned.
ICDPChannel *ChannelManager::HasChannel(const std::string &shortName)
Returns a pointer to ICDPChannel if a channel is found with the same Name() as shortName, otherwise nullptr is returned.
[static]
ICDPChannel *ChannelManager::NewICDPChannel(XMLElementEx *pXML, double &dSize, int moduleNo, int groupNo, bool bInputChannel)
Allocation of ICDPChannel based on XMLElement without Create or Configure calls. Models supported are "CDPSignal", "CDPSignalChannel", "CDPProperty", "CDPPropertyChannel", "ComponentState" or "ComponentStateChannel".
pXML pointer to XMLElement which must contain one of the supported Models and other configuration.
dSize will return the created channel's datasize (1/8 for bool, channel's GetDataSize() for other types)
moduleNo not used
groupNo not used
bInputChannel not used
Returns a pointer to ICDPChannel if successful, otherwise nullptr is returned.
void ChannelManager::RegisterCDPChannel(ICDPChannel *channel)
Registers the Channel in channel manager. In destructor the manager class destroys all channels still in management list.
channel holds the channel-pointer to add. Channel manager takes over the ownership of the channel and will call destructer when manager itself is deleted.
void ChannelManager::SetSyncGroupId(bool bInputChannel, ICDPChannel *pChannel)
Sets the "SyncGroupId" property value. If bInputChannel is true
, value from GetInputSyncGroupId() is used, otherwise value from GetOutputSyncGroupId() is used. SetProperty() is called on pChannel .
void ChannelManager::SynchronizeValuesIn()
SynchronizeValuesIn should be called before using values in a user thread loop or process to get the current IChannel values safely to thread context.
void ChannelManager::SynchronizeValuesOut()
SynchronizeValuesOut should be called after writing values from a user thread loop or process to update the current IChannel values to correct CDPProcess context.
Get started with CDP Studio today
Let us help you take your great ideas and turn them into the products your customer will love.