Jump to content

JackDunaway

Members
  • Posts

    364
  • Joined

  • Last visited

  • Days Won

    40

Posts posted by JackDunaway

  1. Feature. That kind of magical backpropagation is rare in LV but a few nodes have implemented it. There's a lot of internal debate about how good an idea it is. Myself, I would rather the type terminal be a required input.

    Another thought on this matter: a broken run-arrow is your friend; the mentality of "avoid the broken run-arrow" to justify language features feels flawed (think: "auto-insert feedback node into cycles").

    A broken run-arrow and strong, explicit typing is like a friendly heads-up at compile-time saying "you did it wrong". Compare this to the insidious manifestation of a run-time error, or even worse, unexplained or quirky behavior with no error, inadvertently introduced by automatic code mutations. The compiler constantly validates all syntax (yay!), whereas run-time, it's not so easy to exercise every execution path to flush out the bugs.

    • Like 1
  2. So I understand the abuse side of things for sure, but anything can be abused right?

    On the "abusable" spectrum, this ranks more toward the "asking for problems" side. :P

    Should every polymorphic VI not have the "Automatic" option when choosing the type based on the inputs?

    That's a little different, since it's downstream vs. upstream type propagation, and sources-to-sinks is one-to-many.

  3. Erm, Jack this is not technically correct.

    Once an event fires, the naked event refnum IS exposed as part of the data within the event structure allowing foolish of malevolent programs to destroy the user event refnum.

    I have an idea on the labview Idea exchange to remedy this but it has almost zero traction.

    Shane.

    Yes, yes, I know... and I have come to agree with you... hold on, brb... (writing a response on that thread)... OK, back, here's the response copied: "Two and a half years later... I'm on the same side of the fence as Shane now. The points I mentioned above represent anti-patterns I was using at the time, and have since found much greater success wrapping messengers inside a class with a well-defined API. So... Kudos!" which can be read here. Thanks, Shane! It's taken me a while to catch up to you :yes:

    In rare cases the event queue can get muddled if the events are sent more quickly than the timestamp resolution can take care of. This leads to the events possibly being received IN THE WRO_NG ORDER. This is within the same event queue, and can be provoked even with the same event.

    Can you provide a reference? I’ve only seen mention of that problem when the two events are in different event queues in the same event structure, such as a statically-registered event and a dynamically-registered one.

    As far as I'm concerned, this "can't guarantee order" is sort of an urban legend, with a grain of truth. I remember vividly Ton's example, and even though I think there's another thread, here's one instance. As long as you're OK with and understand that these two events are fired synchronously, they are stuffing two discrete queues operating asynchronously, so the order in which they are handled cannot be guaranteed. And here's a screenshot from his post that illustrates the "problem":

    post-17237-0-40020200-1348677374_thumb.p

    — The event structure itself can receive from multiple queues. In particular, the statically registered events are in a separate queue from any event reg. refnum attached dynamically. The order that items are served up from different queues is determined by timestamp. This means that near simultaneous events placed in different queues cannot be relied upon to be received in order. However, items from the same queue will always be in order, which means one can use a User Event to reliably carry messages to a process.

    This is a great explanation of why the "can't guarantee event order" should be considered a false urban legend. By the way, James, many great "random thoughts" that effectively provide a good practical understanding on considerations when using User Events.

  4. When I tried the event registration refnums, they were private data in one of my classes so they needed accessor VI's to be of use to any VI that wasn't a class member. That means that I had no choice except to share the event registration refnum, which turned out to be a bad idea for my use case since it doesn't really allow multiple subscribers. If I just expose the event refs,then its easy for any VI that wants to consume the event to subscribe. I don't find it ever necessary to preload event queues since I don't use the events for any kind of input control - they are only used to publish data to subscribers.

    Ah, yes, I ran into this limitation myself before realizing I had made a fundamental mistake. The Event Registration Refnum should not be part of the Messenger Class Private Data - the User Event Ref (the Messenger) is what needs to be stored in the Class Private Data. When creating a new mailbox, you can call this method N times for each of your N subscribers. This falls into the "messenger is decoupled from the mailbox" feature of User Events.

    Note that once an Event Registration is created by this method, the ownership is passed out of the class and to the subscriber (the VI with the Event Handler Structure that uses the refnum). Here's a screenshot of that VI:

    post-17237-0-24145900-1348628886_thumb.p

  5. Another alternative is simply to create an empty TODO VI (a red or bright green icon for it is a good idea) and simply drop it there. Then, you can do a find all instances on it and go through the instances.

    Go a step farther, and make the VI broken. One easy way is to make one input "Required" -- then you can "turn off" the compiler error by creating a constant on that input. This forces yourself to go back and fix it, ensuring you can't forget and, say, make a build without the fix.

  6. Named queues :)

    Yeah, I keep all mah named queue refs in mah global vars to make the programming more handier. :yes:

    But in a less confrontational aspect. The issue I have is with the idea of "stuffing". That you create a registration, maintain it and generate events, whilst not consuming. At least with a queue you can monitor the elements and even restrict the size (for the scenarios where you want to "stuff")..

    Again, this boils down to best practices. SubPanelling implies asynchronicity, which can lead to race conditions and missed messages. One notable example is the Shutdown event -- it's possible that a system can issue the shutdown command the moment after a command to begin SubPanelling has begun. (We would agree here it's a bad programming practice to "stream" events into an unhandled queue for too long; that would probably be an abuse of pre-registration.)

  7. So how is that any different from anything else (e.g.QE Messaging) except you can create memory leaks?

    Thanks for pointing out this thread, it's got some good topics (with limited bandwidth, I had shied away from that thread on principle, since "QSM in a subject on LAVA" usually equals "religious debate" :shifty: )

    And the answer to the question "how is that different from anything else" is...

    The topology I've now adopted for inter-process comms is a queue for the control, and events for response.

    ... just wait until the next evolution where you use User Events for both control and response! :D

    My proclivity to User Events is perhaps explained by a background focusing on UI and UX design. The ability to combine interprocess commands with UI commands into a single event handler structure is syntactical nirvana. And again, the fact that the User Event Ref and the Event Registration Refnum are two discrete entities - rather than a Queue, where the sender and receiver share the same reference - decouples processes and simplifies philosophical (and practical) issues like ownership and lifetime.

  8. Can you give a real-world example where you might use it?

    Sure! Consider a simple DAQ loop, generating data. Consider one of many types of listeners (consumers)... a logger, a UI, a server that re-broadcasts the event over a network. The DAQ loop can run headlessly and independently of those subscribed to its messages, and they can come into and out of existence as they please.

  9. ...which incidentally demonstrates the beauty and power of separating the messenger (User Event Ref) from the mailbox (Event Registration Refnum).

    Just providing an example below to substantiate this vague statement.

    NOTE: To demonstrate a growing mailbox, this VI creates a memory leak of 10MB/sec once a "Register Mailbox" button is clicked. It can be stopped by hitting Suspend, Unregister, Kill the Messenger, or STOP buttons. Also note that in a real application, you would handle the events once registered and memory usage would stay appx net-zero; this VI is meant to grow memory unbounded just as a demo.

    Try a couple of scenarios, watching the memory usage each time.

    1. Register a mailbox, let it run a moment. Suspend it. Register it again. Suspend it. Unregister it.
    2. Register a mailbox, let it run a moment. Kill the messenger. Note that the memory usage has stayed constant, because the mailbox still exists. Unregister the mailbox. Note memory usage drops to 0.
    3. Try combinations of registering two mailboxes, and note the one-to-many behavior; mailboxes are independent of each other, and independent of the messenger. (There's one behavior I do not understand - when both mailboxes are registered, one would think the memory leak should be 20MB/sec instead of 10MB/sec, but it remains at 10MB/sec. Any takers on explaining this? Is an optimization being applied for unhandled event queues?)
    4. Note that when the VI is first run, messages are being sent, but disappearing into the ether! This is a powerful behavior to have the messenger unaware of whether or not it will create a memory leak if its messages are unhandled (queues don't have the ability to "fire blanks").

    For these reasons (decoupling messenger from mailbox, the ablity to fire blanks, and one-to-many), I prefer User Events for interprocess messaging.

    post-17237-0-40374100-1348594398_thumb.p

  10. If you stuff the event registration with events and then wire that event registration to more than one event handler (as one might, in a publish-suscribe tye design), how do you ever know which event structure will handle which event?

    By convention, the Event Registration Refnum is wired exclusively to one and only one Event Structure, and this wire is never branched -- the exact same convention as the "Register for Events" node. The difference? The User Event ref remains private to the containing Messenger class; no naked refs are exposed to be manipulated with User Event prims by callers.

  11. I'm playing around with the idea of using event structures in asynchronous sub vis which take an event registration refnum as a terminal.

    My only recommendation is to never do this. Event registration refnums are strictly typed and can't be changed easily as you implied. It might seem like a minor inconvenience now, but you can really end up in a bad situation if you start passing those registration refnums all over the place.

    Plus, why would you want to pass an event registration refnum around? There should be a one-to-one relationship between event structures and registration refnums. Make a typedef cluster of your events refnums, pass those into a subvi, then obtain a registration refnum from the cluster in the same VI you need it.

    There's a valid reason to pass an event registration into a SubVI to be SubPanelled, and that's when you want to "pre-stuff" the mailbox with some events prior to the SubVI running. This is because the "Register for Events" node is unaware of User Events that have been sent along a User Event Refnum -- which incidentally demonstrates the beauty and power of separating the messenger (User Event Ref) from the mailbox (Event Registration Refnum).

    Yes, I agree it's a pain if you change the datatype of the message; or if you want to rename the case label on the Event Handler Structure. :(Coerce to Type ostensibly handles the second problem; the first problem is solved by convention (don't change your mind on datatype! :lol: ).

  12. For completeness, this problem still exists on Windows 8 and Windows XP running different combinations of LV2009 to LV2012. It seems firmly related to some incompatibility between LabVIEW and Parallels and/or OS X, which didn't exist until sometime about 6months ago, and was most likely due to a change from either Parallels or OS X.

    One shining glimmer of hope: a workaround exists using AutoHotKey and remapping favorite CTRL+SHIFT+Alpha shortcuts to CTRL+SHIFT+punctuation shortcuts not currently in use by LabVIEW. The AutoHotKey command "^E::," means "when I type SHIFT+E, instead inject a comma into the keyboard input stream". And that way, CTRL+SHIFT+E becomes CTRL+<, which is the new binding in LabVIEW for "This VI in Project".

    Suboptimal solution, but at least the severity has been downgraded to about-as-inconvenient-as-a-pizza-burn-on-the-roof-of-my-mouth. Will continue to investigate, but hopefully this workaround will keep this of-generally-little-interest thread quiet for a while :unsure:

    post-17237-0-15118300-1347056112_thumb.p

  13. I'm just dropping by to register my name on the small (but growing?) list of people who've seen the same problem as Jack.

    Thanks, Justin!

    If you really want to spend more time, I would try to install VirtualBox and check with that.

    OK, after some hiccups finally got LV2012 32-bit running on a Win7 x64 VirtualBox, and CTRL+SHIFT+E works just fine. This might indicate that it's specifically a LabVIEW-Parallels interaction gone bad... but would not explain how/why Justin and I are both running "identical" setups, yet his problem was fixed once upgrading to Parallels 8 and mine remains. (I use the term "identical" very, very lightly)

  14. Well if it would be a LabVIEW only problem it would also happen on non-Parallels installation and as far as I can see that is not the case. It must have to do with the particular way Parallels generates dead keys in its keyboard virtualization driver and how LabVIEW interprets them. That LabVIEW most likely is not just doing the normal standard processing is obvious, but if that is illegal in terms of the Windows API and just happens to work on all real world hardware scenarios or if Parallels is messing up somehow when simulating the keyboard BIOS interface is not possible to say at this point.

    If you really want to spend more time, I would try to install VirtualBox and check with that.

    But this does not explain the WinAPI SendInput calls from within LabVIEW not even working - right? (By the way... I'm creating a new VirtualBox Win7 machine and a Parallels WinXP machine as we speak.)

  15. Latest update:

    • Created a new Win7 Ultimate 32bit VM from scratch, and re-installed LV2012 32-bit f1. Still does not work.
    • Tried "LVdebugKeys=True" in LabVIEW.ini on a whim... as it turns out CTRL+SHIFT+D+H does not work either.
    • Validated with 4 other Windows programs that CTRL+SHIFT+Alpha shortcuts work, but...
    • ...tried CTRL+C and CTRL+SHIFT+C in VIPM, and CTRL+SHIFT+C does not work! Does this again point toward a LabVIEW-only problem?

  16. Casting one of your clusters to a U8 array shows a different number of Bytes than the method in the zip file.

    Oops, you're right, I had wVk as I32 but it needed to be I16. Now, the problem is fixed and Key Up works, but I've still got the same problem; programmatically invoking CTRL+SHIFT+E does not show the VI in the project. Likewise, I tried changing this to 'S', and Save worked but Save All did not. Here's the fixed snippet:

    post-17237-0-71532700-1346905740.png

    Also, I went ahead and upgraded to Parallels 8, and this has not helped :unsure:

    So, if CTRL+SHIFT+E via SendInput is not working, can we say that Parallels brokering keystrokes from the host into the VM is not the problem here?

  17. I don't have 2012 on this box. However, I think sending an array of pInputs is too big. Try sending one keyup/down and one wVk at a time.

    I found the guts of this dll call somewhere on the NI forums.

    This isn't working for me at all... dug through the source for about 10min, but couldn't find any obvious reasons why it would not send keystrokes. Did the snippet that I posted work on your machine? (Especially curious about the FAKE CTRL+SHIFT+E button - because CTRL+E button worked for me... it's just the KeyUp's that were failing)

  18. OK, a little further investigation. I'm trying to directly inject CTRL+SHIFT+E via user32.dll SendInput, and it's still not working (though this could be a programming error on my part).

    The following snippet creates two simulated keystroke events: CTRL+SHIFT+E (An array of 6 events, CTRL down, SHIFT down, E down, E up, SHIFT up, then CTRL up) and then the simpler CTRL+E (an array of 4 events) with two buttons on the FP.

    The CTRL+E shortcut works just fine; when I click the button "FAKE CTRL+E" the Block Diagram window becomes frontmost. However, when I click "FAKE CTRL+SHIFT+E" nothing happens.

    One more problem; this could be a programming error, or a problem with my test rig - in the snippet, the Key Up events are not honored (i.e., dwFlags=2 does not properly KeyUp as per http://msdn.microsoft.com/en-us/library/ms646271(v=vs.85).aspx ). CTRL and SHIFT are still held down, so to "unstick" these keys, I physically press them on the keyboard. Be forewarned, that if you run this snippet, you may need to do the same.

    Does this tell me anything? Does this take Parallels out of the equation? Have I made programming errors that need to be corrected? <headscratch />

    post-17237-0-36361100-1346878497.png

  19. One of the Parallels threads mentions trying: Virtual Machine -> Configure -> Options -> Advanced -> Optimize modifier keys for games. Oh, I have an old Parallels license around somewhere at home - maybe I can play with it tonight.

    That got me really excited, enough to restart the VM and try it out, but no go :( It's worth mentioning that Parallels 8 came out a couple days ago, and even though the features were not enticing, perhaps it's worth a shot to try to fix this problem (now I'm beginning to wonder if it's a Parallels prob after all...)

  20. Not necessarily. From my own battle with keyboard shortcuts, I seem to remember that those VIs and the event structure behaved differently, but I wouldn't swear on it. Try checking the key down event (you'll probably need the modifiers terminal to see those keys).

    You may be onto something here. This is the result I get when pressing CTRL+SHIFT+E:

    post-17237-0-37809900-1346862835_thumb.p

    And here's the snippet in case someone else is able to run on a known-good machine, to compare results:

    post-17237-0-78634400-1346862872.png

    It's suspicious that in my result above Char is '0' (instead of '69') and VKey is 'Ctrl' (instead of 'ASCII').

    • Like 1
  21. Perhaps Parallels isn't sending all of the HID Keyboard information to the guest OS.

    Does this following VI disprove that it's Parallels' fault? Or is this VI using some other keystroke reading mechanism other than the way LabVIEW reads global shortcuts?

    post-17237-0-60267100-1346791465.png

    **EDIT: By the way, thank you for responding, Todd! I'm still desperately looking for any news avenues to explore to solve this issue.

×
×
  • Create New...

Important Information

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