User-defined Templates?

Post your feature requets for new triggers, conditions, actions and other improvements.

Moderator: Martin

98b427af

Re: User-defined Templates?

Post by 98b427af » 13 Oct 2017 15:55

Desmanto: I like the idea of subgroups vs any other way of doing it. If subgroups are going to be implemented, though, based on general coding principles there's no reason not to allow any number of subgroup levels instead of just one. Of course, I don't know the specifics of the AM code so that might not be desirable, or even possible.

Martin: Making flows able to be, in effect, subroutines with parameters would be a phenomenal addition! I've already written a whole lot of code to mimic exactly that, but the solution is necessarily clunky. In my software career, I've always avoided global variables like ex-girlfriends, and apart from the formal global variables in AM (which I really treat as file storage rather than true variables), the fact that all AM variables are global to a flow - even into other flows it executes - has caused me no end of grief. I often create what I think are "local" variables for a flow or script and then, because I've forgotten about some other variable I created months (or even years) before in that or a calling flow, I encounter name collisions that make debugging difficult. Then I get all stressed, red, and itchy and I have to have a glass of wine and hit the heavy bag for an hour. Yes, I'm quite OCD about scoping. ;)

I'm completely unconcerned about the timing of whatever implementation you choose - no quarrel whatsoever with your priorities, of course.

User avatar
Martin
Posts: 4468
Joined: 09 Nov 2012 14:23

Re: User-defined Templates?

Post by Martin » 14 Oct 2017 13:54

@Desmanto: The hypothetical inline feature would work more or less like this: you create a flow that calls another flow as a subroutine by using action 'Execute Flows'. Now you decide that the subroutine-flow needs to be adjusted for the parent flow but the subroutine-flow should stay as is since it's used also in a few other flows so you could either copy the subroutine-flow, modify the new subroutine-flow or you could select action 'Execute Flows' in the parent flow and select the new 'Inline called flows' which would then copy/paste the actions from the subroutine-flow to the parent flow.
The feature is probably not that interesting when I think about it since you already have a way to copy/paste the actions from the subroutine flow to the parent flow if you really want to do it.

@98b427af: I'm not yet sure exactly how I'm going to implement the subroutine-feature. Maybe I will just extend action 'Execute Flows' with a few more options that allows to define what variables should be passed to the subflow and probably the names of the variables the subflow should get the input variables. 'Execute Flows' could also have a new option to define the list of variables it should take back from the subflow. I probably have to add a way for a subflow to define what input variables it expects and the output variables it will provide. Maybe adding a new trigger to define the input variables would be best and a new action 'Return Variables' would be the way to do this.
This feature should greatly help to improve the variable scoping problem.

User avatar
Desmanto
Posts: 2709
Joined: 21 Jul 2017 17:50

Re: User-defined Templates?

Post by Desmanto » 14 Oct 2017 17:37

@98b247af : Yeah, should practically have unlimited sub group. But maybe there will be a problem when storing the grouping in xml, since it will be nested. So, it should be limited to certain level. Maybe 2 or 5, don't know, should be a fixed level.

@Martin : This 'inline called flows' copy the flow directly as is to the current flow? Or it is copied 'on the fly' during execution only? (the main flow only have action execute flow). If on the fly, that is just the same with execute flow, except maybe it can accept parameter. I would rather have the execute flow with parameter directly. But if it is copied directly, it is useful for template, as the first idea is to create simple flow which can be selected to be pasted immediately as template.

I actually wanna know how each flow take the variable passed to it. If I created a barebone flow without trigger, put debug dialog and execute it; it only generates 3 variables : flow_name, trigger and triggertime. So in order to take variable from other flow/action which trigger it, did the flow can pass the variable?

I mean take example, I use action execute flow or widget click to execute that barebone flow. Both will still return only 3 variables + additional flow_count (becomes 4). But if I use action notification click to trigger the flow, it will pass another 2 variables, action_number and action_text.

So as I understand from the notification click above, a flow can immediately accept the variables pass to it without any additional new trigger to define the input. So, the passing variables things should be handled by the execute flow, not by adding new trigger to the subroutine flow. This way, we can call any flow without any additional trigger, including the barebone flow without any trigger (this is the subroutine flow). The variables being passed can be selected using multiple choice option and will be stored the same way, using comma delimited list. GloVar should be excluded, as they are available already in all flows.

