Jump to content

LVOOP and Message Objects (LapDog mainly)


Recommended Posts

Hello everybody, I hope Daklu can add some input to this question but it may apply to LVOOP in general so here goes.

Background: I am using LapDog messaging to send Objects as messages. I have classes which are children of Message.lvclass. The DeQueue message element is, I believe, an object of Message.lvclass

Problem: It is not possible to direclty wire the message output from "DeQueue Message" to the input of a Message child class object's vi.

Here is how I wired it with failure:

post-15786-0-75148400-1329246094.jpg

This was a success:

post-15786-0-66051000-1329246487_thumb.j

Is there a more correct way of doing this? Ultimately, I would like to have dynamic dispatch vi's that DO based on the class of message from the DeQueue vi. Thus avoiding much of the need for the case structure. Actor Framework-ish without the strict overhead.

Edited by jbjorlie
Link to comment

The DeQueue message element is, I believe, an object of Message.lvclass

Close. DequeueMessage is a method, not an object, of the Message class.

Problem: It is not possible to direclty wire the message output from "DeQueue Message" to the input of a Message child class object's vi.

Correct. That gives you a compile error (broken run arrow) because there's no way for the compiler to guarantee the object on the wire during execution will be a LaunchView object.

Is there a more correct way of doing this?

That's what I do when I'm casing out based on message name. I wouldn't say there's a "more correct" way of doing it, but there are "different" ways of doing it, from wrapping the DequeueMessage and downcast in a sub vi to subclassing the MessageQueue class.

Ultimately, I would like to have dynamic dispatch vi's that DO based on the class of message from the DeQueue vi. Thus avoiding much of the need for the case structure. Actor Framework-ish without the strict overhead.

That's the command pattern and it's easy to implement in LapDog.

1. Create a class called "Command" and make it a child of the Message class.

2. Add a single dynamic dispatch method named "Do."

3. Change your messages to inherit from Command.

4. Add a Do method to each message with the appropriate execution code.

You'll still need use the To More Specific Class assertion to downcast the Message wire to a Command wire before connecting to the Command.Do method. If that really bothers you there are various things you can do to hide the downcast from users, from wrapping the DequeueMessage method and downcast in a sub vi to creating a new CommandMessageQueue class.

  • Like 1
Link to comment

Thank you, that pretty much clears everything up! I do already have this "Command" class except I named it "Messages". Hope that name is OK...

Not really a problem adding the downcast & I understand the "why" better now. Could I put the downcast into the Command class Do.vi and then override it for all my child Do methods? I have trouble understanding the override in general vs. the Dynamic Dispatch. For example, in the Actor Framework, there is an ActorCore.vi override where the parent ActorCore.vi unbundles xxxQueue from the parent class and uses it for Do message receiving... How is it possible to work on the parent object when the input object is a child which may not have xxxQueue in its object cluster? Does a child class also contain all the info of its parents?

That last part is probably a new topic but also probably something obvious & I don't want you guys to exile me to the dark side... :oops:

Link to comment

Answering your own questions? Nice! Soon you wil be answering others too!

Just remember it is a 'Cluster of class private data' so your only access to a class's data including a parent class is through methods and properties. Sometimes, you purposely prevent children from reading or writing to your private data by not providing property VIs.

Also, I doubt fellow LAVAG folks will exile you. In my opinion, it is important to answer these kind of questions. LVOOP is a great tool and helping out is a great way to expand its use. Interestingly, I am the only developer on a LV development staff of 4 full time and 2 contractors that follow LAVAG. Probably explains why or code is in the state that it is. I have tried to get them to regularly read the posts but they seem intimidated. Good grief!

Link to comment

I have tried to get them to regularly read the posts but they seem intimidated.

You can lead a horse to water...

(Why would they be too intimidated to read the forum?)

Thank you, that pretty much clears everything up! I do already have this "Command" class except I named it "Messages". Hope that name is OK...

It's okay in that there won't be any naming conflicts with LapDog. My personal opinion is the class name should describe what the class is. Typically if I have a plural class name it's because the class is a collection of items. "Messages," to my way of thinking, is a collection class that holds multiple messages. Additionally, your Messages class is just one particular kind of message--a command message. There may be other messages that are not command messages in your application. My preference would be to name the class "CommandMessage."

[Edit - I rename classes and methods a lot as the code evolves--it helps keep the code readable.]

Could I put the downcast into the Command class Do.vi and then override it for all my child Do methods?

Nope, at least not the way I think you're thinking about doing it. Since the DequeueMessage method output terminal is a (LapDog) Message class, you'll need to downcast to your CommandMessage class in order to wire it to the Do method. The Message class doesn't have a Do method, so trying to connect CommandMessage.Do will give you a compile error.

Downcasting (and upcasting, to a lesser extent) tends to trip people up when learning LVOOP. I know I struggled with it a bit. The key for me was realizing we are downcasting the wire type, not the runtime object. In LV when you create an object, that object will always and forever be an object of that class. It will never be an object of its parent class or child classes.

Labview's on-the-fly compiling feature tends to blur the line between edit-time and run-time. LVOOP is a lot easier to understand when you conciously distinguish between the two ideas.

I have trouble understanding the override in general vs. the Dynamic Dispatch.

They are essentially the same thing. Technically, "Dynamic Dispatching" is what happens during program execution when the LV runtime engine chooses whether to execute the parent vi or child vi. "Overriding" is a more general term that usually means, "create a method in a child class with the same name and conpane as a method in the parent class." It's something the developer does, not the runtime engine. They both refer to using the inheritance feature of OOP.

[Edit - I was thinking about this a bit more and decided that statement isn't accurate. "Override" is context dependent...

"You should override the CommandMessage.Do method in each CommandMessage child class."

"During execution the child class' Do method overrides the parent method on the block diagram."

Both are legitimate uses of the word, even though one refers to developer activity and the other refers to runtime activity.]

  • Like 1
Link to comment

Could I put the downcast into the Command class Do.vi and then override it for all my child Do methods? I have trouble understanding the override in general vs. the Dynamic Dispatch.

You could make a new non-dynamic dispatch VI that takes a Message object, downcasts to Command, then calls the (dynamic-dispatch) Do method. Call this VI “Do Command”” or “Do if a Command”, or something. Note that it doesn’t need to be a member of “Message” class (or any class).

— James

BTW, you could also make the “Do if a Command” VI return the original message if it isn’t a “Command” (this output would return a null message if the command was executed). That would allow you to put it in front of your case structure, acting sort of as a filter for Command Messages.

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.