LabVIEW

cancel
Showing results for 
Search instead for 
Did you mean: 

Queue through Object Oriented design

Solved!
Go to solution

I want to implement Queues in object oriented project.

What is the best way to do this? Where should I obtain the Queues? What is the best way to read a queue reference in different vi's? Should I contain the Queue in the class control? 

0 Kudos
Message 1 of 8
(2,991 Views)
Solution
Accepted by topic author almog.danzig

Hello Almog,

 

My LOOP with (one) Queue:

(I have expected I will have to save more queue data in class, that's why I have "Queues" cluster in class)

But you only need to save Queue reference. Everything else is in VI's.

Upper-left: Writing to queue

Lower-left: Flushing queue

Upper-right: Class

Lower-right: Reading from queue, writing to TDMS.

Jakob_Pin_1-1585603160488.png

 

BR,

Jakob

0 Kudos
Message 2 of 8
(2,963 Views)

Thanks Jacob,

 

Where do you obtain the queue in your project?

 

You then save the Queue reference into the class?

 

Thanks again,

 

Almog

0 Kudos
Message 3 of 8
(2,936 Views)
Solution
Accepted by topic author almog.danzig

Hi Almog,

 

Yes, Obtaining and Releasing is required (sorry for poor writing):

These is all basic of Queue, implemented into class.

Jakob_Pin_0-1585641250171.png

 

PS: don't get confused with that cluster on Release, like I already mentioned in prev. post, I planned to have more data and more Queues references under Queues section of the class.

 

Hope that helps.

 

BR,

Jakob

 

Message 4 of 8
(2,927 Views)

Thank you Jacob,

Almog

0 Kudos
Message 5 of 8
(2,909 Views)

@almog.danzig wrote:

I want to implement Queues in object oriented project.

What is the best way to do this? 


It's not at all clear what you mean.

 

Make your own queue replacement in a class?

Use a queue in a class?

Send a class over a queue?

 


@almog.danzig wrote:

Where should I obtain the Queues?


That depends.

 

Usually you obtain a queue when you're still able to pass the queue reference to a sender and a receiver. But you can cheat (not recommended), and pass the references in a global, functional global. Or pass it through a user event.

 


@almog.danzig wrote:

What is the best way to read a queue reference in different vi's?


Read a queue reference or read a queue element? I'm not being nit picky, that's a totally different question.

 

The reference is simply a value, that is passed like any other value.

 

If you want to dequeue elements in different VIs, and expect each VI to receive all queued values, a queue is simply the wrong solution. You probably want to look into user events. User events are many-to-many, while queues are many-to-one. Reading queues at more then one place is usually (not always) not what you want.

 


@almog.danzig wrote:

Should I contain the Queue in the class control? 


That would hide the implementation, which is exactly the point of OO. So, yes, put the queue reference in the class's private data. Initialize the queue in a class member VI, and enqueue and dequeue the elements in class member VIs. The outside world does not and should not need to know about the queue at all.

Message 6 of 8
(2,892 Views)

Thanks you Wiebe for your answer,

 

I want to transmit data and commands between instruments and vi's. I know that for non object oriented programming the a good way to do it is through queues. I have no experience in object oriented programming and I wonder what is the best way to transmit data and commands between instruments and vi's.

I guess that I am searching a way to use Q in a class or to make my own queue replacement in a class.

 

For my question: What is the best way to read a queue reference in different vi's?

I totally meant to read a queue reference (not an element). I used to do it through FGV, but maybe in OO prog. it better to do in through class controls?

 

About your last paragraph, I understand that, But I don't understand what do I do if I want to send data or commands to other class vi's. Why did you wrote that the outside world should not know about this Queue?

 

Thanks a lot,

Almog

0 Kudos
Message 7 of 8
(2,871 Views)
Solution
Accepted by topic author almog.danzig

@almog.danzig wrote:

For my question: What is the best way to read a queue reference in different vi's?

I totally meant to read a queue reference (not an element). I used to do it through FGV, but maybe in OO prog. it better to do in through class controls?


FGV are still globals. Not ideal. You run risks by using them. One is that the FGV ends up deeply nested in sub-sub-sub VIs. This can be horrible to track or comprehend.

 

If the initialize of the a object (Init.vi) obtains a queue, put in in the private data. Then, pass the class wire. You can simply pass it to the reader and writers. So the downside is that you have to wire the class to each and every VI that uses it. The upside is that each and every VI that uses it has the class as an input. This means clarity. It also means you can copy (or clone) your program, or parts of it, and you don't have to worry about the clones sharing globals. They can, if you give both clones the same input wire, but they don't have to if you don't want them to. This actually means more flexibility, and less worries.

 


@almog.danzig wrote:

About your last paragraph, I understand that, But I don't understand what do I do if I want to send data or commands to other class vi's. Why did you wrote that the outside world should not know about this Queue?


So the class should encapsulate it's solution. Ideally, a class could implement a queue without using a queue (it could use a DVR or FGV or private global, or whatever). You shouldn't expose this implementation.

 

Instead, expose the methods that use the implementation. A queue class should for instance keep the queue inside, and have a Enqueue method and a Dequeue method.

 

The class can now completely change it's implementation, and your program doesn't need any changes (as long as the class acts the same, or 'honors it's contract').

 

Now because of this encapsulation, you can even make child classes that implement the queue in different ways. One might use a queue, the other a DVR. The "Singleton Queue" child could use a private global queue reference, so you have a "singleton by wire" queue. (This child has an annotation to it's contract.) Because of polymorphism, you can actually choose which child to use, without changing your program. And almost without testing (, as long as the class is tested (and uses the class as tested)).

 

The sky is the limit really, once you have it set up like that. There could be a testing queue, where you can see or even pause\continue the queue.

 

Another thing that is interesting, is to make the queue class slightly more complex. I have done this a few times. It's limiting, which is exactly the point. So have split up queueing classes (actually buffers) in three classes. One that creates the queue, one is a reader and one that is a writer. Why on earth would I do that? Well, I can see by the wire what parts of the code write and what parts read. This can be convenient, if the code grows big enough. The reader\writer could be children of the queue class, or hey could have a 'friend' relation with it.

 

You'll find lots of examples in OO programming where you are limiting yourself. Making a method private is a limit. Making it protected as well. These limits tell a programmer a lot about the class, and these limits are just very helpful once you get them.

0 Kudos
Message 8 of 8
(2,846 Views)