Jump to content

Accessing the Middle Class Data


Recommended Posts

I have a hierarchy of classes. Call them Grandparent, Parent and Child.

I have a dynamic dispatch VI in grandparent that child overrides.

In the child implementation, I want to access data in the parent class control.

The template in the grandparent has two inputs of type grandparent. The dynamic one and a static one. The dynamic one is used to dispatch to the correct child.

(this is because grandparent has more than one parent sub class and these have more than one child subclasses)

The static one is used to pass in a parent object so the child has access to its data between calls. (the child is actually a message not spawned from the original parent object and therefore does not contain this persistent parent data)

What I need to do is cast the grandparent wire to the type of parent so I can access the parent's data. I could use the child to do this but how do I extract the parent class type from the child and use it to cast the grandparent to type parent? I need to do this statically as design time, not at runtime.

thanks for any ideas.

-John

An alternative solution would involve having the child (message) object inherit the data in the parent object so I could access it via property nodes. Not sure if that is possible.

Link to comment

Well, it is kinda complex, but here goes:

I am trying to make a messaging system that uses the class hierarchy to route messages and has a plug-in type of implementation for routing methods.

So, I have three main classes: System, Process and Transport.

System holds a DVR containing an array of Process classes.

Process holds a Transport object.

Specific transports types (local queue, remote network message, notifier, etc) inherit from the transport class.

Specific processes inherit from the process class.

Each specific process class has child messages that implement create, send and execute methods.

First, you instantiate an object of type System and create the DVR to hold the data.

Next, you create a transport object for the specific type of transport you want a process to use.

You then create a object for the specific process that will use that transport and store the transport in the process's (parent) private data. You also add this process object to the system object DVR.

Later in your application, you create a instance of the specific process (can be the same as the object used to set the transport, or just another instance) and you set any initial conditions (this specific process, called the parent in the original email, stores any data needed to be accessed between messages). This then passes to a loop that waits for a message using the transport type set for that process and then calls the execute method for the message sent.

The advantage of this is almost everything in the architecture is reusable. You just define the specifics by creating you specific processes and their messages and a transport implementation.

The disadvantages are you can only have one implementation of a specific process class in each application instance.

The other disadvantage is I cannot figure out how to cleanly access the data in the specific process (the parent) from within the execute message method. I have for now cast the process object to the type of the specific process but I would rather do this a better way.

I included a zip of the demo project so far. Feel free to tell me this is a crazy way to solve this problem.

Message System.zip

-John

Link to comment

I need to install the latest LabVIEW version to look at your code, but some of what you describe sounds very similar to what I’ve done. My Transports are called “Messengers”, and I have “Actor” objects that contain a Messenger that is the method to send messages to a process running in parallel. But other stuff mystifies me. It sounds like you have message classes as the children of your Process classes; but aren’t messages and processes entirely different things.

Link to comment

What I need to do is cast the grandparent wire to the type of parent so I can access the parent's data. I could use the child to do this but how do I extract the parent class type from the child and use it to cast the grandparent to type parent? I need to do this statically as design time, not at runtime.

Umm, since class data is always private, you're not going to be able to do this directly in the child class (you could, in principle, cast a grandparent to parent within the parent class method and then access the class data but it would be prone to failures ince you'd have no way of guaranteeing the cast would succeed). The best you can do is created protected class data accessors in the parent class and use them in the child class to get at the class data.

Link to comment
aren’t messages and processes entirely different things.

The architecture I am trying to design is one of a process that has a defined API. So, instead of having a method for each thing the process can do, it has a message (API call) that it can process. So, it made sense to me that these would be children of the process since they were exclusive to the process and operated on the process' private data. Also, by having them be children, I can use the inheritance mechanism to allow my message system to detect what process owns them and then route the message to the process using its chosen transport automatically.

Again, this may turn out to be a bad idea, but I am going to try going down this road as far as it will take me until I make it work or decide it is the wrong road.

The best you can do is created protected class data accessors in the parent class and use them in the child class to get at the class data.

So I have created those accessors in the parent, but the wire type coming into the child is of type grandparent. So, I don't have access to the parent methods without casting it to the parent's type. I was hoping there was a way to do this using the child class wire. But I cannot sort out how to do this.

Link to comment

So I have created those accessors in the parent, but the wire type coming into the child is of type grandparent. So, I don't have access to the parent methods without casting it to the parent's type. I was hoping there was a way to do this using the child class wire. But I cannot sort out how to do this.

Ok, but you can cast the grandparent wire to parent wire using a "to more specific class" node and then call the accessors. You probably want to check the error code from the to more specific class node just in case you accidentally get something which can be treated as a parent class (note that the to more specific/generic class conversion odes are operating on the wire type not the actual data type).

I think, however, that there may be some refactoring you could do with the design - normally when one is facing a series of uphill battles like this it's better to find a way that is downhill :-) !

Link to comment

you can cast the grandparent wire to parent wire using a "to more specific class" node and then call the accessors.

That s what I did. But that means I needed a static parent object on the BD of the child method. I assume that means I had to allocate the memory for the parent's private data even though I did not use it. Seems inefficient to me. I would rather use the child wire to accomplish that. But this gives me an idea I need to go try now...

Link to comment

ok, so this is weird. If you take the grandparent wire with the parent object riding on it and cast that to the parent type, you can use the parent accessors to get at the data in the parent object.

But, if you take the grandparent wire with the parent object riding on it and you cast it to the child, then try to use the parent accessors available to the child class (I made them protected), you don't get the data. It comes back empty. Turns out, this is because the cast fails. But this was not obvious to me at first because I did not get an error message, even though I have automatic error handling turned on.

Link to comment

ok, so this is weird. If you take the grandparent wire with the parent object riding on it and cast that to the parent type, you can use the parent accessors to get at the data in the parent object.

But, if you take the grandparent wire with the parent object riding on it and you cast it to the child, then try to use the parent accessors available to the child class (I made them protected), you don't get the data. It comes back empty. Turns out, this is because the cast fails. But this was not obvious to me at first because I did not get an error message, even though I have automatic error handling turned on.

It's not very weird. You just cast a parent object to a child. You can't do that - it's a parent object and not a child object and casting it to a child doesn't change that fact.

Remember, casting is just about changing the wire type - you're not actually casting the data that is travelling on the wire. If you want to do the latter, then the preserve run time class node is your friend - but you'd better be sure that the data your messing with is really the right type (i.e. you still can't make a parent into a child). I guess the lack of error reproting is down to the casting class being a primitve rather than a subvi. (herein casting==to more specific class/to more generic class)

Life was so much simpler before inheritance came along :-) !

Link to comment

It was the lack of error dialog that was weird. I understand why the cast did not work.

Still, it is a bummer that I cannot extract a parent object from the child object without creating a parent object to feed into the to more generic node.

It may not be such a killer. The child objects have to have the parent (and grandparent) in memory anyway, so the penalty is the memory allocation of the default data for the parent's private data. I'd imagine that large data storage in a class would be in an array or other dynamically growable object (like a waveform or variant). So long as you don't set the default value of tge class private data to contain lots of data, the actualy overhead of storing e.g. empty arrays is not so large.

  • Like 1
Link to comment

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Unfortunately, your content contains terms that we do not allow. Please edit your content to remove the highlighted words below.
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...

Important Information

By using this site, you agree to our Terms of Use.