Jump to content

Daklu

Members
  • Posts

    1,824
  • Joined

  • Last visited

  • Days Won

    83

Everything posted by Daklu

  1. Labview's license allows you to install a copy at home. If it's been 10 years since you've done any substantial programming and you have clients waiting on your code I suggest doing that and spending a lot of time trying out different ways of implementing the practice CLD exams. Like Mikael, I'd approach your problem using classes. However, depending on your experience and requirements it might not be the best solution for you. Learning the basics of OOP isn't terribly hard. Learning how to do OOP in a way that solves your problem takes much longer. On my first OOP project I ended up rewriting it nearly from scratch at least 3 times because I was running into issues that I couldn't solve with the architecture or class hierarchy I had created.
  2. FYI - I set up a SourceForge project last night. If you're interested in participating create a SourceForge account, then go here and click "send a request to join this project." Thanks.
  3. AFAIK while in the dev environment .Net assemblies are only referenced in the constructor node. Do you have any .Net reference controls, indicators, or constants on that vi? That could hold the assembly reference too.
  4. Can you incorporate the requested changes into the existing code without rewriting it? Even if the current code is embarrassing at least you know it works. Unless you sit down with someone and go over your specific requirements, that's kind of what you have to do. Try something out, see why it doesn't work. Try something else, see why it doesn't work. Eventually you learn the limits of different design patterns and know when not to use them. Why parallel loops inside another loop? Producer/consumer is a good starting point. I suggest avoiding the QSM implementation. Beyond that it's difficult to predict what problems you might run into. ("Cloud the future the dark side does.") It all depends on your requirements. How precise does your timing need to be? Do you really have to execute your process every 10 ms? Is 15 ms okay? 20 ms? What about the 250 ms UI updates? Is 300 ms on occasion acceptable? 500 ms? If those are strict timing requirements you might have to add additional loops to execute those processes without other interference.
  5. My crystal ball isn't good enough to guarantee forward compatibility maintenance will occur. With the right licensing the best I can do is guarantee that forward compatibility maintenance will be able to occur.
  6. I had a brief exchange with Jim and it sounds like LapDog doesn't quite fit in with the intent of OpenG. OpenG is focused on low level functions, not a mid level api. If we want to move forward with this we'll be doing it from scratch. We'll have to set up a repository and forums online, define our goals, figure out processes, map out a code plan, etc. I appreciate the excitement (I'm excited too) but I just want it to be clear that this is not a small undertaking. Jon and Mikael both raised very good points. Here are some thoughts that hopefully further explain my intended direction: LapDog is targeted at intermediate and advanced LVOOP developers. Obviously anyone can use it, but documentation and supporting tools will assume some level of OOP knowledge. LapDog prioritizes developer productivity over execution effeciency. Additional execution overhead is inevitable when inserting new abstraction layers. We will attempt to minimize the overhead but accept that as a tradeoff for improved productivity. LapDog emphasizes flexibility. Often users will not simply drop a package class into a project and use it as is (unless their needs are very simple); they will use the package as a foundation to create classes that, through inheritance or composition, work the way the user needs it to work. (I anticipate the bridge pattern and dependency injection will be used a lot.) LapDog strives for package independence. If I want to use the Bag package in my project, I don't need to install any other packages to make it work. [Edit - I'll create a class diagram of how I expect the Bag package to work. Hopefully that will help clarify my idea.] Jon and Mikael, I like the ideas you are proposing. We should move specific discussions into a project forum. Sourceforge seems to be the default choice for online hosting. Is there any reason not to use it? Here's the entire thought process I went through... it took about 1.3 seconds. "Huh... I really should have a name for these APIs I'm developing. Labview Object-Oriented API... LOOAPI? Ugh... Labview API for Object Oriented Programmers? LAPIOOP? Object Based API for Labview? Rats, these words are terrible for trying to make acronyms. Labview Api for Programming Applications? Lapa? *sigh.* "Java's Swing is an easy to remember name for an api. I don't think that's an acronym for anything. Why should I restrict myself to an acronym? I wonder what other names I can come up with? What was I thinking of? Lapa... Lapi... Lap... our stupid cat likes to sit on my lap. The thing weighs a ton and gets hair all over me too. Sure wish we could get rid of it. A dog would be nice. I miss my golden retriever. He was a good dog. He liked to climb on my lap too and he weighed way more than our stupid cat. That's okay, he was a dog. Heh... he thought he was a lapdog. Hey... 'LapDog' is easy enough. I think I'll use that." That said, I'm not married to the name. (The more I use it the more I like it and we are considering moving in together.) I'm open to a good alternative if you can think of one quickly--we need to settle on a name before creating a repository. "LapDance" is certainly memorable and I can think of several interesting ideas for icons, but I'll have to reject that one as not work-friendly. I am not. As a contractor I don't have anyone to pay my way so not only do I have to foot the entire bill, but I also lose any money I would have earned during that time. That's a pretty big hit for a working stiff. Nope. This will be open source software probably licensed under the LGPL. If NI wanted to take it and incorporate it as part of Labview I'd support them. Then I get the functionality I want and I don't have to support the code anymore!
  7. Much of the Bag implementation was done in 8.6 and I simply didn't bother digging up my ornaments. Still, I do switch back and forth on which ornaments I'll use. The only ones I'm sure I like are the scope indicators. I'm still undecided on the folded corners for by-ref classes (mostly because it makes the object cube look funny) and the green/red markers for get/set operations. Since I cannot predict what a user will want to do with a Bag collection, it is better to leave it a by-value class. This way the user has the flexibility to wrap it in their own by-ref class or simply carry the Bag object around in a DVR in their app. If I were to release it as a by-ref class, there is no way for the user to give it by-value behavior. Come on over.
  8. You don't use regsvr32 to register .Net assemblies. If you want to put an assembly in the GAC you use either gacutil.exe or Windows Installer, but an assembly doesn't necessarily need to go in the GAC. George, What are the names, version numbers, and locations of the old dll and the new dll? If the names and versions are the same but with different paths, it could be that the Fusion engine (the MS component that finds the right assembly) is finding the old dll before the new one.
  9. It's been a couple years since I used the 8451, but last time I looked into it you could not easily do it. You might be able to do it if you implemented a whole I2C bit banging library, but that kind of defeats the purpose. I switched over to the Total Phase Aardvark for that very reason. As an added bonus the Aardvark is cheaper and supports 400 kb/s whereas the 8451 only went up to 250(?) kb/s.
  10. Good idea about OpenG. I'll post over on their forums and see how well my ideas fit in with their goals. I'm not that familiar with the OpenG Class templates so my impressions might be completely wrong. Whereas OGCT implements templates for users to create different kinds of classes, LapDog is more geared around components that allow OO developers to do more with the classes they create. Some components, like the different collections, would be accessed through the palette. Others, like the interface framework, would probably have some palette parts and some wizard parts. One of my key goals is for each component to provide at least a minimum amount of functionality "out of the box" while making it easy for api users to extend the component's functionality via inheritance or composition. For example, the List Collection component might be initially distributed with two implementation classes available: a basic array and a buffered array. If the api user wants to use a binary tree for their collection all they have to do is derive a child that implements the tree from one of the existing implementations and wire that into the List:Create method. So, uh... should I read anything into these comments? Where do you *ahem* suggest we start? Yeah, assuming the user has some understanding of the purpose of the component. I'd be hard pressed to explain what Interfaces are, how to create new Interfaces, and how to use Interfaces in less than 10 minutes.
  11. Yep. I have Ultimate Edition at work but at home I use Express. I don't do a lot of text programming, but I've found that the Express Edition is more than adequate for what I need to do.
  12. "Pizzles are almost exclusively used/produced today as chewing treats for dogs. They are a fibrous muscle, and are prepared by cleaning, stretching, twisting and then drying." Ow ow ow ow ow ow ow ow ow ow ow ow ow ow ow ow ow
  13. It's no secret I've been a bit frustrated by Labview's lack of a mid-level api for object oriented programming. .Net and Java have extensive support classes for operations with objects, such as data structures, several kinds of collections, and standard behaviors that can be customized through interfaces. In Labview we have to create our own support classes, which often results in recreating and customizing them for each new project. I've been slowly building up design ideas and a code base for various OOP supporting components, such as an interface framework and collection classes, with the idea of releasing them into the open source community. (Privately I've been referring to them collectively as "LapDog." Why? No idea... it was the first thing that popped into my head.) This is, however, a very slow process for one person who also has the usual work and family commitments, and to be honest, there are aspects of making code ready for public consumption that I'm just not very good at. I don't want LapDog to be a large api that is the Labview equivalent of the .Net framework. I'd prefer to create smaller independent components that provide useful functionality with enough flexibility that the object-oriented developer can extend it to solve their unique problem. This will allow the developer to include only that functionality they need in their project. I anticipate most components will consist of less than a dozen classes. Collections, data structures, and interfaces would likely be the first things we work on. (Primarily because I already have code for those things.) This is just an initial query to see how much need there is for a mid-level api and determine if it's worth my time to set up a public portal for the LapDog source code. If you are interested, please answer the following questions: 1. Would you be interested in using LapDog in your projects? 2. Are you able to help develop, maintain, and support LapDog? If you answer yes to Q.2, please also answer these questions: 3. How much time on average do you think you could spend on this project? (I'm not asking for a commitment, just an estimate.) 4. Given your time constraints and level of knowledge, which role(s) do you think you can fill? Consultant - I don't really have time to help out with dev work but I'm an experienced OO programmer (in any language) and I'd be happy to answer questions or discuss design decisions as my time allows. Architect - I have a working understanding of many of the standard OO design patterns (in any language) and have implemented (or tried to implement) some of them in Labview. I can generally make myself available to respond to issues that will arise when my designs are being implemented and will remain engaged during the entire dev process. Developer - I may not (or may) have much experience with object oriented programming in Labview, but I've been programming for several years, I'm comfortable writing Labview code, and I keep my block diagrams tidy. Tools - I love messing around with scripting and vi server calls! Creating an api for other developers requires different tools than application code; I'd rather work on that than write boring old regular code. Did I mention I love scripting? Documentation & Examples - I recognize good examples and clear explanations are critical to making an api usable. I can put together sample projects that show end users how to use the components in their own projects to solve various problems. Beta Tester - I can't help out with dev work much, but give me a beta component occasionally and I'll happily try to implement something with it and give you feedback on how easy it is to use and any problems I ran into. Graphics - I'm an endangered species among engineers... I have artistic talent! I love creating vi and palette icons, glyphs, animations, etc. I make the most out of the icon editor, but sometimes I'll use a vector graphics program to get the look I'm after. In a pinch I can design a pretty dang good user interface too. These are my initial ideas of different tasks that need to be done to ensure LapDog is a high quality api. I'm under no illusion that lines will be forming to fill these roles, but I do need to have an idea of how many of these tasks can be covered before I'm willing to embark on this journey.
  14. Yep. At least that's the way I use it. No problem. Glad you found it useful. Are you trying to create something that will generate code from a uml diagram, or just a uml diagramming tool for Labview? (Either way you certainly aren't shy about jumping into the deep end of the pool when learning how to swim.)
  15. Geez Kugr, this was six months ago... you expect me to remember? Okay. Umm... we have a solution that is working so I must have addressed my concerns, but to be honest I have no idea what that solution is. I'll have to go back and look at the code. I'm also not sure why I thought I'd have to create a separate case for each combination of test case, device, and position, or what I was thinking for a solution when I posted this question. I need to dredge the depths of my brain... (No wonder nobody responded to this post. Looking at it now I have no idea what I'm talking about.) That much, I recall, is correct. I don't think so, all the switches that are changed during a test case reroute the signals through attenuators and to different instruments. If I'm running test case x the internal switching isn't different if the device is in slot 3 as opposed to slot 2. Switching does need to occur at any arbitrary (but well-defined) point while the test case is executing. Nope. In our implementation the switching takes place on the test case execution thread. I'll review my code when I get some time and let you know what I find.
  16. Yep, if you want the UI to be responsive you will always need multiple threads. A UI thread (loop), a worker thread (loop), and a mechanism to exchange data are the minimum functional blocks required. The Labview QSM is usually implemented as a variation of the Producer-Consumer pattern; however, all implementations that have a UI loop and a worker loop are not necessarily QSMs. Multiple loops are not the problem--the problem with QSMs is they do not adequately separate the three functional blocks. How do you know if your implementation is a QSM? If your worker loop is directly manipulating the message queue (other than dequeuing one message at a time) then you probably have a QSM. There's a long thread discussing it here. There was also a discussion on the dark side within the last couple weeks but I'm at a loss trying to remember where it was. If you want to get out of the pattern of having the UI loop and the application's worker loop on the same block diagram, the Model-View-Controller architecture is a good place to start. It has the benefit of completely separating your application's UI from your application's functionality. As always, there is a tradeoff. MVC requires more framework code than the simpler "single module" design most often seen. Note that in my MVC designs I still have many vis which have multiple loops, usually one loop to receive messages from an external source (be it other code or a UI) and another loop that provides the functionality and sends messages out.
  17. Not a specific design pattern, but if you are just starting out in OOP Head First Design Patterns is an excellect starting point. Head First Object-Oriented Analysis and Design is not quite as good but still a worthwhile read. It focuses more on the entire software development process rather than just OO design patterns. Some books that offer different slightly different perspectives are Design Patterns, Object Thinking, and Practical API Design. By far the best thing you can do write software trying out different things. Keep going with what you've got until you reach a limitation of your design. Then figure out why your design doesn't work, refer back to your books, and see if you can come up with a better solution. As for your specific design, I'd ditch the QSM, but that's just me...
  18. I think I'm going to start calling you Commander Paul. Maybe I'll sponser an over-under line on how many posts you can go without mentioning the command pattern. (I jest. Your advice, as always, is always spot on!) There's always a better option than a QSM. (Not that I have an opinion about it or anything...)
  19. Kugr! Welcome back! I haven't seen you since last fall... thought maybe you and SciWare fell of the edge of the world. Functionally I don't think there's that much difference between the two, though I have not spent a lot of time playing with the object-in-the-DVR technique. Essentially it comes down to how you expect to use the class in your applications. If you're okay with that class *forever-and-always* being a by-ref class, I prefer putting the class data in a DVR and hiding those details from the class user. If I'm not sure how the class will be used I leave it a regular by-val class--the user can always put it in a DVR if they need an instance to be by-ref. You're talking about generics, right? Labview, being a strictly typed language, doesn't support them. I was talking to AQ once about using some of the techniques in the Interface framework to explore generics in Labview. I believe the term he used was "hopeless." I'd love to have them someday, but I'm not terribly hopeful. If pure speed is your objective you'll have to write a unique collection for each data type you want to collect. For clarity I'll separate your apparent objectives into 1) creating a collection, and 2) making it by-ref. Part 1 I'm not quite following what behavior you expect from your collection. MyCollection.GetList implies that you could also have MyCollection.GetSet, MyCollection.GetTree, and maybe a MyCollection.GetLinkedList methods. The problem is that the data you put in a list collection may not translate well into sets, trees, linked lists, bags, etc. I experimented with a unifying parent collection object for while and decided it wasn't worth the effort. I've since decided that I expect my collection users to know what kind of collection they need for their data. As a starting point I've settled on the following kinds of collections: Bag - Not ordered, duplicates allowed Set - Not ordered, no duplicates List - Ordered, duplicates allowed OSet - Ordered, no duplicates These are my four basic collections. Note that these just define the behavior of the collection. They do not define the collection's data structure--i.e. how the collection is implemented. Each can be implemented as a tree, linked-list, array, hash table, etc. The implementations are interchangable. I've attached an *incomplete* implementation of my Bag collection. So for your collection what kind of behaviors are you looking for? Part 2 It appears you want your collection, as opposed to the objects in the collection, to be by-ref. Assuming this is application code rather than reuse code, create a by-val collection object and verify it works correctly. Wrap it in another class that keeps an instance of your collection object in a DVR. Done. Locking is not typically something that is implemented in collections. If you need to lock your collection I think adding simple Lock and Unlock methods would suffice. I would leave it up to the collection user to lock and unlock the collection rather than trying to build it into the collection code. Brief Explanation of Bag Library The project has two classes, Bag and BagImplementation. Bag provides the public api to the functionality implemented in the BagImplementation class and its derivatives. As you can see I convert all the keys into variants and upcast the objects in the collection to LVObject. If I want to ensure type safety or relieve the Bag user of the nuisance of downcasting the object when they retrieve an item I create a wrapper class for Bag and do the necessary type conversions there. (The wrapper class, MyObjectBag, is not a child of Bag. That would allow clients to use Bag methods on MyObjectBag and defeats the attempt to simplify the api.) BagImplementation uses simple arrays (and the build array prim) to keep track of the keys and items. If I need an alternative implementation I derive an child class (BinaryTreeBagImp) and override all the methods with the new implementation. Then, in my application, I use Bag.SetImplementation to change from a simple array to a binary tree. Note that changing implementation effectively erases all the data in the collection. I just yanked this out of existing code the other day and I've been working on cleaning it up and packaging it for VIPM. The Set, List, and OSet collections are still on my to-do list, as are more data structure implementations. I have not yet figured out if it makes sense to write the implementations in a way that allows them to be used for different kinds of collections. If anyone wants to collaborate on reusable collection modules let me know. (And, seeing as how I freely critique others' code, I expect no less in return. Let me have it! ) BagLibrary.zip
  20. Aauuuuugggghhhh... please... make it go away... (Ironically, women pull it off much better than men.) What in the world was the competition for? Speaking of Vulcans, can you do a mind meld? I have a horrifying image I need removed from my memory.
  21. Dude... I'm feeling like totally disrespected. "LAVA'ers?" Surely we can come up with a better name for us than that. Lavers? No, sounds too much like "lovers." Lavanoids? Lavatites? Lavaliers?
  22. Yep, you always want to deploy the .lvlib/.lvclass files with all the vis that are part of the library together. I typically keep all the vis associated with a library (and only vis associated with a library) in a single directory along with .lvlib/.lvclass file. Depends on exactly what you mean by "hiding implementation details." Hiding the block diagrams of each vi requires you to apply passwords to each vi. Not letting users see or use privately-scoped member vis requires password protecting the library file. If you are concerned about users stealing your instruction source code you might consider compiling your core instruction set into a dll and calling that from your main application's source code. I've never built a dll from Labview code but you should be able to strip the block diagrams out of all the vis making it impossible for users to steal your code. The path you were following would not have eliminated that requirement. To discover which instruction versions are being used you'd need to search the plug-in folder to find out what is on the user's system. You'll still have an executable for your scripting engine. The only difference is that you've pulled the core instructions out of the executable to make it easier to deploy fixes. Well, that's one place where it's useful, but it's not the only place. Objects are also useful when you want to change the behavior of something based on run-time considerations. For example, I have a class for a spectrum analyzer that I use to issue commands to the instrument in my applications. However, I want to be able to test my applications when the instrument is not connected to the computer. To do this I simply create a child of the original spectrum analyzer class and override the Read and Write vis (which are called in each of the instrument command methods) with NoOps and replace the original spectrum analyzer BD constant with the child class constant. In two minutes I've implemented a dummy object that has a different behavior and allows me to test my system. I agree with you as far as the core instruction library is concerned. It doesn't sound like you're wanting to execute SqRt function A if the number is positive and SqRt function B is the number is negative but intead completely replacing SqRt function A with SqRt function B. For that you just need a way to replace the vi on disk, which is why I suggested pulling the core library out of the executable. If I were doing it from scratch I'd probably use an OOP based solution that provides each plug-in function library with the ability to describe its capabilities to the main app. Since you've already got working code that extracts the tokens and looks up the commands in the plug-in folder I don't see any reason to change it yet. If it ain't broke, don't fix it. Can't say. It depends on your how well you've modularized and abstracted your application.
  23. I think you have reached a practical limitation of the architecture you have chosen. Can you hack together something that will mostly work? Probably. If this project will be around for a while I strongly suggest restructuring it into something that will be more maintainable. The easiest solution is to pull the core instruction set out of the executable and load them from a MyApp\Core subdirectory. This makes it much easier to deploy bug fixes or upgrades without rebuilding the whole application AND you don't have to write and maintain all the code to decide whether to load the default library or the library in the plugins folder. Another option is to switch over to classes. You are proposing writing an instruction vi that will load various back-end processing vis depending on the run-time conditions. You want the interface to remain the same (so client scripts don't break) but you need to be able to change the implementation. Classes excel at this.
  24. See, where would I be without more experienced developers telling me why I'm wrong? Thanks for not sending the lightning. Pfft... minor implimentation detail. Now where's that foot-in-mouth icon I was looking for... Yep, I agree. My entire post was based on the premise that your solution was the more restrictive case. Take away my work around and I got nothing. I don't like the boolean argument though. I'd prefer something like a bridge pattern that allows more extensibility.
×
×
  • Create New...

Important Information

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