Jump to content

Aristos Queue

Members
  • Posts

    3,183
  • Joined

  • Last visited

  • Days Won

    204

Posts posted by Aristos Queue

  1. It's not a wide dialog, so we decided to just list the unqualified class name there. I take it the path is a less usable solution than you'd prefer... We could also display the qualified name at that point. Would that be helpful? Or would you just prefer that we bite the bullet and allow the horizontal scroll bar? MS Visual Studio has decided to take that approach and show fully qualified name in all dialogs, even if it means horiz scroll. It's a usability trade off, and we could do whichever the community feels is most usable.

  2. I'm not understanding this suggestion. Are you saying I should try resaving the data in 1.0.0.1? I already did that and it didn't help.

    No. I'm saying delete version 1.0.0.2 of your class and redo whatever edit you did to create version 1.0.0.2. The mechanism works by watching the edits you make to the class. For some reason, it thinks that array is new instead of a mutation from the previous version.

    Oh, and I had the path wrong:

    vi.lib\utility\EditVILibs\LVClass

  3. I have some class data that was flattened and saved in class version 1.0.0.1. I can open the data fine with my class of version 1.0.0.1. It's a complicated cluster structure with many sub-clusters. One of the sub-clusters contains an array of cluster data. When I try to read the data and unflatten it with my class of version 1.0.0.2, I get all the data back correctly with the exception of that one sub-cluster. the array comes back as empty. The unflatten function doesn't return any errors.

    At this point i'm basically screwed. Any suggestions?

    I love the idea of automatic up-conversion but right now I'm burned badly.

    A) If you have version 1.0.0.1, you can try the edit again.

    B) If that subcluster is a typedef, it is highly probable that autoconversion will fail for all the same reasons that typedef constants on diagrams loose their values. Classes lose a lot of their ability to automutate at the typedef boundary. Try disconnecting from the typedef in version 1.0.0.1 and then make the edit. Note that this is one of the reasons that I suggest using inner classes instead of subclusters, so you can have data preservation all the way to the roots of your data.

    C) There are VIs in vi.lib\utility\lvoop to let you examine and modify the mutation records of a class. There's no real documentation for the format of the data and the notation can be arcane, but I think Kring has done some work with those VIs and may be able to help you ID the problem (assuming it is something other than the typedef thing).

  4. I hope this makes sense.
    Yes, it makes sense.

    In LV 2009, you open the VI template icon, modify it, apply the changes to all the member VIs, then open it again, undo the edit the template and re-apply the changes to all the member VIs.

    In LV 2010, you... well, since that's not released, I can't say, but it is easier.

  5. I did notice this feature and I have to confess that I am not too found of it. For instance if I have a dark banner on my children class and I use a white font for the banner text I end up having the parent banner color "leak" through (which does sometimes makes the text unreadable).

    Don't use white --- Thomas hacked white to mean "transparent". Not my favorite hack in the world. The composite icons predates the new icon editor.
  6. Does your theme editor maintain the inherited icon layer behavior? You might already know this but I figure it is worth mentioning...

    Suppose class Parent has a template icon that is 32x12 (aligned top).

    If you give the Child a template icon that is 16x12 (aligned top right), then when you add a new VI to the child, the resulting VI icon will use the Parent icon for the left half and the Child icon for the right half. This gives you a way of having a theme in the parent class with each child class adding a glyph to that original theme and then you only have to update the parent class if you want to change the theme across your whole hierarchy.

    • Like 1
  7. The LV 2009 layout is what we *wish* we'd had in LV 8.2, but didn't, so now that we have it, we have to have build options to maintain functionality for existing apps. Read the upgrade notes -- the new 2009 mechanisms are WAY better than anything LV has had in the past, both for loading dynamic VIs from your EXE and for mapping to VIs that are still sitting outside your EXE.

  8. At any rate, it sounds like I MUST load the parent of a particular target class before loading that target or labview will spit out errors.
    No. A child will load its parent automatically as part of its own load into memory.
    This is in the context of a factory pattern and plugin architexture.
    OH. In that case... you want these:

    http://decibel.ni.com/content/docs/DOC-2875 <<< search for "Factory Pattern" for an implementation of exactly what you're trying to do. This is a very CS oriented write up of the pattern and its implementation in LabVIEW.

    http://zone.ni.com/wv/app/doc/p/id/wv-1295 <<< Even more detailed online presentation about the Factory pattern, how it works and why it works and variations that may be of interest to you.

  9. There is no way to accomplish what you are requesting. A parent class is saved without any knowledge of its children. There may be infinite children on your disk, out on the network, anywhere. Some subset of those children may currently be in memory. Those are the only children that a parent knows about, and since those are already loaded, they're of no help to you.

    A class does know who its parent is. When the class loads into memory, it automatically loads its parent class, so you don't have to dynamically load that.

    Once in memory, a class can be asked for a list of all its children *in the editor environment*. You cannot do this in the runtime engine.

  10. OK, so the InPlace-Unbundle doesn't help at all to prevent data copying of the class. Correct?

    Correct. The inplace structure just says that the data coming into the left edge of the structure will be the same memory location as the data going out the right edge of the structure. Between the left edge and the right edge, if you fork the wire along the way, that other branch is a separate object. Under the hood LV might avoid actually making the copy if it can to save memory, but it will behave as if it is a separate object, and as soon as that branched wire leaves the structure or is connected to a node that modifies the value, or any operation like that, then a copy is definitely made.
  11. 1. NI's recommended way of persisting an object is to flatten it, and

    2. NI hasn't provided class developers with a way to hook into and override the flatten prim.

    You are about to scowl at me just as much as Paul did (I forget his username on LAVA -- he's the Paul who works on all the astronomy stuff) when I gave him the following answer when he was talking about customizing the XML flattened format...

    The answer is that as soon as you cross the line where the contents of the string are not enough to know which class should unflatten it, you have to write your own UnflattenFromString function from scratch. You might use our UnflattenFromString internally, but there's no way for LV to magically choose which class should unflatten the data if you want a class other than the one named to do the work of unflattening. Even if LV gave you the ability to add class specific code to the unflatten sequence, the class that would be invoked would be the class named in the flattened data, and that's exactly the class that no longer exists in your scenario. The only way this might work is if the class of the old name were still loaded into memory and had in its mutation history instructions that said, "When I am asked to unflatten, I actually unflatten data of this entirely other class over there..." Then you get into some really messy cross link scenarios where the mutation history has to have a path to the other class even though nothing in the class' current version references that other class at all, you have to keep old classes around long after they should be gone, etc.

    I've delved into allowing classes to have custom hooks to flatten and unflatten data, but none of the variations that I've played with would solve the rename problem. For that, you have to write your own. The easiest is a subVI that takes in a string, does a find-and-replace to substitute the old name for the new name and then calls the unflatten primitive with the modified string. That's a fairly expensive operation, and it's pretty heavy when you don't know if it is needed or not (i.e., you're reading a string that was written out after the name change, but you still have to do the find and replace just in case). It is error prone if there happens to be an actual string value embedded in the flat data that is the name of the old class but means something else entirely.

    Magical mutation is a major time savings. But once you break the spell, you're back to writing the full parse-and-mutate-if-needed code that programmers must write in other languages.

  12. First, any copy operation on the class creates a full copy, GUID and all. One option of handling the GUID issue is that when you next open the class, it recognizes that its current name is different from its last name and asks you "do you want to change the GUID?". A good solution? I don't know. It will likely confuse some users.

    If you do this, you end up with not allowing a class to load into memory because it has the same GUID as another class because having two classes in memory with the same GUID means you cannot unflatten any data because it is ambiguous which class the data represents. The name saved with the data -- what I'll call the data name of the class -- has to be constant from the time the data is flattened to the time it is unflattened. Either that data name is tied to the file name (so that there is an easy and obvious way to control what that name is and to explain why two classes conflict with each other when the data names match) or it is its own independent entity (so that you can change it without changing the name of the class).
  13. There are legitimate reasons for wanting to change a class name without wanting to lose the history, so it would have been nicer if this was some sort of GUID and we would get the option to reset this GUID when renaming the class.
    Yeah, and as soon as we implemented that, even more people would be complaining that when you change the name of a class that the file *doesn't* get renamed. I say this based on the screams and complaints that the project originally generated when renaming a virtual folder did not rename the folder on disk and moving a VI from one folder to another didn't move the file on disk.

    But beyond my wild speculation about the preferences of LV users, there's a very big usability problem with the GUID solution... file copying. How do you resolve the problem of File >> Save As? When a user does Save As, are they making a backup copy (where you'd want to preserve the GUID exactly) or are they forking a copy (where they'd want a new GUID)? When they have to recreate a missing class, how does a user fill in the GUID? Ok, you upgrade this to be a user defined name instead of a GUID. Great... now you have the same problem with misspelling the name that you had before making you want to change it. So that solves nothing. And further, now when you create a class you are prompted for the name of the class and the file name for the class. I'd actually recommend making them *not* match, otherwise you're going to get burned in the rare cases when they don't match -- I know this because it is exactly what happens to me right now in MS Visual Studio where the name of the class and the name of the file start off the same but someone may change the internal class name without renaming the file (generally because they don't want to mess up the source code control change tracking). LabVIEW made the opposite choice, and what we gain in clarity of file contents and findability, we lose in data preservation and source code control. Which is better?

    The debate about name handling in computer environments is endless. I have joked before that management of names is the primary job of a computer scientist. We, as code poets, must give to airy nothing a local memory address and a name. And my studies of mythology and history have taught me that renaming a thing is not done lightly nor without consequence. In the end, we picked a paradigm that seemed like it would work for most situations. It has its pros and its cons.

    If you *really* want a solution, do this: Save every individual .lvclass file inside its own .llb. That gives you the ability to rename the file on disk without changing the class name. It won't help the data unflatten case because that's the data name and any layer of indirection there leads to the GUID problems, but it will help with the source code control name change problem. But I promise you, you'll be ticked off by it, just like I am in MSVS, just as soon as the file name stops matching the contained class name. Trust me.

    Is this presentation available for those of us who couldn't make the live version? Link?

    The presentation is now available.

    http://zone.ni.com/wv/app/doc/p/id/wv-2003

    • Like 1
  14. So how am i supposed to get the refnum of the tunnel for these vis? I was hoping there was some easy method of clicking an object and setting the tag while im in the edit mode for the vi. I dont want to do this from scripting, it is a static template after all, but it sounds almost like i would have to change the tag of the object using a script which accessed the vi, somehow found the tunnel references, and then called the get tag/set tag methods using the refnums?

    Yes, this is exactly what you would have to do. That's the only mechanism that exists.
  15. Am I understanding these consequences correctly?
    Yes, it sounds like you have the right of it.
    If so, is there a way to transfer the geneology information from MessageQueue.lvclass to MessageQueue__v1.lvclass? I assume I cannot simply copy the xml from one lvclass file to the other.
    Yes, but it wouldn't help you.

    You have A.lvclass at version 1.0.0.4. You save lots of data. Now you rename the class to B.lvclass.

    You certainly could bump the class version in the file from 1.0.0.0 to 1.0.0.4. And you could cut and paste the mutation history from A.lvclass to B.lvclass. That's great -- you now have a version 4 of B that can load any data that was flattened as B versions 0, 1, 2 or 3. The problem is that all of your data was flattened as *A*. The name of the class and the version number are both part of the flattened data. It has to be because when I flatten data on an A wire, that data might be a child class like ChildOfA.lvclass. When I unflatten data onto an A wire, the data has to declare which class it represents.

    So, yes, you could preserve all the mutation instructions of your previous class on the new class, but it doesn't make any of your data accessible. To be able to unflatten old data, you have to be a new version of the same class and "same class" means same name.

    This also has ramifications for people who use the Application Builder options to add a prefix to their files as part of the build. You should stop using that option if you want data versioning of class data to work from one version of your distribution to the next. Otherwise every distribution you produce is version zero because the class is just brand new renamed.

    Is this presentation available for those of us who couldn't make the live version? Link?

    The presentation isn't posted yet. When it is, it'll be linked from here: http://decibel.ni.com/content/docs/DOC-8462

    • Like 1
  16. Indeed, common practice is to manage the closing of a reference from the same scope which opened it. I follow this in *any* programming language as best I can.

    It matters what the "Open" function looks like. Again, with DVRs and classes, the Open function is also a subVI, and, in line with what mje writes, I would expect that Open.VI and Close.VI would both be called in the same scope. Thus I wouldn't see it as an exception to "close what you open in the same scope" so much as "parallel operations should have equal depth" --- if your close is in a subVI, your open should be as well, and all the work done in that open should be undone in that close.
×
×
  • Create New...

Important Information

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