LabVIEW Idea Exchange

cancel
Showing results for 
Search instead for 
Did you mean: 
JackDunaway

Expand Data Interface to Built-In Messaging Primitives

Status: New

Now that coding for LVXCC is finished (get over there and vote before November 6 in the UI Controls category!), back to the Ideas drawing board. Smiley Wink

 

A common messaging practice involves creating a messaging ref (whether Queue, User Event, or Notifier) from a clustered datatype. The next step involves sending some data along that ref, and the final step is receiving data from the ref:

 

MessagingInterfaceCurrent.png

 

Above, you can see that the first two messaging types return the entire data cluster on the Receive, thus requiring an 'Unbundle'. I like how the third messaging construct uses the Event Handler Structure to "fan out" the elements on the Event Data Node interface (well, every now and then I'd like access to the top-level data structure on the Event Data Nodes...). All three constructs require fully-formed data structure type information for the Send input.

 

The interface for these Send and Receive primitives could be simplified, yielding a significant reduction in the BD footprint and an appreciable decrease in layout maintenance. 

 

MessagingInterfaceProposed.png

(Note, also, added a third element on the Dequeue graphic and centered the Enqueue by a pixel Smiley Tongue )

 

Since the data is already strictly typed in these messaging references, additional type information is not needed in a separate Data Input Terminal.

 

Below I've illustrated a place I'd love to use this cleaner interface - between a While Loop and a Case Structure. We save 32 pixels - enough space to fit one more primitive into the Case Structure! :thumbup1:

 

TightMessagingInterfaceApplication.png

 

Also note: this follows suit for current practices that allow you to "fan out" data structures on the syntax level, such as Property Nodes (with a cameo appearance😞

 

PropertyNodeInterface.png

 

Discussion questions to duke out in the comments section:

 

  1. Can the developer rearrange the order of the nodes (like in a Bundle by Name), or is the order fixed (like a Bundle)?
  2. Related, can the developer select fewer or duplicate elements that are in the data cluster (like a Bundle by Name), or is the node size fixed to show the exact number of elements in the data cluster (like a Bundle)?
  3. Are inputs Required, or can the developer leave them unwired to assume default data?
  4. Would these nodes replace the current nodes, be an alternate display of the current nodes, or be new nodes altogether?
  5. Should the Error Terminals go above the data I/O (like Scan From String) or below?
  6. Do we want only the small icons (like Bundle, or Scan From String, and shown in proposed illustration) or the full data name (like Bundle by Name) for data IO on the node? Does it need to be configurable, like 'No Names', 'Short Names', and 'Long Names' on Property Nodes?

 

10 Comments
JackDunaway
Trusted Enthusiast

This Idea is something I've been contemplating for a while, but it became fully formed after thinking about David Boyd's comment here and his subsequent Idea posted here.

JackDunaway
Trusted Enthusiast

I'm going to go ahead and respond about the location of the Error lines - they need to maintain correct spacing with respect to the reference to fit the standard 4-in-4-out Connector Pane.

 

I realized that while creating a mock up here. I've copied the two images below, illustrating how dramatic the improvement can be:

 

CleanerUserEventInterface.png

tst
Knight of NI Knight of NI
Knight of NI

I thought you don't like typedef clusters anymore. 😉

 

 

An alternative way of handling your initial example is by using classes - you replace each parameter with a class, and the custom data for that class replaces the payload variant. Then, in the event structure, you get the object and use a dynamic dispatch VI instead of the case structure. Do you think that would work better?

 

 

This isn't to say I dislike the idea, BTW. I think it is interesting.


___________________
Try to take over the world!
JackDunaway
Trusted Enthusiast

>> I thought you don't like typedef clusters anymore

 

Yair is referring to a long conversation we had on LVOOP vs. Typedefs which culminated in my LVXCC Contest entry where I used no typedefs and challenged anyone to show me where a typedef would produce more elegant/maintainable code.

 

Right now I would consider my "hatred" ( Smiley Wink ) of typedefs an intriguing case study, not a syntactical manifesto. Can I say I'll never send a typedef along a messaging ref again? Not yet. Will I see other people do so, and possibly even maintain that code? By golly, yes, indeed.

 

 >> An alternative way of handling your initial example is by using classes - you replace each parameter with a class, and the custom data for that class replaces the payload variant. Then, in the event structure, you get the object and use a dynamic dispatch VI instead of the case structure. Do you think that would work better?

 

Short answer: no. Dynamic Dispatch is sometimes a worse alternative than Case Structures.

 

Rationale:

  • A distinct child class is required for every message type, in addition to more children and overrides for every implementation that "does something" with that message type. The class hierarchy branching from the base "Message" class would be unwieldy - consider what a class diagram of every single message in a larger app would look like, and how many "corner cases" you might need to handle.
  • You might have some noticeable performance loss. For instance, if I want to continually message some code module to update display elements, I can write the control terminal in the module's case structure. If that module handled the message via Dynamic Dispatch, a ref to the FP Control would be required to be passed into the class method (which presents a problem in itself - does every other DD for that method need the same reference? Low Cohesion Alert!)
  • Consider messages to a code module that update different elements of state data in that code module. The entire state data must be passed into the DD method - Low Cohesion Alert! (Going back to the original example and my mini-message-handler, one key element I don't show is the state data cluster wire passing into and out of the case structure)

     

    ***EDIT: This isn't to say I like the idea, BTW. I think it is interesting. (Not joking - I'm ambivalent about typedefs, but I thought the Idea was interesting enough to post, and maybe it could launch some better Ideas)***

  • GregSands
    Active Participant

    I mostly like this, at least as an alternative to the current arrangement.  My quick response to your questions:

    1. Reorder elements: No

    2. Size: Fixed

    3. Required: No (unwired = default value provided in original cluster)

    4. Replace: No (they should be optional alternatives)

    5. Error: Above data

    6. Names: I think icons are sufficient, but others may prefer names.

     

    jgcode
    Active Participant

    This is a great idea - as per GregS (#6). I would prefer names so its easier to see, although this would increase the size of the node dramatically (and programmatically). I still think this would neaten up the BD, without the need for an extra typedef.

     

    One thing I think ties in with this is how the data comes out on the other side:

     

    [LV2009]

    One things I do not currently like with User Events, its that it splits out the elements of a cluster. If the Cluster is a data structure (e.g. Error Cluster) and I am passing that around then I have two choices:

    1. Wrap that Cluster in a containing Cluster to form the datatype

    2. Bundle it back up inside the Event Structure's registered event

     

    I find both these options slightly tedious.

     

    I would like the ability to be able to select the entire cluster from unbundle node of an Event Structure as well as individual items. I think the reason for this is that like items in a multi-configured event case can therefore be easily accessed - so in sticking with that theme, the option should only be available if the datatypes are the same for all configured events. 

     

    Events.png

    Certified LabVIEW Architect * LabVIEW Champion
    JackDunaway
    Trusted Enthusiast

    Jon - check out this oldie. Smiley Wink (Also linked in this original idea: "(well, every now and then I'd like access to the top-level data structure on the Event Data Nodes...)")

    jgcode
    Active Participant

    Thx for the link Jack, I kudos that.

    You should definitely run a advertising campaign for that one, as above, I find it very tedious.

    Certified LabVIEW Architect * LabVIEW Champion
    AristosQueue (NI)
    NI Employee (retired)

    I posted this same comment in David's idea for "A node to return the data type of a user event refnum".

     

    As for the choice between the "easier bundling" that Jack proposed or the "extract the cluster type" that David proposed, I can see use cases for both. I'd be inclined to give priority to David's solution because it provides a partial solution for Jack's. Jack's becomes syntactic sugar if we have David's node, and David's node can be used to solve other data handling situations where I'm trying to bundle in values of the cluster and not immediately sending it to the event, or if I want to wire to an Unbundle node. Jack's solution also has issues in that it does a "bundle by index", where as I would want a node that does "bundle by name", generally a much safer mechanism because it generally keeps up to date as code changes (in fact, it always works as long as you're careful to always have unique names in your cluster, which most people appear to do, whereas "bundle by index" can get confused).

    tst
    Knight of NI Knight of NI
    Knight of NI

    Warning - this is going completely off topic. If you want to extend this, start a new thread.

     

     

    > A distinct child class is required for every message type, in addition to more children and overrides for every implementation that "does something" with that message type

     

     

     

    That is correct. Not having actually implemented this kind of archiecture, I can't comment on the actual performance implications. I should point out, however, that this is an existing design pattern, so I assume some people have.

     

     

     

    > You might have some noticeable performance loss. For instance, if I want to continually message some code module to update display elements, I can write the control terminal in the module's case structure. If that module handled the message via Dynamic Dispatch, a ref to the FP Control would be required to be passed into the class method (which presents a problem in itself - does every other DD for that method need the same reference? Low Cohesion Alert!)

  • Consider messages to a code module that update different elements of state data in that code module. The entire state data must be passed into the DD method - Low Cohesion Alert! (Going back to the original example and my mini-message-handler, one key element I don't show is the state data cluster wire passing into and out of the case structure)
  • Answer to both - C'mon man! I thought you were commited to the "no clusters" idea. Get rid of the state cluster, have it as a class, then have the DD VI accept and return an optional LV object. This can include the reference to the indicator as well.
    Like I said, this is one design pattern. It may or may not work for you. Not having implemented it on any serious code I can't really comment.

    ___________________
    Try to take over the world!