Jump to content

drjdpowell

Members
  • Posts

    1,981
  • Joined

  • Last visited

  • Days Won

    183

Everything posted by drjdpowell

  1. Thanks everyone, I think I'm slowly getting a better feel for how to structure things. Mostly by keeping classes out of LVLibraries, but identifying small groups that need to be closely tied together. I actually have a small section of my messaging code that uses Command-Pattern messages; if I don't put them in a Library I could accidentally build an exe that wouldn't contain its own commands! I might retain a library for the core classes that will always be needed; though the boundary of such a core isn't very distinct, so perhaps not. I also like Paul's idea of a set of classes as one template. I don't (yet) have any such groupings, but I'm toying with the idea of a Command-Pattern-style Actor Template (ripping off inspired by the Actor Framework) and that would involve a template of multiple classes. Part of what motivated my question is that I am currently in the middle of trying to adapt my messaging system, up to this point working only within a single Application instance, to work via TCP between different App instances or over the network. Thus, I've had to consider the issue of different instances having limited subsets of the messaging package (particularly if one instance is on a memory-limited Real Time system). A whole new dimension to worry over... Thanks again, -- James
  2. I have a largish set of reuse code for inter-process messaging that I've been using in all my new projects. But I realize that I haven't really thought about how to organize things in Libraries. Given the difficulty in reorganizing libraries once they are referenced by many different projects, I'd like to get a good organization decided now. Currently, I have one large library with many classes in it, but that leads to any project using any part of the library loading every single class in it (and lots of VIs), even if individual projects only use a small subset of the classes. Classes that aren't in the library only load if needed, which seem a better feature. This makes me wonder if I shouldn't keep Classes in Libraries at all, unless they are very closely connected such that they will always be used together. What do other people do in organizing with Classes and Libraries? -- James
  3. I've been meaning for the longest time to add a Network-messaging capability to this library, and finally made the time to do it this week. I thought I would update my example here with TCP communication. Converting the example took only a few minutes, which shows the advantage of the "plug-and-play" nature of using a LVOOP class structure for message communication methods. Here's good old "Process A", now standing alone in its own App instance (Application 2), with the new "TCPMessenger" plugged in in place of the original QueueMessenger: And here is the rest of the example on Application 1 (haven't had a chance to test on a separate computer yet). It uses "RemoteTCPMessenger" to connect to the server created internally by Process A's "TCPMessenger". Otherwise it is identical to before. Note how the reply from Process A is routed back through the Process A's TCP connection. This is because the "reply address" on the "SendTimeString" message, "CommandMessenger B", is a QueueMessenger, and its internal queue is local, and not valid on the remote Application 2 that contains Process A. The two TCP connection "Actors", running in the background, inspect and alter the reply addresses of sent messages to perform this routing of replies through the sending TCP connection. As the "Observer Registration" messages, shown in Parallel Process, utilize the same "reply address", that system of publishing information also works via a TCP connection, even if the observer has a local-only messenger. Here is a Message custom probe showing summary information about the message received by Process A. The "X"s after the QueueMessenger (queue refnum 4076863496), which is Process B's, and the Message Logger indicates they are invalid in Application 2 (but they are still valid in Application 1). QueueMessenger (refnum 4091543557) leads to the TCP Connection Actor. The TCP communication is all run by "actors" based on the Parallel Process design. Creating "TCPMessenger" launches a "TCP Listener Actor" in the background. "RemoteTCPMessenger" launches a "TCP Client Actor" which initiates the connection; the TCP Listener then launches a "TCP Connection Actor" to handle its side of the connection. Multiple RemoteTCPMessengers can connect to the same TCPMessenger server (a new TCP Connection Actor is launched to serve each new connection). -- James
  4. Wait, wait, wait.. I thought the dialog was a simple while loop with two buttons; where'd this event structure come from? If you have an event structure in a dialog you have to be careful to clear any leftover events, otherwise those extra key presses or clicks will be queued up and ready to go the next time the dialog runs. I think the only way to go is to dynamically register for any events you want, and unregister as you exit the dialog. Re-registering on the next call to the dialog will ensure there are no leftover events from last time. Never use statically-registered events in a dialog, as they can't be cleared.
  5. I found this conversation which illustrates that event registrations seem to behave strangely and not like other refnum objects as I understand them. Something is going on under the LabVIEW hood that might be affected be a subVI, and perhaps I would be better to restrict event registrations to the same block diagram as their corresponding event structure
  6. I learned that through painful experience. But I don't understand the relation to subVI's. I understand that if the subVI returns a previously created and saved reference, then it will be the same each time. But if the subVI creates a new event registration, then it should be different each time. And both these are independent of the subVI being "inlined". Here is an example. Since I did this two days ago, and it is the first time I've put an event reg in a subVI, it is an important case for me! Is there something I should be worried about with this code? It's my understanding that this subVI should always create a new event registration for each call. -- James
  7. Just a small suggestion, but you could place your code in the TRUE case of case structure connected to the "NewVal" output of the event case. That would drop any double clicks by the user (as the second would be false). Can't help with the dialogs; though the primitive 2-button can be OKed with the Enter key, your second one has no key bindings and thus should require a very deliberate User action to dismiss. How do you know the event happened, BTW? Are you sure the action contained isn't being triggered by some other method than the event case? -- James
  8. Hi Norm, I'm not sure I follow. Can you (or AQ) explain more about possible issues with putting an event registration in a subVI?
  9. That was my reaction a month or two ago.
  10. I think GregR means that you provide a function that produces an event registration for just the encapsulated User Event, and that registration is clustered with another registration for any other events before being passed to the event structure. Thus you only need one member VI. However, this doesn't keep the User Event encapsulated, because it can be accessed in the event structure frame itself. See below: -- James BTW, I learned only recently that one can use a cluster of multiple event registrations for handling by the same event structure; does anyone know if there are any performance differences with using multiple registrations instead of a single one?
  11. Is it this library you are using? If so, did you correct the bug pointed out in the comments: a flaw in MB CRC-16.vi in NI Modbus.llb A failure mode turn up in testing at 1200 baud. It turned out to be a flaw in MB CRC-16.vi in NI Modbus.llb. The failure mode is that the MB Serial Recieve.vi that waits for a Modbus reply to a command may falsely detemines that the message is complete before the last byte is recieved. This is becuase because MB CRC-16.vi coerces the U16 CRC to a U8, and the U8 becomes zero for a message with all but the last byte transmitted. The correction is to change the data type of the Exception Code indicator from U8 to U16. - Jim Figucia, Code G Automation. labview_work@msn.com - Sep 15, 2009 I haven't used it but when I downloaded the library a few months ago the bug was still there. Don't know if it could cause your problem.
  12. I've just become an official CLA.......... ......D I wasn't that worried about failing.
  13. If all your doing is showing the User information, you have a third option to Daklu's two. Just have the subVI open its front panel and display the information, then immediately finish (but leaving the front panel open). To modify the example from the conversation you linked to, just delete the loop and the "Stop" button. I think you need to select "Show front panel when called" and NOT select "Close afterwards if originally closed". And make sure it isn't "Modal", as ShaunR suggests. The User can close the window when they don't the info anymore. -- James
  14. I think you badly need the opportunity to use LVOOP for a couple of small projects, in a simple way. First just try using an object or two in place of type-def-clusters. Then a try a parent and two children (your USB or TCP/IP communication might be a good choice). With experience in the basics, you'll be able to get more out of all that reading. There is quite a few examples of people on LAVA trying to develop tools to handle the complex tasks with multiple processes running in parallel, but it would be quite hard to just jump right in without some experience.
  15. BTW, here's an extension I am working on, that uses the "Self-Addressed Envelope" aspect of the framework: a class of Asynchronous Dialog boxes. This allows a process loop to display a dialog box for User input, without waiting. It can then continue to perform other actions. When the User dismisses the dialog, his/her input is sent back to the loop's Messenger via a "reply". So far, I have only created a Dialog that is a modification of the standard LabVIEW "Three Button Dialog"; an example is shown below: Here, the example process increments a count every 200 ms (in the Timeout case). If the User presses the "Clear Count" button, a dialog is configured and displayed. Had the standard LabVIEW dialog been used, this would block the incrementing of Count until the dialog completes. But here the dialog is dynamically launched and asynchronous, and thus the loop keeps counting. Part of the dialog configuration is to give it a message Label (also used as the dialog title) and attach the loop's own Messenger (Event-type, in this case) as a "return address". When the User pushes a button and dismisses the dialog, the name of that button is sent back the the return address with the supplied label. Thus, the loop can perform the required action, such as resetting the Count to zero if the User responded "Yes, please!". The asynchronous dialog box has an optional timeout function (it replies "window closed") and will automatically close if it's calling VI goes idle (it uses a Notifier internally to achieve these functions). -- James
  16. Thanks for replying, If I understand your question correctly, your asking if a message logger could automatically be attached inside the "Create" methods, thus making logging of all messages automatic while hiding this fact in the top-level diagram. Correct? One could easily create a "Create and auto-log" VI that does exactly this, encapsulating the currently existing functions, and setting up a logger that records all messages to the created Messengers. Personally, I wouldn't use this, as I don't actually want all messages logged except when I'm debugging, and when I am logging I want this fact to be very clear from the top-level VI. What is logged and where isn't something that should be hidden, IMO.
  17. Ah, but at least the resources would be spent on "interesting new functionality", rather than boring old "rehashing existing functionality".
  18. Hello, Any comments on the code library I uploaded a month ago? If nothing else, did the thing download without any broken arrows (i.e. did I miss any dependancies)? Did the examples run? -- James
  19. Regarding this code fragment, wouldn't a high-performance, flexible, and clearly-readable solution be to add the functionality to the case structure itself? By implimenting these Ideas: Wire Class To Case Selector and Allow vi server reference type as case selector. It would look something like this (the "default" case would return the parent "Message" wire type): -- James
  20. 24.5, then. Actually, looking at the "Like"s from those who didn't post strongly suggests 4 additional votes for small terminals. So that makes it 28.5 to 4.5. -- James
  21. Final score: Small terminals: 23.5 votes (that includes the "mostly-no"s, the "no"s and the "HELL, NO"s). Icons: 4.5 votes. -- James
  22. Everything's by-value, not by-reference, so the variant attributes disappear with the variant and containing object.
  23. For fun, I whipped up a version of a "Future" in my Messaging Library. It takes my existing "Query" function and splits it among two VIs, connected by a "Future Reply" object. In the below example I have a process that takes a second per received message to reply. I start 10 queries, sending the "SendTimeString" message each time, then simulate doing something else for 2.5sec, then I wait for the futures to be completed. This is similar to the way "Wait on Async Call" works.
  24. Just as an aside, the new "Wait on Asynchronous Call" Node is another example of a type of "future".
  25. The feature I'm imagining will only snap to a possible position when it is within a couple of pixels. This should be small enough that is will act to help the programmer align things exactly as he/she wants. So, if you want the tops of subVIs to line up instead of straight wires then no problem. Want bend the wires in a readable way, no problem. Basically, you place the item where you want and the program helps with the micro-positioning. You would have to place the terminal within two pixels of aligned to trigger the snap-to; nothing is forced on the programmer. Now, if you actually wanted the terminal one or two pixels off alignment with another, you would need to hit the arrow key once or twice. Hopefully, such situations will be rare. If not, there would be the ability (including a hot key) to turn the feature on/off. Unfortunately, it's hard to verbally communicate the advantages of CAD-like guides. -- James
×
×
  • Create New...

Important Information

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