Jump to content

mje

Members
  • Posts

    1,068
  • Joined

  • Last visited

  • Days Won

    48

Posts posted by mje

  1. I've done this, though there's always a pair of accessor VIs attached. I'm one of those people who litter my classes with accessors and never touch the cluster data except in said accessor VIs. It's just too darn convenient when you need to find where a field is used.

     

    That said, I'd be against the idea because now you can't get a good idea of what your state data is by looking at the class control-- it becomes scattered about in several places. Maybe I'd like it if somehow the field automagically also appeared in the state control, but somehow was greyed out and not selectable outside of the VI. Maybe. But then I imagine automatically placing such fields could make for absolute havoc if on unbundle nodes.

  2. Is it the drag event that's mucking things up?

    I do this all the time for tracking movements on graphs, but admittedly there's no native drag event happening. During mouse movement I shuttle data (including position) off to async floating window tasks depending on contexts such as near data, out of bounds, or mouse button state. However admittedly I rolled my own drag logic because the native one didn't suit my needs- not even sure if the graph controls support it?

  3. "So, I think your question indicates you're still seeing Implemented methods like a Dynamic Dispatch override."

     

    No, I get it. You're looking for a statically resolved link. The possible paths code could take is completely resolved when things are compiled.

     

    Note: I'm going to use the word "interface" a lot in this post, and I mean it as a general point of interaction between pieces of code, not the abstract sense which comes up in some languages that use it as a keyword, or in several theoretical discussions we have had here on lava.

     

    I guess for me dynamic dispatch isn't fundamentally about just changing behavior via overrides or producing concrete implementation. Sure, that's the mechanics of it, but in isolation is of very little value.

     

    A class that has any dynamic methods defines a programming interface at one level that derivative classes can modify or must implement. The value in such a mechanism comes when the programmer writes code calling the dynamic methods from the superclass interface-- completely unaware of any derivative classes. This code can be part of the superclass itself or completely separate. The code that operates on the dynamic interface at the superclass level is essentially laying down a series of hooks, detailing the conditions when these methods will be called and has done so completely decoupled from any derivative classes which may exist at run-time.

     

    I suppose if I'm going to boil it down to one sentence it is this: just as important as the dynamic dispatch method itself is the contexts under which the method is called.

     

    (You can at this point hopefully imagine how important I feel documentation is for these methods. I die a little inside every time I see an undocumented dynamic dispatch.)

     

    So that's why I'm not sure I understand why a "must implement" could be useful. You're basically saying if you're going to have an "is a" relationship with me, you need to do something(). But an interface can't be provided so you can't provide the context in which something() will be called. No code that operates via the superclass interface can do anything with something() due to the lack of this interface. The code requires direct knowledge of the derivative class, which has completely defeated the purpose of defining something() at the superclass level.

     

    I will concede one point though, a "must implement" will indeed provide a good set of clues as to what derivative classes should be doing. However I feel the inability to enforce anything beyond the mere existence of something with a given name means these hints really don't belong in code in my opinion.

    • Like 2
  4. SubVIs are separate files. If someone posts an example VI which uses SubVIs which aren't part of LabVIEW they ought to be distributing a collection of VIs instead of just one. Or instructions on where to get the other VIs.

    Alternatively maybe you're dealing with an example VI that uses a toolkit you haven't installed/purchased?

  5. Hmm. Jack, please understand I'm not trying to be hostile, I just really don't understand how this could be used.

    So if a superclass deems MethodX must be implemented, but it can't call this method because no interface has been defined, how is the VI useful to the superclass or any other code that interacts with the superclass interface?

    Something similar would be the ability to overload methods: being able to define a new VI with the same name but different connector pane. This however is mostly syntactic sugar as in languages that allow it as no real functionality is introduced that couldn't be achieved by naming each method differently as we do in LabVIEW. In effect overloading is really an edit-time convenience.

  6. How would you ever wire up to the must implement method if you haven't defined the interface?

    For methods where I need to override but might conceivably require additional or different data, I personally would consider ditching the idea of specific arguments all together: have the connector pane with the usual dynamic dispatch and error I/O if required, plus an additional single/pair of terminals of some Object where descendant classes can cast if necessary?

  7. Probably worth mentioning one other rule I try to follow at all times in subVIs: If you didn't open it, don't close it.
    This is my general rule too, though there are exceptions where documentation clearly states references returned must be closed.

    There are also less clear cases-- the XML library is particularly finicky/inconsistent in my opinion, but this is likely due to the underlying third party binaries rather than LabVIEW.

    Jack's point is very good. The desktop execution trace toolkit is very valuable for tracking reference leaks.

    • Like 1
  8. I'm also curious about this. Such large arrays could pose problems. A 10 M element DBL array is 80 MB, and 160 MB for the resulting complex data type. Do you actually expect to reliably be able to pull continuous chunks of memory larger than that, even on a 64-bit environment? I've done my share of working with large data sets and through experience learned never try to float around arrays like that. LabVIEW does not fail gracefully if it fails to allocate memory...

  9. Thanks for looking into this James.

    I definitely haven't ever noticed the service doing anything from our applications, which is part of the reason I never even knew the RTE installed it until Windows 8 made it plain as day (at least for those of us who use task manager regularly). This however will be the first time we haven't used an NI-built installer so my experience with using a full RTE install is limited-- previous versions of our application used an NI-installer and excluded the NIER option.

    It was indeed a concern as one of our design requirements is the application have no footprint on the network as it can be called upon to handle some pretty sensitive intellectual property for customers who worry about such things.

    That document you linked though is very useful. Especially this quote:

    How does NIER work with the LV RTE (LabVIEW built apps, dlls, interop assembly etc.)?

    You will get a crash dialog when an internal error (DAbort) or exception is detected. However, the crash dialog does not have the option to send the report to National Instruments. The product name shown will be the name of the process that's crashing and not LabVIEW. Internal Warnings will cause mini-dumps to be created, but the Internal Warning Reporter dialog box will not appear when you close the application. These characteristics apply to LabVIEW built applications, dlls and interop assemblies

    So it seems we're in the clear: data will not be sent over the network to NI.

  10. So I was "playing" by installing our latest release candidate on Windows 8 even though we don't officially support it. This is a fresh OS I just installed with the following extras installed:

    • Our application
    • LabVIEW 2011 SP1f2 RTE*
    • Microsoft .NET 3.5.1
    • Microsoft Visual Studio 2010 SP1 Redistributable

    We have 32-bit and 64-bit installers, each with the appropriate applications/run-times. Anyways, the first thing I notice in the task manager is this on our fresh Win8 64 OS after getting things up and running:

    post-11742-0-86470100-1355775325_thumb.p

    Does this imply that the default RTE install activates the NI error reporting service which has the potential to send back data to NI? Under which conditions would the error reporting be triggered for a LabVIEW-built executable?

    -m

    *I'll note that due to a defect in the 64-bit LabVIEW application builder, we are forced to go third-party for the installer. Thus the RTE is installed via a silent install of the extracted downloadable RTE installer (that is we don't have an NI built installer). The installer is executed via:

    setup.exe /q /AcceptLicenses yes /r /disableNotificationCheck

  11. I have an incoming message that has an array of u8 data. A subset of this data is parsed to determined the "type" of the message. There are 4 different types of messages so I have a class for each type, and a factory that creates the proper one based on the type. Then I have a method for each type that futher parses the u8 array (the array is parsed differently based on message type). This gives me a bit more information, and I finally know the "final" type of message so I can generate that class.

    Sounds to me like a classic example of serialization. The caveat being you might be forcing a hierarchy that is different (or possibly didn't exist) on the other end.

    Why not just extend the factory up through the various layers?

    It probably goes without saying, but I'll be explicit: the factory methods are static (not dynamic dispatchers, probably don't even have a class terminal). BaseMessage.Create() reads what it needs to in order to delegate to any of the TypeN.Create() methods. Similarly the TypeN.Create() method reads what it needs to, and delegates another level to the appropriate FinalSubclassN.Create() method. It's only however many levels deep into the Create() methods when the class is fully resolved that the appropriate type is determined and returned. Any dynamic dispatching happens after the create factory stack has sorted out the type.

    Err yeah, looks like PiDi had a similar recommendation.

    And for the record, when I said "probably don't even have a class terminal", I meant input terminal.

×
×
  • Create New...

Important Information

By using this site, you agree to our Terms of Use.