Jump to content

drjdpowell

Members
  • Posts

    1,969
  • Joined

  • Last visited

  • Days Won

    172

Posts posted by drjdpowell

  1. first decide if it's a library, Framework or Toolkit (I would suggest it is a framework since you have to write custom messages)

     

    I’m specifically avoiding “Framework†because it’s meant to be a toolkit that one can take only some elements and not others.  Of course, it is really the framework that I use for real-world applications, but it isn’t intended to be restrictive.   It also doesn’t require much in the way of OOP skills; I’ve never created a custom message class for an application, and my “Actor†classes are thin shells, with no private data, wrapped around single VIs.**  This is basically text-variant messaging between individual asynchronously-called VIs.

     

    — James

     

    **I’ve recently experimented with a non-class actor design which is just a VI template.  This has the advantage that the VI can be set non-reentrant, rather than shared reentrant, making debugging more straight forward.   But i haven’t been able to make such an actor avoid the issue of root-loop blocking, which is problematic.

  2. I’m in the process of getting my “Messenging†package put on the LV Tools Network, and they have politely suggested (as others have) that shouldn’t it be named “messagingâ€, as “messenging†isn’t an actual word.   Yes it is a messaging library, but I want a more unique name.  Other similar packages use unique names that don’t directly suggest what they are, such as “Alohaâ€, or use longer descriptive names that shorten to acronyms, like “AMCâ€.  I also like the focus on the “Messenger†rather than the “Messageâ€; maybe I should call it Messenger?

     

    What do you think?  Is the “Messenging†name annoying, and should I change it?  

  3. The OpenG does have feature that the NI lvlib doesn't though, like getting the values of the elements of an array. The lvlib GetArrayInfo.vi only gives the element type of the array. So my code uses OpenG when necessary, and VariantType.lvlib when possible, in order to use as much native NI code as possible.

     

    Yes, it’s important to note that NI provides a VariantType library, rather than a full Data library like OpenG does.  I wish NI would add the necessary VIs to make its library a complete VariantData solution.  I’ve been toying with the idea of doing it myself.

  4. Quick note on possible changes in the next version:

     

    We currently have two types of message “notifications†with the “ObserverRegister†helper object:

     

    1) Event —> send the message to all currently registered observers.

     

    2) State —> compare to last notification message, and if different, send to all registered observers

                  —> send the latest notification message to any newly-registering observer.

     

    State notifications have more overhead than Events, due to the saving of a copy of the message.   But the ability to send a message immediately to new observers is very valuable, eliminating the need to query or repost unchanged state information, removing the worry about the order of startup of different actors, and making dynamic “hookup†of new actors near instantaneous.   

     

    However, the other feature of State notifications, only sending updates of state change, is more problematic.  The reasoning of this feature was to reduce overhead by not sending new messages if nothing has changed, but in day-to-day use I find this isn’t that valuable, and I often actually want all the messages, even if unchanged, because I use them in a Chart/Graph or otherwise have actions that I want triggered regardless.  So I am considering changing it so State notifications are always sent.

     

    I am also considering making the matching of message labels in the Observer Register be case insensitive.

     

    Comments?

     

    — James

  5. Here it is, for what it’s worth.  From 2008, I think, LabVIEW 8.6.   It’s rather too complicated for a first time programmer.  You should either see if the Example program works on a NE-500 or NE-1000 and just hack that, or use the low-level communication subVI “New Era Pump CommandResponse.vi†along with the New Era manual (which contains the text commands for it).

     

    New Era Syring Pump.zip

  6. Hi this thread is quite old but I find myself in the same dilemma as the original poster. It's not with LabView in particular but I was just simply looking for a way to create a completely automated syringe driver array to carry out a lab protocol. I was looking around online and stumbled upon this thread and was wondering if the original poster had any success?

     

    I’ve used New Era NE-500’s before quite successfully and could possibly dig up some code for it.

  7. We use them to create collections of, say, typedefs (for namespaces, in particular) and similarly, of course, shared variables (LabVIEW does this), and we create collections of certain types of classes (a set of Command classes or State classes).  This is especially convenient since, for example, we often need to include the typedefs from one component in the project for another component.  It is convenient to load the entire collection as a unit, and the namespace avoids collision with the other similar collections in the project. 

     

    Hi Paul,

    Are the current LVLIBs the best for the use case of “collections"?  If you were to reuse most of your Commands in a modified component in a new project, but with some replacement Command classes, you would not be able to do that, as a Class/VI can only belong to one library.  You could reorg things to have a “CommonCommands†library and a couple of “ExtendedCommand for XYZ†libraries, but this requires changing the namespacing of your original project.  Aren’t LVLIBs combining too many features into one construct?

     

     

    Also, to all:

    It may be the case that “Best LabVIEW Practices†will naturally lead to use of Libraries that is non-problematic.  But reasonably good LabVIEW practices should produce reasonable good (and reasonably easy) solutions.  LVLIBs don’t currently allow that, at least in combination with LVCLASSes.

  8. I don’t think you an avoid a history recorded somewhere.  Your solution above won’t get notifications that occur between calls to “Wait on Notificationâ€.  Though if you were to keep a history of listeners in the Notifier structure (in contrast to the current LabVIEW Notifier that keeps a history of Notifiers in the Wait node), then this might be better, as the list of Wait nodes should be finite, in contrast to the potentially limitless number of Notifiers.

  9. When the compile occurs, references to those unused functions are removed.

     

    That’s just it; the LabVIEW IDE is not removing unused functions.   The EXE builder might, but not the IDE.   It is compiling them and otherwise using them fully.   If a C IDE had compile-on-the-fly where it compiled all those unused functions then it might well have performance issues that annoy some C developers.  

     

    I would be happy for unused library members to appear under dependancies, greyed out to show the compiler is ignoring them.

  10. Wait, never mind, I think it is a Mercurial/TortoiseHg problem (or User error in using it).  Reverting back to a month ago, then reverting forward to today fixed the issue.   I think the class file wasn’t being reverted correctly. 


    After reading replies:

     

    Compiled code cache, of course!  Should have thought of that.   Reverting far enough back may have triggered a recompile thus clearing the error.   Thanks guys.

  11. I cannot figure this out.

     

    I made some changes to the private data of a class that caused the various unbundle nodes to get mislinked when they tried to auto-select the right new elements, leaving several broken methods.  No problem, I thought, I will revert to the previous clean copy in Source-code control (using TortoiseHg).   However, whenever I reopen the class, the unbundle nodes are still mislinked and VIs are broken!   I reverted the entire codebase to a week ago to be sure I had a good copy, and I rebooted the computer — still broken!   All my methods, even the unbroken ones say they need to resave because “Type Definition modifiedâ€.

     

    My question is: what is modifying my “Type Definitionâ€?   It can’t be any of my source code, so what can it be?   Where is the change located on disk?

  12. In my opinion the advanced behavior is the more intuitive way. It's not intuitive (as you saw with the original post) that the order of the senders should matter. We normally don't think about the receivers having an internal memory (we expect the primitives to be stateless except for the ones that enable statefullness). The other primitive (no history) maybe should be on the advanced pallet because it's for the power users that go faster.

     

    It is more intuitive, quite true, but it also has the potential ability to consume memory until an app crashes, which is a possible argument for keeping it advanced.

     

    Personally, I would advise against using Notifiers in complex ways like this regardless.

  13. What you start to get towards here is dependency inversion to decouple elements of code, 

     

    I’m all for advanced stuff to do advanced things, but I don’t want to have to build a carefully-structured dependency injection just to use a utility subVI.  I’d rather just leave it a library orphan.

    • Like 1
  14. Sorry OP if this is derailing the conversation but I think it still is relevant to the original question.

     

    That’s alright.  Polymorphic VIs certainly have the same issues.  Though at least with them I can see why they might entail loading unused code, while with the library thing it seems entirely pointless.  Similarly with Classes; I can see why one might need to load all Dynamic Dispatch methods, but not why LabVIEW insists on loading classes or static methods not used by any in-memory VI.   

  15. This is a standard thing to learn with SQLite, which is an “ACIDâ€-compliant database.  The “D†is for durable; by default SQLite is durable against power-failure of the computer, meaning once a transaction has executed, in can be relied on to remain, and not be corrupted, even if power is lost in a subsequent transaction.  Durability requires that SQLite verify proper writing to hard disk, and as hard disks spin at about 100Hz, this mean that the number of durable transactions is limited to an order of 20 per second.

     

    You can disable the durability requirement, but a better strategy is to group multiple INSERTs into a single transaction by wrapping them in BEGIN…COMMIT SQL statements.  See on of the Examples provided with the package to see how this is done (you just need to execute “BEGIN†before your loops and “COMMIT†after**).  For simple INSERTs, one should get greater than 100,000 per second.

     

    **also see SAVEPOINTs in the www.SQLite.com documentation.

    • Like 1
  16. You can make it so both messages are delivered by using the "Wait on notification with history" primitive in your "wait on notification" VI instead of the normal "wait on notification" primitive.

     

    Oh yeah, DUH, this is why the “Advanced Notifier Waiting†subpallet exists, isn’t it?  I’ve never used notifiers in such complex ways and so I forgot about it.  If one doesn’t need the many-readers ability of notifiers, one is better off sticking to queues.   The “Future Token†class, which is what I use to solve “wait for something to reply†problems like the OP’s, is a Write-Once, Destroy-on-Reading, single-element queue.

     

    I shall add a "Wait on notification with history†method to my NotifierMessenger class in case people find uses for this.  Thanks.

  17. Everything in the lvlib should be something you want to be loaded atomically, in my opinion.

     

    Is that wise?  What if your API optionally interacts with some other API, and you have optional methods to support easy interoperation.  It’s possible that a particular programmer my want to use one or the other APIs by themselves.   Where do the optional VIs that depend on both go?

     

    An example might be: I have a message-passing API, and a TCP API, and I want to pass messages by TCP sometimes, without tying these two APIs forever together?  And without having the extra burden of stewarding LabVIEW to do the obvious: don’t load it it it isn’t used.

  18. How did you select the place for the function block (fb) you want to insert:

     

    I use the menu of the picture control, dynamically built in the “Shortcut Menu Activation?†event and let the User insert after the clicked-on icon.

    post-18176-0-97811200-1416945455.png post-18176-0-91040500-1416946525.png

     

    Did you have a simple Demo of the surface, wich you can send us?

     

    Sadly, I do not.

     

    We planed to program it with classes so we can send each object the mouse event with the coordinates. One of them will be get active then.

     

    Should your “objects†know about the mouse?  My “analysis pipeline actorsâ€, represented by the icons, do not know anything about the picture UI used by the top level VI.   The top level determines what was clicked on and does the appropriate action or sends the appropriate message.

×
×
  • Create New...

Important Information

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