-
Posts
1,068 -
Joined
-
Last visited
-
Days Won
48
Content Type
Profiles
Forums
Downloads
Gallery
Everything posted by mje
-
Heh, that is pretty fast. I'm just thinking of possible design patterns for something I've been playing with in my mind for a while. If I were to do it event based, at it's heart would be a mechanism similar to the above as objects drop in and out of being subjects. I don't like events that much since I have no control over the underlying queue, but they do have one benefit in that UI events drop right in with zero effort. This is sort of a reverse observer pattern with a single observer, and an unbounded number of subjects. Might be a name for it, but my lack of a formal CS education fails me here in producing a buzzword... I suspect that since it's a registration refnum, the reference is locked for the duration of the registration primitive, which would force any subject to block when it operates on the reference to queue up an event until after the re-registration is done. But I've learned to not make assumptions like this if they're not documented, especially if you're taking a typical use-case and turning it inside-out. -m
-
I'm curious about a detail of dynamic event registration. Consider the following bit of code (example VI is attached at end of post): What's going on in the displayed frame is I'm changing which controls are registered for the mouse enter/leave events based off the value of an enumeration. Works fine, an explicit unregistration for the old array of controls does not appear to be needed. What I'm wondering about is the atomicity of the registration operation. If A was previously registered, then the code is called so A and B are both registered, is there a set of implicit serial operations where an unregistration is followed by a new registration? That is is there any possibility of missing events from A? Ignore the fact that these are UI events and the event structure locks the panel until the frame is done (which makes a definite "no" to the question above in this case), I'm wondering more about the general case where I might not be talking about UI events. -m dynamic reregistration.vi
-
Thanks for the feedback! SuperS_5, your idea definitely works. The unfortunate side is far as that example goes, it requires the parent VI to be aware of the state of the contained VI. Adapting it to hugo's idea though should make everything work the way I'd like. Good ideas, thanks again. -m
-
Is it possible to set the cursor for a VI which is embedded in a subpanel? I keep getting a null window error. Example code attached. I know I can set the cursor on the parent VI, but that's not what I'm after, I'd like to localize the busy state if possible? Something tells me I'm out of luck... SubPanelCursor.zip
-
I've seen this. It's related to some static reference voodoo, and when you try to allocate new copies of the reentrant VI it doesn't quite work. Banged my head for a while on that one when I was creating my messaging library. You should be able to do what you need using generic (non-strict) references. Unfortunately this means interacting with the front panel and doing value set/get methods for each item, dealing with variants, etc. Slow, but I doubt you're going to be doing this in a tight loop or anything. REALLY crude proof based off your original code: You then need to retrieve the control values...Messy I know, but as far as I can tell it's the *only* way to go if you want platform independency. Keith's proof is really the best way to do it (once the polling is removed) if you can stick with Windows...
-
That is the most awesome thing ever.
-
I also don't understand the auto-tool hate. Just diable it? But it is not better than the quick drop. Those who say otherwise are clearly just wrong. I'll throw in support for UI/panel "feel" gripes. The icon editor was a huge step in the right direction and I didn't criticize it in 2009 since it was new, but since it's still chock full of bugs in 2010, I feel laying into it is justified. It's a good idea not fully executed, and as a result poorly executed. I won't say it shouldn't have been released in the state it's in, because it is better than the old one, but it is slow and annoying to say the least. -m
-
Finally getting to the point where I have something to compile in my latest application, and I actually browsed the emerging *.exe folder as the build is being made for the first time: I laughed. 1abvi3w si teh h4x! Ok, back to work (as soon as the build finishes...) -m
-
Make a little demo about how easy it is to do synchronization between parallel tasks? A simple example using queues can go a long way to demonstrating this, even a simple producer-consumer pattern.
-
From the IDE side: long live the quick drop. Best set of features: Synchronization objects and structures. That upgrade (6.1?) will forever be the best. Best underdeveloped feature: OOP. I *love* that its here, but it could and should be so much more.
-
I realize you maybe were being smug owing to the window title, but that does indeed look like it could be LabVIEW 3, back when it was Mac only. Things were...different back then.
-
That thought scares me, I don't know if I trust the IDE not to get annoyed when it attempts to modify a read only file. Besides, the library still gets worked on from time to time, I'd rather not have to reset the flags each time. I'm aware of those changes, and have posted about it before. But in this case, the files actually are changing, hence the need to do SCC reversions. Next time it happens, I'll run diffs and see if there actually is any difference beyond timestamps I suppose.
-
I've been ignoring them too for ages, mostly because I was developing the libraries in tandem with the core project. But now I'm trying to pin down one of the libraries to a static tag, so I explicitly don't want my library to change, even if it is one of these phantom changes. I've done similar comparisons and seen the same results as you, Daklu. It would be neat if I could include a library as read only, to force LV to discard any changes it thinks it makes, might be an idea exchange entry brewing...
-
This has happened to me a few times now, but I'm not sure this behavior is intended or a manifestation of larger problems I've been running into with the IDE. I have some reuse libraries that have classes in them, these are actual lvlib files that have some public classes exposed. In a project, I include the libraries, and extend from the classes defined in the livlib files. After working for a bit, I go to do a save all, a bunch of stuff saves. I then go to commit my changes to source code control, and find that my re-use libraries have been modified. So I then shut LabVIEW down, revert the library changes via my SCC, then open up the project to confirm everything is a go, then do the commit proper. Why is it LabVIEW is modifying the base classes? Is this normal? When this happens, the library files that are modified are always the base lvclass file and some of the base's dynamic dispatch VIs that I was overriding in the extending class. I'll re-emphasize I had not explicitly made any changes to the base class. Reverting the base class files via SCC has no apparent effect on the project: loading the project again does not trigger any automatic changes to the base files. They just seem to get saved for some reason the first go around? I don't know what to expect by posting this, it seems I've run into so many weird things in my dealings with LabVIEW OOP, there must be something I'm doing that is just wrong. But surely I'm not the only one though? -m
-
Things like this make me wish I had maintained my cert.
-
Haven't played with pipes yet (too short on time), but I gave up on ever obtaining the standard output. Research into Windows architecture seems to indicate that GUI applications just aren't initialized with the Standard I/O/E streams, so it seems futile to obtain them. I was hoping that launching the application from a command line would make the OS initialize the streams, but no luck so far... So I settled on creating my own console. Kudos goes to the several posts referred to above, they helped point me in the right direction. Not sure how this will translate if it's plopped in a 64-bit application, if someone cares to test it that'd be great (my guess is WoW64 will take care of everything, but you never know...): It's a one-stop shop for console output. The snippet will create a console if one doesn't exist already, then write a string to it. You need to supply your own CRLF sequences. The snippet will also change the window title if you supply one. One bad thing about consoles is they're meant to be attached to a process, and when the one (and only) console exits, the OS kills the process. Hence the VI also disables the Ctrl+C/Alt+F4/Close commands/handlers. This means (unfortunately) that once open, the console will persist until the process that created it returns. If you're in the IDE, it means you need to quit the entire IDE. For an application, the console will vanish when your application returns. Even gracefully detaching your process from the console (via kernel32.dll:FreeConsole) will cause your process to terminate, as far as I can tell... Cheers, -m
-
Thanks! I forgot about that gem... I'm not aware of being able to do it in other languages/RTEs. You never know though, I thought maybe the presence (or lack) of a standard output might provide a hint as to how the executable was invoked. Nothing special. I have a LabVIEW executable that responds to command line arguments. I wanted to print out a usage summary if invoked without arguments. Also want to print out debug messages over the course of execution and allow redirection to files etc. I wasn't sure that if there was a stdout in LabVIEW if printing to it would force it to show if a command line wasn't used. Seems like a moot concern now though. I'll review the other thread again and see if I come up with anything. Thanks again, -m
-
Here's a quick one: Is there a native way in LabVIEW that I can first of all tell if my built application was launched via the command line? Also, is there a native way to print to the standard output if it was?
-
Thanks for the info, Paul. I noticed as much. I switched to a packaged library and it went off without a hitch*. In addition to the inability to go back to an lvlib, I don't see a clean way to switch from say a debug version of the livlibp to a release version. *Except for a pair of internal .cpp errors during the course of the build, but LV does that so often for me I don't feel like it's working right unless I see an error dialog in response to any arbitrary action beyond wiring or dropping VIs. But that's another story, and despite the errors, the packaged library does get produced and is usable...ish. Yes! I'm finding the same. My project opens pretty snappy still, but when I open a VI to edit it, it is very slow. The entire IDE begins to crawl, to the point where window dragging becomes painful or even impossible in some cases. Not impressed. I'm about ready to throw in the towel as well after only a few hours. The edit-time performance of the IDE is just plain unacceptable now that I've started dealing with the packaged library. I'm also concerned about switching out debug/release versions, or committing any changes since reverting to a normal library as you implied is not supported. -m
-
Recently when I was in a discussion with a colleague of mine, the issue of packed libraries came up, and I’m getting a little nervous. A few questions: What happens to namespaces? I have LibraryB.lvlib that uses classes from LibraryA.lvlib. If I make LibraryA into a packed library, do the inheritance chains in LibraryB all break because instead of LibraryA.lvlib:SomeClass.lvclass, I now have LibraryA.lvlibp:SomeClass.lvclass? That is can the packed library serve as a drop in replacement? It’s not too big of a deal if it can’t, I can go around and change all the classes this one time. What happens if a packed library include the same VIs from another library which is also used by a project that uses the packed library? Say LibC.lvlib is used by LibD.lvlibp. If I then need both of these in my project, do I run into problems because ultimately two versions of some of LibC will exist? Or does namespacing prevent the ambiguity from arising (though at the expense of having multiple copies of the same VIs in different namespaces, which I might add can become very inefficient with common re-use objects)? I see the benefits of packed libraries, but I’m also very skeptical that they won’t complicate the project or just make everything implode on me. After reading through threads like this one I get the impression I’m not the only one with some questions about these beasts. I’m still having trouble convincing myself that packed libraries bring anything useful to the table that a normal library won't do-- or which won’t be offset by the headaches which will be caused . I’m looking to see if anyone will point out pitfalls that won’t be immediately obvious when I get around to at least trying to implement packaged libraries. Thanks, -m
-
Resurrecting this... I needed to evaluate the version number of my objects at run-time so I've been parsing the flattened data and came across a slight inconsistency in the discussion. Take for example the Bacteria.lvclass we have been discussing, which yields the following flattened string (in hex words): 0000 0001 1210 4261 6374 6572 6961 2E6C 7663 6C61 7373 0000 0000 0000 0000 0000 The name section is highlighted in blue. The first byte of the name section (0x12) is the length of the entire name section including the size byte, but excluding the padding. The following byte is the length of the first PString, etc as described before, however I'll say that when dealing with qualified names, the colon character is not encoded (rather the qualified name appears as two distinct PStrings, with the colon appearing in neither). There is an additional word of padding added after the name segment to align with a four-byte boundary, then the four version words are present. For example, a class called MyClass.lvclass produces the following bytes: 0000 0001 110F 4D79 436C 6173 732E 6C76 636C 6173 7300 0000 0000 0000 0000 0000 Note the name section is shorter (0x11 bytes), and the padding has increased to three bytes to align with the boundary. In both cases, the version words start at 0x18 bytes (red). Both of these examples are generated by just dropping a class constant on the diagram, hence the 0.0.0.0 version number (and the first four bytes == 1). Now what struck me while playing with this is that there seem to be two levels of default value. For example, if we now take the wire and operate on it explicitly, but make sure the class value is still default, we get a different data string (using MyClass.lvclass again): 0000 0001 110F 4D79 436C 6173 732E 6C76 636C 6173 7300 0000 0001 0002 0003 0004 0000 0000 Now we've recorded a version number of 1.2.3.4, and we also have a data segment (in green). The data segment starts with a U32 stating the length, which in this case is zero, meaning no data, or a default value (for this specific version?). Now if we actually operate and store non-default values, we get what I'd expect according to the documentation and discussion in this thread: 0000 0001 110F 4D79 436C 6173 732E 6C76 636C 6173 7300 0000 0001 0002 0003 0004 0000 000C 4009 21FB 5444 2D18 1234 5678 The data string stores the length (0xC) followed by twelve data bytes. Figured I'd clarify this. A default value does not always produce a version of 0.0.0.0. Example code is attached, LV2010. -m TestBinaryObjects.zip
-
use more than 28 input terminals with webServices
mje replied to carri's topic in Remote Control, Monitoring and the Internet
Never used WebServices either, but can you not encode several pieces of data into a single input? Encode it on the client and interpret it in your VI. Ugly I know, but I don't think you can get around the hard limit of available connector types. -
You pretty much need to use a variant, or of course have an army of polymorphic VIs which demand every type be accounted for. I have done what you're describing using variants. They do have meta information, which you take advantage of. I don't have the info handy, but there is a library meant to handle variants, I believe it is called VariantType.lvlib and is somewhere in your vi.lib/utilities folder. A word of caution though that since these VIs are not on the palette NI might change them some day... The key is recursion. Take the variant, act accordingly if it is a primitive type (bool, double, etc). If it's a complex type (cluster, array, waveform, etc) do what you need to do then recurse on the contained type(s). Note because variants do involve a lot of copying, this can get prohibitive for deep/large data structures. You will never get as good performance as doing a "hardwired" VI for whatever your type is. I ultimately abandoned my variant approach because serializing my main data structures could take minutes using this method (compared to seconds by keeping things type specific). I still use it for simple or small data structs though.
-
Gotcha. The answers are indeed "yes" to both, a library containing several classes. Cheers -m
-
Any ideas on how to coax more information out of LabVIEW on this one? When I open my library, immediately the dirty little "*" appears in the project explorer. Trying to close the project prompts me to save my "changes", shown above. If I save the file, the time stamp on the file indeed does change, but the contents do not. This means the project is forever dirty. Running a checksum recursively on the library folder shows no changes in any of the file contents. However, when the file is included in a project, the problem does not happen. Ideas?