Jump to content

drjdpowell

Members
  • Posts

    1,964
  • Joined

  • Last visited

  • Days Won

    171

Everything posted by drjdpowell

  1. I do have an example of a parent-class restriction that I wish I could make. I have an abstract “address” object that defines a method for sending a message. The framework that uses this parent assumes that “Send.vi” is non-blocking (and reasonably fast). But there is nothing stopping a child-class being implemented with a blocking enqueue on a size-limited queue, other than documentation.
  2. One of the topics in the thread following this post by MattW is a possible reduction in performance due to LabVIEW needing to check if the dll path input has changed between calls. In this later post by me I explained why I switched to using an in-place structure: "I found through testing that some of my subVIs ran considerably slower than others, and eventually identified that it was do to details of how the class wire (from which the library path is unbundled) is treated. Basically, a subVI in parallel to the CLN node (i.e., not forced by dataflow to occur after it) would cause the slowdown. I suspect some magic in the compiler allows it to identify that the path has not changed as it was passed through several class methods and back through a shift register, and this magic was disturbed by the parallel call. This being a subtle effect, which future modifiers may not be aware off, I’ve rewritten the package to use In-Place-Elements to access the library, thus discouraging parallel use." Opps! I really should document more. This was only my second “wrap a C dll” job, and the first time I’ve used “MoveBlock”. The issue is the fact that C strings have an extra 00 byte at the end and thus are one byte longer than their LabVIEW string length. I’m not sure I’m doing it correctly, but in “Pointer-to-C-string to String” I’m walking along the string to find the 00 byte, while in the other MoveBlock uses I’m getting the exact string length from sqlite. Check that you are “reseting” any statements when finished (or you’ll be holding a Read lock on the database file), and that you aren’t holding an SQL transaction open (a Write lock). — James
  3. Could you post some code illustrating the problem? Or images of your producer and consumer code? I can only guess that your holding a lock on the database open somehow.
  4. I wonder if anyone has ever saved Timestamps needing better than millisecond precision in a config file. That would be the potential issue with this suggestion.
  5. AQ, Good arguments for “Must Override”, but does that have anything to do with “Must Implement”? A child must still respect the requirements of parent code, but “Must Implement” tries to define what can be done for child-type static methods that are independent of parent code.
  6. Hi, You have a call to a missing xnode: "Minimum Array Size.xnode" in your “Toolbar.xctl:Set Toolbar Images.vi"
  7. I assume you meant “Must Override”; I don’t use that much, but I’ve never had experience with writing parent classes for other designers to make children of, so I can’t really comment on that. As far as “Must Implement”, I can’t really think of a good use. Child classes can be used for purposes that are different from what the designer of the parent class envisioned, so adding restrictions at that stage seems inappropriate. Especially ones that can be easily broken by adding a not-to-be-used extra methods (what icon glyph should we have on VIs never meant to be called but needed to satisfy misguided restrictions?).
  8. More than that. The IPE makes explicit what the compiler tries to do anyway: minimize copies. In fact, the IPE’s real benefit is as a guide to the programmer in writing code that can be done in place, rather than actually allowing in-placeness.
  9. References deallocate when their owning VI hierarchy goes idle. When calling by reference synchronously, as your doing, the dynamic VI is running under the hierarchy of its caller. When one uses the asynchronous methods (“Run VI” or ACBR Fire-and-Forget) then that creates a new VI hierarchy. Added later: using ACBR Call-and-Collect also creates a new hierarchy (I’ve not used it before); the following mod causes the reference to deallocate. You can figure out what hierarchy a VI is running under by using “Call Chain”. With the original version, the call chain of “ThrowDVR.vi” showed it to be running as a subVI of the calling VI.
  10. Perhaps it would be best if you explained what you’re trying to do.
  11. Looking at this one, I would get rid of the child classes entirely and just have two VIs, “DisplayMessage-Bool” and “DisplayMessage-Numeric”. But this is perhaps because the example is (as most examples are) a very simple case. Even with child classes, though, I would just rename the methods. I’m not sure it is desirable to "contractually require functionality in subclasses”. That’s the author of the parent class trying to constrain and dictate the design of every yet-to-be-thought-of child class. Too easy to over-constrain. “Must override” and “must call parent” are different in that they are often actual requirements to make the child class function with parent-type code, and thus it is reasonable for the parent’s author to dictate this.
  12. Just my two cents, but as the designer of a child class, I wish to have my child objects function properly in code written for the parent (and thus am interested in overriding and/or calling parent methods where required), but I am not actually interested in being required to do things with code written for the child.
  13. The “shared clones” setting affects operation of statically-called VIs (such as an ordinary block-diagram use). Dynamic use depends on the options to the “Open VI ref” function; in your case option 0x8 creates a new clone with each use (with “auto dispose ref” you are destroying the clones and just reusing the clone numbers in new clones). To use “shared clones” dynamically, look at the NI example "AsynchronousCallAndCollectUsingOption0x40.vi”. — James
  14. I was just recently sorely wishing NI-IMAQ had by-value image frames. — James PS to manigreatus> have you considered turning it inside out; make a by-value object and keep it in a DVR if (and only if) your application needs it?
  15. That code should work fine without the DVR. It shouldn’t hang the application. — James BTW> look into “Variant Attributes” as a higher-performance way of doing look-ups like that.
  16. One can have a “Hardware” actor, that is the only process to actually communicate with the actual hardware. That actor pulls from the hardware, but pushes status changes to other actors. [AQ may be thinking of this “Hardware” actor rather than the actual hardware.]
  17. Random comments: 1) An “action engine” is a by-ref construct very similar in use to a DVR, so I don’t understand how you could have experience application hang with an action engine. Having an action engine with a DVR inside it seems redundant and overly complicated. 2) I actually have some mixed by-val/by-ref objects, but they are “naturally” that way, because they are a by-value object that “decorates” or extends a reference. For example, a “configurable forwarding address” which wraps a communication reference (queue, etc.) with by-val instructions on how to modify messages sent to this reference. I also have some mixed objects that I would probably have been better off making entirely by-ref.
  18. One other useful technique is to create an “abort” notifier in your “Controller” process, pass this as part of a “Do<whatever>” message, and have the execution loop check this notifier at appropriate points. It can even use “Wait on Notification” in place of any “Wait” nodes it might require. Package the “wait on notification” inside a subVI that outputs a “process aborted” error cluster, and you can stick it in any chain of subVIs sequenced by the error wire. — James PS to Daklu> I was excepting you to mention a true state machine as a “Sequencing alternative to a QSM”.
  19. If you’re following the Actor Model then actors should not share data by-reference. This means that different Actors often must either keep a copy of the info they need, or request the info from other actors when needed (the first option is probably best). For your “Resistance=5” example, the UI could send a “Set Resistance Request” Message, and the Controller would check the value against its copy of the parameters. If invalid, it would sent a “Resistance=<old> value” back to the UI, followed by some message to display a warning to the User. If valid, it would send a “Set Resistance” message to the Hardware Actor. The Hardware would then send a “Resistance Update” message to the Controller, who would send a copy to the UI.
  20. Funny, I got my CLA late last year with exactly the same set of marks, 10-16-18-26, with an architecture quite different than the example. I was annoyed by the low architecture mark, as I felt the architecture was complete and solid. — James PS. I was particularly annoyed by a comment of "Architecture not abstracted to switch over to field hardware.” I used abstract parent classes, with “Simulated” child classes injected at runtime, and a large comment explaining the intention to replace the simulated modules with hardware ones as required.
  21. Those VIs work fine for me, and they don’t contain any references to subVIs that aren’t part of the standard LabVIEW package. You might have a problem in your LabVIEW installation. I would suggest you try reinstalling LabVIEW.
  22. Be more specific. What “example VIs” are you talking about?
  23. And one can have a single task waiting on multiple notifiers, which is also event like and something one can’t do with queues (though, unlike with the event structure, the notifiers all need to have the same datatype).
×
×
  • Create New...

Important Information

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