Jump to content

LapDog Messaging Library v2 Beta 1 is available!


Daklu

Recommended Posts

The LapDog team is pleased to announce the LapDog.Messaging 2.0 Beta package is available for download from our SourceForge repository. In addition to the conveniences found in version 1, such as built-in error trapping and priority queues, version 2 introduces a few key time-saving improvements:

Simplified Data-less Messaging

Sending a data-less message in version 1.x required users to drop a Create Message method on the block diagram, attach a string to the Create Message's 'Message Name' terminal, and finally wire the message object to the EnqueueMessage method. It's not particularly difficult, but it does get repetitive and uses up block diagram space.

Version 2.0 streamlines the process and allows users to send a data-less message by connecting a string directly to the EnqueueMessage's 'Message' terminal.

Improved Message Renaming

One of the principles of good application design is encapsulation. In other words, try to limit the amount of information that passes between distant parts of your application. Changing a message's name as it travels down the message handling chain helps keep information localized and can improve readability.

Version 2.0 makes this easier by factoring out the RenameableMessage class and moving the RenameMessage method up to the Message class. Now all messages have the built-in ability to be renamed, eliminating the annoying step of downcasting a Message object to a RenameableMessage object just so it can be renamed.

New Namespacing

Unfortunately, removing the RenameableMessage class breaks backwards compatibility, making direct upgrades a little more difficult. Since backwards compatibility is already broken, we decided to use this opportunity to change LapDog's namespacing and bring it more in line with modern text languages.

Libraries are organized into a "virtual" hierarchy using a dot naming convention. For example, the linked VIPM package contains two different libraries: LapDog.Messaging.v2.lvlib contains the queue classes a few core messages. LapDog.Messaging.v2.NativeTypes.lvlib is an extension library containing message classes for select data types in Labview and is dependent on the core Messaging library. It is hoped that using this naming convention will make it easier for developers to understand how libraries (and packages) relate to each other without having to dig into the source code.

The new namespacing also makes it possible to have different major versions installed side-by-side without cross linking or conflicts, allowing you to try out the beta without worrying about breaking existing applications.