Then the 'Return Variables' should be put on the subroutine flow, (not in the execute flow), to return only certain variables those we want to the parent flow. Since we don't know how the subroutine flow will run in the branch logic before it is finished. This will solved the inconsistency of flow_name, mentioned by clive.pottinger in another thread viewtopic.php?f=4&t=7011

In short, I am OK with the Return Variables. But for the passing variable, it should be handled by the Action Execute Flow; not adding new trigger just to receive the variable. But, I am just assuming here, I don't know what happen under the hood. Don't know it is possible to implement it.

===========
Using the concept, I will have no problem if I have multiple branching in the subroutine flow, as long as I can pass the variable. Supposed I have some subroutine flows, to do 3 things : convert currency by using yahoo finance data, checking weather in certain city and checking traffic from one location to another location. Using the passsing variable feature, I can merge those 3 flows into single flow and differentiate them by using another variable (example : {command}) when calling it. Then in the subroutine flow, separate them using multiple parallel expression, to check on the {command}. That way, I can reuse a single subroutine flow by putting more and more parallel expression as needed.

I just realized this actually can be done easily already using GloVar with Map type. Just put a new gloVar, global_parameter = {parameter1=convertcurrency, parameter2=this is variable 2, parameter3=500} But having the execute flow with parameter will mainstream the idea and no need to write to GloVar or call GloVar anymore.

BTW, I think we stray away too much from the first idea of defining user template to execute flow with parameter. :D
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.

User avatar
Martin
Posts: 4468
Joined: 09 Nov 2012 14:23

Re: User-defined Templates?

Post by Martin » 16 Oct 2017 19:05

@Desmanto: The inline called flow would copy the actions as is to the current flow, not on the fly during execution. It's really more a copy/paste helper. That's also the reason it's not that interesting.

When you have a parent flow and execute a sub-flow with action 'Execute Flows', the sub-flow will inherit all variables from the parent flow. The idea would be that the sub-flow can define what variable it want's to take as input argument. For example you could define a flow that adds two numbers:

Flow name: Add flow
-trigger <none>
-action Script: c = a + b;

For the user it might be hard to know what the input variables are. In this simple example it might be easy to see that it's variable a and b but for more complex sub-flow, it could be hard.
The idea is to use a new mechanism that allows sub-flow to specify what variables in wants to take. My current idea would be via some kind of new "trigger". Let's call it Input Arguments (just an example). You could tell the "trigger" that the flow would like to get values for variables a and b. Maybe one could even define some documentation for each variable.

A user would now add an action Execute Fows: Add flow in the parent flow. At the time you select the 'Add flow' in the action, a dialog would be shown that asks the user to either define values for variables a and b or to specify which variables from the parent flow should be passed as a and b to the sub-flow.

The return would work more or less the same way. The sub-flow developer adds a new action Return values and specifies a list of variables (maybe along with some documentation).
When configuring action Execute Flows, the user would again be asked to select the name of the variables it would like to assign a and b to.

No other variables would be passed from parent to sub-flow and also no additional would be passed from sub-flow to parent flow. Both creators of the parent-flow and the sub-flow would be sure that no other variables are passed so the sub-flow would not suddenly get any temporary variables from the parent flow which would greatly reduce the chance of naming conflicts.
This would also allow to create and share really useful sub-flows in the flow sharing area.

Regards,
Martin

User avatar
Desmanto
Posts: 2709
Joined: 21 Jul 2017 17:50

Re: User-defined Templates?

Post by Desmanto » 17 Oct 2017 15:27

Oh, sorry. I was wrong from the beginning. I put the script after the execute flow, thus subflow didn't get the variable. My bad. I only use execute flows once in my whole flow, and didn't pay attention to the variable being passed from parent to subflow. Which means any other use of execute flow besides using it in widget, can pass parameter properly. (this is no longer a weakness compared to tasker). I mostly want to use execute flow in widget click. But I need parameter, thus I have changed it to send broadcast/general broadcast pair.

That means current concept of execute flow actually is fine already, as the variable can be passed properly. Without any additional trigger, every flow should behave this way, accepting every variable from parent flow. For variable duplicate, I think this should be the homework of the user to make sure the variables don't overlap. We have a lot of name variation can be used. The only problem now is for widget, as the widget can only have one action mapped to the clickable action. Thus execute flow with parameter is requested.

Probably there is a better way to solve this widget problem. If you can add a new function executeFlow(flowname,skip,wait,returnvar) in the Script action, widget click problem can be solved. No need to add additional parameter option, or to execute with certain variable. Since I can use single action script only, declare the variable first and use function executeFlow.

