Jump to content


  • Posts

  • Joined

  • Last visited

  • Days Won


Everything posted by jon_mcbee

  1. I think that we are saying pretty similar things. The only reason you would ever chose to consume a package is that the API hides complexity in a way that simplifies your application. If the cost of consuming the API is high then you probably will decide not to consume it. If the cost of the implementation behind the API is high you definitely will decide not to consume it (because what is the point?). That said I suppose I should update the slides to explicitly show that cost/benefit is a sliding scale, something with low cost probably has high benefit, and something with high cost probably has low benefit, and that is true for both the API and the functionality behind it.
  2. So Stream is a mediator-ish message/data bus with transport abstraction, so two parts of the code can publish/subscribe to data/message by type and name and not be concerned with how the data/message moves. MVA takes what Stream does and uses it to extend the Actor Framework, while also building in extension points for Views, View Management, Models, and a ViewModel (so MVVM as an extension of the AF with a built in message/data bus to help decouple Views from Models). Over the past two and a half years we have only used MVA for project code, so it is under active development/maintenance while Stream is not and has not been used in project code. I am working on ramping back up with the blogging, been too busy with business lately unfortunately, and MVA will be featured more prominently in the new blog entries.
  3. So what I was going for was that the API has a cost associated with learning and using it as a consumer of the component, while the functionality encapsulated within the component is the benefit that you get when you pay the cost to consume the API. As a consumer of the component you don't pay a cost for the functionality hidden behind the API, I suppose that if you find yourself paying a cost for the functionality hidden behind the component you would probably stop using the component because it isn't adding any value.
  4. As Michael mentioned above we (Composed Systems) primarily use the MVA Framework (which is an extension of the Actor Framework). One note is that MVA is our separation of concerns focused framework that we use for decoupling of UI and Business Logic and the messaging between them, but we also use other frameworks that are not messaging frameworks for other aspects of development. After a few years of building up our tool chain we have MVA for messaging, a sequencing framework (Test Executive), and an event logging framework. We use each of these frameworks in each of our projects and extend each for application specific needs. I had lunch with a customer last week that we have been working with for coming up on two years, and he was saying that from his point of view he doesn't program in LabVIEW anymore, he just uses our tools (frameworks). I think this is great, I'd be curious if other people agree or are horrified by it.
  5. Composed Systems will be donating an Uncle Bob Book Bundle comprised of "Agile Software Development, Principles, Patterns, and Practices"; "Clean Code: A Handbook of Agile Software Craftsmanship"; and "The Clean Coder: A Code of Conduct for Professional Programmers".
  6. Just got my ticket, I actually remembered to buy it ahead of time this year (although I was still too slow for the early bird pricing so there is room for improvement next year).
  7. Hey guys, I updated the tool based on some feedback from John Lokanis, I'd be interested in hearing your feedback, especially on how to host the VIP. I put the VIP on my blogsite as an experiment to see if I could drive traffic up but I know its not the proper place for it. http://www.labviewcraftsmen.com/blog/labview-class-dependency-viewer-part-2 Thanks Jon
  8. Hey John, I updated the tool based on your feedback and added the force directed graph as a visualization option. Let me know what you think: http://www.labviewcraftsmen.com/blog/labview-class-dependency-viewer-part-2 -Jon
  9. Hey John, I'm a little late to the party, but I am curious what metric you used to drive the size of the nodes in your graph? Thanks, Jon
  10. I dont know if this will help you or not, but would love to get feedback from you on its usefulness. I have attached an example project that compares a very simple piece of code written with a QMH, written with an LVOOP approach, and written with the Actor Framework. I used this as a demo at a recent CLA/CLD summit. It is intended to be an apples to apples to apples comparison for someone who is looking to learn LVOOP/Actor Framework. It was originally posted on the NI Community Forums, but I apparently cant link to the page from LAVA(?) (Thanks Todd). EDIT: Replaced attached files with link to files on the NI Community Forums so that I only have to maintain one set of files: https://decibel.ni.com/content/docs/DOC-32600
  11. Is it possible to call the oldest ancestors implementation of a dynamic dispatch VI? Lets say that I have an inheritance hierarchy where the oldest ancestor is called DUT and has three abstract dynamic dispatch methods (to be overridden and not extended by children): Read Torque, Read Trip, Read Serial Number. DUT has a child class called Mindbender3000, and Mindbender3000 overrides all of the parent dynamic dispatch methods: Read Torque, Read Trip, and Read Serial Number. Somewhere down the road an upgrade is made to the Mindbender3000 product, and Mindbender5000 is born. The upgrade incorporated two main improvements, a clock was added to the new hardware that we can now query using a Read Clock method, and the ability to Read Trip was removed from the device. To account for these changes, a new abstract dynamic dispatch method is added to the DUT class, Read Clock, and a child class of MindBender3000 is created, named Mindbender5000. Mindbender5000 uses its parents implementation of the Read Torque, and Read Serial Number override methods, and overrides the DUT classes dynamic dispatch method for Read Clock. Ideally, Mindbender5000 would use the DUT classes implementation of the Read Trip method, as it is abstract and doesn't really do anything. However, because Mindbender 3000 has already overridden the Read Trip method, the Mindbender5000 product wants to use its implementation. Is there a way to call DUTs Read Trip dynamic dispatch method from the Mindbender5000 class? Lets assume that DUT has other children that need to be able to override these dynamic dispatch methods, including the new Read Clock method. Thanks!
  12. I admit I am not as well versed in UML as I should be, so I may be misreading your diagram. I don't understand why the DUT class holds a reference to the Message class in its object definition.
  13. I see. The Message parent class is abstract and its implementation of the "Execute Message" dynamic-dispatch method does nothing. Message's children override (not extend) the "Execute Message". An extra input is added to the "Execute Message" method for DUT class. The DUT parent class has a dynamic-dispatch method for every child of the Message class. The DUT dynamic-dispatch methods are embedded in their corresponding Message child override "Execute Message" method. The trick to making this work is that the DUT parent class must have an abstract dynamic-dispatch method for every child class of the Method Message class, and the corresponding DUT dynamic-dispatch method must be embedded into the "Execute Message" override method of each Message child class. Is there a name for this pattern? Is this a pattern? Or is this just common knowledge?
  14. I have a problem I am trying to solve using LVOOP, it seems like there should be an established way to solve it but I have been unable to think of/find anything that works. Here is a description, I dont have any code mocked up that I can attach, but if it would be helpful I can put some together. I am writing a test executive that will test multiple families of devices. Each family has the same set of commands, but the commands may be implemented differently (don't have to be though). I have an abstract parent class called DUT, and have children for each device family. I also have an abstract parent class called Message, with a child message class for each command in my command set. This is where I am getting stuck. All devices have the same messages, certain devices implement (structure and parse) certain messages differently. It smells like I want to override based on both device type and individual message, but this is not possible. I am hoping that someone can point out either where I went wrong, or what the logical next step would be. If more information is needed, please ask questions and I will do my best to answer. Thanks!
  15. I found the problem, it was a timing issue that had nothing do with how many subpanels I had running at once, i just had the same problem in each plugin.
  16. I am working on a GUI that is modeled off of this post by DFGray http://forums.ni.com/ni/board/message?board.id=170&message.id=466872&query.id=526816#M466872 on the NI forums. I am using the same LVOOP structure to create plugins that are launched into subpanels. I have five subpanels on my GUI, each subpanel is a different size and functions are launched into the appropriate subpanel based on their minimum window size. The problem i am seeing is that a plugin launched into a subpanel runs much more slowly than a when it is run by itself, I thought I must have left highlight execution turned on in one of the subVI's. As a test I called one of the plugins, without the LVOOP using the Simple Subpanel shipping example and it loads just fine. This makes me wonder if the problem is either the LVOOP, which doesn't make sense to me as it has nothing to do with the VI once launched into a subpanel, or with having multiple subpanels on my GUI running at once. Any thoughts on this? Regards
  17. I am looking at using Trac and Subversion together for project management and wanted to see if anyone else is doing the same. For more info on Trac see here: http://trac.edgewall.org/
  18. Have you guys ever tried Argo UML? http://argouml.tigris.org/
  19. Thank you both for the response. I plan on using the queued message handler inside my modules, using dynamic events to pass commands from a controlling VI to the modules. I was hoping I could find a way to assign priority levels to these events, so i could broadcast an abort command to all modules registered at a higher priority. I think the solution will have to be that I have a seperate event struct only registered for a high priority event that can take control of the producer/consumer that drives the module. Regards
  20. Is there a way to get access to the queue that holds events that need to be handled by the event structure? I think that there can be multiple queues if the structure is registered for multiple events, but I assume that at some point they are all loaded onto a single queue for handling. I would like to be able to insert an event at the front of the queue in certain situations to ensure that it is handled immediately. All thoughts appreciated. Regards!
  21. Hi Ben, Can you provide a link to the Tomi M thread? I looked for it but couldnt find it. Regards
  22. QUOTE (normandinf @ May 13 2009, 08:17 AM) It looks like this is the same method used to launch daemons. I am thinking of using the plugin architecture as a way to distribute a main code base with a different set of sub VI's, the sub VI's being the plugins, to our customers. In the past we have modified our code base per a customers request and then shipped them the code, this leaves us with countless different versions of code to support, not to mention that we have been doing it for 15 years and the code base is getting difficult to manage because it so many pieces have been hacked in over time. We are now ready to rewrite the code base and I thought that the plugin architecture may help us to avoid recreating the same problem we are fixing with the current rewrite. It seems that by breaking the code into as many plugin classes as possible and creating a generic main architecture all we have to do is ship the main architecture with the correct set of plugins to customers. In an ideal world all custom software would be developed as plugins and we would never have to touch the main code again, keeping it clean, readable and using the plugins for maintainability and scalability. I am starting to get the feeling that one mistake at the this point in development can ruin everything, and the amount of forthought necessary seems daunting. So I want to be sure that I have considered all available options before I get going. It seems that other people must have gone down this road, assuming that what I want to do is possible. I would like to take it as far as being able to create a plugin to modify the execution of a state machine. It seems that a plugin could be created to add states to a state machine. But I am worried that what I want to do and what is possible aren't going to match up in the end.
  23. QUOTE (normandinf @ May 12 2009, 08:02 PM) In my hunting around I had not come across using OpenG with the "Run VI" method as a way to implement the plugin architecture. Could you point me towards an example, I don't know which OpenG tools you are referring to. In fact, if anyone has any good resources for the plugin type of architecture (other posts, or KB articles...) I would love to take a look at them. I literally stumbled across this architecture and have been trying to fill in the gaps as I go, if there was one place that presented all I need to know about the plugin architecture I would be beside myself with joy. I appreciate all the feedback, and welcome more if anyone has any tips they think may be useful. In the meantime I will look into using the "Run VI" method with OpenG as another way to attack this problem. Regards
  24. I am trying to implement a plugin architecture and am starting to feel like I am missing something. I want to be able to drop a vi in a folder and incorporate it programmatically. To do this I have to use a strict type def to the plugin vi so that I can call it using a call by reference node. This seems to defeat the purpose of the plugin architecture because I have to know what the strictly type defined vi ref is in the main code. What I would like to do is to see a vi in the plugin directory, and be able to get the strictly type defined vi ref from the vi programmatically. I cannot figure out how to do this. What/where am I going wrong?
  • Create New...

Important Information

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