User Defined Structure Example A
Example A
Select UserComponentA under UserDefinedStructureLib
In Resource tree, CDPModel should have appeared. Right-click AggregateModel and select Add option in the context menu
Scroll down to Element-section and find the Element just added (AggregatedModel)
In the AcceptsModel column, enter the model-name which shall be accepted ('UserDefinedStructureLib.UserNodeA')
Change the Element name from AggregatedModel to UserNodeA
Note: Build your library: Right-click UserDefinedStructureLib and select Build.
Select UserComponentA under UserDefinedStructureLib
In Resource tree, UserNodeA should have appeared under UserDefinedStructureLib. Right-click UserNodeA and select Add, and then Add a second UserNodeA so that you have two UserNodeA.
Give names to the added nodes (UserNodeA1 and UserNodeA2)
Note: Build the library before you continue: Right-click UserDefinedStructureLib and select Build.
Now create a system UserDefinedStructureSystem containing an application called App. If this is new to you, please see the following getting started guide: How to Create a System.
Select App under UserDefinedStructureSystem
In Resource tree, right-click UserComponentA under UserDefinedStructureLib and select Add
Select UserComponentA under App in UserDefinedStructureSystem
In the UserNodeA section, you can see that 2 nodes of type UserNodeA are already added
In Resource tree, right-click UserNodeA under UserDefinedStructureLib and select Add
Give the name UserNodeA3 to the newly added node. There should now be 2 "grey" nodes, which comes from the model (not possible to delete), and the newly added node (UserNodeA3).
If you now try to Run & Connect the application without any modifications in the C++-code, no UserNodeA will show up:
Right click on UserDefinedStructureSystem and select Run & Connect
Select UserComponentA under App in UserDefinedStructureSystem
Changes to UserComponentA
The UserComponentA behavior is described by two C++ files UserComponentA.h under Headers, UserComponentA.cpp under Sources in the Code mode Project tree.
The UserComponentA configuration options for CDP Studio are described by the model file UserDefinedStructureLib.UserComponentA.xml under Other files Templates/Models.
The UserComponentA is referred to in the library meta file UserDefinedStructureLib.xml under Other files exposing the file as a user resource that can be added during configuration and in UserDefinedStructureLibBuilder.cpp builder class that is used to create instances during runtime startup.
UserComponentA in the Model File
The syntax of model files is detailed in help page: CDP Model syntax. The configuration done in start of Example A (adding 'AggregateModel' and configuring AcceptsModel), enables UserNodeA to be dragged into UserComponentA during configuration:
<Element Name="UserNodeA" Property="0" AcceptsModel="UserDefinedStructureLib.UserNodeA"></Element>
The "Name" attribute in the Element defines the name used/generated in the configuration files - It can be named anything, except names already used in this model or its base model(s).
The Property="0" attribute makes the element a section definition and not a property element definition.
The AcceptsModel attribute lists one or more ; separated models that are aggregated by the user model. The model syntax provides also an alternative attribute called AcceptsBase that makes the section accept all models that inherit a given base model.
Note: The set of models the section accepts can't intersect with other sections in given model or its base models. This means that the same model can't be used in two different sections in the same view-level.
In addition, 2 UserNodeA prototypes were added to UserComponentA model-file:
<UserNodeA Model="UserDefinedStructureLib.UserNodeA" Name="UserNodeA1"></UserNodeA> <UserNodeA Model="UserDefinedStructureLib.UserNodeA" Name="UserNodeA2"></UserNodeA>
UserComponentA in C++ Files
To enable UserComponentA to show the nodes of type UserNodeA during Online view (when connected to the running application), we need to add some code. It is has three main items: the container used to keep track of the UserNodeA instances, custom XML configuration handling and exposing the container to serialization in StudioAPI (so they will show up with values in Studio).
Firstly, UserComponentA.h needs a container to hold the pointer to created instances of UserNodeA, but the UserNodeA class should be forward declared before the class definition starts.
Before class declaration:
class UserNodeA;
In class declaration:
protected: std::vector<UserNodeA*> m_userNodesA;
Secondly, UserComponentA.h/.cpp needs to override HandleXMLElement() to handle defined UserNodeA tags defined in the XML. The section in component xml-file for UserComponentA which we need to parse, looks like this:
UserComponentA.xml:
<UserNodeA Description="Simple node example." Model="UserDefinedStructureLib.UserNodeA" Name="UserNodeA1" UserAttribute="StringA1"></UserNodeA> <UserNodeA Description="Simple node example." Model="UserDefinedStructureLib.UserNodeA" Name="UserNodeA2" UserAttribute="StringA2"></UserNodeA> <UserNodeA Description="Simple node example." Model="UserDefinedStructureLib.UserNodeA" Name="UserNodeA3" UserAttribute="StringA3"></UserNodeA>
UserComponentA.h:
bool HandleXMLElement(XMLElementEx *pEx) override;
UserComponentA.cpp:
bool UserComponentA::HandleXMLElement(XMLElementEx *pEx) { const XMLString& currentElement = pEx->GetName(); if (currentElement == "UserNodeA") { m_userNodesA.push_back(new UserNodeA(pEx, this)); return true; // done with handling the structure } return CDPComponent::HandleXMLElement(pEx); }
Thirdly, UserComponentA.h/.cpp needs to override FillNodeChildren() to expose UserNodeA instances as its children in StudioAPI during runtime.
UserComponentA.h:
void FillNodeChildren(CDP::StudioAPI::NodeStream &serializer) const override;
UserComponentA.cpp:
void UserComponentA::FillNodeChildren(CDP::StudioAPI::NodeStream &serializer) const { serializer.StdContainerStreamer(m_userNodesA); CDPComponent::FillNodeChildren(serializer); }
To finish up, the class destructor should delete the nodes instantiated, and the UserNodeA header must be included in the UserComponentA.cpp file.
Changes to UserNodeA
The UserNodeA has similar definition files as UserComponentA: header, source and model. The only difference is that UserNodeA is not added to the Builder class. For the default UserNodeA in UserComponentA to work, the generated UserNodeA definition need no further changes.
Note: After the changes done in the C++ files (UserComponentA.h/.cpp), remember to build the library.
Configuring UserNodeA's Property Values and Show Values in Runtime
By default, a CDPNode created by the wizard has one property to contain a user-value (in addition to the standard attributes/properties called "Model" and "Description"). In the model-file, this property is called "UserAttribute" of type "string" with value "Simple attribute". To modify the value for the 3 UserNodeA in UserComponentA:
Select UserComponentA under App in UserDefinedStructureSystem
Find the "UserAttribute" column in "UserNodeA" section and change the value to "StringA1" for UserNodeA1.
Modify the UserAttribute value to "StringA2" and "StringA3" for the other nodes as well.
If you now try to run the application, nodes of type UserNodeA will show up in default section UserNodeA:
Right click on UserDefinedStructureSystem and select Run & Connect
Select UserComponentA under App in UserDefinedStructureSystem
A section called UserNodeA shows the 3 nodes with correct values.
Example A-2
If you want to inhibit the possibility to add nodes of type UserNodeA, remove the following line from the library meta file UserDefinedStructureLib.xml, found under Other files in the Code mode Project tree:
<Model Name="UserDefinedStructureLib.UserNodeA"/>
Then UserNodeA will not appear as a resource in the Resource tree any more. Since there is no available resource for the table, CDP Studio will not allow adding any resources.
Files
Get started with CDP Studio today
Let us help you take your great ideas and turn them into the products your customer will love.