Jump to content

Public malleable class members


Recommended Posts

 

Just ran into an issue with malleable VIs I had not thought about before, and now that I have I cannot find any mentioning of it anywhere (?):

Because mallable VIs have to be marked as inlined, you cannot use them in classes if the VI is to be public....:( It then breaks because inlining it means accessing private data in the calling function.

In my case I wanted to use it instead of a polymorphic approach to supporting read/write operations with different data types on a file class.

Or am I missing something?

It all reminded me a bit about this old thread about the lack of support for polymorphic VIs in classes - 

 

 

Link to comment
On 6/6/2018 at 9:33 AM, Mads said:

you cannot use them in classes if the VI is to be public....:( It then breaks because inlining it means accessing private data in the calling function.

Can you clarify a little or throw up an example.

Do you mean you want the .vim to be a member of the class or used inside a public VI in the class?
I presume you mean the former.

What happens if you use private accessors in that VI instead of calling the unbundle directly?

Link to comment
On 6/6/2018 at 3:33 PM, Mads said:

Because mallable VIs have to be marked as inlined, you cannot use them in classes if the VI is to be public....:( It then breaks because inlining it means accessing private data in the calling function.

I've used public inlined methods (non-VIM), so that can't be the issue.

Link to comment
On 8.6.2018 at 0:42 AM, Norm Kirchner said:

Can you clarify a little or throw up an example.

Do you mean you want the .vim to be a member of the class or used inside a public VI in the class?
I presume you mean the former.

What happens if you use private accessors in that VI instead of calling the unbundle directly?

I meant that the VIM is member of a class yes. I've been informed now that this can be achieved as long as the VIM uses an accessor when operating on private data...Now at first that did not seem like a solution as I then expected the accessor to have to be public, and I do not want that particular private data available at all, but the accessor *can* be private, so that makes it a solution. Not a very intuitive one - but at least it is doable.

(It seems a bit strange that the VIM is not allowed direct access to private data, but it can still call a private method to effectively do the same thing (so why not allow it to access the private data without the accessor in the first place...)).

Link to comment
  • 2 months later...

I've been informed now that this can be achieved as long as the
> VIM uses an accessor when operating on private data...

That information is in the error message. Do I need to clarify the message? 

(It seems a bit strange that the VIM is not allowed direct access to
> private data, but it can still call a private method to effectively do the
> same thing (so why not allow it to access the private data without the
> accessor in the first place...)).

There's a pretty crucial optimization that LV classes are built upon that when the private data changes, the only VIs that need to be evaluated for recompile are the members of the class. The dependencies between VIs are tracked (i.e. when one VI calls a subVI), but creating a similar web of dependencies on the individual fields was significant work that was unnecessary ... until the advent of malleable VIs. When I considered the work of adding such a matrix compared to the workaround of providing a private accessor VI, it just didn't seem worth it. So, I put the limitation in for private data access and waited to see how many people would object. One so far. :-) 

Link to comment

Having to use the accessor vi rather than a property node tripped me up - I can see how the compilation issues mean not accessing the private data directly, but not the difference between calling an accessor vi directly or inside the property node.....

Link to comment
12 hours ago, Aristos Queue said:

There's a pretty crucial optimization that LV classes are built upon that when the private data changes, the only VIs that need to be evaluated for recompile are the members of the class. The dependencies between VIs are tracked (i.e. when one VI calls a subVI), but creating a similar web of dependencies on the individual fields was significant work that was unnecessary ... until the advent of malleable VIs. When I considered the work of adding such a matrix compared to the workaround of providing a private accessor VI, it just didn't seem worth it. So, I put the limitation in for private data access and waited to see how many people would object. One so far. :-) 

Increased quirkiness can be a silent killer...:ph34r:

Malleable VIs combined with LV classes is not the busiest road, I guess. I'm sure there will be more than just me getting frustrated. Happy to be the first to voice it ;)

Edited by Mads
Link to comment
  • 2 weeks later...
On 8/28/2018 at 8:09 AM, bbean said:

Two

BBean: How bad is the limitation? Just annoying or is it actually blocking work? And was the error message sufficient to explain the workaround?

I've looked further at creating the mapping system -- it's a huge amount of effort with fairly high risk. I'm having a hard time convincing myself that the feature is worth implementing compared to other projects I have in the pipeline.

On 8/28/2018 at 4:58 AM, Mads said:

Stephen - did you see this video I made of the behavior of the Malleable VI when trying to call a *protected* VI? Looks kind of funny, or?

As I said on ni.com, I investigated Mads' bug where malleable VI fails when calling protected scope subVI. I was unable to replicate the issue. Mads could not replicate it again either. So it is definitely a corner case bug. If anyone sees it, please share VIs that replicate.

On 8/16/2018 at 1:36 AM, gb119 said:

Having to use the accessor vi rather than a property node tripped me up - I can see how the compilation issues mean not accessing the private data directly, but not the difference between calling an accessor vi directly or inside the property node.....

When you change a subVI, which VIs in memory have to recompile? Only those that call the subVI. How do we know those? Well, we have a network of links between VIs (and libraries and projects) that track all the dependencies, so I just traverse the links from the subVI to all of its callers. I don't have to recompile every VI in memory on the off-chance that it calls the modified subVI. Conversely, when you run a VI, which subVIs need to be locked so they can't be edited while you're running? Again, I can traverse the linker graph to lock those that are dependencies of the top-level VI.

When you change the private data control, which VIs in memory have to change? Prior to malleable VIs, I didn't need any sort of tracking for which VIs accessed the data -- I just told every member VI to redo its compilation... fast and narrowly scoped. No link information required. And when you run a VI, does the private data control need to be locked? Only if a member of the class is invoked.

But with malleables introduced, if they could talk to private data directly, the linker graph wouldn't reflect the dependency of the malleable instances on the main malleable VI. If you go through a subVI or subVI-masquerading-as-property-node, there is a link, so when the private data control changes, we change the subVI, and that causes the caller to recompile (if necessary... usually only necessary if you've inlined the subVI).

