Jump to content

ShaunR

Members
  • Posts

    4,871
  • Joined

  • Days Won

    296

Posts posted by ShaunR

  1. I don't fully understand what you are saying but am curious.  I have used event call backs on .net DLL calls so I am passingly familiar with them but I don't know how they could help simplify my code.

     

    So when the mouse enters my panel VI I can have that run a VI through the callback feature, which can generate a user event, that tells the parent this event has happened?  I don't see how that is better then at the moment where the VI ref can be passed to the parent, then register for the mouse enter event, causing the event to be handled in the parent when the mouse enters the panel.

     

    Don't take this post as me saying "This is stupid and my way is better" I just don't fully understand how it can help because I've had very little experience with event callbacks.

     

    It does run the VI, but the VI is attached, externally, (for want of a better explanation), so you do not need any code whatsoever in the child to get it's events and the top level VI doesn't co-opt the childs events (the child can behave as as a discrete module-handle its own events and broadcast them when actioned to the parent).

     

    I'm also not saying it is better. It's just a technique I have found that keeps responsibilities modularised and the parent clean of module specific event handling.

  2. Had a chance to look more closely now.

     

    You can save yourself having to load "special" VIs that take a custom event via controls or detecting mouse over/move events on the child FP (checking mouse coordinates in region etc in the main VI) by attaching a callback to the VI when you load it. The callback can be attached to any VI to piggy-back the child VIs events and inject your own user event that you can access in your main VI. You can attach these call backs to not only the VI server events (close, mousemove, resize et. al.), but controls/indicators as well. I think it would greatly simplify you main VI.

     

    mdiCB.png

     

    mdi.png

     

    mdiExample.png

  3. Your code already has this problem with tabs - what if someone wants more than 20 pages?  But since Tab Controls are Enums, I don't think there'll ever be the facility to add pages at run-time.

     

    If you use the OS tab control via activex or .NET. you can add/remove pages dynamically.

  4. There are many use cases that the new JSON primitives miss. There are a few that they hit, and those few are home runs. Essentially, if the same code base that does the serialization is the same code base that does the deserialization -- i.e., they are chunks of code that rev in lockstep and where there's an agreed schema between the parties -- the prims are great. Step outside that box and you may find that making multiple "attempt to parse this" calls into the JSON prims is more expensive than getting some VIs somewhere and doing the parsing yourself. That was my experience, anyway.

     

    For those who are familiar with my ongoing character lineator project (which released a new version on Monday of NIWeek), the new prims are useless for me. I still have to do my own parsing of the JSON in order to handle all the data mutation cases that serialization requires.

     

    I wouldn't say "many", probably just two - the "string" anality and you can't wire an object to it. The former is trivial to resolve and based on a whim. If it did not behave in this fashion, it would be great for 99% of cases. The latter? (1%) I expect extremely difficult and was probably flagged as "too much hassle", but it would have had far reaching positive implications for networked transfers and possibly dynamic instantiation of objects.

  5. Before I could program the same functionality in LVOOP as I do nowadays in an AE, would require me quite a bit more than weeks. And I still would have to do a lot of LVOOP before I would have found what to do and what to avoid.

     

    Naah. It's just splitting the frames into separate VIs.

     

    There is no real practical difference between a class and an AE apart from code bloat :) In fact, many people put classes into polymorphic VIs so they can get back to a single VI (ala an AE ) once they've split out all the functions. If it's warranted, I usually just cut out the middle-man and create the polymorphic VI with a LV2global which solves the many conpane connection problem and gives adapt-to-type as well as a nice selector instead of an enum (and avoiding some of the nasty side effects of adding items to enums).

     

    Slightly off-topic. But I've noticed a preference of combo-boxes as selectors instead of enums in LV2013.

  6. Have you looked at the 2012 QMH project template?  Would you consider the Initialize, Initialize Data, and Initialize Panel messages interdependent?  If so, then is that template not, in fact, a QMH?

    Just looked now. There are only two frames. Exit and "No Event", Default.

     

     

    What do you call a module that does have state (behavioral or data,) but does not have interdependencies between the frames?  It doesn't fit into your QMH or QSM definition.

    Well. I'm going to shift/clarify my position, just slightly, although I maintain all I have said is correct. The QSM is as described and the other example is a QMH, but the QMH example doesn't define a QMH, but it a more common one.

    As I said on another thread. A QMH just means it's a buffered message handler (buffered by a queue, shift register, lemons). How it is handled or how it is buffered is irrelevant. It is a genericism that has buffered messages and are handled by some code.

    So the QSM is a QMH with specific characteristics that make it behave as a state machine and I have tried to define what those differences are in comparison to a non state machine QMH.

  7. Rather than argue the difference between a queued message handler (built from from loop) and a message-handling loop (sitting behind a queue), would it be better to focus on the difference between a message queue with only a single enqueuing process, versus one with multiple writers in parallel that could lead to race conditions?

    Indeed. In the sense of an ordered list of messages and "how" it is realised (queue primitive or while loop with shift register) is, IMO, irrelevant (thanks for spelling out MHL->Message Handling Loop. Maybe I can make up the acronym OLOM :D Lets see if it catches on ;) )

    A message handler, handles messages. Period. A queued message handler buffers the messages before it handles them. That's really all there is to it.

  8. OK. Here's how I see it, for my sins (it's rather similar to FGV and AE).

    A queued message handler is a collection of frames that are basically an API of discrete functions driven by an ordered list of incoming messages. There are no inter dependencies between the frames and they can be called in any order at any time. You are sort of right in your thinking out loud, in that they generally do not have shift registers but that isn't a defining feature since it may have shift registers to maintain the state of that individual function/frame (lets say a counter). But that state is not used by any other frames and is not propagated. The module, as a whole, does not have any state. Any frame, at any time can be executed without regard to previous calls or calls to other frames.

    An example of this definition would be something like a Drive controller. It has moveTo, Stop, Reset, getPosition etc. The "state" of the drive would be maintained by an external module (usually a sequence engine) which would call the methods in the right order and at the right times. The drive state is maintained external to the module - it is just a collection of functions. There are very good reasons for doing this, most notably, that the sequence engine knows of other dependent states of the system so you don't do something like drive a ream into the bed when no part is present. Externalising the state in this case helps you decrease application specific functionality of the module and reduce module interdependence.

    A QSM is also a collection of frames driven by an ordered list, but they are interdependent and must be called in various orders depending of the internal state of the module. Additioanlly, the frames may add messages that were not on the original list. As said before. I use the reading of file as a trivial example as I've seen it many times and think "what a lot of code to achieve very little" :D There, you may have open, read, write and close frames, but the API interface is ReadFile/WriteFile. When actioned, each frame is called in the correct order dictated by the internal decisions about the state of the file. It is no longer just a collection of functions, it has interdependent frames and maintains internal state (of the file whilst executing).

  9. I disagree.  Here's how I differentiate between them.

     

    Normal Global - A data storage container.

    Functional Global - A data storage container with get/set methods, allowing the developer to check data validity prior to getting or setting the value.

    Action Engine - A functional global that adds methods--other than get/set--to operate on the data.  Essentially when a third method is added to a FG it becomes an AE.

     

    Well. There is no real difference between FGV and AE from your definition apart from an arbitrary break point to try and make a differentiation.. They both have methods. They both enforce interaction to the internal memory only via those methods  and they both only operate on the data supplied externally to their terminals. It's a bit like saying there is a special name for a class that only has methods and no properties-it's still a class.

     

    What about a self incrementing counter that gives you the next value when it is called? That only has a Get method-what is that under your definition?

     

    If you really wanted to make a differentiation so as to define a FGV as something different from an AE,, Then you could argue that a FGV does not contain state (only functions and its output is predictable and constant given the inputs), whereas an action engine does contain state and it's output is dependent on the internal state. Under this definition, the Get/Set would be a FGV and the self incrementing counter would be an AE. But I think the number of methods is a bit weak

  10. I asked Steven Mercer during his presentation what the difference between a FGV and AE were.  He stated that a FGV was a LV2 global with just a Get and a Set case.  Still trying to figure out how much of that statement I agree with.  But this is something I really wish we all can agree on because I don't like how we mix FGV, AE, and LV2Global all the time.  There really should be a distinction.

    Agreed. I don't think there is a difference apart from terminology. The get/set FGV is just a problematic corner case AE. I equate AEs with singleton classes rather than global variables and that a LV2Global is the protected storage of an AE just as the private cluster is in a class.

  11. Thanks for the responses so far.

     

     

    I wouldn't call "the semantics between an Actor and QMH" a heated topic.  I can get... energetic... when I'm trying to explain the difference to people, but I don't get angry about it.

     

    The reason I talk about the differences between a QMH and an Actor is to try and show it's not just semantics--there are huge differences in how external entities interact with a QMH compared to how they interact with an Actor.  Your comment indicates I didn't do a good enough job communicating that message.  Either I didn't explain it well enough or you have a different idea about what a QMH *is* than I do.

    I didn't attend. But I watched the vid.

    The QMH was confusing to me. I don't see any difference personally between an actor "Do" and QMH as I don't think there is one and it seemed that you were not really convinced there was one either I do however see a huge difference between Actors,QMH and Queued State Machines (and you mentioned the JKI QSM as in reference to QMHs) and in that context I agree with many of the things you often espouse. The usual example I give for QSMs is reading a file, since it is a lot of code and a lot of messages all to do something that can be done in a single simple VI and there is little benefit in splitting out the states. That VI would then be put in a QMH or Actor.

    In terms of presentation skills. The only thought I had was something I was taught which is that it's not productive to read verbatim what is on the slides. The audience will do that. It only eats time and doesn't purvey any more information.

     

    ........later....

    Nope. I do know the difference between a QMH and Actor and I don't think it's semantics. QMHs don't contain state and the state is driven by the producer. If they do maintain state, then they are QSMs (QSMs and Actors being subsets of QMHs). So an Actor can be the same as a QSM if it does not manage it's state (unusual) but a comparison between Actors and QSMs would have been clearer.

  12. I believe this issue was raised in the beta, and the NI response was something along the lines of "Meh..."

     

    Pretty much my response when I found out it behaved like this.

     

    The mutability of types in ECMA/javascript always made me wonder how reliably one can interact with strict-typed languages. I suppose to use the built in version you need to enforce a stricter version of the JSON schema you'll be reading in that includes types. My guess is this limitation is also a good part of why it's so fast.

     

    When converting between dynamic and strict typed languages, I suppose it's expected that there needs to be an extra burden somewhere to enforce types. It's unfortunate though that LabVIEW leaves this burden to the writer's side. Of course what happens if you don't have control over the source of the JSON? Do you honestly think MtGox has a specification that prince_int and amount_int are to be serialized as strings? Who's to say, though it seems rather unlikely. What happens if one day price_int suddenly comes in as an integer but amount_int remains a string? Need another work around.

     

    I'd argue that unless you have direct control over the source of the JSON, or unless there is a schema or documentation defining types (and obviously structure) within that JSON, then the native API shouldn't be used. Shame, because it is really nice. Really, it's nothing new-- serialized data is only useful if you know how to read it.

     

    Indeed. Although I don't think the decision has anything to do with speed, That comes from the fact it is compiled rather than labview code. It's just an unnecessary  literal interpretation of "string" that hobbles the API. You see this kind of thing quite often when designed purely from spec without use cases. There is no advantages to this behaviour apart from specmanship, but there are serious disadvantages IMHO

     

    The frustrating thing for me (as I think I said to AQ when he was talking about his serializer) is that it is probably the one feature in LV2013 that would make me consider switching from LV2009, They've fixed a few of other things I wasn't happy with 2010 onwards that made me completely resistive to upgrading and the JSON Vis were just the sort of feature upgrade I have been waiting for all these years. So as excited as I was to see these in the palettes, I think I will stay with 2009 and use the 3rd party libraries as it is a lot cleaner, more compact and vastly safer.

  13. Very pleased to see the New JSON Encode and Decode in the palettes of LabVIEW 2013. I've looked at using them instead of the various libraries out there and I'm in two minds whether I will convert my current apps or use them in the future instead of those 3rd party libraries now I have had a chance to play..

     

    Let's start off by saying they work great :worshippy: They are orders of magnitude faster than 3rd party ones and they adhere vehemently to the JSON standard. It's the last bit I'm in two minds about.

     

    JSON is subset of Javascript (EMACS). Javascript is dynamically typed, which means that any variable can hold any type and although a string may have quotes around it, it does not preclude inserting it into, or operating on as a numeric type. Whilst the JSON spec does specify that string types be encased in quotes, Javascript (and PHP, for that matter) programmers don't really care and it doesn't break their code if they are present or not. Therefore it is very common to see quotes around numerics and even quotes left off of strings and most parsers will cope with this.

     

    LabVIEW is strictly typed and when the JSON Decode encounters quotes, it will error if you have defined the field as, say, a double. and then will not process any further fields. This is a right, royal pain! It also misses a trick that would make our lives so much easier and our code much simpler.

     

    Take, for example, the following real JSON stream from MTGox.

     

     

    {    "channel":"dbf1dee9-4f2e-4a08-8cb7-748919a71b21",    "channel_name":"trade.BTC",    "op":"private",    "origin":"broadcast",    "private":"trade",    "trade":{                   "type":"trade",                   "date":1376196221,                   "amount":0.3333,                   "price":102.95507,                   "tid":"1376196221462784"                  ,"amount_int":"33330000",                   "price_int":"10295507",                   "item":"BTC",                   "price_currency":"USD",                   "trade_type":"ask",                   "primary":"Y",                   "properties":"limit"                }}

     

    The "price_int"," amount_int" are encased in quotes when quite clearly they are integers and, more importantly, we need to manipulate them as integers. This forces the use of cluster elements that are strings and then to convert those fields to the appropriate type. It is compounded further since the structure is nested which means we have to unbundle all of the elements and then re-bundle to our desired types as we cannot use a single cluster definition. Additionally, the "date" is a numeric of the correct type, but that is not very useful in this scenario since it will need to be converted to a string. So defining that field in the decoding cluster as a string would have been a bonus. .

     

     

    This is the conversion using the native JSON decode.vi.

     

    JSON1.png

     

     

    This is using the JSON API available in the CR.

     

    JSON2.png

     

    The JSON API in the CR is much more forgiving in that the cluster, alone, decides on the type. So type conversion can be done transparently by defining the cluster regardless if a value is quoted or not. This yields a much simple, easier to maintain VI and, should the server generating the JSON decide to strictly adhere to removing quotes from integers; it will not break our code as it would with the native VIs.

     

    The native JSON decode has a "strict validation" boolean that states

     

    strict validation determines whether LabVIEW returns an error when the JSON object contains items not defined in the input cluster. If strict validation is FALSE, JSON objects may contain items not defined in the cluster.

     

     

    It would be useful if this boolean also disabled type checking of quoted strings. It would also be useful if it didn't stop at the first field it couldn't interpret and tried harder to continue. I could live without the latter, but not sure I can without the former - hence my ambivalence.

     

    Did I mention how fast the native VIs are?  :worshippy:

  14. New - Event Inspector Window (you're gonna love this!)

    - Never had a need for this, but it may come in handy if you don't know what events you are firing ;).


    New - High Priority events

    - Don't have a use case at the moment. But I can see edge cases where it may be useful.


    New - Flush Event Queue Function

    - I've always considered flooding event queues as bad and lazy programming, so I think this will just let bad and lazy programmers off the hook.


    New - VI Scripting methods and properties for events

    - Good for tool-chain developers. But no real use case for me.


    Improvements to the Edit Events Dialog:

    - Didn't notice :D Will look again

     

    You forget the big one - MOUSE WHEEL :worshippy: . By far the most useful, just a shame it's the only one.

    • Like 2
  15. Also, is there a mechanism for sending an event to the service so it can stop gracefully?

    I'm having problems caused by not closing the VISA session for my serial ports when calling 'net stop', if an event could be passed I could close the port properly.

     

    There's a setting in the labview options under environment that should sort that out (it puts cleanupVisa=True in the ini file).

     

    Automatically close VISA sessions—Automatically closes VISA sessions left open by the application when the top-level VI becomes idle. This checkbox does not contain a checkmark by default.

  16. I have something in mind - There are three flurbs, each with a few pages worth of code, all in the same VI (they're actually called in sequence). The flurbs are similar, so the code for them is similar, but the code has many constants which are different for each flurb, as well as some actual differences in code, some of which are quite significant (to the degree of "the first half of the flurb is similar, but the second half has mutated and now has four arms"). For ease of coding, understanding and debugging, the code for the flurbs is duplicated rather than handled using other means, but that means that every change which affects all of them has to be made to all of them separately.

     

    Is that the kind of thing you were thinking of? I'm curious as to what mechanisms NI has in mind which can help with such code.

    I'll have a quart of what you are drinking  :yes:

    • Like 1
  17. Don't get me wrong, I can't wait to try it out and see what other features 2013 is going to have.

     

    So generally LabVIEW releases are hit and miss.  They will have a stability build, then a feature build, where the feature build will be great but usually rough around the edges.  Since having a service pack mid-way through the year this seems to make sure all released versions are solid.  For this reason I have no fear about using a SP1 version of LabVIEW.  But I am still apprehensive about switching to a new version before this SP1.  

     

    This could probably be made into a new topic, but do you believe you will switch to 2013 as soon as possible?  Or are you going to wait a bit and test the waters before diving in?  The idea of using new awesome stuff both frightens and excites me.  My colleges usually wait until SP1 because it lines up with the Veristand release so if I did go 2013 I would be the one finding all the issues first.

     

    Let John find all the issues :D then switch when you start a new project (if it is after SP1). By all means "play" but as far as real projects are concerned; you are spot on with your current regime IMHO

     

    It's all very well "embracing change" but changing/upgrading tool chains is a huge project risk and there have to be specific, justifiable benefits. Unfortunately, I have not seen any practical benefits of note after LV 2009 for my projects. Lets see if that changes with LV 2013.

×
×
  • Create New...

Important Information

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