Ah, from the debug dialog. Never really paid attention to that variable indeed, i totally forgot about it. But flow_name is holding the currently executing flow's name, nothing more. If i execute twice, in parallel, the same flow, flow_name will be the same for both instances. It's not holding any data about which flow triggered it, how many instances are running and so how to act on a particular instance (eg. stop only the instance triggered by "Flow B", even though "Flow A" also triggered that same instance). The same for "trigger" variable, it holds some data about what was the initial trigger but no flow names or data related to running instances..
So, unfortunately, not what i would like to achieve
Calling a flow with arguments/parameters
Moderator: Martin
Re: Calling a flow with arguments/parameters
You can manually assign a variable before executing other flow.
e.g
1) Flow B executes,
2) saves flow_name to other Variable calling_flow_name
3) now Flow B executes Flow X.
So now instance of Flow X called by Flow B will contain calling_flow_name
Flow X will check Global Variable everytime it loops for if any instance which matches calling_flow_name need to stop.
Global Variable will be assigned by other Flow A.
============================
Well its upto you if you want to wait for Martin to add that feature or use workaround.
e.g
1) Flow B executes,
2) saves flow_name to other Variable calling_flow_name
3) now Flow B executes Flow X.
So now instance of Flow X called by Flow B will contain calling_flow_name
Flow X will check Global Variable everytime it loops for if any instance which matches calling_flow_name need to stop.
Global Variable will be assigned by other Flow A.
============================
Well its upto you if you want to wait for Martin to add that feature or use workaround.
-
- Posts: 69
- Joined: 14 Feb 2019 15:04
Re: Calling a flow with arguments/parameters
You don't have accurate control like this...
You have to check conditions (probably read a list) after each command (-> delays, small, but delays), if the timing is crucial, and you don't want to wait for some timeouts, a list which has to be constantly updated/cleaned up/maintained, and so on...
Although it is a workaround which might work, it's too big of a headache. The whole idea is to have easy control over multiple running instances of the same flow, lower the memory footprint if you choose to pass arguments to that particular instance of the called flow, and speed up the entire process.
Anyway, thank you for your input
You have to check conditions (probably read a list) after each command (-> delays, small, but delays), if the timing is crucial, and you don't want to wait for some timeouts, a list which has to be constantly updated/cleaned up/maintained, and so on...
Although it is a workaround which might work, it's too big of a headache. The whole idea is to have easy control over multiple running instances of the same flow, lower the memory footprint if you choose to pass arguments to that particular instance of the called flow, and speed up the entire process.
Anyway, thank you for your input
Re: Calling a flow with arguments/parameters
What I see, also based on your previous similar thread about widget; you have a flow function F, which contains some routines and can be called with certain parameter and do certain task based on the parameters. Then you have another flows A, B, C to call this flow function. When A call flow F, it started its instance of AF, B become BF and C become CF. Now in any part of other flow, you want to stop let say AF, while BF is running. You can't use stop flow, since it will stop both AF and BF when they are running at the same time.
There are 2 ways I thought about to solve this.
1. Same as both of you have thought about. Create a stopping glovar map to store the checkpoint of each execution. When A call F, before execute flows, store the flow name and create a glovar map in script
In between each of the element of flow function, add expression
This will always return true if nothing change the value. If you need to stop that instance, set the global_function[calling_flow_name] to false, and that instance is stopped (evaluate to false and do nothing afterward). The downside is, the function flow now check so many times to the glovar and slowdown the running process. Flow become twice the size, because added with expression in each element. And when stopped, it won't stopped realtime.
2. Create several copy of the function flow acting as buffers. So you will have F1, F2, F3, F4, .... Create as many as possible multithreading you need.
Use a glovar map as the buffer mapping. When A execute F, it will check first if the glovar map is empty. If there is/are buffer flow being used (example F1 and F3), it will use the next available buffer flow (F2 or F4). The script will create glovar map for the flow name and the buffer it use
Next execution will use "F4" (because F1 and F3 were used alread) and so on. Basically each execution will map the flow name to the buffer function flow it use. In each of the flow function, after the execution finish, it will remove the glovar
So it means the buffer is released and ready to be used again.
To stop the flow, simply stop global_function[calling_flow_name], this will evaluate to F1 or F2 or F3, ... depends on which caller flow instance you want to stop. This way, you have perfect control on each function flow instance. But using this method, you still can't control the same call from the same flow A, as the flow_name is the same. You probably need to add another tag, example the timestamp tagged to it. But this will complicate so much, better design it properly so your caller flow won't execute function flow twice.
Downside of these method, you have to create several copy of the flow. But this is better than method one, which sacrifice the runtime. I better have more flows footprint, rather than have slower execution. Beside that, method 2 also stop the flows realtime, not waiting until the next expression check. Per flow size is not inflated by the expression. But you have to copy the flow and rename them everytime you made some changes. You probably can create a export/import method flow to copy the F1 to be reimported back as F2, F3, F4. So you can change only F1 and execute another helper flow to copy it to F2, F3, F4.
There are 2 ways I thought about to solve this.
1. Same as both of you have thought about. Create a stopping glovar map to store the checkpoint of each execution. When A call F, before execute flows, store the flow name and create a glovar map in script
Code: Select all
calling_flow_name = flow_name;
global_function[calling_flow_name] = true;
Code: Select all
global_function[calling_flow_name]
2. Create several copy of the function flow acting as buffers. So you will have F1, F2, F3, F4, .... Create as many as possible multithreading you need.
Use a glovar map as the buffer mapping. When A execute F, it will check first if the glovar map is empty. If there is/are buffer flow being used (example F1 and F3), it will use the next available buffer flow (F2 or F4). The script will create glovar map for the flow name and the buffer it use
Code: Select all
calling_flow_name = flow_name;
global_function[calling_flow_name] = "F2";
Code: Select all
removeMapEntry(global_function[calling_flow_name]);
To stop the flow, simply stop global_function[calling_flow_name], this will evaluate to F1 or F2 or F3, ... depends on which caller flow instance you want to stop. This way, you have perfect control on each function flow instance. But using this method, you still can't control the same call from the same flow A, as the flow_name is the same. You probably need to add another tag, example the timestamp tagged to it. But this will complicate so much, better design it properly so your caller flow won't execute function flow twice.
Downside of these method, you have to create several copy of the flow. But this is better than method one, which sacrifice the runtime. I better have more flows footprint, rather than have slower execution. Beside that, method 2 also stop the flows realtime, not waiting until the next expression check. Per flow size is not inflated by the expression. But you have to copy the flow and rename them everytime you made some changes. You probably can create a export/import method flow to copy the F1 to be reimported back as F2, F3, F4. So you can change only F1 and execute another helper flow to copy it to F2, F3, F4.
Index of Automagic useful thread List of my other useful posts (and others')
Xiaomi Redmi Note 5 (whyred), AOSP Extended v6.7 build 20200310 Official, Android Pie 9.0, Rooted.
Xiaomi Redmi Note 5 (whyred), AOSP Extended v6.7 build 20200310 Official, Android Pie 9.0, Rooted.
-
- Posts: 69
- Joined: 14 Feb 2019 15:04
Re: Calling a flow with arguments/parameters
Yes, both methods will probably work.
But it would be so much simpler to just call a flow with parameters, pass just the necessary data as arguments, including an ID of some sorts, or maybe set a variable by default (which obviously would be used to act upon a certain/specific instance of a flow, like global_[called_flow]_[calling_flow]), or even dynamically change some values (why not), as the flow executes, once you can identify its instance.
I don't think I'll implement anything anymore regarding this, as both methods are workarounds, and I like straight forward stuff, accurate and efficient, by design (although not always reflected in my shared flows, as i modified some of them to be easier to understand and modified if necessary). It's how AM usually is, one reason i enjoy it so much.
But i think that if Martin will consider adding these features to AM and flows, he will make more advanced users very happy, as it opens up different roads.
I can live without these features of course, it's just that i'm missing them.
Thank you both for your extensive input, i really appreciate the effort. I'm happy to be a little part of this great community!
But it would be so much simpler to just call a flow with parameters, pass just the necessary data as arguments, including an ID of some sorts, or maybe set a variable by default (which obviously would be used to act upon a certain/specific instance of a flow, like global_[called_flow]_[calling_flow]), or even dynamically change some values (why not), as the flow executes, once you can identify its instance.
I don't think I'll implement anything anymore regarding this, as both methods are workarounds, and I like straight forward stuff, accurate and efficient, by design (although not always reflected in my shared flows, as i modified some of them to be easier to understand and modified if necessary). It's how AM usually is, one reason i enjoy it so much.
But i think that if Martin will consider adding these features to AM and flows, he will make more advanced users very happy, as it opens up different roads.
I can live without these features of course, it's just that i'm missing them.
Thank you both for your extensive input, i really appreciate the effort. I'm happy to be a little part of this great community!