In OPC UA, we link multiple objects via OPC UA References and that can be considered as C++ References or Aggregation or Pointers or Containment of objects in one another.
But, while implementation and designing for companion specification, we create new user objects and variables. What is the best way to link different objects?
Is it like one object has a pointer to other object OR one object has full copy of other object or one object has a reference?
While defining companion specification, Types are defined easily via OPC UA References but when we really want to add real-time objects, we write classes and implement them as C++ objects.
If we have multiple objects references in recursive way, the object will have too many C++ objects inside it and it will grow bigger in size.
Can anyone add suggestions or comments on examples or better ways of defining?
One Tricky Use Case:
We want to define a data model which is suitable to all types of our applications. We have data directly exposed from controllers and references implemented as C++ pointers or containing objects can work. But the same model will be tricky to implement for an OPC UA Application which would like to map to a database. In database applications, probably, we would like to link different objects via Identifiers.
Now, do we have both identifiers as attributes and also C++ references added in the classes?
Any suggestions would be really helpful.
A generic implementation of the UA information model would have an instance of C++ for each Object. References would be implemented by pointers to other C++ instances which may or may not me shared with other Objects. The easiest way to manage the lifetime of Objects is to introduce reference counting semantics that mean a Object is automatically deleted when its reference count drops to 0.
Thanks Randy for the response. In the system we do have objects which can be considered as data from devices. Those data will again can be consumed from applications which push to data storage. Ofcourse, we can have association implemented via references but sometimes, is it again good to add Ids of the referenced target objects as properties in the source objects?
May be its duplicate again since we already have a pointer to the complete object and id is part the target object. Sometimes, it is like mapping the object model to a table in the database and multiple objects have multiple respective tables.
I was thinking to avoid adding both pointers and ids as option in the object implementations and have only one option when we implement the application.
Properties would always be members of Objects and not shared.
In most cases Variables are also members.
I am not sure you understood my point.
Reference counting semantics are not related to UA references. They are used with C++ pointers.
You add AddRef/Release references on all Objects.
AddRef is classed when pointer is stored in a Object and Release is called when the pointer is removed.
Thanks Randy, and yes, i understand the RefCount mechanism you said.
What i meant is explained in following way:
Let us take following three objects which has UA References to each other.
Controller -> IsConnectedTo -> Tool
Tool -> HasSoftware -> Software1
Controller -> HasSoftware -> Software2
Now, all these objects has a property called ID which is a unique identifier of that object in the system.
Now to link these multiple objects, i can use pointer references and that is fine. What i meant is, i wanted to avoid IDs of other referenced objects in source nodes.
Example: class Controller
int toolIdentifierConnectedTo; -- This will be a duplicate thing but few places i have seen models where we use identifiers of other objects to link them. I do not prefer this approach but may be it is easy for database application approaches.
Tool *referencedTool; --- I will use the ref count mechanism and if i want ID of Tool, i will get from this variable.
I hope i was able to put my point. Basically, to link objects, i wanted an approach to avoid using IDs and references together. Own ID as property is fine, but ID of other object to reference along with its pointer is duplicate...
You can do it any way that makes sense for your application.
Lookup by ID will not perform as well but it will be more robust and less likely to generated a pointer error.
If you do not implement reference counting then you should use look up by id.
Having raw pointers to loosely coupled objects is memory nightmare waiting to happen.
I have one more related question regarding this. Can you please help me some pointers?
When we have UAObject Types defined and relevant UAObjects are created in a server.
For Example, UAObject - Controller, Tool and these two objects are references using HasComponent reference.
How the UA Client and UA Server will communicate these objects data and semantics with each other. I know that the data will be encoded at atomic level for each data type but how the UAObjects and its references are parsed or decoded by UA Client.
For example, if a data inside Controller object and Tool Object are sent to UA Client, UA Client needs to parse/decode the message and construct the object in the same way. Controller -> HasComponent -> Tool, now these are objects with unique NodeIds and respective properties and components inside a server and how this information can be modeled and sent to UA Client where UA Client will parse the required information and show the correct objects and its references?
Clients need to build their own internal representations of the Objects based on the Nodes and References returned via service calls.
This internal representation should be optimized for whatever purpose the Client is designed to fill and there is no reason to assume it would preserve the generic node-reference model found in the UA Server address space.
The generic address space model is flexible but it is hard to work with in code because the structures are cumbersome.
That is why developers should not feel they have to preserve these structures unless they are building a generic engine designed to handle any OPC UA information model.