So what are you waiting for? Download it now and give it a try! (Don't be afraid to leave feedback... positive or negative.)

  • Like 2
Link to comment

For the final version it would be useful to include examples.

Cool. Thanks for volunteering. I look forward to seeing what you come up with. :lol:

(I do have an old example project in SourceForge that needs to be updated, but I don't think I've ever included in the package.)

[Edit]

The only documentation is in context help. Complete documentation is one of those things that would be nice to have and give the package some more polish, but I just don't have time to do it.

Link to comment

Cool. Thanks for volunteering. I look forward to seeing what you come up with. :lol:

I actually wouldn't mind helping on some of it. There are a couple of problems though. One is time. The other is that I don't know if my company would be ok with it even on my own time since they own the software. But I will definitely check into it. But that leaves the first problem.

Link to comment

The other is that I don't know if my company would be ok with it even on my own time since they own the software.

NI licensing agreements allows users to install Labview on home computers as well as their work computers. I'd be surprised if your employer balked at that... after all, you'd be developing your programming skills on your own time.

I can't help you with the time issue other than to say even if you can only do a few hours a month it would help. (I've learned that if I wait until I have time before I start doing something, I'll never start.) I have other stuff I'd like to release but too much of my time gets spent on the "other" things. Areas where I need the most help right now are writing examples, reviewing the help text to make sure it is descriptive enough, and someone to manage the builds/versioning/packaging.

Link to comment
  • 4 months later...
So what are you waiting for? Download it now and give it a try! (Don't be afraid to leave feedback... positive or negative.)

Question: Why don't you have a "VariantMessage" Type? You have an I32Message, and one could extend that with U32Message, I16Message, DBLMessage, etc. etc. etc., but that's a lot of message types! Is there a reason not to use a single VariantMessage Type to send all simple data messages, rather than a long list of native types?

I ask because I've been experimenting with my own (similar to LapDog) message design, and there seems to me to be a lot to be said for using VariantMessages.

-- James

Link to comment

I have created a bunch of datatypes as I needed them and put them into my own library. I gave up on adding them all to the palette and now my create and get messages are all in polymorphic VIs. Variant is one of them. But I don't like that one because I have to convert the message to the variant subclass then to the datatype. I would rather just add a new entry to my polymorphic VI whenever I need something not already there.

Link to comment

[Grr... whoever decided the backspace key is a great hotkey for the browser back button needs to be shot. :angry: ]

Question: Why don't you have a "VariantMessage" Type?

I had a rather lengthy response typed up, then made the mistake of trying to delete text using backspace. Here's the short version:

There are several reasons why there isn't one. You may or may not view them as valid.

1. Variants are usually used for custom data types, which implies typedeffed clusters or enums. I don't like using typedeffed clusters as part of my public interfaces between components. Their lack of mutation history makes it too easy to unintentionally and unknowingly introduce bugs.

2. Historically, the current LapDog.Messaging package evolved from a similar library where every message was a unique class. When that proved too cumbersome for my liking, I moved towards the current system with message classes based on message data-types instead of the message itself. Since my goal is to send data, not send a variant (the variant is just packaging that allows arbitrary data to be sent on the same wire,) I never had a reason to create a variant message type.

3. When I'm building an application one the things I'm most concerned about is the interactions between components and what the dependency graph looks like. Variant message, imo, obscure the dependency relationships that are being created. Sending data via a variant message is as easy as hooking an arbitrary wire up to a variant input terminal. I may not realize I've created a new dependency until I go to code the message receiver and try to convert the variant to real data. Who knows how much work I'll have to redo to break the unwanted dependency. By requiring a new class for each message data type (or to a lesser extent dragging the message creator from the project window) I'm forced to confront and resolve the dependency issues before I write the code.

Ultimately, the decision about VariantMessages is left to the individual. I never intended the packaged message types to be a complete set... just the most common ones. I always create application-specific Message child classes with custom data types, and users should feel free to create their own Message child classes for reuse that are appropriate to their situation.

...but that's a lot of message types!

Yep, it is. Personally I have no desire to create and maintain all of them. Maybe someday NI (or a charitable Lava contributor) will do it. I've already explained why I don't use variants, but that doesn't make the need for classes for each custom data type any less daunting. Personally I think that requirement is more or less a result of Labview's G's nature as a statically typed language. Using variants doesn't solve the problem, it just moves it around a bit and makes it harder find.

Any reason why not just to use the Merge errors or has this been automatically inserted by LV during conversion? (These are from 2011)

Looks like a conversion issue. Here's a bd from LV2009.

post-7603-0-59935100-1315289063_thumb.pn

Link to comment

1. Variants are usually used for custom data types, which implies typedeffed clusters or enums. I don't like using typedeffed clusters as part of my public interfaces between components. Their lack of mutation history makes it too easy to unintentionally and unknowingly introduce bugs.

I see the great value in using custom message objects instead of custom cluster typedefs (particularly if you use the "command pattern" and dynamically dispatch off the message), but I'm talking about using variants for standard LabVIEW datatypes. From my (more limited) programming experience, I more often use variants to write "generic" code that handles multiple simple datatypes, not large typedef clusters. Now, a large number of simple-type classes (combined with large polymorphic VIs as Steve mentions) will perhaps do everything Variants do, BUT, isn't this reinventing the wheel? Variants have a lot of nice features and are pre-existing, supported by NI, and have lots of utility code written in them already (love the OpenG stuff). Using Variants lets one interface more cleanly with LabVIEW features that already use variants to represent simple data types. For example, here's a simple code for a test UI, where all front-panel controls are connected to a message queue such that all "Value Change" events on any control are sent out as "Set>>{control name}" messages in a VarMessage:

post-18176-0-13243000-1315302528_thumb.p

post-18176-0-38790700-1315302570.png

Here, I'm directly connecting to LabVIEW's ability to handle multiple control types in a single event frame, via variants. If I want to add a control, I just drop it on the front panel and give it the right name and it's done. Writing code to receive variant messages and update the appropriate control (by lookup of the control name) is only slightly more complicated. To do this UI without variants, I would have to stop and create new message types for the pressure and temperature unit DBLs (it's going to be a big polymorphic VI, Steve, once you get to all the different possible units!), then configure an event frame for each control.

2. Historically, the current LapDog.Messaging package evolved from a similar library where every message was a unique class. When that proved too cumbersome for my liking, I moved towards the current system with message classes based on message data-types instead of the message itself. Since my goal is to send data, not send a variant (the variant is just packaging that allows arbitrary data to be sent on the same wire,) I never had a reason to create a variant message type.

But again, isn't this reinventing the wheel? Your goal is to send data, and variants are designed to send data.

3. When I'm building an application one the things I'm most concerned about is the interactions between components and what the dependency graph looks like. Variant message, imo, obscure the dependency relationships that are being created. Sending data via a variant message is as easy as hooking an arbitrary wire up to a variant input terminal. I may not realize I've created a new dependency until I go to code the message receiver and try to convert the variant to real data. Who knows how much work I'll have to redo to break the unwanted dependency. By requiring a new class for each message data type (or to a lesser extent dragging the message creator from the project window) I'm forced to confront and resolve the dependency issues before I write the code.

I like things to be as "easy as hooking up a...wire". I imagine one could design a "SimpleTypeVarMessage" that would produce an error if one connected a cluster to it; that might address your dependency issues.

Ultimately, the decision about VariantMessages is left to the individual. I never intended the packaged message types to be a complete set... just the most common ones. I always create application-specific Message child classes with custom data types, and users should feel free to create their own Message child classes for reuse that are appropriate to their situation.

Custom messages I see the advantages of, but that seems a lot of work. Also, isn't the use of custom messages a "dependency" in an of itself? I haven't worked with them enough to know, but it seems like custom messages to talk to a module is a dependancy.

Yep, it is. Personally I have no desire to create and maintain all of them. Maybe someday NI (or a charitable Lava contributor) will do it. I've already explained why I don't use variants, but that doesn't make the need for classes for each custom data type any less daunting. Personally I think that requirement is more or less a result of Labview's G's nature as a statically typed language. Using variants doesn't solve the problem, it just moves it around a bit and makes it harder find.

But variants ARE a pre-LVOOP solution to the problem of a wire carrying multiple datatypes. Wrapping that solution in a message class is a lot easier than reinventing it.

-- James

Link to comment

I have created a bunch of datatypes as I needed them and put them into my own library. I gave up on adding them all to the palette and now my create and get messages are all in polymorphic VIs. Variant is one of them. But I don't like that one because I have to convert the message to the variant subclass then to the datatype. I would rather just add a new entry to my polymorphic VI whenever I need something not already there.

I guess one of my problems is that my own messaging design has too many polymorphic VIs to add to. In the quest to make the wiring simple I have polymorphic VIs for Write(create), Extract(get), Send, Reply, Query, and Notify Observers. So using the inbuilt polymorphism of the variant-to-data primitive is attractive. For example, here's a quick rewrite of the lower receiving loop in my previous example, where the "Sett>>..." messages set the internal data values of a cluster in a shift register (a form I use a lot):

post-18176-0-23617900-1315310807_thumb.p

To extend this to accepting Set>>Temperature messages, I just need to duplicate the frame and select the right element of the shift-register data cluster. I don't need to change the message type. Or alternately I could use the OpenG Variant tools and write one case to handle all "Set>>..." messages:

post-18176-0-46832500-1315310917_thumb.p

The "Set>>" subVI:

post-18176-0-51070200-1315310929.png

Now I can add new "settable" items to the shift-reg cluster (and drop corresponding controls in the UI) without any new wiring to do.

-- James

Opps: just noticed I left the "Get Var" subVI with the original "Get LVObj" icon; hope that isn't confusing.

Link to comment
Here, I'm directly connecting to LabVIEW's ability to handle multiple control types in a single event frame, via variants. If I want to add a control, I just drop it on the front panel and give it the right name and it's done.
That is an interesting idea - registering all controls. I use a lot of latching boolean controls so I would have to put all the terminals in one event case to make sure they all got reset. It is interesting and I will keep that in mind. It seems like it could get confusing though. If I have an event for the individual control then there is a frame with the terminal and any code specific to the event. But I can see that for some applications this is useful. I would have never realized you could register all events like that.
To do this UI without variants, I would have to stop and create new message types for the pressure and temperature unit DBLs (it's going to be a big polymorphic VI, Steve, once you get to all the different possible units!), then configure an event frame for each control.
I would not create a polymorphic instance for temperature and for pressure. I only have the generic types that were not included in the native types library. Since both of those are DBL and I already have that I do not need a new entry. I might have a set pressure and set temperature vi in some module library that use the DBL message and set the name with a constant. But no additional polymorphic instances are necessary. The list is kind of big. I think I have about a dozen or so. But I have it set to automatically adapt so there is no need to worry about a big selection list. If I see a cohersion dot then I know I might need another instance.

Edit: Maybe we should move this off of the announcements board :)

Link to comment
But I can see that for some applications this is useful. I would have never realized you could register all events like that.

In practice I wouldn't register all controls on a front panel like that; instead controls (or groups of controls) which need special code would have their own case. But multiple controls can be registered for the same case, either statically or dynamically as an array of references.

I would not create a polymorphic instance for temperature and for pressure. I only have the generic types that were not included in the native types library. Since both of those are DBL and I already have that I do not need a new entry.

A DBL with an attached unit is a different type than a DBL (no unit). The wire will break if you wire them together (or if the units are incompatible). So to use units with messages you need separate message types for each base unit. Or use a variant.

You could just not use units, sending raw DBL messages and relying on the receiver to know what the unit is, but united numbers are useful for preventing bugs.

Edit: Maybe we should move this off of the announcements board :)