Link to comment
21 hours ago, Aristos Queue said:

BBean: How bad is the limitation? Just annoying or is it actually blocking work? And was the error message sufficient to explain the workaround?

I've looked further at creating the mapping system -- it's a huge amount of effort with fairly high risk. I'm having a hard time convincing myself that the feature is worth implementing compared to other projects I have in the pipeline.

Its just a hassle.  I understand the risk reward decision.  I just wanted to indicate Mads isn't a lone wolf.

Link to comment
  • 4 months later...
On 8/30/2018 at 10:35 AM, Aristos Queue said:

As I said on ni.com, I investigated Mads' bug where malleable VI fails when calling protected scope subVI. I was unable to replicate the issue. Mads could not replicate it again either. So it is definitely a corner case bug. If anyone sees it, please share VIs that replicate.

Hi AQ,

I submitted an example that reproduces the failure to dispatch protected methods to NI a couple weeks ago and haven't received any reply. Let me know if you're interested in exploring further. (You were also on one of the community threads to which I redundantly posted the example code.)

Also, I'm finding the inability for a privately-scoped malleable method to access class data very limiting. Using accessors prevents some crucial in-placeness optimizations and making the in-place method public makes for a super leaky API. I found yet another (slightly less bad) workaround in my current case, but only by totally sacrificing encapsulation.

Link to comment

Ethan:

Your CAR has been received, and I believe I have it fixed for LabVIEW 2019. Testing is ongoing to verify, but I’m confident.

The in-place optimizations for class field access should I hope be addressed in LabVIEW 2019 if you have simple, inlined, static dispatch accessors that do not include error in and error out. We found a way to make the magic pattern that works for clusters apply to classes. Fingers crossed.

Relaxing the block on access to class private data has even more gotchas than I expected, and not just at the technical level... since we do method substitution within the VIMs, if we allow access to class private data then it seems like we should allow substitution of the fields. But that is a pretty ill-defined interface that crosses the line to admit some of the hardest-to-debug C++ code. I’m opposed to admitting that to G language, even as I acknowledge its powerful notation. Even if I bought into it, I still don’t have a good solution to the technical barriers, at least not in LabVIEW 20xx. In LabVIEW NXG, it seems like it may be more viable.

 

Link to comment

Very cool, and thank you! The scoping fix and the in-placeness will allow me to get the performance and the public APIs I was aiming for. If statically placing a private method with unbundle/bundle data access opens a can of worms, I'm happy to make a couple private accessors. Fingers remaining crossed for 2019 release.

-Ethan

Link to comment
  • 4 months later...
  • 11 months later...

LabVIEW 2020

I am seeing an inconsistent behavior with a public vim calling a dynamic dispatch protected member. The calls is not broken as long as no child is made or loaded into memory. Once a child has been made (and the override created) trying to reconnect the call to use the child brakes the wire (at that point I am unclear what is the desired behavior).

image.png.3a9c4eb18432e95d3f1d20e4d182b207.png

call is not broken (but converted vim is broken with a scope error).

Also, this code above just run fine (and the protected dynamic dispatch does as well).

 

2020-06-13_16-07-19.png.2fc0c94860101b6ccb954b9114524a24.png

everything seem fine (but converted vi is still broken)

 

2020-06-13_16-08-17.png.bcf91984c5a1bf24506c598f1b962bbb.png

code is broken and can not be "unbroken"

class vim bug.zip

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.