Jump to content

Daklu

Members
  • Posts

    1,824
  • Joined

  • Last visited

  • Days Won

    83

Everything posted by Daklu

  1. And lose that cool toolbar? Heck no! Actually, I have restarted IE several times but I don't think I've restarted Vista since I first noticed it. I do have a consistent repro through. Refreshing a page always sends the toolbar into orbit, although I can click in the text section to type a quick reply and the toolbar will revert to normal.
  2. After you finish that book I suggest picking up Head First Design Patterns. The way it presents information may lead you to believe it's a throwaway book but it has surprisingly deep explanations of design patterns. Each chapter often starts with application requirements and a naive implementation. Through the chapter the code is refactored and functionality is added until you end up with an implementation of the design pattern. This technique really helped me understand the problems each design pattern addresses. A word of caution: Expect to make lots of mistakes designing your first several object models. They will be design mistakes, not implementation mistakes, so it will take more time to fix them. Be sure to give yourself extra time to deal with them. And try to resist the temptation to immediately rewrite your reuse library as classes.
  3. That is very cool. Any plans to have the different panes snap into position near the edges of the containing window?
  4. I'm going off of memory since I'm not at work right now, but the problem didn't fix itself automatically. Refreshing didn't fix it either. But if I reopened the link the problem didn't show up.
  5. It happened several times today, but not all the time. Possibly only after I hit the refresh button, but I can't swear to that.
  6. Good idea! Except it doesn't work in our cases. I went back and looked a little closer and the libraries in question use .NET Constructor nodes which don't use the path. You have to go through the dialog box to select an object out of those that (I assume) have been registered with windows. The reference to the .NET object is then stored in the class private cluster. The .NET Refnum control in the class data cluster uses the same dialog box to define the reference type, and I'm guessing this is what is causing the constant resaves. It looks like any VI that uses that reference to call the object's properties or methods triggers the 'vi changed' flag and prompts for a resave because "Name or location of VIs in the file system changed." Any other ideas?
  7. Our Labview test tools team is a fairly new organization and we're just starting to get into code reviews. I held one earlier this week for an application I developed that is nearing release that I felt went okay, but due to time constraints was fairly shallow and the few deep dives into the code were extremely narrow. It would not have uncovered a bug I found last week that resulted in a robot crashing into a fixture. For those that do code reviews, How often/at what stages do you have code reviews? Our projects may run anywhere from 1 week to 6 months of development time with the majority on the shorter end of the scale. I think this particular code review was much later than it should have been. How much time do you budget for code reviews? 2% of total project time? 20%? How much participation do you expect from other developers? Do you find reviews more productive when conducted 1-on-1 or in a small group (4-6 developers total) setting? How much code do you try to cover? Ideally a code review would cover all the code and at the end all participants understand it as well as the developer; however, that simply is not practical in our environment where each test tool is typically owned by a single developer. Business realities dictate the review focus on 'critical' sections, which leads to the question... How do you decide what code is 'critical' and how much does application architecture dictate critical code? For an application with several asynchronous threads the message timing could be critical. Do other design patterns suggest different places to look for critical code?
  8. Just curious... is it possible to use the Computer ID via the NI License Manager?
  9. We have a multi-developer project that currently depends on several DLLs, some of which are kept in windows/system32 and some which are kept in a directory near the code that depends on them. Our developers have the source code tree mapped to different locations on their computer so every time we check out a version another developer has checked in we end up with whole libraries that need to be recompiled and resaved simply because the absolute path changed. As a result, whenever we merge a branch back into the trunk (or forward integrate the trunk into a branch) we have dozens of VIs that have to be manually compared before the merge can be checked in. This overhead is getting cumbersome; it's getting to the point where I will postpone merges simply because I don't want to deal with that. Is there a good way to handle project DLLs in a source control environment?
  10. Select the node with your mouse, hit 'Delete' on your keyboard.
  11. One area LV falls well short of other modern dev environments is in cutomizable hotkeys. I'd love to see more flexibility in that area but I have read that the functionality is buried very deep and would be difficult to implement.
  12. It's been said many times but I'll repeat it again... it sure is nice to have NI insiders responding to questions and comments on public forums. It leads to a level of understanding that otherwise would take years to achieve. Thanks. I like magic. So much of the world can be explained with it. I don't think I've run into this problem yet, but I can see how it might happen when deploying reusable code packages to an application subdirectory instead of a common shared directory. Got it. Typedefs within a package = good; typedefs across package boundaries = bad. (Unless you are 100%-for-sure-guaranteeing-cross-my-heart-hope-to-die-swear-on-my-mother's-grave that it won't change later.) I've been more concerned with a developer accidentally breaking a client with a future change. The specific example I was thinking of with the question of enums was the factory pattern example with Orange and Blue classes. Using an enum as the class selector makes it easier for the developer using the factory, but it also seems like a prime spot for bugs to appear. LV developers are used to being able to change enums and having the changes propogate through all the code. Good unit testing is certainly needed but I'd prefer to prevent the errors from making it into the code in the first place. I'm tempted to limit cross-package data to natural data types (numbers, strings, bools, etc.) and objects. Hopefully that would remove the temptation to make "easy" changes. I'm not convinced the added developer overhead in maintaining string processing is worth it in the long run though. If you don't mind my asking, how do you manage to allow us to step through the code if it's primarily machine code? VB6 was interpreted so I can understand how they managed that. C#/VB.NET are compiled to IL so I can see how they could do it there too. There's a big gap in my knowledge between high level programming languages (LV, C#, VB) and my low level hardware knowledge (68HC11 & AVR microcontrollers) so if it's too much to explain don't worry about it. And the changes that trigger that might be...?
  13. Hit Prt-Scr. Doesn't get much easier than that.
  14. You can find lots of interesting comments by viewing the strings in the Labview.exe. They are not all error text, but I believe the following are: -"Exception caught and ignored. <email address> didn't think that was possible. Please tell him how you did it." -"If you hit this, file a CAR (see comment for who to file to) - we thought this was stale code."
  15. I've run into this quite frequently. In every* case it's because there was something in my project that still depended on the item I removed. Usually I'll find the offending dependency in a diagram disable structure or buried somewhere in a case structure. Unfortunately Find->Callers is not a reliable way to find out if your project depends on a given item. Ironically the best way to see if you have a dependency is to remove the item from the project and see if it shows up in the dependency section. I've learned not to delete items with the hope the problem will go away. It doesn't--it just gets worse. If I really can't find the dependency I'll close the project, rename the file I want to remove, and reopen the project. The vi that is loading when the browse dialog pops up is the one that has the dependency. (*The one exception is if the removed item shifts into the 'Items in Memory' subfolder. In those cases your project doesn't depend on the removed item, but you have a non-project vi open that does depend on the removed item.)
  16. So the background compiler generates machine code on the fly in a single step and stores it in memory? Or does it compile down to function calls for the runtime engine to translate into os specific commands? Ohhhhh, so that's why Labivew is so expensive. (I'll gladly use a compile button if it knocks a few thousand dollars off the price.)
  17. Thanks to AQ's explanation above, some solitude courtesy Nickelback and loud speakers, and fixing a problem with circular dependencies, I was able to develop a better model of what I was trying to do and get it to work! This model isn't exactly what I'm doing in my real code, but it's closer. I have a reusable code package with two classes developers can use in their applications either directly or as parent classes for their own application-specific classes. In this example parent 1 is a simple counter with Increment Counter and Get Counter Value methods while parent 2 is a helper class that operates on parent 1 and makes a "Multiply by 2" method available. (They are shown with abstract methods but they could be implemented.) While writing an application a programmer realizes he needs a counter object that can also count down and handle negative numbers, but he can't change the reuse code package. He creates Child 1 to extend Parent 1 and adds the decrement method. Now his counter can count up and down. To correctly multiply negative numbers by 2 he creates Child 2 and overrides the Mult by 2 method. Inside that method he uses Parent1:GetCtr to check if the counter is positive or negative. If it is positive he uses Child1:IncCtr to provide the x2 functionality; if it is negative he uses Child1:DecCtr. The problem was that I couldn't figure out how to use Child1 methods inside the InpEl:DVR structure even though the value on the wire at runtime is a Child1 object. That's when I started floundering and ended up with the example posted at the start of this thread. But now, thanks to the fine folks on LAVA, I see where my assumptions were wrong and things are much more clear. *sniff* I love you guys... *sniff* It might take me a bit longer to make it around the block, but I'll get there eventually. Here's the test vi I wrote and the code for Child2:MultBy2. DVR Composition.zip
  18. The candles are starting to flicker to life... I read that and immediately wondered why the first case causes a broken run arrow and the second doesn't. (Hey, it was in CAPS... it was easy to skip the preceeding sentences.) Then the word "object" in the PRTC context help hit me over the head. From my end user perspective, previous versions of Labview don't make a distinction between classes and objects. (For example, the To More Specific Class prim has 'Target Class' as an input that in reality accepts an object.) Despite my attempts to differentiate between the two when posting, in my head I often use the terms interchangably. I'll have to work hard to change my way of thinking. I'd give you more kudos if I could...
  19. I saw that over on the LVOOP thread and it does provide a lot of benefits, but I not sure it quite solves the larger problem I'm trying to address. (If I could describe the problem without causing you a severe case of MEGO ("my eyes glaze over") I would, but I still don't understand the problem enough to do it concisely.) Ahh, this is key information I missed. I thought the parent class data was preserved in the child class. Meh... you wouldn't be far off. I'm the backyard mechanic who knows just enough to really screw things up. Yeah, when you put it that way it's apparent why the example doesn't work. Too much time in the trenches makes it easy to miss the obvious. The example I posted is a simplified representation of what I'm trying to do; I'll have to see if I can create a more accurate model to experiment with. Ahh... I didn't know this either. It says so right in the help file but every single one of the dozen times I looked at it I read it as "the function returns an error and the data value of the object out is of the same wire type as the object in" instead of what it really says, "...same wire type as the target object." (In fact, it wasn't until after I pasted that quote here to show you that the documentation was wrong that I discovered my mistake.) Not yet, but there's lots of stuff here for me to digest. I really appreciate the detailed response. It can be hard getting a good overall view of things by picking up tidbits of information here and there. I'm sure I'll be back with more questions later.
  20. Here's one of the prototypes I worked up. As I was looking through it I realized my memory about what it did wasn't quite right. (Getting old is the main disadvantage of getting older.) I developed this as a way to explore using User Events to send messages across package boundaries. My main goal was to make it as easy as possible for the subscriber while maintaining reasonably loose coupling between the producers/event monitor package and the consumer. Although you can use it for a many-to-many model, it is more geared towards registering/unregistering events at runtime. I've put more details in the Readme file in the project. As always, comments and questions are welcome. If you need a more general purpose solution the link ESST provided is probably a better fit, although I haven't looked at the code in detail. Publish-Subscribe with User Events.zip
  21. Is there a "right way" (or any way for that matter) to call child class methods on a parent object that was stuffed into a DVR? Like everyone else I've been playing around with DVRs lately, focusing primarily on ways to use object references to simplify various design pattern implementations. Today I identified a behavior that has been giving me fits for weeks. If you create an object reference to a parent object, after dereferencing the parent object there does not appear to be any way to downcast it to a child object or use dynamic dispatching to call child class methods. I built a simple example project with a parent class and a child class to illustrate this. These show a simple implicit downcast and upcast to static dispatch methods. The downcast not working isn't surprising since wiring the parent object directly into a static dispatch child method breaks the wire also. Here I tried explicitly downcasting to the child class before calling the static method. There are no bad wires but the run arrow is broken with the error, "Although you can modify the class object inside a reference, you cannot substitute the class object for another object, even if the object belongs to the same class. This restriction prevents you from changing the data type of the object in the reference." This limitation did surprise me, although I suppose it is consistent--bundling the parent in a cluster and using the in-place structure's unbundle/bundle elements generates a runtime error. The difference is the in-place unbundle/bundle elements can easily be replaced with regular unbundle/bundle nodes. There's no equivalent for DVRs. This is as close as I could come to regular unbundle/bundle nodes when using DVRs The downcast gives me a runtime error. What's really odd is that the downcast works despite the error. If I clear the error the child class correctly updates its private data in the static method and a new object reference is created for the parent. I'm not sure if I'll be able to use this for my purposes but at least it's an avenue to explore. I'm also curious which is the bug: the runtime error or the downcast actually working. I tried several other techniques as well, but I always either got a broken run arrow or a runtime error. Are there other solutions I've missed? Parent-Child DVR.zip
  22. I prototyped an Event Manager class very much like what Ton describes. The Event Manager had a separate accessor vi for each user event consumers could monitor. It followed a broadcast model. The Event Manager had no idea how many subscribers there were for each event; it just fired the event when it needed to. Consumers were responsible for handling all registering/unregistering processes. I don't remember how the event producers notified the Event Manager class. If you're interested I'll try to dig it up and give you some more details.
  23. Thanks for the detailed responses Adam. Letting your answers percolate for a few weeks helped clarify thing for me, but of course also raised a few new questions. To put the questions in context, I'm currently in the early phases of designing internal frameworks that will be distributed to other Labview developers for creating applications to test our devices. I'm planning on deploying the components as multiple OpenG packages and these questions come up when I consider updating a package without having the application source code loaded into memory. Also, since these are under source control I'd prefer not to have to checkout and resave a bunch of vis when updating a package. 1. In the .lvclass file there is a property named "NI.LVClass.FlattenedPrivateDataCTL." What information is actually stored in Composite (Base).lvclass when a Base.lvclass object is included as private data? Given that Composite (Base).lvclass doesn't need to be resaved when Base.lvclass changes, it implies that Composite (Base).lvclass is in fact storing a link to Base.lvclass rather than a representation of the object (and data) itself. What happens if I use a Base object with non-default data as private data in Composite (Base).lvclass? Composite (Base).lvclass needs to maintain a representation of the data, right? Suppose I go back later and delete a private data member from Base.lvclass that is no longer needed. How does Composite (Base).lvclass handle this? 2. If my package exposes a typedeffed cluster for clients to use, what changes can I make to the typedef in the package without breaking (either broken run arrow or unexpected runtime behavior) client code? Obviously deleting items could break clients. What about renaming items? Reordering? Renaming and reordering? 3. How does the answer to Q2 change with respect to enums rather than clusters? (My gut is that renaming or adding would be okay but reordering would be bad.) I was using 'JIT' to refer to the background compiling that happens in the Labview dev environment. What do you call that process? Precompiling? A level 1 compiler? On large projects I've seen a several second delay between hitting the run button and having the application actually start, so I don't think it compiles directly to machine code.
×
×
  • Create New...

Important Information

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