Jump to content

K-node

Members
  • Posts

    90
  • Joined

  • Last visited

  • Days Won

    1

Posts posted by K-node

  1. For the VI that is going idle, why not just use the VI Invoke Node with the Front Panel:Close in its ChangeView event handler.

     

    Then for the VI that is going visible, use SubPanel Invoke Node with Remove VI followed by Insert VI in its ChangeView event handler.  I would add a Clear Errors in between in case there is nothing in the subpanel.  You might also add a Front Panel:Close in front of all of this in case the VI is already being displayed somewhere along with a Clear Errors in the event it is not currently visible.

     

    Your race condition you describe would not occur.  However, your user could go click happy and keep changing views faster than the clients can update.  It may happen that the last view desired is not the one that ends up showing simply because the last one clicked processed the event fast.  I personally would not bother handling that use case.

     

    I also agree with James, that you should pass in the reference to the subpanel and not store it.  My apps have lots of subpanels.  Front Panels are swapped around all the time.  Each user wants to see things a bit differently.

    • Like 1
  2. I am a bit confused so I will write it as I understand it.

     

    Your class has some private data that has in it a cluster.  I think this is what you call the object control element.

    You added a accessor method to Read this cluster as a complete block (not the element of the cluster).  I think this is your property node. And it is used by some member method vi.

    In this member vi, you used the Read <cluster> property node and then the Bundle By Name primitive to set the value of the desired element.

    At the end of this, you expected that the value supplied to Bundle By Name would be in the object's private data cluster.

     

    If that is correct, did you actually write the cluster obtained from the property node (the Read <cluster>) and changed the element value back to the object's private data? For instance using a Write <cluster> method (you would have to create such a method).

     

    Remember this is all data flow.  The Read makes a copy of the data from the object's private data.  If you change your copy, you need to write it back.

     

    If I am off base here, sorry, perhaps you can correct my interpretation.

  3. I periodically do what Paul suggests; adding what I think might be a class with few dependencies.  Before doing that set the 'Arrange By' of the Project's My Computer to be Custom.  The Dependencies should already be 'Same as Parent'.  You have a better chance at figuring out where that odd dependency came from when you 'Find callers' on a class, class data ctl or class method. 

  4. If done right, the collection class should not know anything about the classes it contains.  Though not using a class, in the attached example I have included a function that takes an array of vehicles and returns a properly cast vehicle (vehicle, truck or car).  It will error if you index a car and expect a truck.  You could actually make the icon look like the Index Array icon.  Anyway it is an example of the use of the Preserve Run-Time Class node which often confuses the new OOP user.

     

    I do agree with Paul in that once the entities are in an array they should be considered homogeneous - as in all vehicles.  I should be able to wire the output of the array to any method supported by the base class.  I can deal with an array of vehicles that are all trucks and require the cast.  But a collection of cars and trucks and treating them all like trucks is not a good design.

     

    I understand your dilemma with those unfamiliar with OOP.  I think though, you are setting up the user for unexpected runtime errors. In your real life example, what happens when I wire an AnalogInput to a write byte method?

     

    It is Friday night and I am about done with a Long Trail Limbo IPA (delicious by the way) so this is pretty much all I can add for now.

     

    -Kurt 

    ObjectInterfaceProblem_ALT.zip

  5. Yup, I got that.  Not happy with it, though I do not have the CompSci background to say exactly why.

     

    One thing that makes me uncomfortable is that as a developer using this API, I would not expect it to error if I asked a simple question like 'what is your capacity?'.  Or more importantly, why I am allowed to ask this question on an arbitrary vehicle if it is truly not a valid request.

     

    That aside, what if I have a chain of inquiries to do that are specific to a truck: capacity, # of axles, gross vehicle weight, etc.  Do I create a static method that encapsulates the To More Specific node (with the call to the property method) and chain these together?  Seems that it is adding unnecessary overhead on the repeat To More Specific call, error trapping, etc.

     

    As an alternate to a full collection class, even a simple function that accepts an array of vehicles (or even LVObjects), an index and a target class (constant of Truck in your example) that uses the index to access the array and passes the value to a PRTC node returning a properly 'cast' Truck if the index was a Truck.  Otherwise it returns an error.  The error would be a 'natural' result for this type of function because the developer could anticipate the request might not be valid.  This approach encapsulates the cast in an expected location, 'cleans up' your diagram and maintains design time type safety.

     

    Just my opinion, but then that is what you were asking for. :yes:

     

    Kurt

  6. Here are a couple ideas.

     

    Do all vehicles have a 'Capacity'?  If so, you might consider having a method or property with dynamic dispatch terminals that returns Capacity.  It would be defined in Vehicle.lvclass.  Car and Truck (Motorcycle, Boat, etc.) would override to supply their respective capacity if they had any.  By default, Vehicle.Capacity could return 0.

     

    Also, consider creating a Collection class that holds the array (or some container) of Objects.  Methods like Add would allow you to build the Collection up.  GetAtIndex would return the Object.  Adding an LVObject terminal to GetAtIndex and wiring that into the 'target object' terminal of a Preserve Run-Time Class node will encapsulate those 'To More Specific' nodes and still give you design time type safety. Still, a the PRTC node will error at run-time if you try to make a truck into a car.

     

    My development machine is not on the network so I cannot supply an example at the moment.  Let me know if that would be valuable and I can try tonight.

     

    -Kurt

  7. Kugr: I have no idea why we made pre-launch init.vi be reentrant. No point since it is only called from a non-reentrant caller. Unfortunately, changing that would be a breaking change needing mutation.

     

    I just want to make sure I understand this.

     

    Pre Launch Init.vi  is actually called from Actor.vi which is reentrant and launched by the ACBR node in Launch Actor which is non-reentrant.  However, at runtime it is operates like a non-reentrant VI since another Actor.vi/ACBR will not happen until the 'active' Pre Launch Init completes and the new Actor's Enqueuer is sent back to Launch Actor.

     

    So unless some developer calls Pre Launch Init from somewhere else in their code, albeit a bad practice, there will only be one shared clone.

     

    If that is the case, I take back my statement in Post #3.

  8. Non reentrant VIs called from pre launch init will cause the others to wait. Just a thought.

     

    Update:

    If you look ahead at posts 14 and 15 you will see that though Pre Launch Init is reentrant, it will never act like a reentrant vi during the launching of an actor.  So making any Pre Launch Init supporting VIs reentrant will not improve the launch performance.

  9. jackmax,

     

    AQ last year posted this: 

     

    http://forums.ni.com/t5/LabVIEW/A-more-successful-experiment-in-creating-compositable-user/td-p/1276802

     

    Look for his post with v2.3, I think that is the latest.

     

     

    While it does not answer creating your tab control, it does show how to mimic the creation of multiple controls on a front panel.  Controls are not really created, but rather an image of the control is drawn on the front panel.  At least I think that is how it works.

     

    Kurt

  10. Ton, I think 2Ls wants the DVR to reference a different or rather extended collection of data that the parent object has.  For 2Ls, it is important to remember that a DVR is a reference to specifically typed data.  There is no way to make a DVR reference something that it isn't.  So, the DVR does not really buy much here.

     

    A suggestion for 2Ls...  Perhaps the private data in the parent can be an object itself, call it ObjectData.lvclass.  Now when a child gets Initialized, it can call the parents 'Write ObjectData' accessor with a class derived from ObjectData.lvclass.  This derived class has the extra information needed.  

     

    If you still need to use a DVR, perhaps supply a 'New Data Value Reference' node with ObjectData.lvclass or one of it's derived classes.  Now 'parent' methods can get access to the what the child implementation created.

     

    Is that what you were thinking 2Ls?

     

    Kurt

    • Like 1
  11. I have had similar problems to mje's with altering a Private Data Cluster and having LabVIEW peg the CPU for longer than I wanted to wait (overnite once). Yesterday, I had another situation and wanted to share my work around.

    Yesterday I wanted to start a new empty project and load my libraries one at a time to see what the dependencies had exploded to. I had an existing working project with all of the libraries. My project is heavily OOP with a hierarchy of up to 6 derived classes. Well, on the second library added to the project, LabVIEW2011 was trying to resolve something. I was about to hunker down for a long evening of disecting lvlib files but then I though about separating compiled code in my working project. I saved and closed the working project. Then I created a new one and added the two libraries. On the second one the dependent libraries came in fast with no problems.

    I will have to look at the cross dependencies between libraries, but at least I loaded a fresh project and got to go home for the night.

  12. Couple of questions on separating compiled code...

    In LV Help on this topic, it states:

    • To prepare VIs in source control to be upgraded to a new version of LabVIEW—If you separate compiled code from VIs, you do not have to check out the VIs from source control to upgrade them to a new version of LabVIEW.

    Does this mean I don't need to store the reusable, compiled code separated VIs under multiple locations for each LV version in a repository?

    Is this a good idea?

  13. Answering your own questions? Nice! Soon you wil be answering others too!

    Just remember it is a 'Cluster of class private data' so your only access to a class's data including a parent class is through methods and properties. Sometimes, you purposely prevent children from reading or writing to your private data by not providing property VIs.

    Also, I doubt fellow LAVAG folks will exile you. In my opinion, it is important to answer these kind of questions. LVOOP is a great tool and helping out is a great way to expand its use. Interestingly, I am the only developer on a LV development staff of 4 full time and 2 contractors that follow LAVAG. Probably explains why or code is in the state that it is. I have tried to get them to regularly read the posts but they seem intimidated. Good grief!

  14. Thanks for all of your replies. It seems that everyone favors communications. Not a problem as all of us are in neighboring offices, and with the exception of me, there are no prima donna's :lol:. Also, as our common code matures, we won't run into each other as much - I hope.

    I will explore the separation of source and compiled code. We are developing under LV2011 now so hopefully any previous woes from this capability are minimized. I assume that you only put the VI under source control, not the viobj file.

    I am so used to hitting 'Save all' at this point, that would be tough to stop, but that is probably because I develop opn my own.

    Yair, thanks for the link, I am still reading this. Good stuff.

    It seems that the MSSCCI for TFS requires the licensed client for an install. Not a problem for me as I have an MSDN subscription, but I am the only one among my fellow LabVIEW developers at this point. There are four others that have LV licenses, plus at least one in another group. So, we are still working out that issue.

    It just so happens that our NJ LabVIEW Users Group is having someone talk about SCC this Thursday.

    I got a little link-happy in this post. :rolleyes:

    Thanks again!

  15. Most of our projects in the past have been single developer based. We are now trying to get a common code base on new projects and there will be multiple developers. The development is almost all LVOOP, but I am not sure that really matters. Also, it is likely we will be using TFS but I don't think this matters for my initial questions at least.

    I played around with Tortoise/SVN and the file based repository and had one other developer along for the ride, so if you want to respond with that as a reference, that is OK too.

    This first question is a very basic one. Sometimes a small change in a VI has an incredible echo in other VIs. I am not talking about changing an API for a method. Clearly that would require callers to be updated. I am remembering a change to say the icon of a VI and all of a sudden here is a huge impact. There may be other things. I guess my question is LabVIEW retains the interdependencies, how do you get a handle on these changes as they might impact another developer of a 'somehow' related module?

×
×
  • Create New...

Important Information

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