Jump to content

jgcode

LabVIEW Tools Network
  • Posts

    2,397
  • Joined

  • Last visited

  • Days Won

    66

Posts posted by jgcode

  1. Can anyone else comment on CC license with respect to LabVIEW?

    I was able to answer this question regarding if CC licenses were suitable for LabVIEW code when I was researching for another thread.

    From Creative Commons website:

    Can I apply a Creative Commons license to software?

    We do not recommend it. Creative Commons licenses should not be used for software. We strongly encourage you to use one of the very good software licenses which are already available. We recommend considering licenses made available by the Free Software Foundation or listed at the Open Source Initiative. Unlike our licenses, which do not make mention of source or object code, these existing licenses were designed specifically for use with software. Furthermore, our licenses are not compatible with the GPL, the most frequently used free software license.

    Note that the CC0 Public Domain Dedication is GPL-compatible and acceptable for software. For details, see the relevant CC0 FAQ entry.

    Good to know :P

    • Like 1
  2. Software released... ...But what about the example code etc posted in threads - not only here, but on any other boards (like NI)?

    This thread is slightly depressing because the whole reason the community exists (IMHO) is to share ideas/issues/code relating to LabVIEW.

    E.g. If I post code (to a thread) on LAVA (or NI or wherever) I don't really care about people copying it - this point is to share.

    I also want to take other people's posted code and use it if they e.g. present a solution to a problem I am having etc...

    In both transactions I do not care or can be bothered with Attribution.

    However, if code is posted in the LAVA-CR then yes, it should be licensed (and has to be as per LAVA-CR rules) - so that is a different case.

    Either way, if there was a license then it would be respected and followed.

    Regarding licensing I did do some digging and came up with this:

    CC0 is a license designed for posting in the public domain (and therefore waiving your rights) and compatible with software.

    CC0 is compatible with many software licenses

    88x31.png

    This creates Non-Copylefted Free Software which, if there was a default on LAVA (??) I would vote for CC0.

  3. Yup (for objects). It will return if it is a boolean, number etc.My bad (good call)."myobject.prototype" will return the class and you can just check with "===".

    Nice!

    Here is my contribution to find an object's name :P

    
    // Custom TypeOf Function
    
    function returnObjectType(object) {
    
      // Constructor has syntax 'function Object(){ [native code] }'
    
      var typeRegex = /function [A-z_][A-z0-9_]*\(/;
    
      var testType = typeRegex.exec(object.constructor.toString());
    
      // Parse and return the object's name, otherwise return null
    
      if (testType != null) {
    
        // Slice off leading 'function ' and trailing '(' to resolve object's name
    
        return testType.toString().slice(9, -1);
    
      }
    
      return null;
    
    }
    
     
    
    // Test returnObjectType function
    
    // Constructor for Data Type
    
    function UserDataType() {}
    
     
    
    document.write(returnObjectType("hi") + '<br />'); // returns String
    
    document.write(returnObjectType(2) + '<br />'); // returns Number
    
    document.write(returnObjectType(true) + '<br />'); // returns Boolean
    
    document.write(returnObjectType(new Array) + '<br />'); // returns Array
    
    document.write(returnObjectType(new UserDataType()) + '<br />'); // returns UserDataType[/CODE]

  4. I'm not sure if your method fully works, because if the equal primitive only compares the data, it will presumably also return T if you have two different classes with the same data (which is obviously not something which is likely to happen).

    The OP does works as each PRTC primitive will return the class' default data (which when compared will be equal if they are of the same class) because the code forces an error (at the PRTC).

    <edit>

    In any case, I can think of another option where the code is simpler - Call PRTC twice, just like in your code, but instead of using a constant as the input, use 2 as the input for 1 and 1 as the input for 2 and then check the error. If neither has an error, that should mean they're of the same class. I didn't test this, but I believe it should work, because that should be the only case where you can successfully cast both to each other.

    That doesn't work as if the class' are of the same type no error will occur at the PRTC - so if the class are the same, but contain different data the equality will fail (when you want it to be true).

  5. Are there any resons why is a new sibling inserted before existing siblings and not after them? After would seem more logically to me...

    I agree - comparing this to e.g. traversing/working with the DOM; you have an appendChild() method which adds the element to the end of the parent's existing child nodes, and when position is important you have insertBefore() method.

    ...but it's something you grow accustomed to.

    But I also agree with this - it's definitely something you get used to / don't even think about too much after using LabVIEW for a while. :)

  6. I don't believe that a forum needs to so inform particular persons. Once material is posted, unless it is specifically marked as protected in some way, it is de facto, no longer protected. If a license hold (or equivalent) of some protected code posts such code, then that person is liable for that and any subsequent non-authorized use of the code.

    At least that's what I understand about it.

    I could be wrong, but I seem to recall there was a post made a few years ago that stated that we are covered e.g. under some CC license by default, if we post code to LAVA?

    I couldn't find that info in the forum guidelines tho.

    I am sure a mod could answer this question.

    In terms of NI - there is this thread here with some interesting info.

  7. This is the way I code my AEs. I usually have single input accessors...
    I tend to make a distinction here. An accessor (for me) will be of the ilk "do one thing, do it properly" (get name, get value set name, set value etc). But a wrapper would be a simplifier of a more complex function or "wrap" several "Methods" to yield a new function.

    I agree with Shaun to make the distinction for the purpose of discussion.

    And yes, if you define accessors then they should get/set one piece of the internal state data. (because that's what accessors do).

    In the examples I have posted I haven't mentioned accessors - I have been talking about supplying inputs/outputs for methods (I guess that's a distinction made there) - and the issues I have with that in the past and trying to make it more robust.

    I wanted to present other way of creating an AE using a DVR-IPE.

  8. I believe this to be the more right way, but one way is to do as you said, where you have a value signaling property on a control that calls an event. I feel like this is harder to follow, and harder to debug.

    I agree.

    If I find myself in this position then it means that I want to call code in the Event Handler.

    Simply refactoring it out into e.g. it's own case, solves the problem.

  9. I don't think it's any different to the boiler plate code that you have to use with a DVR... ...You still have to create the bundle and un-bundles in the accessors (and the extra controls/indicators etc) the same as I do

    There is no boilerplate code with the DVR (that is why it is less coding).

    Sure data is bundled/unbundled but this is the state data i.e. the data that is persistent for that module - same as in an AE:

    post-10325-0-03961700-1325147059.png

    post-10325-0-54917900-1325147064.png

    This is the (single) accessor for the AE with the 6 extra operations (1 extra type-def).

    I don't agree with sharing inputs for methods.

    Yes, it may appear advantageous to share them initially - especially if a module starts off small.

    But it violates encapsulation (and I aside for that I find it confusing).

    What if we have to change the inputs for Method 1 in the future - how do we know that it won't affect any other methods?

    We don't. If each method has it's own input/output cluster then we can confidently make changes to that method.

    We do not need to worry about this with the DVR-IPE implementation.

    In the example you are referring to, this is your method's interface:

    post-10325-0-26709900-1325147969.png

    In order to reuse your states you have created an input Enum that is a subset of your module's Command Enum - now they are coupled to each other.

    A change will mean you will need to make a change in two places.

    post-15232-0-49717500-1325138229_thumb.png

    Now this method interface can still be replicated using a DVR-IPE - and I think it's cleaner/more-robust (just throw in the paths):

    post-10325-0-79745200-1325148425_thumb.p

  10. (great documentation post, want to write my websocket help files :P ).

    Thanks! And no ;)

    The thing is though, they are not a fair comparison. and this is why......In the second example a DVR is used purely because it is the only way for you to create a singleton (maybe I'm still hung up on classes but you wouldn't be able to unbundle so easily without it). Secondly (and more importantly) it allows you to un-type the inputs and outputs to one generic type.

    It does not have to be a class, here I changed it to a cluster and updated the DVR refnum and the rest of the code stays the same (in that example).

    post-10325-0-31051800-1325124983_thumb.p

    post-10325-0-50838100-1325124985_thumb.p

    I've attached an "equivalent" classic AE of your 2009 API based on a method I've used in the past (My apologies to John, I think I now understand what he was getting at with variants-without using a poly wrapper, that is). There is very little difference apart from the features that I have outlined previously. Arguably potato, potAto as to variants vs DVRs. But the (major) effect is to push the typing down into the AE thereby making the accessors simpler than equivelent DVR methods (and if those god-dammed variants didn't need to be cast, you wouldn't need the conversion back at all!)

    Ok, so now you have a wrapper methods and you have created a robust API IMHO - I like this API think it is robust like the DVR and the AE I posted e.g. you could change the implementation of underlying code (from DVR/Variant/AE) and it would not affect the API or end user.

    However, I would disagree that it less work than the DVR module I posted:

    So the example I posted (and you modified) is quite simple.

    How are you going to handle multiple inputs for a method?

    E.g. each method has 2 or more inputs.

    For your implementation (variant) I see two options (there may be others?)

    1. More Variant inputs on the CP of the AE
    2. Or the interface to the AE stays the same and you create a typedef Cluster of the inputs for that method and convert them back on the other side.

    In (1) more variant inputs could get messy fast and hard to manage in the AE?

    In (2) creating a Cluster means that you are going to have the exact same issues I have highlighted in terms of boiler plate code.

    So the typing issues has to do with the inputs/outputs to the AE not the state (persistent) data of the either module.

    The DVR is the state (albeit a reference to the state - accessed safely using the IPE)

    The DVR method inputs/outputs do not need to be isolated/grouped/protected etc... as there is only a single VI that will use them.

    In order to handle multiple inputs I don't have to do anything special, thus this makes the DVR less coding.

    So back to the case in point. I think that the example I have provided is a fairer comparison between the super simple 2009 API and a classic AE. Which is more robust? I don't think there is a difference personally. Which is less coding? Again. I don't think there is much in it except to point out that changes are concentrated into the 1 VI (AE) in the classic method. You could argue that to extend the classic AE you have to add a case and an accessor rather than just an accessor, but you don't actually need accessors in the AE (and they are trivial anyway since they are there just revert to type).

    IMHO the classic AE is not as robust, I have already addressed the following as to why I think it is not and why it should be wrapped to provide a more robust API to the end user:

    The first thing that come to mind from looking at it is that when I go to select a method I do not know which data I should set without opening the block diagram and looking at the code.

    This is a simple example, but what happens when the code is more complex?

    What if there 2-3 inputs are needed for each method and there was 5 methods?

    What if some inputs are required and some are optional - how do you specify that?

    It's going to get harder to figure out what is going on for the end user.

    Once you run out of room for inputs/ouputs then you will need to use clusters - exposing this data (clusters, enum) leads to higher coupling.

    Additionally the Command Enum should be private/hidden as e.g. this will not allow user to run private methods.

    <edit>

    For discussion here are some images of the Variant implementations when I had to increase the number of inputs to a method:

    1. More Variant CP inputs:

    post-10325-0-17919800-1325127402_thumb.p

    post-10325-0-76365500-1325127404_thumb.p

    2. Switch over to a cluster:

    post-10325-0-45276000-1325127409_thumb.p

    post-10325-0-35086800-1325127413_thumb.p

  11. There are times when I switch to a new approach and leave the old one while I test the new implementation, but I'll usually delete the structure when I'm done.

    Yes, I use the disable structure for testing too (as you mentioned because it's easy to switch back if needed).

    But I have not used it to facilitate discussing/commenting code.

  12. My instinct in this case would be to put a Diagram Disable structure down and put the other version that I had tried in the Disabled frame -- then I don't have to describe what I tried, people can look at it.
    It is also a best practice IMHO to include the previous attempts at resolving the requirements using the diagram disable structure.

    I have never seen (or thought of doing) this before reading it here.

    Do any other developers do this?

  13. I am with Shaun here. What magic ingredient are we missing that allows the DVR method to not have to have individual wrapper VIs for all "actions"?

    Edit: should have refreshed my browser, looking at your new example now

    Jon,

    I still don't think your examples are the same. Surely for consistency your Singleton methods should have typedef inputs as well? If you do this you get a very similar number of files for both architectures.

    No, the LV2009 Singleton methods do not need typedef inputs.

    In the AE each method should access it's own data - it unbundles it's own inputs and in bundles up it's own outputs. The cluster helps enforce this which leads to more robust code. Additionally it standardises the API (i.e. CP) to the AE main VI.

    In the LV2009 Singleton example I don't need to worry about any of that as each method is a VI so it only uses those inputs/outputs.

    That is why I consider the examples the same.

  14. Hmmm. It seems you have picked a rather "special" action engine to demonstrate. I'd even go so far as to saying it's not one at all.

    Why? In terms of the module (as a whole) it's core is an AE, with the those AE methods wrapped.

    So to me it's an AE/FGV/MFVI/VIG etc...

    Perhaps if you could put it in context with something simple (I like simple) and I'm more familiar with (e.g a list) I might be able to see the benefit. A list will have things like Add, Remove, Insert, Get Value etc. At it's heart will be an array of something. It will basically wrap the array functions so that you have the operations exposed from a single VI. There are two inputs (a value to do the operation on and an index if required for the operation) and one output.

    With this AE, how is the DVR method more robust, simpler, less coding et al?

    As mentioned above I do not think this implementation is robust (I am assuming the the Enum is not a type def for ease of posting).

    The first thing that come to mind from looking at it is that when I go to select a method I do not know which data I should set without opening the block diagram and looking at the code.

    This is a simple example, but what happens when the code is more complex?

    What if there 2-3 inputs are needed for each method and there was 5 methods?

    What if some inputs are required and some are optional - how do you specify that?

    It's going to get harder to figure out what is going on for the end user.

    Once you run out of room for inputs/ouputs then you will need to use clusters - exposing this data (clusters, enum) leads to higher coupling.

    Therefore by wrapping the AE I can provide a more robust API for the end user.

    And if I was to go this route I would prefer to implement it with the DVR-IPE as it's less coding for me.

    Don't get me wrong, writing AE as you have is valid, lightweight and works - I just think it can be more robust.

    Here is an example - unlike yours, it just some BS functions, but it demonstrates the framework:

    Each module has the exact same API - and that API is robust IHMO.

    post-10325-0-18974400-1325072480_thumb.p

    The DVR-IPE is more lightweight it terms of number of files and coding.

    post-10325-0-28300700-1325072482.png

    I am not saying this is the only way to make an AE more robust and I always like seeing different implementations.

    If you check out LabVIEW For Everyone 3rd Ed pg 910-912 they show a similar implementation but the main points about encapsulation are the same:

    • Each method bundles/unbundles has it's own input and output cluster respectively and
    • The enum command is wrapped by the method

    However, they pass each cluster as a connection on the CP where I prefer to use a super-cluster and one in and one out connection and I like to use some real estate to pass the input into the state data, but this is all programming-preferences/style and has nothing to do with the point I am trying making about robustness :)

    Robust AE.zip

    Code is in LabVIEW 2009

×
×
  • Create New...

Important Information

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