Join us today!
[Solved] How to create a generic queue which works for every datatype including structs?
The queue would be a first one in, first one out (FIFO) type, much like this example from InfoSys. But then I want to have a generic implementation. The example from InfoSys works with a fixed STRUCT.
Ideally you would instantiate the struct and pass the size of the queue with it:
VAR queue : Queue(n=40) END_VAR
Then you can add and remove items and get the size of the queue as follows:
VAR position1 : Coordinate3D := (x:=3, y:=8, z:=-1); position2 : Coordinate3D := (x:=9, y:=1, z:=0); size : UINT; currentPosition : Coordinate3D; END_VAR queue.Add(position1); queue.Add(position2); size := queue.Size(); // 2 currentPosition := queue.Pop(); // (x:=3, y:=8, z:=-1) size := queue.Size(); // 1
Is this possible in TwinCAT? Making some sort of generic queue for basic types like INT, BOOLs is probably possible using T_Arg/ANY. But how would you do it if you would also include STRUCTs?
My blog: https://cookncode.com/twincat
My code: https://github.com/roald87
@rruiter (just remaking a broken post link)
This is possible. The only thing you can't do is currentPosition := queue.pop() as this would require the method having it's return type known at design time. Instead you would do queue.pop(currentPosition);
This example can be found here.
https://github.com/benhar-dev/tc3-push-pop-stack
This repo shows how you can push and pop any variable type. The queue will automatically type check on the way out and will prevent the pop if you try to pop it to the wrong variable type.
If you are going to be pushing huge numbers of things in to the queue then just keep an eye on your router memory (as that is the pool which __NEW objects are created from) and you may want to increase this if need be.
I've used this style quite a bit in a few projects. You can then make small tweaks to the code to make it a key/value pair, a dynamic array, a sorted list. Ultimately it's an object that holds objects which it looks after. 👍
My blog: codingbytes
My code: https://github.com/benhar-dev
Hi,
I have attached a generic data tracking function block (dictionary) and a program to test it. I have added one integer and one real data type into the list. Inside the Prg_Dictionary program, you need to give a key name to your generic data and use the correct argument conversion function to set your value. (F_INT(), F_REAL(), F_DINT(), F_BOOL() …)
I have used two data types for test purposes but you can use any data type you would like.
fbPartList contains the key lists and value lists as well as the list size. This is what it looks like after adding an integer and a real value.
Hope this helps! It would be great if you can share your thoughts after using it. Maybe you can get it to working with generic structures as well.
In case you want to say thank you !)
We'd be very grateful if you could share this community with your colleagues and friends. You can also buy us a coffee to keep us fueled 😊 This is the best way to say thank you to this project and support your community.
twinControls - https://twincontrols.com/
@beckhoffsupport Thanks for the reply! I like that your solution makes it easier to see how many items there are in the buffer during debugging. But, I find the solution of @benhar-dev easier to use. With T_Arg you always need the extra function (F_INT, F_REAL, etc.) to get the type information. Also Ben's solution doesn't require a global variable to fix the size of the buffer.
My blog: https://cookncode.com/twincat
My code: https://github.com/roald87
@rruiter You are welcome! Yes, @benhar-dev solution's works great and you don't have to define the list size as you said. The one I shared works as a hashmap . It's nice to be able to pop anything by using its 'key name'.
In case you want to say thank you !)
We'd be very grateful if you could share this community with your colleagues and friends. You can also buy us a coffee to keep us fueled 😊 This is the best way to say thank you to this project and support your community.
twinControls - https://twincontrols.com/
-
I cannot add a variable to the TwinCat scope project.
2 months ago
-
Twincat 3 HMI Server Graph display problem
10 months ago
-
Detecting low voltage on PLC bus
2 years ago
-
Passing a structure between PLCs via ADS using symbolic addressing
2 years ago
-
TwinCAT - using a single input link to read 18 individual bytes from an EtherCAT slave
2 years ago
- 17 Forums
- 265 Topics
- 932 Posts
- 1 Online
- 688 Members