Jump to content

Thoric

Members
  • Posts

    155
  • Joined

  • Last visited

  • Days Won

    3

Posts posted by Thoric

  1. 11 minutes ago, drjdpowell said:

    I am considering changing the LabVIEW version I develop Messenger Library in from 2011 to either 2013 or 2015.  Does this cause a problem for anybody?  Older versions would still be available through LAVA-CR.

    Not for me, I develop in 2014/15 so preferably keep it in 2013 if you can. What's the reason for the upgrade, there a particular feature you want to adopt that's not available in 2011? Or are you simply abandoning older LV installs on your dev machine ;-)

  2. Shaun is right. As a student (a long time ago) I found OpenG code very valuable and had no issues with the licensing structure. When I moved from academia to industry the terms became a problem and I justified creating my own substitute software so that I could avoid the license, but I also didn't put much effort into it so my own VIs were inferior (less well scoped/tested). As a consequence I didn't use OpenG much.

     

    Since those days I now work for a manufacturer, not a software consultancy, so I'm happy to return to using OpenG internally for my test system development. I can see how other, perhaps struggling, developers might see the opportunity to cleanse the licensing from the OpenG libraries and pass the code off as their own work to an ignorant employer. It's very shortsighted, but easy to see how they might choose to take the gamble.

     

    I've contacted the person who received the software from the outside consultancy - I'm awaiting feedback.

  3. Today I inherited some LabVIEW code created by an external consultancy. Whilst reviewing the quality of the code I came across a series of subVIs which are indubitably OpenG VIs with the license information stripped out.

     

    One particular instance is a VI called "Variant to Header Info.vi" and the front panel is identical in layout and size to "Variant to Head Info__ogtk.vi" except the license text is missing. The VI icon is identical, and the VI description word for word. There's no doubt in my mind that this developer took the Open Toolkit, stripped all the licensing out, and is using the code in their own distribution without honouring the license agreement.

     

    Is this something I ought to follow up, or does this happen a lot these days?

    • Like 1
  4. Actually, option 1 is the option I implemented, but afterwards led to a dependency complication that made me wonder about alternatives (hence my post above).

     

    My current situation is now this:

    post-33316-0-42413200-1454068673.png

     

    Main launches View Main, Project and ConfigData actors.

    View dynamically launches View subactors, as and when required.

    Because the View subactors require access to the Project service, I need to pass the Project actor messaging queue to both View, and then subsequently onto each View subactor. This is first conducted by Main, then by View to each subactor.

     

    The View actor provides a menu from which the operator can select, for example, "Add Data Source to Project", which causes a message to be sent to Project actor instructing that a new data source be included in the project. The path of the new data source is part of the message, so the View actor has a little bit of code (a subVI) that requests a path from the operator, performs some checks and returns the path value.

     

    One of the View subactors also has an onscreen option to add a new data source to the project. This is where I tripped up. Currently, this subactor uses the exact same subVI as View actor. The intent was for sensible reuse, but I've created a dependency link. The View actor is now sharing a resource *(subVI) with an entirely independent subView actor, and there potentially many more examples of this in the other View subactors. This makes the plugin based solution tricky, I've lost my component cohesion. It's much neater to have each actor's dependencies distinct (zero-coupling?).

     

    So I began to wonder if the subactors shouldn't be performing any work at all, and instead be passing messages up to View and have something else conduct their activities? That would mean this particular subVI is called in only one place, probably only by View actor. But that doesn't work without creating a fair bit of coupling between actors - we lose the flexibility to add new View subactors with unique functionality.

     

    So I still agree that it makes sense to pass the Project reference down to the subView actors so that they can independently get on with their duties, but I'm not sure where to put common dependencies (subVIs called by both View actor and the View subActors).

     

    If I create a library of common VIs called by multiple View-related actors (viewcommon.lvlib) how do I best ensure this linkage is honoured when building an executable? If the View subactors are distributed as built PPLs then it will draw into the PPL a copy of viewcommon.lvlib (as well 5Mb worth of Messaging framework too!). If I distribute the subactors as pure source then I think that will work as the links are rebuilt on dynamic load within the View actor, but distributing source code isn't good for control purposes. Turning the subactors into traditional llbs doesn't work (I tried - they end up broken).

     

    Sorry for the long posts. Any thoughts?

  5. That's neat. My configuration implementation is different, in that I have a specific list of stats that I want to write and a service actor is responsible for controlling the values. Therefore updates are sent to it live (notifications) from the other actors. On exit (or on demand if needed) the actor saves to file. Your implementation which is entirely re-usable as there is no coupling whatsoever, mine not so much. I did however take the elements associated with file I/O and make a reusable lvlib out of those, so there's some reuse.

     

    Speaking a little more on Service Hierarchy. I came across a conundrum with my user interface sub-actors (think of them as A1 and A2 in your topology above). There is a pool of n sub-actors that the caller (A) loads dynamically from file when required and inserts their FP into it's own sub-panel. This is a plugin approach to allow feature extension by creating additional sub-actors without needing to touch the rest of the solution. And this is where my puzzle begins.

     

    Each sub-actor provides a unique view of the project data. Additional future subactors will provide new views and new functionality, as requirements are defined. Therefore, these sub-actors present an unknown to the caller (A). So caller A can handle messages that are common to all sub-actors, but it can't handle specific messages because it can't know what they are.

     

    So the way I see it, my options are:

     

    1. Where a sub-actor (A3) needs to cause some specific action to occur, such as asking the Project actor to add a new source object with a provided path, it will have to bypass the caller (A) and directly message the Project actor. This means providing the Project actor's messaging queue to the sub-actor. However it defeats the Service Hierarchy proposal as it allows sub-actors to bypass the preferred message paths and creates hard to debug links between actors.

     

    2. Create a generic messaging structure, probably a class hierarchy, that somehow allows caller A to receive and handle requests without knowing in advance what the content will be. This maintains the hierarchy tree and supports future messages.

     

    3. Use sophisticated Translators in A that receive all messages from the sub-actors and parse the content to interpret their intent, following a predefined syntax, and forward requests/notifications onto other actors. This maintains the hierarchy tree and supports future messages.

     

    4. Other?

     

    Any thoughts James?

  6.  

    3) Give the subUI the address of a third party (“DataSourceâ€) from which it can request the data (request directly, not by notification, synchronous or asynchronous).   Note that this address cannot be the Caller, as we are placing the subUI above DataSource in the service hierarchy (subUI is below Caller by definition).

     

    — James

     

    So this is the option I went for. It provides the subView with a reference to the service actor, placing the subView (and it's caller View actor) above the Project service actor.

     

    This seems to work well, and I'm progressing my trial project nicely. I'm learning the power of the framework as a I go, and realised a few places where using the State Notifier instead of an Event Notifier would have been better. For some reason I thought there could only be one state notification, as compared to any number of event notifications. I think maybe I misinterpreted the intent in one of your instructional videos.

     

    It would be possible for Main to pass the address of B to A in a message.   In which case, A can use B as if it were a subactor, like A1 and A2.  But this should be rarely used.   Main should never pass itself to A, or pass A and B to each other, as this makes actor subcomponents of each other, and that can lead to problems.

     

    Hmm. So does this not conflict with advise earlier to share the registration handle of B with A1, which is what I did, so that A1 can directly ask B for it's required info. This is working well for me, B is unaware of any other actor so it's at the bottom of the chain and cannot demand anything synchronously of any other component.

  7. Another question, if I may.
    I have a View actor with a subpanel. It dynamically launches child actors (that I'm calling subViews) and docks them in the subpanel. Numerous subViews exist, they can be switched using controls in the View UI. View actor registers for all notifications from the subViews, as these are often requests for information, to which it can reply.

    When a new subView actor is loaded and launched it needs to populate it's internal data, so the Self:Initialise case includes in the list of actions "Request Project Data", a case which calls a Notify Event labelled "Request Project Data". As the View actor is listening to all notifications, it replies with a copy of the latest Project data, which the subView actor receives and stores in it's private internal shift register.

    The problem I have is that it appears the View actor is failing to register for the subView's notifier event messages in time to notice this "Request Project Data" notify event. I'm wondering if a caller's request to register for notifications is processed after the child actor has completed its Initialisation cases. If that's true then I have a race condition here and I need a way to ensure the child actor doesn't send the notification message until the caller has registered itself to its notifier event messages.

     

    I suspect I'll be advised to try a different approach, such as explicitly sharing the caller's message queue so that the child actor can directly post messages to its caller. Is that better, or does it have other drawbacks?

    • Like 1
  8. Another question James, this one is more academic. I'm trying to maintain zero-coupling between my actors, and in the current situation I have two independently designed actors called View and ConfigData.

     

    ConfigData stores and retrieves the application information from file, including an array of a cluster that contains two elements: the Title (string) and Path (path) of the most recently opened Projects.

     

    View actor hosts the User Interface and customises the menu to show the four most recently opened projects, stored internally as an array of Title strings.

     

    Whenever the application opens a new Project it must inform ConfigData of the project name, and if this results in a change to the arrayed list of recent projects then the revised list must be shared with View so that it can be ready to show the latest information at all times.

     

    So, there are numerous options available for sharing the revised list between ConfigData and View, but I want to maintain zero-coupling - that is, View cannot know of the existence of ConfigData, and likewise ConfigData cannot know of the existence of View. I can use the Observer-Notification registry in ConfigData actor to push updates out, and subscribe to these in View as events. But something else needs to create this binding because these actors can't know of anything outside of their simplified existence. In steps the launching actor Main.

     

    Main launches View and also ConfigData and can establish a communications link between them such that changes in ConfigData are immediately sent out on the Observer register to subscribed View. But their datatypes are different, so they can't simply pass the information between themselves because ConfigData's cluster array isn't the same as View's string array. To maintain zero-coupling I cannot simply change one of their datatypes, so there needs to be some conversion of the data somewhere between. (Actually, it probably helps in this example to consider these two actors as something much bigger, with far more complex data payloads to share. That way the simple answer to change one to match the other cannot be recommended).

     

    I see from the Messenger Library there are Translator methods, which can cause messages between actors to be mutated, and the data payload adjusted. How do you properly use these to morph the outgoing message from ConfigData into a suitable message for View? I expect that getting Main to establish this translation link will mean both View and ConfigData remain zero-coupled, and also Main doesn't have to maintain a role in the communications whenever a message is passed, which is good for performance of Main.

     

    The key for me here is:

    1. View and ConfigData must remain zero-coupled (the ideal for any system of reusable actors)

    2. Prevent the need for the parent actor Main to be continuously aware of and monitoring the communication path, translating the payload data each time and distracting it from it's primary duties.

     

    If I understand Translate properly, it looks to me like an excellent way to establish links between zero-coupled actors without having to establish a route through a parent actor, or any other actor. But maybe there's a better/simpler way?

    • Like 1
  9. I'm experimenting with this framework, and my early impressions are that it's very powerful and flexible. In my experimentation I created a Messenger Event for registering with a sub-actor Observer registry. In the code I can give the User Event a custom label to make the Event Structure case more understandable (green highlighting in image), but I'm struggling to set a custom label for the Messenger Event, which I store in the actor internal data shift register (Blue highlighting in image). Is there a recommended approach that I'm missing? Applying a typecast always fails.

     

    post-33316-0-53819900-1452075848.jpg

    • Like 1
  10. I'm creating a utlity VI to launch from the Tools menu. When a VI is launched from here it is thrown into the unique NI.LV.Dialog application context. From here, things get tricky, because we can't immediately see the VI from which the menu item was called.

    If you call:

    Example_VI_BD.png

    then you get an application instance and a VI name to use in Open VI reference. But that doesn't seem to solve an issue I'm having.

     

    In my calling VI (from where Tools > MyUtilityVI was selected) I have front panel control with User Tag information in them. I can get a reference to this VI and use Read User Tag.vi to get to the string data I've embedded in the controls. The string data is actually a LV class flattened to XML. This is where I get a bit confused - in the utility VI I can read the XML string and place an unflatten from XML string function to typecast it back to a LV class. When I debug and run the utility VI in the dev environment (Project application instance) it works fine. But when called from the menu, and in NI.LV.Dialog app instance, I get error 1527 "Attempted to read flattened data of a LabVIEW class that is not currently loaded into LabVIEW"

     

    This is presumably because some derivative/child of the class is not in memory in the NI.LV.Dialog app instance. So how do I make sure that the entire class hierarchy is available to this application instance? Into the Unflatten XML String function I'm passing an instance of the class parent, but presumable a child or two is missing. Unfortunately the class has dozens of children, and I'm not keen on placing them all into the block diagram to ensure they're accessible to this application instance!

     

    Here I read about accessing VIs across contexts, but I don't see a solution. This opens a reference to the VI in the original instance, but the utility VI is still in NI.LV.Dialog instance so cannot access the class hierarchy.

     

    Here is a chap attempting to dynamically launch a VI into the application instance of the calling VI, but it fails. According to Stephen this is not possible, LabVIEW prevents it to keep everything in the NI.LV.Dialog context.

     

    Ultimately, my LabVIEW Project will become a tool installed into user.lib, with the utility VI in the Tools menu (project folder). It needs access to the VIs that define the toolkit, which currently are in the active Project (because I'm still developing the tool), but ultimately will be found in the user.lib folder. Will it start working once I migrate all the VIs like this?

     

  11. . I personally do not feel comfortable being a facilitator at this level without more express permission from the presenter.

     

    Totally understand, and completely agree. I've had my presentations recorded before and I think I'd be fine with them on the searchable domain (YouTube), but I know there are others who wouldn't be. Good call.

  12. I'm looking for a way to get the color of a datatype wire, i.e. as it would appear in the connector pane for an associated front panel control.

     

    A little more detail: Take a standard VI with a handful of controls and indicators wired to the connector pane. Each datatype's core wire color is shown in the associated connector pane terminal box. Can you programmatically retrieve this color for any datatype?

     

    What I've tried:

    I've looked for a "datatype" property node in the hope of extracting further information, but not sure that's helpful.

    I've played around with the Class Identifier for a control reference, but not sure what use that really is?

    I've looked for a way to grab an image of the connector pane's terminals to grab the color from the filled rectangles. I can only seem to get the VI icon with the connection text as seen in context help.

     

    Any ideas?

  13. Yair, Rolf,

     

    Thanks for the replies. I agree, the IDE has always been difficult to tap into, and this was something I wasn't truly expecting to get to work, but it was always worth asking the world's best before giving up.

    The Fake Exec state isn't going to work for me, the VI has to remain in true edit mode for what I had in mind.

     

    Back to the drawing board...

  14. Is there a way to interfere with the edit time shortcut menu of a front panel control?

     

    I want to be able to register for the Shortcut Menu Activation? filter event for the controls of a VI that's in edit mode, and inject my own menu items. I can only get this to work if the target VI is reserved for execution (running state), and not when idle.

     

    (To be clear, there are two VIs here. A running VI with an event structure that's meant to be interfering with the shortcut menus of the other's front panel controls whilst the operator is editing it. I want to be able to inject my own menu items.)

  15. If you drop a dummy object on the diagram, then delete it, without wrapping those operations in a Begin Undo/End Undo transaction, it looks like it clears the Undo history.

     

    How bizarre! Yes, that works. Dropping a simple ADD function, then deleting it, vaporizes the Undo History. Any thoughts as to why? Can LV not cope with changes that aren't wrapped in an Undo transaction?

    post-33316-0-34725100-1395936366_thumb.p

    • Like 1
  16. Changing the password erases the undo history.

     

    I can't get this to work programmatically.

     

    If I manually set a VI's protection to password-protected through the VI Properties window, then unprotect it again, I see the Undo history is emptied.

     

    However, if I programmatically invoke LockState.Set with Password-protected, then invoke LockState.Set with Not Locked, the VI undo history remains in tact.

    Inserting a Save.Instrument makes no difference either. The Undo history always persists! Any thoughts anyone?

     

    Below is a snippet of some example code that attempts to prove that password protection of a VI clears the undo history. It creates a new VI, uses a Windows API call to simulate a standard window move operation as normally performed by an operator, then sets and unsets a password to clear the undo operation but it remains intact.

     

    (I will get the snippet up here once I figure out how!)

×
×
  • Create New...

Important Information

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