bitfocus / companion

Bitfocus Companion enables the reasonably priced Elgato Streamdeck and other controllers to be a professional shotbox surface for an increasing amount of different presentation switchers, video playback software and broadcast equipment.
http://bitfocus.io/companion
Other
1.46k stars 489 forks source link

[Feat] Modernize way of action advancement #2882

Open dnmeid opened 1 month ago

dnmeid commented 1 month ago

Is this a feature relevant to companion itself, and not a module?

Is there an existing issue for this?

Describe the feature

Today although the actions of a set are shown in a list, they are all executed at the same time or with fixed delays. I think it would be a good feature if we would have the possibility of a better control of the actions execution. Im thinking of something like the powerpoint way of advancing to the next animation.
The user would have a choice if:

Actions can still have an optional delay, but this delay would always be relative.

Biggest advantage would be the part "after previous action has finished" making it possible to program sequential workflows without unnecessary delay times. E.g. time until a variable is set or time until http get has a result. Biggest concern here is that modules now should actively handle return values for the action callbacks, at least for actions which may run for a long time or which may fail. And we would have to deal with what happens if the action fails. Shoud it throw an error or return a special value or reject a promise. And do we just log it and proceed in the action set or give users a way to decide themselfes how to handle failed actions.

Usecases

No response

thedist commented 1 month ago

I like this idea, especially as I've seen a growth in more complex setups, and automation, that requires a lot of actions on a button or trigger.

My suggestion would be to make it its own thing, for example just like we have a page just for triggers, why not a page for 'Action Sequences' or whatever you may call them. The user could create and name a sequence, and the page could allow them to easily create parallel groups, or series groups, add actions to those groups, chain one in to another, maybe even have each group split at the end into a 'Success' or 'Failure' section so if a set of actions succeeds it continues on to the next thing, but it also lets the user branch off to do something if it fails, like log to console, or retry x times, whatever the user may want. When a sequence is run it could even act as a monitoring page to allow users to see what action it's up to, what actions may be holding it up, etc... Then it'd just be a case of the user adding a 'Run Sequence' action to a button/trigger in the usual button/trigger pages.

On the module dev side of things this would likely require actions to return a promise to be properly supported, which shouldn't be particularly difficult but I would expect that some modules may not be able to fully support it if their actions do things that don't have a way to determine if the action succeeded or not.

Julusian commented 1 month ago

the action starts after the previous action has finished

I was confident this was how it behaved today, but I am wrong on that.. :facepalm: Internal actions will generally behave this way because they aren't async so will execute synchronously, but yeah module actions are fire and forget.

Biggest concern here is that modules now should actively handle return values for the action callbacks, at least for actions which may run for a long time or which may fail. And we would have to deal with what happens if the action fails

With the way the module callbacks are in the new module api, when the callback returns a promise, the call companion makes into the module only completes when that promise resolves (or the 5s timeout that companion defines is reached). we do this today mostly just so that we can log any errors the call throws.
So the api is ready for this, it just depends on modules doing things correctly.


I am on board with this. I think this would be best achieved by creating new actions which have these behaviours. This would mean it is very related to #1052. (they would both need the framework of 'composite actions') My reasoning for this is that it means that it would be possible to compose these much better. such as:

This does feel very much like our own building block programming language. I'm not sure if that is a good or bad thing..

I would be tempted to say that with this model, maybe the delays we currently have should be moved to be composite actions like these too, rather than a builtin concept.

I'm not immediately convinced by the action starts after a manual trigger, I think this needs some thought on how it should work and be implemented that the other two don't pose due to the nature of delaying for an unknown duration, possibly infinite.

fbosman commented 1 month ago

I think the time has come to take the next step in this marvelous program.I propose a way of connecting triggers, actions and conditions in a (easy and limited) structured programming setup.Let us define programmed snippets which can be fired by button presses, triggers and contain conditionals and actions.Met vriendelijke groet,Frans BosmanVerstuurd vanaf mijn iPhoneOp 26 mei 2024 om 14:12 heeft Jeff Martin @.***> het volgende geschreven: I like this idea, especially as I've seen a growth in more complex setups, and automation, that requires a lot of actions on a button or trigger. My suggestion would be to make it its own thing, for example just like we have a page just for triggers, why not a page for 'Action Sequences' or whatever you may call them. The user could create and name a sequence, and the page could allow them to easily create parallel groups, or series groups, add actions to those groups, chain one in to another, maybe even have each group split into a 'Success', 'Failure' so if a set of actions succeeds it continues on to the next thing, but it also lets the user branch off to do something if it fails, like log to console, or retry x times, whatever the user may want. When a sequence is run it could even act as a monitoring page to allow users to see what action it's up to, what actions may be holding it up, etc... Then it'd just be a case of the user adding a 'Run Sequence' action to a button/trigger in the usual button/trigger pages. On the module dev side of things this would likely require actions to return a promise to be properly supported, which shouldn't be particularly difficult but I would expect that some modules may not be able to fully support it if their actions do things that don't have a way to determine if the action succeeded or not.

—Reply to this email directly, view it on GitHub, or unsubscribe.You are receiving this because you are subscribed to this thread.Message ID: @.***>

dnmeid commented 1 month ago

I'm glad to see that some of you have the same or similar idea like I proposed in #2387:

My suggestion would be to make it its own thing 'Action Sequences'

framework of 'composite actions'

Let us define programmed snippets which can be fired by button presses, triggers and contain conditionals and actions

In #2387 I called this a "stepped script" (working title). Go find the details of the idea there, the bottom line is that I want to separate the functionality from the button. We would have something like a script or snippet or composit actions, which is a new entity. The script can be run by a button or by trigger or by API. So buttons wouldn't have actions any more and triggers wouldn't have actions any more and they'd have a script instead. In #2387 I also propose inline editing for the script, so you can edit the actions of the script right where it is used in the button or in the trigger.

But all of this is independent of just changing the way how/when the decision is made to run one particular action.

maybe the delays we currently have should be moved to be composite actions

Im also not super happy with the current implementation of delays. If we give actions the choice wether to run at start or at end of the previous action, I'm wondering wether it would be better to have the delays as a separate wait action. This wait can then just be inserted where you need it and it could also easily take variables or an expression as a parameter and you can temporarily enable/disable the delay (#2172).

This does feel very much like our own building block programming language. I'm not sure if that is a good or bad thing..

Does anybode here know Medialon? I'm a veteran Medialon programmer, it is quite old and nowadays not maintained a lot any more but it still is by far the best and most complete show control solution. For me Medialon is a constant source of inspiration for the development of Companion. Their "language" looks like this: image If you look closely, you can see how they implemented a if/else. The lines within each block are indented, this also works multi level. You can simply drag lines in and out of a block.

In the screenshot you can also see a wait like I described above.

The Medialon way of doing "start action at a trigger" is called "wait for" where you can give a condition and it waits until the condition evaluates true.

I'm not sure if the Medialon way is 100% what we should aim for. It is super powerful and for me quite simple to use, but maybe it is too advanced for a lot of our users.