LabVIEW

cancel
Showing results for 
Search instead for 
Did you mean: 

Follow-up questions from "G Interfaces in LV 2020" webcast (May 1, 2020)


@jsiegel wrote:

I don't have that option.  Is there something I need to do to enable it?  I do already have an actor in my project.


Works for me. I tried several variations. Anyone else having this difficulty?

 


@jsiegel wrote:

Note that the slide also shows a menu item for creating a new XNode,


Ah. I forgot to turn that off. Good eye! But -- correct -- that's not a released option.

0 Kudos
Message 21 of 50
(1,746 Views)

@pawhan11 wrote:

Are there plans to expose native LV interfaces so we can iterate over class (i am thinking like ienumerable and ienumerator in c#)

pawhan11_0-1588567225577.png

and many others that are used in LV primitives?


Same could be done for compare functions. If a class implements a > and =, two objects could be compared. Min\Max would be possible, and an array of objects can be sorted.

 

More general, all 'operators' (++,--, +, - *, etc.) could potentially be overloaded 😎...

 

EDIT: I guess we can already partially make that with .vims that implement the normal functions, and a type specialization for a class method. But that would work best if the methods are from  standard interfaces used by and available for everyone. And it wouldn't work for growable functions.

0 Kudos
Message 22 of 50
(1,725 Views)

wiebe@CARYA wrote:

EDIT: I guess we can already partially make that with .vims that implement the normal functions, and a type specialization for a class method. But that would work best if the methods are from  standard interfaces used by and available for everyone. And it wouldn't work for growable functions.


Check out "vi.lib\Array\*.vim" -- you'll find a bunch of places where I've already defined the standard comparison patterns. I wanted to add those to the palettes this release, but I was distracted by the larger interfaces feature. I put those .vims out in LV a couple years ago when the interfaces go/no go was still in doubt. (Originally they were in "examples" dir, but another dev needed them for real work and moved them to vi.lib in LV2019.)

Message 23 of 50
(1,707 Views)

@pawhan11 wrote:

Are there plans to expose native LV interfaces so we can iterate over class (i am thinking like ienumerable and ienumerator in c#)

pawhan11_0-1588567225577.png

 

and many others that are used in LV primitives?

 

 


Perhaps related to this, is there any preference for/against LabVIEW defining some common interfaces that customers could choose to reuse.

An example, again taking from pawhan's choice of C#, might be something like IDisposable, indicating that a class implements some Close/Shutdown/Cleanup/Dispose (in the C# case) method.

 

I don't know what a suitable list of these might be, but perhaps "Init" and "Shutdown" are common enough operations.

It might allow multiple developers to more easily share reusable components.


GCentral
0 Kudos
Message 24 of 50
(1,682 Views)

@cbutcher wrote:

Perhaps related to this, is there any preference for/against LabVIEW defining some common interfaces that customers could choose to reuse.


I suppose there is already a place to find out if an idea has support for or against...

https://forums.ni.com/t5/LabVIEW-Idea-Exchange/Ship-common-quot-Interfaces-quot-for-use-in-customer-...


GCentral
0 Kudos
Message 25 of 50
(1,681 Views)

@cbutcher wrote:
I suppose there is already a place to find out if an idea has support for or against...

https://forums.ni.com/t5/LabVIEW-Idea-Exchange/Ship-common-quot-Interfaces-quot-for-use-in-customer-...


I'll comment on this on the Idea.

0 Kudos
Message 26 of 50
(1,684 Views)

Not sure if this is the right place to put this question, so please let me know if I should post it elsewhere.

 

When trying to use an interface to isolate a message from the actor that will execute it, I ran into a strange issue.  I probably am doing something wrong but I have not been able to sort out what yet.

 

I will try to describe this in generic actor based messaging architecture, not AF specific, but I think this would apply in AF as well.

 

When sending a message from one application to another, there is a static dependency between the message and the actor that will execute the message due to the need to give the message the ability to modify the state of the receiving actor.  As a result the sending application requires the receiving actor's class to be included.  I want to use an interface to break this dependancy.

 

I built a simple example to test this.  It has:

A generic parent actor class.

A generic message class.

A specific child actor class (inherits from generic parent actor)

A specific child message class (inherits from generic message)

An interface that the child actor inherits from.

 

The generic message class has a must override method to execute the message.  It takes the generic parent actor class as an input.

The specific child message class has an execute method that casts the generic parent actor class to the interface (instead of to the child actor class).  This makes the specific child message dependent only on the generic parent actor class, the generic message class and the interface class, not the specific child actor class. Once the cast is done, the message method can call the interface method and provide the message specific data so it can be used to modify the state of the specific child actor.

In the specific child actor, there is a method that overrides the interface method called by the message to do the work of updating the specific child actor's state.

All this seems fairly straightforward.  But here is where I run into an issue:

The message execute method takes in the specific child actor class but on the generic parent actor's wire.  After I cast it to the interface class, I can call the interface method without issue.  The interface method output is the interface class, but with the specific child actor class on that wire since that is what went in.  But I cannot wire that to the message execute method's generic parent actor indicator.  I get a broken wire.  I cannot cast it to the generic parent actor either.  That makes a broken wire as well.  But, I can cast it to LV Object and THEN cast it to generic parent actor.  This seems like I am doing something wrong.

But the end result is it works.  The message can be executed and the specific child class's state will be modified.

Is this the right way to do this?  Or did I miss something along the way that would make this simpler?

 

I attached the source code of the test project, saved in LV2020 beta.

 

Sorry for the long post.  I hope I described it as clearly as possible.  And thanks for any help understanding this better.

-John
------------------------
Certified LabVIEW Architect
0 Kudos
Message 27 of 50
(1,567 Views)

@jlokanis wrote:

Sorry for the long post.  I hope I described it as clearly as possible.  And thanks for any help understanding this better.


You did describe it just fine.

If you let the Actor Framework script the message for you, it'll correctly take care of the casting problem for you. In a project with at least one actor class already loaded, right click on an interface's method and go to the Actor Framework menu item. Should work the same as creating a method on an actor class.

0 Kudos
Message 28 of 50
(1,560 Views)

Thanks for the presentation Stephen. A friend and I were reviewing the Basic Interfaces shipping example in 2020 and we were confused once we started looking at the dependency relationships. I don't remember you ever showing us a UML diagram in your presentation... or did I miss that part?

 

I attached a sketch that shows some of the dependencies. Box class implements Pryable interface AND depends on a Lever interface which depends on a Pryable interface. Doesn't this look and sound... strange? After studying the example, I walked away wondering if I should expect these types of dependency relationships to appear in my designs now that I have interfaces at my disposal. I'm asking you this because something about that design choice makes me uncomfortable, but maybe it's an adjustment period I need to go through.

 

In the past I found myself striving for a tree-like dependency structure in my application architecture. Now that I have interfaces, should I abandon that effort? Should I expect dependency arrows to be pointing in opposite directions in my UML diagrams?

 

The Basic Interfaces example has a Lever interface that is expecting to find a Pryable interface to act on. For me, this is counterintuitive because I never walk around with tools in my hand looking for things to use them on. However, I do look for a specific tool with specific capability when I'm working on an object that demands it. In my mind, a Pryable interface (or a Pryable object) demands a Lever, not the other way around.

 

If you showed us a UML diagram during your presentation, apparently I missed it. If you chose not to show us a UML diagram, why not? I'm baffled when people write software and don't keep track of the dependency relationships. The longer I do software, the more important this seems. Keeping track of dependencies is one of the most important things I do on a daily basis. In LabVIEW projects, the only way I know how to do this is to keep a UML diagram up to date. I would never open the LabVIEW Class Hierarchy window and use it to try to explain project architecture to someone unless I was trying to be intentionally vague.

 

Regards,

Eric Graham

0 Kudos
Message 29 of 50
(1,515 Views)

egraham:

Answer comes in two parts... first "why no UML" and then discussion of this specific diagram.

 

I did not include any UML for two reasons.

  1. This was a general LV presentation, and UML (in my experience) tends to confuse more G users than it helps. Even among CS professionals, it's unintuitive. You included a legend in your picture -- that's critical, in my observation, for every diagram because of the unintuitive nature*. Generally when I pull out UML, I need to spend an hour talking about what UML is before we even start on any specific diagram. To me, it's a pretty bad notation for learning an application. It works great as a language when two engineers already know an app and are discussing how to adjust it. I do not know of any single graph notation that is good for learning... generally, I have success talking about each type of relation individually and then overlaying them with some animation. I did not do that here. Which leads to my second point...
  2. In this particular presentation, my goal was not to go into all the depth of dependency tracking. This was merely to talk about the role of interfaces as defining behaviors and showing the multiple parents aspect. And that's the graph I did show and focused on. If we were actually having an NIWeek, I had intended a deeper dive into dependency inversion to be part 2 of 3 of interfaces presentations. COVID-19 disrupted many plans. 

> Should I expect dependency arrows to be pointing

> in opposite directions in my UML diagrams?

 

No, you should not expect backward arrows. Backward arrows imply cycles. Cycles are bad.

 

In your picture, slide "Box" down to the row below Lever. All the arrows will now point up. There are no cycles in this graph. A thicket of overlapping trees is fine and expected.

 

> In my mind, a Pryable interface (or a Pryable object) demands

> a Lever, not the other way around.

 

That's a viable way to model this system. It all depends on which way you write the sentence. "Lever affects Pryable" is how I phrase it. You phrase it as "Pryable needs Lever". The subject dictates which class gets the method, and the direct object dictates which one is the parameter. Both work. To me, Lever is an active thing affecting a passive object, but you can just as easily see Pryable as the thing whose state is changing and therefore is the active partner.

 

In typical LV apps, I tend to model the device-under-test as something that I pass into sensor and control classes. Others invert that. As long as you're consistent, everything works out. I suggest that one significant reason that general HALs are so hard to define in committee is competing visions of which party is the active party. It is also, I think, commonly why beautiful code is declared "poorly written" by a newcomer. The newcomer doesn't share the system's perspective and is constantly fighting it. See my left-handed scissors post on LAVA.

 

* PS: I have a standing request for anyone that can me a concise way to differentiate "association" from "dependency" without making "association" sound like "aggregation". Please start a new forum thread somewhere if you want to tackle that.

0 Kudos
Message 30 of 50
(1,496 Views)