Jump to content

Leaderboard

Popular Content

Showing content with the highest reputation on 07/30/2012 in all areas

  1. Symbio is giving away 3 UML Architect GOOP Development Licences. FYI the new GDS release is supporting the Actor Framework, what better way is there to modelling your Actors in UML. //Mike
    2 points
  2. Cool! You better wire that error through, though.
    1 point
  3. Sorry Alex, I completely forgot about this! Three questions, three answers. Close & Reopen The simplest implementation doesn't allow exiting and restarting a slave loop. Since most slaves are idle unless they are handling a message, this design is adequate for many situations. If you have a continuous-process slave that consumes a lot of resources and want to be able to shut it down when it's not being used, I'd build an internal state machine with "Active" and "Standby" states. In the Standby state the slave simply monitors messages. In the Active state it's monitoring messages and doing the resource consuming processes. OOP Run VI There is no "OOP equivalent." If you want to dynamically launch a slave loop you still need to use that function. (Or the Call Async VI function introduced in 2011.) When I wrap a slave loop in a class, the class usually has three methods: Create MySlave, ExecutionLoop, and Destroy. If I need dynamic launching I'll add a fourth method, Launch. Launch simply loads the ExecutionLoop vi and launches it using the mechanism of your choice. (Note: Dynamic launching adds complexity to the code, so I'll only use it if I need a large or unknown number of identical slave loops.) Plug-ins To me, a "plug-in" is the ability to add functionality to an application without recompiling any of the original source code. When the application starts, it searches the plug-in directory, finds the installed plug-ins, and hooks into them. If that's what you're looking for, then you'd probably need to launch each plug-in slave loop dynamically unless there's a known upper limit on the number of plug-ins that will be running at any one time. I've never done plug-ins with slave loops so I'm not sure what issues you'll run into, but it seems like it'd be fairly straightforward. I occasionally use a queue timeout case for very simple situations, but I consider it code debt because there's no way to guarantee the timeout case will ever be called. I'll usually refactor it into something more robust the next time I'm adding functionality to that loop. There are two ways I've dealt with "continuous process" slaves in the past: Heartbeats and DVRs. Using Heartbeats for Continuous Slave Loops A heartbeat is a simple timer that sends out a single message at specific intervals. (I've also called them "watchdogs," "timers," and in a fit of lyrical excessiveness, "single task producers.") In the example below, every 20 ms the heartbeat loop sends a RefreshDisplay message to the Image Display Loop, ensuring the display will be refreshed regularly regardless of the timing of other messages it might receive. However, it's still possible for the timing to get out of whack if the queue were backed up. [in this example the image display slave loop is not wrapped in an ExecutionLoop vi--it's on the main UI block diagram with several other slave loops and a mediator loop to handle message routing. A heartbeat can be put on a slave's ExecutionLoop block diagram if it is an inherent part of the slave's functionality, but usually setting up the heartbeat on the calling vi is more flexible. Either way the heartbeat is set up to automatically exit when the slave loop exits.] Using DVRs for Continuous Slave Loops When a simple heartbeat isn't an adequate solution, I'll refactor to use a DVR instead. This is the ExecutionLoop of an ImageComposerSlave class. In this particular case the SetOverlay message comes in bursts--a few seconds of high volume messages followed by relatively long periods of no messages, so there was a risk of the message queue getting backed up and throwing the timing off. The ImgCmp object (containing all the relevant information needed to compose an image) is unbundled from the ImgComposerSlave object and immediately put into a DVR. The DVR is branched, with one branch going to the message handling loop and the other going to the image rendering loop. When the message handling loop receives a message that changes a value related to image rendering, it locks the DVR, changes the value in the ImgCmp object, and unlocks it again. The image rendering loop executes at regular intervals, ensuring the rendered image gets produced on time. In principle the rendering loop can block for an excessive time waiting for the message handling loop to release the DVR. However, because the DVR never leaves this block diagram it is easy for me to verify there are no lengthy processes locking the DVR. Does that help? -Dave
    1 point
  4. So I whipped up a little table that correlates the locations from 'Get System Directory.vi' and the Windows Installer variables (used with the built-in install builder) with Windows XP and Windows 7. None of the locations that you can easily get to via Get System Directory and Windows Installer are appropriate for a machine-wide config file. If you create the config file at run time instead of installing it, the Public Documents tag for Get System Directory will work. You can avoid having them show up in each users' My Documents folder by stripping "Documents" and appending "AppData\MyApp\MyApp.ini." It's not ideal, but it's workable. Windows 7 has a %PUBLIC% environment variable that maps directly to Users\Public, but that variable doesn't exist in XP so it's not much help with cross-os compatibility.
    1 point
×
×
  • Create New...

Important Information

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