Jump to content

Stagg54

Members
  • Posts

    149
  • Joined

  • Last visited

  • Days Won

    6

Posts posted by Stagg54

  1. Here is what I need to accomplish:

    The powers that be want all front panels in a particular application to have this feature they call "auto-snap". Basically all visible front panels should "snap" back into place if the user tries to moves them around (by clicking on the title bar and dragging them). The user should be able to hit the F2 key to unlock the window and move it where ever they want. Pressing F2 again should lock it again and snap it back into its original position.

    My original design was to create a "brat vi" (I got that term from Norm Kirchner - he calls it that because it manipulates its parent). Basically you dropped it into each vi that had a visible front panel. All you had to pass it was a notifier to tell it when to exit. It ran in parallel and automatically pulled out the callers ref and registered for the key down event and took care of everything. Very cool and it worked very well. Only downside is that you had to drop it into every vi with a frontpanel. A bit of a pain for anything you may want to reuse for another project.

    Now here is my problem. Now they want to pull in this reusable library that I have. I don't want to drop this brat vi into my reusable library. Most of the timeI don't want this feature and I don't want to pollute my library with something that is only going to be used for this one special case. Now this reusable library has one main entry point/UI vi. Now I can modify my brat vi to accept a reference and run it in parallel with the main UI of my reuse library. All works well until my reuse library calls up a subvi that shows its front panel.

    What I would like to do is launch a vi in parallel with everything that would automatically detect when a new vi is opened and becomes the active front panel and then to act upon that. That would be nice because then instead of dropping it into every UI vi, I can just drop it once and run it in parallel with my main vi.

    I guess my question is:

    How do I get a reference to the vi that is active (ie. that the user is currently interacting - ignoring subpanels for the moment -although my reuse library uses those heavily so maybe that will cause some problems as well.)

    I found the Application.Active VI property which I thought would do want I wanted. (Its a scripting node, but is supposedly works in the run-time which is what I need.) Unfortunately it does not appear to be returning what I am looking for. I'm nost sure what its returning. Even though Scripting is now supported (I'm using LV2009 by the way) there is not any documentation on what the term Active VI means. I does not appear to mean what I thought it did.

    Anyway, is what I'm trying to do possible? Does anyone see a better way to solve my problem? Did I do a good enough job explaining it?

    thanks,

  2. First, since you want to make this a generic messaging framework, I assume you're planning on adding it to your reuse library. Second, I know you mean "which bit of code should define the log text," but let's take a step back and read it a bit differently. Which developer--the library designer or the library user--should define what messages and text are logged? To me the answer is clearly the library user. (Maybe the user wants to log message data along with the message name... maybe the message contains a queue and the user wants to log the number of items on the queue... the possibilities are endless.) What part of the system is customized by the user on a per-application basis? If I'm understanding your system correctly, it's the messages. Therefore, the decision about what text to log should be left up to each message--option 1 from your list.

    What if I want the log file in xml format instead of text format? What if I need the log file stored on a server instead of the local computer? What if I just want the log messages to appear in a window instead of on disk? In other words, how can I, as the user, change the logger behavior without editing the distributed reuse code?

    4. Create an abstract MessageLogger class that can be injected into the Message Interface Object by the library user. If no MessageLogger is injected, no messages are logged and you don't suffer any performance penalties. You can supply a simple text file logger with the distribution. If users need different behavior, they can create their own MessageLogger child class that does exactly what they want it to do and inject it into the Message Interface Object.

    Those are some good thoughts.

    I really like #4, although I'm not entirely sure if that fits into my paradigm.

    If I was going to do something like that I would like some way to implement it "globally" within a specific application, rather than having each process specify which Logger to use. I already have a "Master Table" that records what process is registered for what messages. Perhaps I just define the logger there.

    Which developer--the library designer or the library user--should define what messages and text are logged?

    Obviously I am thinking the end-user (who in this case happens to be me as well). My end goal is to develop a framework where when I start a new project I can just grab a copy of this framework and I already have certain tools built in (ie. I already have a debugging window that lets me view who is registered for what message, and I can view all the message traffic.) I'm trying to include some kind of logging and basic error handling in that. Then I can take that basic library and I can start building my application from there. Obviously I should be able to customize the logger or error handler, etc. as needed, but I'm hoping that I can design something that will cover 90% of my uses cases.

    Right now I've got the messaging framework built up pretty well and I'm very happy with it. It's just a matter now of how to extend it.

    I'm kind of new to this whole object oriented thing. I'm just trying to make sure I get the design right.

    Also I was kind of thinking of the logger as more of a template.

    When you get a new copy of the framework, you get a copy of this logger and then you edit it to suit the needs of your specific application. In most cases it would already do 90% of what you need.

  3. Why not have the parent message class implement a dynamic method that logs some default information. Override methods can override/extend/extinguish as needed?

    I've done a few variants of this. Some parent method defines an interface, maybe it's supplied with a byte stream refnum, maybe it's as simple as providing a ToString() method that returns a log friendly form of the object. Regardless of the exact interface, the parent method ultimately logs some basics such as the timestamp, fully qualified class name, whatever is relevant. Some extending classes override this with other information entirely, other implementations call the parent then concatenate extra information, and others in turn override the method only to not do anything and therefore keep the messages entirely silent from a log perspective.

    This model of course depends on the message itself being able to define what needs to be logged and what doesn't, which is what I think you mean by your modules being unaware? That is the observer doesn't decide what gets logged, and the signalling process doesn't have direct control over the logs, except by virtue of what messages it sends.

    That was my initial though.

    I had some misgivings and things got a little hazy when I started thinking about who was responsible for what.

    But I think that idea might work after all.

  4. Ok, so here goes.

    Basically I have set up an observer pattern and I have a few questions about how I should handle a few things, most notably logging.

    Here's how my pattern basically works.

    I have a variety of independant processes running. Each one has it's own Message Interface Object. Through the Message Interface Object (really just a sophisticated queue based system with a "global" registry) it can send any messages that are descendants of "Message Parent". When any message is sent, the parent class captures the sending process and a time stamp and then sends it out to whoever is registered for it. I also have a hook so that any child class cna execute a specific piece of code right before the message is sent for error-checking or whatever. So any process can send any message and then it can also register to recieve specific messages. I also worked in an inheritance scheme, so if you register for a particular class you get all its children as well. One of the main design considerations though is that is a broadcast type system. That means when a process sends a message, it doesn't care if it gets a response or if anyone is listening. The only time it cares is when it is waiting to recieve a message. Even then it shouldn't care who sends it, it should just care about the message itself.

    So far I have the messaging scheme all worked out as far as sending and recieving messages. I'm trying to build a nice demo program to demonstrate it (I don't have an actual project to use this on at the moment).

    So I have nice debugging tool that is registered for the parent class, so it recieves every message that is sent out and it pulls out the timestamp and sending process etc. And I have a few dummy processes just sending data out.

    Now I'm trying to work on a logger. Something that would run in the background and just log important events. I'd like to make it as generic as possible, but I also want to have my other modules not care about the logger (ie. I don't like the idea of them determining what gets logged.) My question is what is the best way to log things? I guess my real question is whose responsibility should it be to determine what text gets logged?

    As I see it I have 3 options:

    1. Add a logtext field to the parent class and allow children to update it. Then when a child can update that when its private data is changed. In this case the responsibility would belong to each message child class.

    2. Add a loggable message class and have it contain a logtext field, which its children can update. This is nice because then I can just register my logger for the loggable message parent class and get all loggable messages.

    3. Have the logger itself determine what text to put in the file for each type of message. I think I am ok with this. My main concern is that the sending process be unaware of what is out there. THe recieving process kind of has to know what's out there or what to expect, or do I have this all wrong?

    Anybody have any thoughts?

  5. Edit: It seems like there is some hope by using the Search and Replace text feature that's built into LabVIEW. I think this will work for now.

    That sounds like it might be easier than scripting.

    In general I find scripting to be a pain to write. Once written it tends to be invaluable, although I find that most of the scripting I write tends to be very narrowly focused and address one specific use-case (maybe it's just me using poor programming practices and not being general enough.)

  6. I was refering to the terminal on the icon connector.

    Ben

    I found it!!

    Double clicking on the terminal did not work. It just brought up the icon editor (perhaps that's some sort of LabVIEW options setting?)

    Anyway I found it by making sure I had saved all my changes in SVN. Then I just started deleting things with the Context help open. As soon as I saw it disappear from context help, then I knew I must have deleted it, so it must be inside that structure. Then i just hit ctrl+z and went down into the next nested layer.

    thanks everyone for the help/advice.

    oh and on a related note apparently the search function by default does not search for hidden items. So if the label of the control terminal is not visible searching for it by the label will not get you anywhere. You can always change this though.

  7. I'm cleaning up some old code (not mine) and I have run into the following problem.

    I have an indicator that is wired to the connector to pass data out of this vi. Unfortunately I can't find the thing on the block diagram. I've tried searching for it by name and haven't really had much success. (If you think this should be simple then you haven't seen the vi I'm dealing with) Is there any way to right click on the connector pane terminal and find the terminal of the corresponding indicator/control? This would also be useful because in this particular vi there are several controls/indicators with the same label. (I know - bad practices. They are not mine. Unfortunately the responsibility to make this code work is now mine. I can't throw it all away and start from scratch. As much as I'd like to, my boss seems to think it is more productive to remove cards from the house of cards instead of building the house out of bricks.)

    Any ideas?

  8. When I create a new vi for my class using New-> New vi from Dynamic Dispatch Template or New vi from Static Dispatch Template, Autogrow is always enabled on the error case structure, even though my in LabVIEW options settings I disabled the place new structures with Autogrow enabled.

    This is in LV2009SP1. I haven't checked in other versions.

    Has anyone else run into this?

  9. I have several channels worth of data.

    I want to be able to have a horizontal bar plot where each bar represents the RMS value of the channel.

    I also need to have some kind of marker to mark the peak value.

    Anyone have any experience with bar plots in LabVIEW? I've done a little research and I haven't found a lot. It doesn't seem like it should be this hard.

  10. Yes, I was aware of this function, but I am not looking for a way of comparing two refnums (I'll need it of course), but I am looking for a way of instructing "set this variable to not-a-refnum".

    Miha

    You could probably just wire it through a case structure. In one case jus pass the refnum. in the other case (ie. when you want to set it to not-a-refnum) just leave the output tunnel unwired and select "use default if unwired"

    that should do the trick.

  11. If you mean "make the Singleton inherit from another class", that should work just fine.

    If you mean "inherit from the Singleton", that's correct. This particular implementation is not intended to support inheriting from the Singleton. Singletons don't generally have inheritance in my experience -- there's supposed to only be one of them. If you want inheritance, there are variations on this theme that can be applied. All of them involve passing in some sort of "key" that says which Singleton you would like to use or moving to a "get and lock, then operate, then unlock" paradigm. But these are generally undesirable for singletons since even asking the question "which of several singletons do you want?" is somewhat ridiculous, since singleton should mean "there is only one."

    The application I'm thinking of is an error logger. Within each application there should only ever be one instance of the error logger and I don't want to pass an error logger wire through every vi in my application, hence the singleton makes sense.

    I would have a generic error logger class that would work in 90% of my applications. Perhaps that other 10% of the time I want to do add something else to the file or do something slightly different but almost all of the basic functions are the same. It wouldn't make sense to duplicate everything. I think it would make sense to be able to make a child class for that occasion. With this implementation, there doesn't appear to be any easy way to do that.

    Is there a better way to go than inheritance to achieve this?

    But these are generally undesirable for singletons since even asking the question "which of several singletons do you want?" is somewhat ridiculous, since singleton should mean "there is only one."

    That doesn't seem so ridiculous to me. What if your program uses a DMM and at any given time there is only 1 DMM in the system. It would make sense to use a singleton. Now say that DMM could be one of 3 types, it could be Keithley, NI or some other brand. But each performs the same basic functions. It would make sense to have a subclass for each meter that inherits from the generic DMM.

    Am I thinking about this the wrong way? I'm kind of new to using classes but to me this seems to make sense. How would you solve a similar problem?

  12. It's been in my head in theory, but I hadn't had time to type it out. I declined to make it a shipping example in LV 2009 because the DVRs were new and I needed to see how they'd be accepted (or not) by the community. Including it (a cleaned up, more commented version of it) in 2010 is probable if the folks here think it solves the issues.

    I like it. One issue I see that doesn't really seem to have a workaround is inheritance. I don't see how it could be done with this model, at least not easily.

  13. I'm curious if anyone has ever run into this before and how they deal with it.

    Here's my problem:

    I have 1 program that depending on which location/setting it is used in ( currently only 3 options here) it has a different front panel appearance (ie. BGcolor, text colors, boolean colors, plot colors, line styles, etc.) My world would be much easier if everyone could just agree, but that's not going to happen (which is good in a way because it keeps me employed.) Oh and also for each of these locations, when the user prints the screen I have to change all the controls to another appearance.

    I'm weighing a few options:

    As far as actually updating the control properties

    1. I could do the brute force method and have a case structure in the init stage of every VI that is displayed and use proprty nodes to set every control/indicator based on which location/setting I am in. Not elegant at all but it works. Not exactly very expandable either. Everything is pretty much hardcoded unless maybe I read it in from an .ini file. Also a lot of duplicated code. If I have a particular graph that appears on 3 screens and is handled the same way, I have to repeat the code 3 times. Maybe I make a subvi - who knows.

    2. I looked at xcontrols and having a method for each xcontrol something like set color scheme, but from what I can figure replacing all of the controls with xcontrols would be a complete waste of time.

    3. The most promising appears to be using vi server because we have a splash screen that loads all of the VIs so when I load each one I can set the properties of each control using property nodes and references.

    4. There has to be some way to incorporate classes and dynamic dispatching into method #3.

    As far as managing the different schemes:

    1. I could read all the info from an ini file - seems straightforward

    2. If I classes perhaps I could create a child class for each location and one for the print settings for each location.

    If anyone has any thoughts or ideas it would be nice. This seems like a pretty overwhelming problem and I'm just trying to wrap my brain around it. I figure no matter what it's going to take a lot of effort, but I figure any planning I can do ahead of time will really pay off in the end. Of course I'd like to come up with somehting that is readable, scalable, and maintainable. Knowing the people that I'm dealing with their liable to change their minds 20 times yet today about what colors they want and what line types, etc.

×
×
  • Create New...

Important Information

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