Jump to content

QueueYueue

Members
  • Posts

    68
  • Joined

  • Last visited

  • Days Won

    7

Everything posted by QueueYueue

  1. That reminds me: Design criteria #6. was "Don't change the base actor framework"
  2. I thought of a quickdrop tool at first as well. The problem with that is you'd have to select the wire, the do a ctrl+space. This would bring up a generic quickdrop. Now you'd need to do what? If you start typing, it just does default quickdrop search. It's not possible (as far as I know) to use a plugin to change what is searched. So maybe instead of typing you hit a quickddrop shortcut. Ok, now we have a list of methods, how do I display them? Can you just populate the quickdrop combobox? I could never figure out a happy way to make the plugin work, so i ditched quickdrop all together.
  3. NOTE: THIS TOOL WILL CURRENTLY CRASH LABVIEW Checkout this pseudo code: Class Vehicle{ Public Methods: Go(), Stop() } Class Car inherits Vehicle{ Public Methods: FloorIt(), ReFuel() } In school, I programmed java with Eclipse. In Eclipse, when you have a variable named myCar with a type "Car" you could type: myCar. (notice the period). When you typed the period, eclipse would pop up a little dropdown with the following in it: Go(), Stop(), FloorIt(), ReFuel(). These are all the methods that i'm allowed to call on the myCar variable. It's a car type, so I cal call all the Car methods, but a car IS A vehicle, so I can also call all the vehicle methods on it. Eclipse would figure this all out for me, and just show me everything. I wanted something like this in labview. I always found it a pain to look at the class I'm working on, then have to find it's parent in the project and find all the methods of it that i'm allowed to call, then go up another layer perhaps. Additionally, I need to remember access scope. So if I have class A that's calling a method on class B, what is it allowed to call? It depends on if the classes are parent/children, or if they're friends. I made a tool that does all of this for you. All you have to do is click on a class wire in a VI, and the tool creates a list of all VIs that you're allowed to call on that wire. It looks at access scope and it traverses the class hierarchy. And it does all this fast. (notice the car wire has been selected, and the Class method browser shows all the methods that it can call) Double clicking on a method name in the method browser will place the VI on your mouse so that you can drop it on the block diagram wherever. Shift double clicking on the method name will insert it on the currently selected wire (using a very bad insert algorithm). Hovering over a class name will show the method's description in the context help. HOW THIS TOOL WILL CRASH LABVIEW I wanted this to be fast. I didn't want there to be a wait every time you selected a new thing on the block diagram. Unfortunately, all of what I'm doing involve VI server calls, which are not super fast. The main culprit is when figuring out what the parent of the class is. So to avoid these slow VI server calls, I cache everything I will need. I make the slow calls once when you boot up the tool, and then every other time I need the info, i just have to look it up in a variant database. Perfect, and blazing fast. Well somewhere along the lines LabVIEW complains. Basically, if open the tool, then change a classes private data, LabVIEW will crash. I've submitted this to NI, but all I've heard back is "This is in CAR....." I wish this didn't happen. If it didn't then I would've spent some more time polishing this up, and then proudly released the tool (with lot of money, fame, cars and houses to follow). But it was not meant to be. So i post it here. In hopes that someone gives me an idea of how to avoid the crash. Or maybe you'll just tell me it's a dumb idea. mgi_lib_class_method_browser-0.1.0.2.vip
  4. I don't think it takes too long after deciding to do an actor based project to run into the case where you have an actor spun off without a way to kill it. You'll figure that out and get your solution working so you can pass it off to someone else and forget about it. Soon after, that someone else will come to you and say something like "yeah, those actors are cool and all, but they're really hard to debug" I ran into some of these problems a while ago, so I decided to write a little tool to help with it. I decided to call it a monitored actor. Here were my design criteria: I want a visual representation of when a monitored actor is spun up, and when it is shut down. From the visual representation, I want to be able to: stop actor, open their actor cores, and see if they're answering messages The visual representation should give you an idea of nested actor relationships. Implementing a monitored actor should be identical to implementing a regular actor. (meaning no must overrides or special knowledge) Monitored actors behave identically to Actors in the runtime environment. It turns out that you can pretty much accomplish this by creating a child actor class, which I've called Monitored Actor. A monitored actor's Pre-launch Init will try to make sure that the actor monitor window is made aware of the spawned actor, and Stop core will notify it that the actor is now dead. The actor monitor window contains ways to message the actors and pop up their cores and such. I think it's fairly obvious what each button does except pinging. Pinging will send a message to the actor and time how long it takes to get a response. This can be used to see if your actor is locked up. The time it takes to respond will be shown in the ping status column. if you want to periodically ping all the actors, set the "poll Frequency" to something greater than 10ms. This will spawn a process that just sends ping messages every X ms. Where I didn't quite meet my criteria: If you were to spawn a new actor and Immediately (in pre-launch init) spam it with High priority messages, the Actor monitor window will not know about the spawned actor until it's worked through all the High priority messages that got their first. You probably shouldn't be doing this anyways, so don't. Download it. Drop the LVLIB into your project. Change your actor's inheritance hierarchy to inherit from monitored actor instead of actor. You shouldn't have to change any of your actor's code. The monitored window will pop up when an actor is launched, and kill it's self when all actors are dead. Final note: This was something I put together for my teams use. It's been working well and fairly bug free for the past few months. It wasn't something I planned on widely distributing. A co-worker went to NI week though and he said that in every presentation where actors were mentioned, someone brought up something about they being hard to debug or hard to get into the actual running actor core instance. So I decided to post this tool here to get some feedback. Maybe find some bugs, and get a nice tool to help spread the actor gospel. Let me know what you think. Monitored Actor.zip
  5. What you're talking about is called "Chunk Size" Notice when you enable loop parallelism, you get a radio button that defaults to "Automatically Partition Iterations". You can however change it to "Specify paritioning with chunk size ( C ) terminal". If you specify the paritioning, you'll get to specify how many iterations are in each chunk. The compiler will then break them up into chunk. Each "thread" (sometimes that means processor, sometimes not) will execute it's chunk, then grab a new chunk from the pile waiting to be processed, and repeat. Obviously there is some overhead to this. That means that you may not want to set the chunk size to 1, which would result in ultra parallel execution, but you'd get hit way more by the overhead. You also don't want to set the chunk size to P (meaning the total number of iterations), that means that 1 thread will get assigned all the work, and the other will just sit there waiting! By default LabVIEW uses large chunks at first, then smaller chunks at the end. This hopes to minimize overhead, at the beginning of the process, then to minimize idle processors at the end. Honestly, 90% of the time, it is probably best to leave it like this. Here's an example to illustrate why chunk size matters. Lets say you have 2 processors (meaning P=2) and you have 10 iterations to perform. Lets say that the default chunking algorithm says first go each processor will get 3 iterations, then the remaning 4 iterations will be in two chunks. First we'll assume that each iteration takes exactly 100ms to execute. That means that each processor will first get 300ms of work to do, then go back and pickup 200ms of more work to do, so the total time to execute: 500ms. Easy Now, let's saythat each iteration takes exactly 100ms to execute, except for one randomly determined iteration. The randomly determined iteration will take 5000ms. Making the assumption that random long iteration gets into one of the first set of chunks (the ones that contain 3 iterations each). So when the processors execute their chunks, processor 1 will have 300ms of work and processor 2 will have have 5200ms of work to do. While processor 2 is chugging through it's work, processor 1 will finish it's first chunk, and ask for another, it'll get 200ms more work to do. After that 200ms, processor 2 is still chugging away (we're only 500ms from when we started) so processor 1 is assigned the last chunk, it does it's 200ms of work, and then sits idle. Finally after the 5200ms, processor 2 finishes, and our loops stops execution. so what if we specify chunk size as 1. Best case senario: processor 1 or 2 gets the long iteration on the first chunk it gets. So that processor works on it, while the other processor chugs away on all the other chunks. This means one processor will do 5000ms of work while the other does 900ms of work. They are executed at the same time and the loop takes a total of 5000ms. Now if we get unlucky and the long interation gets into one of the last two chunks, then processor 1 and two will do 800ms of work before one of them hits the long iteration, so our total time of executiong is 5800ms. obviously there are a few other ways of this situation playing out, depending on what iteration gets the long instruction and what chunk that falls into. Just some food for thought.
  6. I've seen this issue as well. Typically when I open several discussions all in independant tabs.
  7. Nice! I expected it would be something simple like that. Didn't have time to investigate myself. Only thing I'll add is that you need to close your references to all of your .Net objects (i count 3, Barcode reader, bitmap and results) I love when a .NET object does exactly what you need it to.
  8. It looks like there is a .NET version of the ZXing. I think that would by my first approach. I would take a look at one of the C# examples and recreate it in labview.
  9. They aren't. Abstract Classes: There's no way to say "you're not allowed to drop this class by it's self". Maybe that same checkbox that i suggested for constructors would allow this. Then again, you'd also need a way to make sure that a default value for a tunnel never created a new instance of my abstract class (i'm sure there are a few other special cases that would need to be addressed) Final methods: Static methods are close. If my class has a method that I don't want overriden, i just make it static. However, if my parent(parent.lvclass) has method "doSomething.vi" and it is dynamic dispatch, my new class(child.lvclass) can override. Let's say however, that I do not want anything that inherits from child.lvclass to be able to override "doSomething.vi". In child.lvclass i would mark "doSomething.vi" as final http://stackoverflow.com/questions/797530/c-sharp-is-it-possible-to-mark-overriden-method-as-final I'll vote for interfaces way before i'll vote for duck typing.
  10. The only one of these that I'm on board for would be constructors. Although it is possible to create a VI that is called something like "initialize.vi" or even "classname.vi" there is no way to guarantee that someone calls it. They can still just drop a class constant. It's possible to enforce something like this if you use a by reference scheme (using the "Restrict References of this class....." checkbox) but then you're doing things by reference. If there was a checkbox that made it illegal to drop a class constant (except for in the class's methods) on the block diagram, then we'd be able to enforce this rule. Since we're adding OO features, my vote would be for abstract classes, interfaces and final methods/classes (I don't know the generic word for this).
  11. I think this is pretty much always the case. Roflk, do .NET components behave the same way with respect to threading? I've recently had some success with tlbimp and i'm curious if that would change anything. I think for(imstuck) would have to use aximp since he's working with a control instead of just a component, but I'm not to sure about that. Tlbimp and aximp create a .net wrapper around an activex component.
  12. I'm not super good with the specifics of your problem, but this is whats causing your issues. I've seen similar problems where you're trying to use an activeX component to talk to galil motion controllers, but a lengthy UI task delays your activex calls.
  13. There is a difference between frameworks and design patterns. You seem to be asking me for a name of a design pattern, then you go on to talk about actor framework and such. These are two separate things. In terms of design patterns, honestly, I don't know patterns may have suggested. I've read up on the design patterns in the past and implement them as needed. Usually you need to mix and match a bunch of the formal design patterns to implement your solution. Here are a bunch of design patterns: https://decibel.ni.com/content/docs/DOC-2875 From memory about the solution I proposed, you'd probably use the following design patters: Template Method and Factory Patter. I'm trying to get at 2 main points here: 1. Frameworks and Design patterns are not the same thing. 2. You don't pick 1 design pattern. They are tools to help solve your problem. Use them as needed. Side note: I'm not a fan of the OO Plugin Framework. I don't think there is a good way to actually deploy these solutions.
  14. You should watch Trevor's Presentation that is stickied on this board, you should look at the built in examples, and then you should develope your own projects using OO principals. After you have some OO experience, and a decent understanding of how OO things work, you should take a look at the actor framework.
  15. I'm pretty sure that what I originally suggested would still work even with the more specific details. Morel of the story: you want to keep all the TCP communication in the parent class, and then your child classes will be the ones to decide how to display/parse this data. Your INI file would would probably be used to build an array. The array contents would be instances of the children classes. If you want to do the "Several Data Displays at one time" Actors would be a pretty good fit. There is a bit of a learning curve, but basically it'd take care of a lot of the asynchronously spawning things for you. Don't use Actor Framework to try to teach yourself OO though. Learn OO first, then start to look into actors.
  16. You're a bit vague, so I'm gonna make as good of a recomendation as I can. It seems like this will be a really slick object hierarchy that will really help you out in the long run. I'm making 1 big assumption: That the TCP connection is opened at the beginning of the Manager class' lifetime (see below for class description) and closed at the end of the Manager class' life. note: when i talk about "tabs" i'm actually talking about changing the active VI in the sub panel. There are two main components in this implementation: An overall Manager class (the Top Level VI would belong to this class) and a set Clients. The Manager class would be responsible for opening the TCP connection, and passing that connection off to to the active Client. He will also create the "Stop" user event ref, and be the one generating events on it. Next, I propose you have a parent class called Client. This will handle all (or almost all) of the house keeping type tasks in private static methods. From what you've told me, here are the methods and access scopes I'd have for this class: Public Static: Run Client: This is the main entry point for the client. When the user changes "tabs", this is the VI that will be run. It will have an input of the TCP connection, a reference to the Sub panel and a "Stop" user event ref. All this VI should do is store the Active Connection it it's private data and then call the Insert And Run UI.vi with the sub panel ref and user event ref. Protected Static: Query Data: This should send a TCP string to the server to get the data. You do not want to make this dynamic dispatch. It's function is to generate a query string to send over TCP, wait for a response, and parse the response. It's supposed to handle the lower level stuff. The real question mark here is how do you generate the query string. It may be the case that they all have the same query string. This would be the easy case, then all you have to do is hardcode (or make a config paramter, whatever normal tricks you'd use) the query string. If they're not all the same, then you'll have to use the Generate Query String.vi method described below. Again, the goal of this function is to handle the writing/reading from the TCP connection. This will keep you from having to expose the active connection reference via an accessor VI, and more importantly, keep you from having to copy/paste code. Protected Dynamic: Insert and Run UI: This is an abstract VI. It should have an Input of the sub panel reference and user event ref. This is where all of your children will implement their UI. Each child should insert itself in the subpanel reference, then run it's UI logic. Make sure your child registers for the Stop User event ref and stop your UI when needed. Generate Query String: (optional) This is an abstract VI. Each child instance should override this VI and output a string that will be sent over the TCP Write buffer. OK, now that we have the parent all setup, all that we need to do is create children of the Client class for each "tab" you want. The only VI that they'll need to override is the Insert And Run UI, and possibly the Generate Query String. You'll write your UI pretty much as you'd normally would any other sub panel VI. The only extra thing you need to know is that you now have a built in Query Data VI that will auto-magically query the server and get back the data for you. Call this VI whenever you need to update the data. If you need to add a new type of UI in the future, then just create a new child class and override the one VI. You'll only ever need to mess with the specifics of TCP and stuff the one time (when you're writing the parent class) Let me know your thoughts/question.
  17. No super private keys turned on. This event shows up when you enabled scripting I believe.
  18. NI documentation: http://zone.ni.com/reference/en-XX/help/371361J-01/lvscript/vi_bd_selection_change/ I'm working on creating a development tool. What I want is to be able to know when the user selects something new on the block diagram of the VI they're developing. This is my thought process: 1. Register for the VI Activation Event of the top level project. 2. Open a reference to newly selected VI. 3. Use the Register For Events node to register for the BD Selection Change on the VI ref that I just opened. 4. Perform my action on the new selection. Seems like it'll work, but if I Click on the block diagram of a VI in edit mode i get the following error from the Register Events node Error 1027, Saying "For the requested operation, the reference cannot be reserved as requested, is in an improper reservation mode, or the execution state must be set to running or reserved." I guess this isn't completely unexpected, it's not often you want to register for an event of a VI that's not running. This gets me thinking though, when will the BD Selection Change Event ever be used? You can't select something on the block diagram of vi that IS running, and you can't get events on a VI that ISN'T running. Am I missing something? See attached scratch code.
×
×
  • Create New...

Important Information

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