petehorn Posted March 18, 2013 Report Share Posted March 18, 2013 Hi everyone,I had this (possibly hairbrained and madcap ) idea a few weeks back - and have been trying to figure out a solution to it since. I've been playing around with LV OOP a lot recently and thought it would be really cool if I never had to make an FGV again. I'm not sure if someone has done this in the past but I thought I would give it a go.My thought was that I could create a heirachy of LV classes for different data types and then when I need a new FGV, just create a sub-class off one of the data type classes to build a new FGV.I've now got this working for standard data types (string, boolean and numeric - I could easily build classes for others if needed but haven't done so yet). Check out the attached code. Because I'm using OOP and dynamic terminals in places, I can't use the standard FGV uninitialised shift register, so am using a single element queue to store the data. This seems to be working OK now (feel free to use the code if you like - but I'm not promising it is bug free).The part that I'm having real trouble with is supporting custom data types. I thought it would be really cool if the user could create a new FGV class - and then add in private data to the class which would then be converted to be the data type stored in the FGV. The problem I'm having with this is the connector pane on the FGV, as I can't find a way to easily update the data type on the input and output to the FGV. I have tried a few ways but none seem like less hassle than just creating the FGV from scratch anyway...... Probably the easiest method I've found is to create separate dynamic accessors which can be dropped either before or after the FGV vi which stores the data. This isn't too bad but doesn't give the simplicity and ease of use I was hoping for..... Any ideas??? Let me know what you think. I've possibly made this far more complicated than it needs to be but its been a bit of fun anyway..... Cheers, Pete Universal FGV.zip Quote Link to comment
Yair Posted March 18, 2013 Report Share Posted March 18, 2013 (edited) You'll be happy to hear that people have thought of similar things before (for instance - http://forums.ni.com/t5/LabVIEW/LV2OO-Style-Global-VIs-from-NI-Week-2007-presentation/td-p/562527) and that LV has a much simpler mechanism for doing this - create a regular class, then create a data value reference to an object of that class. The DVR allows you to access the object using the reference. If you create property folders for the class, then the property node can even accept a DVR and get the object out of it automatically. A simple example: Edited March 18, 2013 by Yair 2 Quote Link to comment
monzue Posted May 30, 2013 Report Share Posted May 30, 2013 (edited) WOW, I had no idea that you could hook the DVR directly up to the Property node. Thanks for showing this here. I am trying to think of a good way to pass UI settings (i.e. On/Off switch states or User location) down to Data Processor Actors. I think I'll just create a UI-Real Time Variable Class, make a DVR then Send a Message to the Actors with the DVR. Then any Actor Process that needs these Real time Updateable Values set by a User can pull what it needs directly from the DVR. This method would be instead of Messaging each Actor with the new Value every time that the UI had a setting Change. Any Thoughts on this? Does this seem exactly what I should do? Should I just Use a <gasp> Global? Edited May 30, 2013 by monzue Quote Link to comment
Naity Posted May 31, 2013 Report Share Posted May 31, 2013 Hi, I am not sure I understang the last question you asked (should you use a gasp global?). Just to point 2 things out in addition to the post of Yair: DVR over Classes are indeed very powerful (to make sure you can use the same object instance in 2 loops for examples). However it is advised not to allow to use the In Place Stucture outside of the class method (it can be forbidden in the class properties in the Inheritance menu). This mean only working with the DVR in the main program and getting the object instance only inside your FGV. This also means using a create and destruct method to instanciate your class. Using DVR you can still use most of the common OO Design Pattern as the classes references are castables. HOWEVER you can not define the Class Reference Input Terminal of a method as dynamic dispatch terminal. This means, if you want to use dynamic dispatch methods, you have to wrap them around a static dispatch method which would get the object out of the reference (it basicaly obliges you to use the channeling pattern for dynamic dispatch methods). Summary: * DVR are good. * The object should only be accessible from the class method * You should use a create and a destruct methos tocreate the object and delete it * References are castable * You have to use the Channeling Pattern for Dynamic Dispatch method from a class reference Hope this helps Quote Link to comment
drjdpowell Posted May 31, 2013 Report Share Posted May 31, 2013 Any Thoughts on this? You mention “actors”, but one of the main points of the Actor Model is to use message passing instead of sharing by-reference data. So why not just send update messages when the User changes something? Quote Link to comment
monzue Posted May 31, 2013 Report Share Posted May 31, 2013 (edited) drjdpowell, using your messaging framework, My main reasoning was using a DVR requires less code work to recieve the data in the Actors and there are no memory copies(granted, most UI settings are not very memory intensive): When not Using a DVR: -- one has to make sure that every actor recieves an update when the UI actor has a user change something. - This could be done easily enough with writing the variable to the Notify Observers (Event) in your messaging framework and having all actors that need to be updated register for this event. Then each Actor should contain the UI-Settings class stored in a shift register that is the same as the one in the UI actor. And as events happen, the UI-Settings class is updated with the new values. NOW, here is something that Gets me also....... Some of my actors have a communication loop AND a processing loop that Runs as fast as it can. Now i have to not only pass my UI-settings to the Communication loop, but also to the Processing Loop. So In this case, I am passing the UI-Settings between the two loops on the vi via Notifier, and the Notifier updates every time the Communication loop gets an update. Much like what you have in the Metronome Class. -- If Using a DVR, then the Reference is passed once, and every time a Process actor needs a parameter from the UI, it simply pulls the Correct value from the DVR. I am sure you may loose some encapsulation here, but the gain in coding speed from not having to register for all the events and no memory copies may be worth it? Granted if the UI-Settings needed to be shared over a network, the way to go would be not using a DVR. I started thinking about DVR's because i just used one in my code. Consider This Case: The User launched a TCP Client Actor from a setting on the UI. This TCP Actor was constantly fed an image. The way I handled this, was I created an Image DVR and put it in the class that launched the Actor. So i fed the Image DVR around to every Actor that needed it and as the TCP Actor Updated the Image, it was accessible everywhere very conveniently. Edited May 31, 2013 by monzue Quote Link to comment
JamesMc86 Posted May 31, 2013 Report Share Posted May 31, 2013 However it is advised not to allow to use the In Place Stucture outside of the class method I would suggest it is not as black and white as that. If you are trying to guarantee the correct use of the object in a reference design that is correct. However I have used designs where I still make the methods take the object directly and the application is in charge of dealing with the DVRs. There are a few advantages: The class is more reusable, it can be used by value or by reference. DVR is a form of communication, the application architecture should and can dictate the communication method, not the library. You can decide what functions are 'atomic operations' i.e. you have methods A, B, C. If each method passes a reference to another and you have two loops you could have the execution order A1,A2,B1,B2,C1,C3 or any other combination. If the methods pass objects you can wrap all 3 inside a in place element to guarantee A1,B1,C1,A2,B2,C2 or 2 then 1. Quote Link to comment
Aristos Queue Posted June 1, 2013 Report Share Posted June 1, 2013 monzue: yes, it seems easier. Yes, the code can be lighter. It is one of the best ways to introduce race conditions into your actor interactions. Quote Link to comment
viSci Posted June 1, 2013 Report Share Posted June 1, 2013 Maybe a hybrid approach could work... You could create a singleton class that provides global access to an encapsulated DVR that references your 'Model' data. You can put semaphore mutex functions in the class so that Read/Modify/Write sequences can be safely performed by any processes in your app. Quote Link to comment
Naity Posted June 2, 2013 Report Share Posted June 2, 2013 I would suggest it is not as black and white as that. If you are trying to guarantee the correct use of the object in a reference design that is correct. Hi, First of all, I just realized I got some stuff wrong on this toppic. I did not see at first that Petehorn and Monzue are not the same users and my message was more ment for Petehorn. Sorry for that. Secondly, I tend to disagree with what u said (not the use of both object and reference for a class instance, but the use of in place structures outside the class methods). Not to pollute the thread with 2 parallel discussions, I opend a new thread in the OOP.section with some follow-up questions to your post. The link is http://lavag.org/topic/16866-use-of-in-place-structure-outside-a-labview-class/ Cheers Quote Link to comment
drjdpowell Posted June 2, 2013 Report Share Posted June 2, 2013 Some random thoughts: 1) I tend not to have an actual “UI actor”; instead I have each actor have it’s own UI on its front panel, and have the main actor present the subactors in one or more subpanels (or just open their windows. This involves less messages to pass around. 2) One can also deal with needing lots of messages for lots of UI controls by treating the controls generically using techniques illustrated below. This is a “Control Server” example that I don’t think is in the version of “Messenging” in the code repository, but will be in the next version. Changing any control in Pane 2 of the “Control Client” sends a Variant Message that then fires a Value Change event in the Control Server. You can do the same thing with “Notify”, and you can also write generic code for setting cluster items using OpenG functions. Would this kind of stuff help reduce the programming burden? 3) The above technique in (2) is event driven (User pushes button —> sends message —> fires Value Changed event). In contrast, using a DVR requires the receiver to poll for changes to the UI settings it cares about. It also works remotely (the example above works over TCP), though that is often not needed. Quote Link to comment
monzue Posted July 10, 2013 Report Share Posted July 10, 2013 (edited) monzue: yes, it seems easier. Yes, the code can be lighter. It is one of the best ways to introduce race conditions into your actor interactions. I understand that this can easily introduce race conditions. However, in my case where I used the DVR (as essentially a FGV by reference) , I only desired to have access to a recent image for viewing. I understand that this DVR method would not work effectively if I was trying to capture every single frame sent over the network, or if I needed to associate a real time parameter to an exactly timed image. Maybe a hybrid approach could work... You could create a singleton class that provides global access to an encapsulated DVR that references your 'Model' data. You can put semaphore mutex functions in the class so that Read/Modify/Write sequences can be safely performed by any processes in your app. Why would I simply not use the In-Place Structures? Some random thoughts:1) I tend not to have an actual “UI actor”; instead I have each actor have it’s own UI on its front panel, and have the main actor present the subactors in one or more subpanels (or just open their windows. This involves less messages to pass around. 2) One can also deal with needing lots of messages for lots of UI controls by treating the controls generically using techniques illustrated below. This is a “Control Server” example that I don’t think is in the version of “Messenging” in the code repository, but will be in the next version. Control Client Server.png Changing any control in Pane 2 of the “Control Client” sends a Variant Message that then fires a Value Change event in the Control Server. I have a Main UI actor that has subpanels, menus, right-click menus on the subpanels as well as the controls inside the subpanels. For charting, I mainly have Simple Vi's that only process and display a chart information. For example, the Main UI actor will get a Chart1 data message and this variant will be directly passed into a simple Charting vi that executes once and Updates the Chart control on the Front Panel, which is user selectable to be placed into a subpanel on the Main UI. So basicly I didn't see the point in making the simple VI another actor. However, I do also have other pop up windows that are actors in themselves that are launched by the Main UI. My Main problem is communicating the UI Variable information to the select locations / actors in the code where the processing happens. Currently, I am doing a mix of event messages, and DVR UI Variables that are polled by the processor when the select variable is needed. The thing is, I seem to be having to pass the DVR UI Variable Reference to almost every Actor, and I don't think that I should be doing that. Anyways, I am going to think on how my UI is laid out, and I am going to describe it more in this thread: http://lavag.org/topic/15438-re-designing-multi-instrument-multi-ui-executable/ I'll continue to comment on UI layout and communication with controls there to save this thread from going off topic too much. Edited July 10, 2013 by monzue Quote Link to comment
monzue Posted July 10, 2013 Report Share Posted July 10, 2013 3) The above technique in (2) is event driven (User pushes button —> sends message —> fires Value Changed event). In contrast, using a DVR requires the receiver to poll for changes to the UI settings it cares about. It also works remotely (the example above works over TCP), though that is often not needed. Yes, I like the way that this is flexible for any control, but my Multiple Actors individually need different control events. Polling is ok for me, because usually in the Proccess actors, the process is started on a timed basis, or is freerunning in a loop as fast as it can go. In these cases, I just want the latest or close to latest desired variable from the UI as parameters in the process math. 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.