Code: Select all

number = 0;
executeFlow("Multi Clipboard",false,false,false);
{number} is passed to the flow Multi Clipboard, where in the flow it paste the clipboard index 0. I have 5, so each of the widget will have the {number} changed to 1, 2, 3 and 4 (pasting clipboard index 1, 2, 3, and 4 respectively). I can put more variable as I wish, without using broadcast anymore.

Execute flow with variable/parameter is considered done then, if we can have this new function executeFlow() in Script action.

=====================================

The first idea of mapping variable is actually for dealing with template, to change the parameter in the template to match the variable we are using at that flow when creating the template. But now it developed to function :) I have contemplated on this several times.

Adding new trigger Input Arguments will act just like a firewall, to block any variable being passed from parent to subflow. But I think it will become a separate function on its own. Since flow and trigger are different, I can add multiple triggers to a single flow. You maybe need to create a new action, Execute (flow with) Input argument. Or maybe just name it as "Execute Function" in order to execute the input arguments trigger. If you reuse the same Execute Flow, it will only execute only the flow, not the trigger. While we need to be able execute the trigger separately from the flow, if we are going to use this Input Arguments trigger.

If I understand correctly, First we define Trigger Input Arguments : "Addition", with two arguments a and b, with return value x. We can also in another flow (or maybe same flow but different trigger), define Input Arguments : "Subtraction", with 3 arguments : a, b and c; and return value x and y. Then in the parent flow, use action Execute Input Argument (or Execute Function), we can choose from any available input argument triggers we have made. (the same way we choose shortcut from available triggers shortcut we have made).

I choose to execute Input Argument "Subtraction", then in the parent flow i will have the field a, b, c provided. In each of the field, i would define which variable to map
Input a : {biggernumber}
Input b : {smallernumber}
Input c : {comment}
If the trigger also return value, the return field x and y also provided. we can fill in the return variables
Return x : {confirmation}
Return y : {result}

No need for additional action return value, as the whole thing is handled by the trigger itself, which act as a firewall to allow only return value of x and y.

This way, we can view the trigger input arguments "Subtraction" as a new function
Subtraction(Number a, Number b, String c) with the return value (String x, Number y)

Execute function "Subtraction" with the arguments above is almost like executing
substraction(biggernumber, smallernumber, comment)
and return the result in {confirmation} and {result} to the parent flow. Only {confirmation} and {result} will be returned back. a, b, c, x, y all stays in input argument flow.

I see this Trigger input argument becomes a kind of custom user defined function. It doesn't share variables from the parent flow, but only take arguments and output return value. Basically the whole concept is very similiar to execute flow, except input argument create a separate sandbox enviroment for all its own variable. If it is going to be this way, I wish it can be also called from the script executeFunction(), the same way executeFlow() to be implemented later.

We can put multiple Input arguments trigger in single flow and separate them using the same concept multiple parallel expression. This way, I can put the frequent used "function" in single flow and maintain from there.

Regards,
Desmanto
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.

User avatar
Desmanto
Posts: 2709
Joined: 21 Jul 2017 17:50

Re: User-defined Templates?

Post by Desmanto » 21 Oct 2017 05:02

I am here again. Sorry, my bad again. I should have tested it before posting.

I just checked again, widget click will pass variable widget_cell_x and widget_cell_y to the executed flow. Which mean I can map the xy index value to do what I want. Yay :)
Execute task with parameter is completely redundant then, as it can be done without it anymore.

Something cool I have discovered too when playing with widget. If I use action swipe, it will pass variable swipe_velocity_x and y too. The value depends on how fast we swipe it.
I am thinking something evil then after discovered this :twisted:

===========================

But it will still be nice if we can have the executeFlow() function in Script, as long as it won't break anything.

Recontemplate on the topic again, I think maybe no need to create a new trigger anymore. Just make it possible to create our own custom function in Script.
It has been done brilliantly by clive in his thread viewtopic.php?f=4&t=7011#p19358 using eval()
Maybe the custom defined function can be declared something like this.

Code: Select all

newFunction(subtraction, a, b)
{
  c = a - b;
  return c;
}
Next, to call this custom defined function, we will use

Code: Select all

x = executeFunction(subtraction, y, z)
The result will be the value of y - z.

If we can have executeFlow() function as well, we can integrate it inside the script and put it in custom Function too. So we can still execute flow using custom Function.
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.

Locked