LabVIEW

cancel
Showing results for 
Search instead for 
Did you mean: 

Event Callback VI with LVOOP / overhead, caveats, future

OK another exploratory post from me.  To anyone who has put up with this kind of thing from yours truly many times in the past, apologies.  Completely impervious to any objections, here goes:

 

I have discovered a new toy : Registering event callback VIs.  OK, I have used them before but a previous post by James McNally about his MVC framework revealed to me a usage which I had not previously thought of.  Thanks for that James. Smiley Happy

 

I like LVOOP.  One pattern which is quite easy to understand is the command pattern in conjunction with state machines where we essentially replace the individual states of a state machine with external VIs.  This makes it far easier to customise behaviour and allows for re-use of the core state machine for differing functionalities.  Cool.

 

We can leverage this with LVOOP by passing different "commands" to the state machine depending on the real object being utilised and thus we have a nice extensible architecture.  Again, cool.  If we need to change one common action, we simply update that VI and instantaneously all ancestors share the new code in that command object.  Double cool.

 

Problem is that I love User Events.  The idea of having an extensible object model gets awkward to handle when you start using Events to handle communications in and out of the object.  Create a Parent, Implement the 15 Events required.  Create a child, Implement the 15 Parent events and the 12 new events.  Create a Grandchild, Implement the 15 Grandparent, the 12 Parent and then the 25 new Events.  Armageddon occurs when you want to change the common functionality for the sixth Event of the Parent.  Now you need to go to each and every ancestor which uses them and update them.  Wait a second, isn't LVOOP supposed to save me from this kind of crud?  Frustration ensures.  Can you ever be sure you got all instances?  What about those obejcts not listed in the project, maybe you forgot one of them...... Nasty testing and debugging ensues.

 

I think I may have (partially) found the answer.  What we need to do is basically do the same thing we have done with the command pattern and extract the individual frames of the event structure and place them into external VIs so that we can 1) re-use the VIs in each level of hierarchy and 2) maintain all the other niceties of Events.

 

Turns out that using Callback VIs for each level of the object hierarchy can help to solve this problem.  You need to have a method with a different name for each level of the hierarchy which exposes the events int his way because each method will most likely have different input values.

 

Has anyone else done things like this?  Are there limitations as to what can and can't be done with this arrangement?  Any nasty bugbears waiting for me around the corner?  How to deal with events which should give some kind of return value?  Do I encorporate the return value into an implementation-agnostic return channel (again Events of course) with the object in question providing one return user event for each callback function which requires a return value?

 

Message 1 of 6
(3,438 Views)

I'm not really following what you're actually doing. Can you upload an example with a couple of children with a couple of events each so that we have a baseline?


___________________
Try to take over the world!
0 Kudos
Message 2 of 6
(3,402 Views)

Yes, I'll try to do that.  Even though my words might be cryptic, hopefully code will help more than it hinders.

0 Kudos
Message 3 of 6
(3,396 Views)

Grr, I was trying to attach a file (whose contents apparently didn't match the file name?!!) when I ran out of time to edit and now I lost my text.

 

Here's an example.

 

Base class swaps out a control Caption for Label upon "Mouse Enter"

Child class swaps out a control Label for Caption on "Mouse Leave"

Grandchild increments a counter (stored in Description) for every "Mouse Enter"

 

Trivial but get's at what I mean.

 

I know I can do this in other ways but

1) I don't need a parallel process

2) I'm just having fun

 

Darn, I can't attach a zip.  Rename this file to .zip and unpack.  Sorry guys.

0 Kudos
Message 4 of 6
(3,391 Views)

No, can't say that I did anything similar and at the moment I can't come up with a proper use case either. It certainly looks interesting, but I would need that to really be able to assess it.

 

Some semi-random thoughts:

  1. I haven't worked with callbacks much, but my problem with them was usually that they're running off somewhere in la-la land, so if you want them to interact with an object with some state (like an actor), they would need to send a message back. Another problem is that it's hard to understand what's going on, because you have dynamic VIs being loaded and run in the ether.
  2. I'm not sure if inheritance is the right mechanism for it, mainly because it might be an issue if you want an object to get multiple behaviors. For something like that, composition might work better.
  3. There might also be an issue with conflicting behavior. For instance, what happens if class 3 wants to do something different from class 1? It can't just avoid calling the parent, because class 2 is in the way, and because it's callbacks, there may be race conditions.

___________________
Try to take over the world!
0 Kudos
Message 5 of 6
(3,356 Views)

Thanks for taking the time to investigate my ramblings.

 

1) I often have the same feeling regarding running somewhere in la-la land with the command pattern.  While its eadier tl know where something is executing, knowing what is executing is more difficult.

2) Im not interestedin whether inheritance is the best for this example but much more whether the combination of LVOOP and callbacks offer new ways of achieving better extendable yet sstrictly-typed APIs.

3) Again, the example is a bit contrived and was all done in about 15 minutes total. The ability to do something different than a parent is retained by having the option to override individual functions.  If i design the classes so that each callback registration is in a dynamic dispatch vi, then each individual function can be overridden by any ancestor.

0 Kudos
Message 6 of 6
(3,348 Views)