Jump to content

drjdpowell

Members
  • Posts

    1,981
  • Joined

  • Last visited

  • Days Won

    183

Everything posted by drjdpowell

  1. I would say “no”, as generally one could choose to either use variant messages or a long list of specific-type messages. Array of Variants is kind of a mix of both. — James Aside: After our previous conversation, I actually modified my own message hierarchy by eliminating all simple-type messages in favor of VariantMessages, except where there was extra functionality involved (for example: ErrorMessage). And in actual use, I tend to either use completely generic messages (Variant) or create specific-purpose messages for specific uses. The latter can have multiple data elements and are usually used in the “Command Pattern” (i.e. they have “Execute" or “Do" methods rather than “Read”). Thank you for considering VariantMessage for LapDog, BTW. I have recently been doing consulting work where I can't use my own messaging package, so I’m interested in Lapdog being widely adopted and as flexible as possible.
  2. How do your B and C VIs communicate with the outside world? If I were doing something like this, each VI would have a queue (or similar) message receiving system and it would shutdown on receiving a “Shutdown” message or if it’s message queue becomes invalid. This makes full shutdown of everything quite easy.
  3. I’m not sure there is anything wrong with using your LV2 globals, assuming they are entirely internal to one actor (i.e. not a by-ref connection between different actors).
  4. A Seems very like the Set and Delete Variant Attributes. Also, if the table just disappears at some point, then it is perfect intuitive that I don’t have to unregister (as the registrations are part of the table).
  5. Some control over text size (i.e., the ability to increase it) would be nice.
  6. Ah, but 1 developer x many (small) projects that could use logging and it gets expensive. Anyway, it’s looking like we’re going with modifying a text-log system from another project. Boring. I’ll keep your API in mind, though, for any large project where a SQLite database would be a prime feature, rather than just a nicer way of logging.
  7. Sorry, I know little about the terminology of licensing. At a consulting firm I’m doing some work for, they would like a reusable error/debug logger for use in their many projects. I suggested your logger. But, if I read it right, the SQLite API has to be licensed for each project (each “product”), which isn’t going to fly. My other options are a non-database solution, using Saphir’s SmartSQLVIEW, or calling the SQLite all directly with SQL statements. I actually prefer the last option (even though it will be much more limited and less polished than your stuff) as I can then use it as a logger in my message/actor framework without inheriting any licensing issues. Need to polish up my SQL, anyway.
  8. Hi Shaun, Can you clarify the “fair use” of your database logger (and SQLite API)? I’d like to use it (or a modified version) as an error logger in custom software projects for clients. — James
  9. You could make a new non-dynamic dispatch VI that takes a Message object, downcasts to Command, then calls the (dynamic-dispatch) Do method. Call this VI “Do Command”” or “Do if a Command”, or something. Note that it doesn’t need to be a member of “Message” class (or any class). — James BTW, you could also make the “Do if a Command” VI return the original message if it isn’t a “Command” (this output would return a null message if the command was executed). That would allow you to put it in front of your case structure, acting sort of as a filter for Command Messages.
  10. Hi Alex, One slightly annoying thing at first about LVOOP child classes is that they cannot directly access their own “parent” data via “unbundle”. All child objects have the parent private-data cluster, but methods of the child class need to access it via methods of the parent class. If you create VIs in the parent that return InputQ and OutputQ, then the child class VIs can use them instead of unbundle. Creating “accessor” VIs like this is automated, so it takes less than a minute to make several. One can even make them be usable in a Property Node structure to access several things at once. The reason for this, I believe, is to allow the designer of the parent class to have a well-defined public interface, and thus he/she can change the internal private structure without breaking any children written by other developers.
  11. I’m afraid I’ve lost the code itself (computer failure and I never checked it in to my code repository), but I have an image: This is the CLA practice exam, rather than CLD; those subVIs are mostly empty but for a single comment on what needs to be coded in them.
  12. I am reminded of one of my first posts on NI.com: I haven't done the CLD myself, but this conversation prompted me to look at the Traffic Light example exam, along with the NI-supplied sample solution. Although I'm sure it follows standard "style", IMHO it is a pretty poor attempt at the described problem, at least if this were to have any connection to a real-world problem of programing a traffic intersection. 1) Real-world intersections come in many different configurations, but the solution presented is inherently specific to only one very-specific configuration with no thought applied to producing software that can be customized. Every different intersection type would require a different version of the code. A fully general solution is too big for a four-hour test, but one could at least set the groundwork by having some "intersection configuration" constants feeding into a more generalized intersection state machine. It would be easy to write code that could be configured with an arbitrary number of lights and states by using arrays, for example, allowing easy generalization to a five-way intersection. 2) The solution ties together the implementation of the intersection state machine and the implementation of the specific type of light. If traffic engineers were to start using four-bulb lights (Red, Y, G, and Left Turn Arrow) then the entire intersection code would have to be modified. The code should be more "modular"; there is no reason why a programmer implementing a new type of light needs to delve into the details of the intersection, nor does the intersection programmer need to know which specific light bulb signals "Left Turn". The clean coding and extensive documentation is nice, but useless if the code becomes obsolete the instant it confronts the first real-world complication. Admittedly, this is just a test question constructed from a predetermined answer, and the test-taker should be able to guess what the test makers really want in place of an actual scalable design. This was pre-OOP for me, but you can see how LVOOP might help in points (1) and (2). Problem is, it’s an exam question; any kind of investment up front for pay off in future development is a waste of time because there is no future. — James BTW, what about CLA exams? I tried out the practice ATM exam for that and used LVOOP.
  13. Ben, small note: I see in one of your images that you index over your array of Instruments and individually configure an Observer to substitute a message and then register this Observer with the Metronome. You’ll have less overhead if you take the entire array of instruments, create a single Observer, configure it to substitute a message, and register it. Observers can hold any number of “Send” objects internally. To make your array into a single Observer, use what is now called “Create Observer (polymorphic)” but was then called something like “Make Observer” or “Add Observer”. Another small note: There is a bug that is a problem for a feature that you might not be using but should know about. For Variant-type messages, one can not fill in the label and let the message use the variant data name as the label. But a bug in converting to variant sometimes doesn’t take the right name:
  14. The new version uses the VI qualified name, rather than the path. Hopefully, this will work better. Some of those are experiments, since this framework kind of grew over time through trial and error, so be careful. There are two ways that one can get information out of a launched Parallel Process: (1) having it respond to a message sent to it, or (2) “registering" with it to have “notification” messages sent whenever something happens (an “event”) or the state of the actor changes (“state”). These are separate methods; one could probably just use one or the other. My examples are perhaps overloaded with trying to do both, and that might be confusing. But then, a reusable component may be more useful if it can communicate in a variety of ways. I actually tend to rely on the Observer Registry stuff primarily, but having replies can still be useful, especially for synchronizing things (as you do in your application). Exactly. Note, however that this is NOT a global thing like a named queue or global variable. To “register” to receive a notification one must send a registration message to the Parallel Process in question. You do this in your App when you register for “MetronomeTick” events. An “Event” is, well, an event. ”Tell me when this happens”. “MetronomeTick” is an event. If you look at the “Metronome” Block Diagram as an example, you’ll see that you can also register to receive Error Messages, and the “Shutdown” event which is the last thing sent when the Metronome shuts down. A “State” Notification is slightly different. Here, you don’t want to be told when something happens in the future, but what something is right now, and to be notified of any changes. Metronome has a “MetronomePeriod” State notification. If you were to register to receive this notification, you would immediately be sent a message containing the current period (the Observer Register remembers the last state message so it can notify any new observers). You would also be sent a message any time the state changed. Nothing happens. Neither “Notify Observers” nor “Reply” throws any errors if no one is listening. If you launch an actor and don’t subscribe to its published notifications or bother to listen to its replies that is not the responsibility of that actor. It is the job of the code launching the actor to decide who should receive messages from it. This is a deliberate design choice; actors are reusable components that are not coupled to the code that launches them. They don’t demand anything and only provide services. If you don’t use all the services… whatever. In your code, for example, “Metronome” attempted to reply to your “SetPeriod” message, but you attached no return address. It also published its period and a shutdown message, but no one asked to be notified of them. No problem, “Metronome” doesn’t mind. It stands ready to provide these messages, should the code that launched it want them. You could, for example, register your UI to receive “MetronomePeriod” state updates so you could display the period. Or you could change your “SetPeriod” message from a “Send” to a “Query” (that waits for a reply) to check that Metronome did what you asked (if you try to set the period less than 10 ms, for example it will comeback saying 10, because that is the lower limit). Queries are good for making sure something has happened before continuing; if you sent a “SetPeiod” message by accident, the reply would be the Error Message “Unhandled: “SetPeiod””, code 52. This message would also be published to anyone registered to receive error messages. Not necessarily. My simple examples mostly involve commands that change the actor’s important state (“SetPeriod”, etc.), so they naturally involve a Notify. But one could have commands that don’t change state, or the state can change for some reason other than a command. And it is OK to have actors that don’t have an Observer Registry at all, if that isn’t really needed. — James
  15. Hi Ben, It’s late where I am, but I’ll try and reply tomorrow, particularly with a better description of what the Observer Register is for. Your code looks good. — James
  16. I too didn’t like that “Low Coupling Solution”. I spent some idle time trying to think of a way to make the “Zero Coupling Solution” simple enough that one wouldn’t ever need to consider the “Low Coupling Solution”. After I while I realized: it already is simpler! Not trivial to see at first. So I think it would be better if the documentation never mentioned the “Low Coupling Solution”, and instead concentrated more on demonstrating how to do zero coupling, and presented it as the standard way to use the Actor Framework. In fact, with a simple guideline, one could write “High Coupled” actors in such a way that they could later be easily upgraded to zero-coupled actors. I’ll try and get this suggestion, with more detail, in the 2012 beta forum (once I’ve figured out how to download the beta software ). — James
  17. Need to get me some of that some day.
  18. That’s what I thought, but AQ stated:
  19. Note to Darin on in his Champion’s profile picture: I recognize that hardware! Axions! Or search therefore. Did a very little bit on it as a Post Doc long ago. I’m very, very least author on an axion Phys Rev Lett from 1998 (I see from my CV that you're second author). Found those things yet? — James
  20. I was under the impression (from a post somewhere by AQ) that lvclass references work in run-time as of 2010.
  21. Oh good! Having to put those terminals in was annoying. I second the suggestion to go without the terminals. Though we might want a temporary note in the VI descriptions and/or on the block diagrams explaining this issue. — James
  22. Oh, man… The number of times I’ve double clicked on a subVI, double clicked on its icon to bring up the editor, made a copy, closed the editor, opened another VI’s editor, pasted. What a waste of time!
  23. Oh, the new version will also contain the “Actor Manager” (I’ve started to call my “Parallel Process” things “actors”, it’s a lot shorter and is an established computer science term) which makes knowing what’s running, and accessing the Front Panels or Block Diagrams, much easier. Below is a tree of actors running TCP communication tests (same computer, but three different projects): If one tries something complicated, with umpteen copies of “Observer Register” or “Metronome” used in different ways, this really helps diagnostics. As does being able to quickly open the Block Diagram of any actor and place the “MessageTable” probe to observe the incoming message stream. — James
  24. Hi monzue, thanks so much for your highly positive feedback! Gives me the impetus to push forward and get a new version in the Code Repository. I wasn’t aware of anyone using this, and I apologize in advance as updating your code to use the new version will involve a couple of tedious hours tracking down and replacing VI’s that have moved/been renamed/put in a different library. I’ve done a lot of reorganization. It looks scary the first time you open a VI that can’t find some of its classes, since all the class methods show up as question marks, but it is usually easier than it looks to fix by just replace the missing class constant, with all the methods magically reappearing. I promise to make the next version more finalized so you don’t have to do it again. Alternately, feel free to take the previously posted version and build on it to make it your own. The new version will have the TCP Messengers shown above, though, which is a major new feature if one has a distributed application (unfortunately, I don’t have a distributed application at the moment to really test it on). It will also have the above "Asynchronous Dialog box” and Futures. BTW, what LabVIEW version are you using? I have recently upgraded from 8.6 to 2011, and I was going to use the new “Async Call by Ref” node of 2011 in place of the “Run” method for launching VIs (this has very important performance advantages), but I could try and keep a separate 8.6 version available. It’s more (unpaid) work for me, so I need to know if there’s a need. Thanks again, — James BTW on the Actor Framework: My Messenger library is the work of a lone programmer who’s interested in easy use of dynamic VIs talking to each other. The Actor Framework comes from a very different perspective, that of a framework for a diverse team of programmers working on a large project, where restrictions are needed to prevent hard-to-see flaws compounding into severe problems. I don’t have the multi-programmer experience to analyze my Messenger library from that perspective.
  25. Not trying to hassle AQ. OK, a hopefully constructive hassle. One problem with complex designs is that people rarely take the effort of digging into them enough to make a constructive criticism of them. I was lamenting that fact one day (since I have complex design posted here myself) and I thought I really should make an effort. I’d be happy for AQ to point out the security flaws in my own, made by lone developer with an eye only for flexibility, designs. Or of other worthy ActorFramework-like targets, like mje’s “MessagePump". — James
×
×
  • Create New...

Important Information

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