lvb Posted March 25, 2014 Report Share Posted March 25, 2014 There has to be a better way of doing the following, so I thought I would query the hive mind of LAVA. Please note the user events have different data so the cluster to/from array functions will not work. Quote Link to comment
hooovahh Posted March 25, 2014 Report Share Posted March 25, 2014 After a few tests I didn't come up with anything. I thought I'd be smart and use the Coerce to Type but it also only works with user events of the same data type. Another method was OpenG Variant to Array of VData, then Variant to Data, or Coerce to Type of a user event that is a variant type. That didn't work either. So my official solution is to change your architecture to either have all user events user the variant data type. Or only have one user event with the variant data type. And in both situations convert back to the usable data type where the data is used. Sorry I couldn't come up with something better. Quote Link to comment
lvb Posted March 25, 2014 Author Report Share Posted March 25, 2014 So my official solution is to change your architecture to either have all user events user the variant data type. Or only have one user event with the variant data type. And in both situations convert back to the usable data type where the data is used. Sorry I couldn't come up with something better. Thanks for taking a look. Your work-around seems to be more work than just adding the extra code to close the events. Quote Link to comment
MikaelH Posted March 25, 2014 Report Share Posted March 25, 2014 Create a Base class for the Events and inherit it for all the different type. It’s lot of work but that makes it possible to destroy them using a for loop. Quote Link to comment
lvb Posted March 25, 2014 Author Report Share Posted March 25, 2014 Create a Base class for the Events and inherit it for all the different type.It’s lot of work but that makes it possible to destroy them using a for loop. Thanks also, I should probably change my original post to state I am looking for the solution that requires the least amount of "coding" time but yet still performs everything in parallel. I think the best answer is to create a scripting VI. It would be nice if LabVIEW had a "close cluster of events" primitive. Quote Link to comment
soupy Posted March 25, 2014 Report Share Posted March 25, 2014 (edited) here ya go. this only works if your cluster only contains user events but it'll close all data types. if your cluster needs to hold more than user events, you could probably get around things by storing user events in a sub-cluster. Edited March 25, 2014 by soupy 2 Quote Link to comment
ShaunR Posted March 25, 2014 Report Share Posted March 25, 2014 Thanks also, I should probably change my original post to state I am looking for the solution that requires the least amount of "coding" time but yet still performs everything in parallel. I think the best answer is to create a scripting VI. It would be nice if LabVIEW had a "close cluster of events" primitive. The only time I ever need to do this kind of thing is when the app is exiting. Then I just don't bother and let LabVIEW clean up my mess. Quote Link to comment
lvb Posted March 25, 2014 Author Report Share Posted March 25, 2014 The only time I ever need to do this kind of thing is when the app is exiting. Then I just don't bother and let LabVIEW clean up my mess. Doesn't this make debugging true memory leaks a needle in the haystack situation? Quote Link to comment
ShaunR Posted March 25, 2014 Report Share Posted March 25, 2014 Doesn't this make debugging true memory leaks a needle in the haystack situation? Memory leaks are caused by not closing registrations (event reg refnums) rather than user event refnums. If nothing is registered, you can generate your events 'till your hearts content and you won't leak memory.That's why you can have plugins that come in and out of memory and attach to existing events. Besides. When I exit, I want all memory cleared up including any leaks and LabVIEW takes care of that. When the app is running, I generally want all events running too and let whatever needs them regsiter and unregister.. 1 Quote Link to comment
Popular Post lvb Posted March 25, 2014 Author Popular Post Report Share Posted March 25, 2014 here ya go. this only works if your cluster only contains user events but it'll close all data types. if your cluster needs to hold more than user events, you could probably get around things by storing user events in a sub-cluster. Thanks soupy, this works very well. It also is properly reported via the Desktop Execution Trace Toolkit. To simplify the code, I used a constant "Generic Event" with a variant data type. 4 Quote Link to comment
Yair Posted March 26, 2014 Report Share Posted March 26, 2014 The other suggestions brought up notwithstanding, you could also simplify the original code by getting rid of the reference check and simply clearing any error at the end. Also, if you do want this, there is already an idea for this, so you could try getting people to vote for it - http://forums.ni.com/t5/LabVIEW-Idea-Exchange/Allow-Destroy-User-Events-and-Unregister-for-Events-to-Accept/idi-p/1219096 I haven't checked, but I'm assuming that the changes made to events in LV 2013 didn't cover this suggestion. Maybe someone can verify that. Quote Link to comment
hooovahh Posted March 26, 2014 Report Share Posted March 26, 2014 Yeah stupid me forgot to test the type cast. In either case I can suggest an improvement. Turn on For Loop Parallelism for the for loop, and for the number of instances wire the array size. This way they will all be closed in parallel like your first post. To do this you'll need to remove the shift register, but again as stated we don't care about the error so just pass out the last one from the for loop and clear it. Quote Link to comment
chris754 Posted March 26, 2014 Report Share Posted March 26, 2014 IN either case the shift register should be removed. In error in closing one reference should not prevent others from closing. Quote Link to comment
hooovahh Posted March 26, 2014 Report Share Posted March 26, 2014 IN either case the shift register should be removed. In error in closing one reference should not prevent others from closing. I don't believe it will. There are several functions (like Close VI Ref) that will function even if an error is passed in because it knows it is a cleanup operation and should try to run no matter what. Quote Link to comment
soupy Posted March 26, 2014 Report Share Posted March 26, 2014 (edited) I don't believe it will. There are several functions (like Close VI Ref) that will function even if an error is passed in because it knows it is a cleanup operation and should try to run no matter what. yeah, close functions should always execute. you wouldn't want to have a shutdown error and leave thing allocated. you should keep this in mind when making your own tools. my teams has formalized our style to always call this VI "destroy.vi". it should have an 'X' on the icon and should always execute even if errors are passed in and should pass through incoming errors. This follows the NI paradigm. We believe that the more our code resembles NI code style & interface, the more likely it will get reused by ourselves and others (less learning curve). Edited March 26, 2014 by soupy Quote Link to comment
lvb Posted March 26, 2014 Author Report Share Posted March 26, 2014 IN either case the shift register should be removed. In error in closing one reference should not prevent others from closing. I don't believe it will. There are several functions (like Close VI Ref) that will function even if an error is passed in because it knows it is a cleanup operation and should try to run no matter what. As hooovahh said, it doesn't change the behavior in this instance. It also makes the diagram cleaner. FYI, I always pass the error wire as a shift register with a loop. If the loop doesn't run (i.e. empty array auto-indexing), tunnels will "clear" any error on the wire. This is a very common bug I see in applications. Quote Link to comment
hooovahh Posted March 26, 2014 Report Share Posted March 26, 2014 If the loop doesn't run (i.e. empty array auto-indexing), tunnels will "clear" any error on the wire. This is a very common bug I see in applications. I this case I would call that a feature, which clears the error, which is the intent. EDIT: I also like the idea of putting an X on VIs that run regardless of the error. I do this on driver level code I write for the close tasks but think it would be best to make it clearer. Quote Link to comment
JackDunaway Posted March 26, 2014 Report Share Posted March 26, 2014 This is simultaneously horrifying and elating. I love it! It's a bastardization of the type system, true, but to our advantage -- and seems to be proof that the Destructor is able to dispatch error-free on the ancestor type, regardless of assumed type. Which begs the request -- I think it makes sense to formalize this rule in the type propper, enabling User Events (and generally, other Refnums which carry/assume a type) to be arrayed, enabling the the more intuitive syntax of auto-indexing through a For Loop. It's already a by-ref OO API -- like VI Server, this ability would feel and look natural. Quote Link to comment
soupy Posted March 26, 2014 Report Share Posted March 26, 2014 This is simultaneously horrifying and elating. agreed. this is sort of a hack. i wouldn't be surprised if this functionality broke in future labview versions. I'd suggest not ignoring all errors coming out of this so you'll know if something changed. instead, ignore only error 1 coming out of the close VI Quote Link to comment
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.