Probably, is there a LapDog discussion group?

-- James

Link to comment

Here's another modification of my example of Variant messaging, this time to send an Enumerated Constant to another module that doesn't actually know what the Enum's definition is. Imagine the sending module has a configuration Enum that it sends to the UI module to allow the User to select a configuration. Coupling would be looser if the UI didn't need to depend on the definition of the Enum. We can do this by having the UI module use the OpenG "Get Strings from Enum" VI, and setting a Ring control to match the Enums strings. When the User selects a configuration, the UI sends back the corresponding Ring value (U16), which is automatically cast back into the Enum by the "Variant to Data" primitive in the sending module:

post-18176-0-72767000-1315492145_thumb.p

-- James

Edited by drjdpowell
Link to comment

A DBL with an attached unit is a different type than a DBL (no unit). The wire will break if you wire them together (or if the units are incompatible). So to use units with messages you need separate message types for each base unit. Or use a variant.

You could just not use units, sending raw DBL messages and relying on the receiver to know what the unit is, but united numbers are useful for preventing bugs.

Yes when you start to take into account units there really are a lot of datatypes. But as I said if I need one that is not in my polymorphic VI I just create a new one. I can see how this can end up with many entries over time. But with autoselection I don't think it is a problem. Anybody know the limit to the number of polymorphic entries? I think the select node in scripting is an I32 so there probably is no practical limit.

Probably, is there a LapDog discussion group?

-- James

There is one on NI but it is pretty low volume. I was thinking maybe the Object Oriented board here on Lava or something else. [Edit: I created a new thread. I hope this is OK]

Link to comment
  • 1 month later...

I released it specifically so other LV developers can use it in their day-to-day work, even if you are hiring out as a contractor/consultant. I have no problem with anyone using it as part of a customer's application or including it in the source code given to the customer.

To be honest I have mixed feelings about people redistributing it to other developers as a toolkit and claiming it as their own. I don't really like the idea of someone else selling LapDog as a LV toolkit, but I haven't specifically taken steps to prevent it and I don't anticipate doing it in the future. I've considered a 'shout out' license, which means if you use it in a for-profit endeavor you have to drop me a note letting me know--just 'cause I'm curious how it's being used. But I haven't done that either.

So no, there are no restrictions on its use. You can use it in a commercial application. You can give it away to your friends. You can change the banner color and re-release it as LapFrog if you're so inclined. It's free, it's open, and it's there to be used.

  • 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
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.