Jump to content

John Lokanis

Members
  • Posts

    797
  • Joined

  • Last visited

  • Days Won

    14

Everything posted by John Lokanis

  1. Due to the overwhelming response I put together a solution using some free online tools. First, you will need a tool called yEd. (http://www.yworks.com/en/products_yed_about.html) This is a very nice free tool for generating various graphs and charts. Next you will need Excel because that is the file type yEd uses to import an adjacency matrix. Last, you will need some LV code to generate an adjacency matrix and node property list from a project. Here is one I made for Actor Framework. Please excuse the poor code layout as I hacked this together quickly. Generate AF Node Map Data.vi (Note: this can easily be adapted to other message systems. The only change would be the mapping for the color properties to the appropriate parent classes. Open the VI, choose your target project and your destination xlsx file and run it! You will get a file like this: AF Demo node list.zip (zipped for your protection. ) Next you need to open this file in yEd. When you do, you need to set the data ranges correctly, like this: and choose a presentation configuration like this: which I created earlier using this: The end result, after a few cosmetic tweaks results in this: Pretty cool, eh? (Well, I think it is useful. I always prefer to visualize my applications. Complex apps using messaging architectures can get pretty hard to follow without good documentation.) I hope others find this useful. -John
  2. I'm looking for a Node Map tool to document my applications using my messaging architecture. I want to write some code that can extract relationships between classes (some being processes and some being messages) and then feed that data into a tool to visualize the relationships in my application. The end goal would be something like the http://www.visualthesaurus.com/. Unfortunately, the software behind that tool starts at $5k. I am hoping to find something a bit less expensive. Has anyone found a solution they like? thanks, -John
  3. Interesting. I had not tried that. I am still waiting on the CAR#. I also demonstrated to NI the crash if you try this with the class locked. So, I hope to see 2 CARs issued. Let's hope they can get this into LV2013.
  4. Well, if I check out the file it wants to save and then save it, the date is definitely changed. But the point is the contents of the file are not changed so there was no reason to need to save it in the first place. LabVIEW is simply marking it with a false 'changed' flag. Personally, I do not care for any merge process. As a solo developer, I have no need for this. I simply want to backup my code and be able to revert to older versions if needed.
  5. Nothing is changed. It is identical before and after saving.
  6. I have an additional bug to add related to this. In this case, it is more severe. Here are the step to reproduce: 1. Create a second project just like the first one in the ZIP above. (Here is one I created: Parent Save LVOOP Bug2.zip) 2. Open both projects at the same time. 3. Note that the shared classes are now locked. 4. Follow the steps above for the first project (creating a child class, adding the override VI). 5. At step 7, when you try to save your Execute.vi method, this will happen: This one obviously causes much more grief when it happens. The trick to avoid it is to close the other project so the locks go away before you try to save. But, I think it is related to the first bug because it happens with the same class and the same actions to reproduce. I will be reporting this as well to NI.
  7. Reported to NI. Confirmed by the app engineer to be reproducible. Once they tell me the CAR, I will post it here so other can track it if they run into the same issue.
  8. I tried to create a simple test case to repro this but I could not get it to show the issue. But, I can make it happen with my message architecture. So, I am including a zip of the required files to reproduce it. Steps: 1. After unzipping the project, verify that all files are read only except the project itself. (simulates everything being checked into source control) 2. Open the project and create a new class. 3. Save the project (should work). 4. Have the new class inherit from Message.lvclass. 5. Save the project (should work). 6. Create an override method for Execute in your new class. 7. Save the new Execute method. (should work). 8. Try to save the project. You should get a dialog that says Message.lvclass has unsaved changes. Do not save it. Allow the save process to continue with prompts. It should complete. 9. Close the project. Again you will be told to save Message.lvclass. Do not save it. Allow the project to close. 10. Open the project. 11. Close the project. Notice that Message.lvclass no longer wants to be saved. Why? And why did it want to be saved in the first place? Here is the project: Parent Save LVOOP Bug.zip I will send this to NI as well, but wanted to post here in case someone wants to try to repro the issue and confirm it for me. thanks! -John Can you post the link to report bugs. I can't seem to find it on the web site. No, I have not tried that. Just curious why you suggest that. The method is abstract. There is really nothing in it since it must be overridden.
  9. I have a class that defines a message. I inherit from this class for all my messages. The class contains a must override method called 'Execute'. Every time I create a child of this class and create the override method for Execute then go to save it, it wants to save the parent as well. This only occurs after I create the override method for Execute. If I just create the class, save it, change its inheritance and save it again the parent class is not affected. I have no idea why it is doing this but it is really annoying. Especially since everything is in version control, I end up having to check the parent out just to save the project. The reason given for the need to save the parent is 'Item moved within library'. The parent class is in a lvlib. I am running LV 12.0f3. Any ideas? Is there a CAR for this or am I just doing something wrong? thanks, -John
  10. Ok. I think I got it working and in a way that is generic enough that only applications that need this feature will be affected. Here is what I did: I created a virtual class called 'Execute Remote Message'. This class has no properties or methods. (this is so my architecture is not tied to a specific project's implementation or messages) In the "System (Remote Enabled)" class, I added the 'Execute Remote Message' class to the private data and created accessors. I put it here because only systems that do remote messaging need this feature. I then created a child of this class for my application that contains a method for each remote message (both those sent from the Client and those sent from the Server). All these methods are dynamic dispatch and NOP. Next, I created a child of the NOP class just for the Client. In this class, for each message the Client is intended to receive, I created an override method with the actual execution code in it (that links to other parts of the Client system). I only needed to override the methods that relate to messages the Client will execute. After that, I created another child of the NOP class but this time for the Server. Here I only implement overrides for messages the Server will execute. When my main VI constructs the system, I place the appropriate child class (Either Client or Server) on the diagram and wire it to the generic 'Execute Remote Message' property of the "System (Remote Enabled)" class. Inside the execute method of the messages sent between the systems, I extract the 'Execute Remote Message' object from the "System (Remote Enabled)" class and then cast it to the NOP class so I can call the specific method for this message. When the message is executed at runtime, dynamic dispatch will call the appropriate child implementation of the execute method based on which class I provided the system at the time of creation. And, since the code with the linking lives in the the child execution classes which only live in the separate applications, my Server is no longer linked to all the messages and classes in my Client. Thanks again for all the help. This one really twisted my brain but I learned a lot and am happy with the solution. I owe ned and kugr (who sent me some additional ideas) a at the next NI Week or CLA Summit. Thanks guys. I would not have solved this without your help and LAVA!
  11. Ok. Now I am starting to understand. The trick will be to make the solution generic so my core architecture does not need to be specific to the messages one of my applications has implemented.
  12. Do both the parent and child receiver classes have methods for each type of message? (the only difference is the parent methods are all empty NOP and the child versions do the actual work?)
  13. Ok. I think I got it. So, my parent message class needs a receive method that each message can override. In each message that I want to receive remotely, I implement the receive method. The receive method takes an input of type receiver class. In the Remote Send.vi, I need to call the receive method of the message sent and pass it the child of the receiver class for this application. I don't want to use a static call to the child because that makes Remote Send.vi specific to this application. Instead, I need to store the child receiver in the private data of the system class and extract it in Remote Send.vi and then pass it on to the message Receiver method. In the receive method of the message, I need to use the receiver object (cast it to the child receiver for this application) and call the specific method for this message in the child receiver class. Inside those specific Receiver methods I place the code that passes the data in the message to the new internal message within my application. So, my message is statically linked to the Receiver child class for the application because I need to call the receiver method from the message.recieve method. And that Receiver class is statically linked to the internal message class. So, don't I still have a linking problem? Maybe I still don't get it. I cannot see how the linking get separated.
  14. Ok, so I have thought about this and I am still not sure how to fit this into my code. For purposes of clarity, I and going to call the sender app the Server and the receiver app the Client. The Server still has to construct the message and set it's attributes (properties/data). So, both Server and Client will need a copy of that message class. But, in the execute method of the message, I need to call this new receiver class and pass it the message. The receiver class then has a child class that gets called via dynamic dispatch where I implement to passing of the message to the appropriate internal processes via Client side messages only. That disconnects the received message from the internal messages. But I am not sure how the receiver class will work. How can I get the dynamic dispatch to work when I am passing a message object? If I create a generic method that gets overridden by the child receiver for that message, what triggers the dispatch? Where does the original receiver child object get created to allow the dispatch to happen? Maybe I am just confused.
  15. Thanks for the reply. I am not entirely sure how to combine this with my current code but I think I might understand it after I read a few more times. If you have a moment, take a look at the Message System Client Example and Message System Server Example code that I posted in this thread: http://lavag.org/topic/16683-yet-another-messaging-systemarchitecture/ The way I am sending messages now is to call a remote VI in the receiver and give it the message object and the name of the receiver's process that the message is directed at. The receiver code then puts the message in the queue for the correct process, which then de-queues it and dynamic dispatches to the execute method in the message's class. As a result, my messages do not know if they are sent between applications or just within an application. It sounds like I need to put another layer in that translates the received message into an internal only message and then passes it to the proper internal process. Am I understanding your idea correctly?
  16. I have run into a problem with passing messages as objects between applications. My architecture is similar to AF in that messages have an execute (do) method that is run by the recipient of the message. For this to work, both the sender and the recipient must have a copy of the class. I am also trying to send messages between applications. In my application, I have a process (actor) dedicated to receiving messages. That way, I can quickly dispatch the message to another process and be ready to receive the next message. (kinda like the event loop in a producer/consumer architecture) This also allows me to take several actions when a message is received, such as passing some of the data to one internal process and some to another (via more messages). The problem I have run into is how the messages are linked to one another. Since the sender application must construct the message and send it, they need a copy of the message class. On the receiver application side, the message is executed and within that method, I create the other messages to be sent to internal processes, populate their properties and send them. Due to this, my original message contains a static link to the class of every message it will send internally. And if those messages in turn send other messages as part of their execute methods, then those will also be statically linked. The end result is my sender application has dependencies on nearly every message class in my receiver. Something I definitely do not want. This seems like a situation that AF users might run into so I am wondering if there is a way to break this dependency so the sender only needs the message class of the object that will be sent to the other application. I tried to think of a way to do this with dynamic loading classes, but the need to set the properties of the message to propagate means that I still need to cast the object and am therefore creating a static link again. Thanks for any ideas. -John
  17. OK. Confirmed the bug where the projects show up in the class hierarchy even when closed. The other side effect of this is the VIs do not close when the project is closed. Still not sure what causes this since it does not happen every time.
  18. That sounds like a real bug to me. I will try to repro it.
  19. Found the leaks. One was a DVR I was disposing of in two different possible places but not closing it in one of those places. The other was I needed to close the array of project refs I got from the App:Project.Projects[] property. Kinda surprised that I needed to close that one. Looks like a static value to me. Shows you never can tell what is safe to close/not close... Still have no idea why the lock was going on. I wonder if it could be related to the ref closing issue? Seems unlikely. Either way, I owe you a Todd!
  20. Weird. I will have to dig into that ref issue. I checked out the source code on a different machine, recompiled it and then saved and checked it back in. I then went back to my main machine and synced to get the new version. Now I cannot repro the issue. So something got fixed but I will never know what I suppose.
  21. Any idea why DETT cannot keep track of the ref numbers? I have code that closes the refs those VIs open when the app shuts down. Just because I store the refs in a variant for awhile seems to confuse DETT. Makes it kinda useless to me.
  22. Ok, I just tried the 2013 DETT and the ref leaks are not real. The Destroy code at the end of the project cleans up those refs. Weird that the DETT cannot see that. Seems like if your refs do not get closed in a normal dataflow then the DETT cannot tell they get closed. By design or a bug? I also tried it on a different machine. I was not able to repro the issue yet, but it also wanted to save 24 VIs that it claimed had changed (exact same LV version, exact same file system layout). One note: to get the app to work, you need to change your VI Server port to 3364.
  23. Here is the missing reuse VI: Append info on error.vi Run the server first and then run the client. When you close the client UI it sends the server a message to stop so everything should stop without error. I have not tried the DETT yet, but I should be closing all the refs on a proper shutdown.
  24. Bummer. I don't even need to press any buttons. Just by running the example VIs and then stopping them, all classes are locked and remain locked. Guess I need to try this on a different machine.
  25. Nope. Although I am hoping to get a copy of GDS approved soon. I can readily reproduce the behavior. I am attaching two projects that can be used to repro it. Simply open both projects at the same time, run the example VIs and press a few buttons to test the application. Then close the UI window to stop the application. Next verify that the class libraries in the projects are locked. Next try closing the projects. You will see that the VIs owned by the projects do not close. (first strange effect). Close those VIs manually and return to the start-up screen. Open one of the projects again and verify that the class libraries are still locked. Close LabVIEW and restart it. Open the same project again and verify the class libraries are unlocked. I would appreciate anyone who can verify what I am seeing. I would be greatly indebted of you can tell me what I am doing to cause it! (ie: I will buy you a at the next LAVA BBQ) Here are the projects: Message System Client Example.zip Message System Server Example.zip Thanks! -John
×
×
  • Create New...

Important Information

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