Extending EG's actions
Posted: Sun Feb 28, 2010 2:55 pm
I've been working on a fork of EG for a while now, based on some ideas that Bitmonster was not really interested in. Now that Bitmonster is leaving EG, I think it is worth discussing these ideas with the EG community.
Note, my fork is not available. I will make something available when the code is at that level, but it isn't yet.
When I saw how EG worked with actions, I thought of programming's functor. While a function is something you call with a set of arguments, a functor a kind of extension of that.
A common example is the power function:
pow(x,y) = x**y
Using functors, you could create a square and cube function, like:
square(x) = pow(x,2)
cube(x) = pow(x,3)
From then on, you could call square or cube with a single argument.
In EG's case, this allows you to define a functions arguments once, then call it without user interaction from then on. All of the parameters are already defined - and a simple call to RunMe() is triggered by some event. The parameters are defined, in advance, with the action's custom UI.
I don't think EG took this idea quite far enough. EG uses a tree, which can jump to different nodes, or associate multiple actions with an event. Instead, I have group actions and if actions, which allow multiple or conditional functors to be combined into another (single) functor. LongPress is another example that combines two conceptually distinct actions into a single functor, as is autorepeat.
To me, this makes the event/response process a little clearer. The response is simply a fully defined "bundle of work", whatever that may be. Put another way, configuration is the process of defining in advance (with a few exceptions) all of the values needed to do the "bundle of work", so it can run without user input when a triggering event runs.
When you look at plugins as a way of defining (or providing UI's to customize) these "bundles of work", an interesting idea develops. If you think of a plugin as a way for a developer make a common/useful "bundle of work" accessible to others, why can't the developer make autorepeat part of a plugin? My answer is he/she can.
I will finish that thought, but let me bring up another concept that I'm implementing in my fork. A very common use case is to use EG to control software with a remote. So I'll have a "play" button on the remote, and several programs with "play" actions.
My fork does two things to simplify this use case. First of all, there's a built in plugin that watches Task events to tell when programs start or stop. This way, if you want to control TheaterTek and iTunes, you don't need to use exclusion macros, you can just let the software send the events to the program that was most recently in focus. Second, when the event gets sent to a specific program (most recently in focus), if the remote key ("play") matches an action name, it will automatically be called - the user doesn't have to assign every event to every action.
With these two ideas, a lot of the work users do to just get EG up and running work right away in my fork.
And if the plugin developer assigns the name "left" to a functor with AutoRepeat already set up, the user can have a pretty robust experience right out of the box.
And that seems like a great way to use functors....
Brett
Note, my fork is not available. I will make something available when the code is at that level, but it isn't yet.
When I saw how EG worked with actions, I thought of programming's functor. While a function is something you call with a set of arguments, a functor a kind of extension of that.
A common example is the power function:
pow(x,y) = x**y
Using functors, you could create a square and cube function, like:
square(x) = pow(x,2)
cube(x) = pow(x,3)
From then on, you could call square or cube with a single argument.
In EG's case, this allows you to define a functions arguments once, then call it without user interaction from then on. All of the parameters are already defined - and a simple call to RunMe() is triggered by some event. The parameters are defined, in advance, with the action's custom UI.
I don't think EG took this idea quite far enough. EG uses a tree, which can jump to different nodes, or associate multiple actions with an event. Instead, I have group actions and if actions, which allow multiple or conditional functors to be combined into another (single) functor. LongPress is another example that combines two conceptually distinct actions into a single functor, as is autorepeat.
To me, this makes the event/response process a little clearer. The response is simply a fully defined "bundle of work", whatever that may be. Put another way, configuration is the process of defining in advance (with a few exceptions) all of the values needed to do the "bundle of work", so it can run without user input when a triggering event runs.
When you look at plugins as a way of defining (or providing UI's to customize) these "bundles of work", an interesting idea develops. If you think of a plugin as a way for a developer make a common/useful "bundle of work" accessible to others, why can't the developer make autorepeat part of a plugin? My answer is he/she can.
I will finish that thought, but let me bring up another concept that I'm implementing in my fork. A very common use case is to use EG to control software with a remote. So I'll have a "play" button on the remote, and several programs with "play" actions.
My fork does two things to simplify this use case. First of all, there's a built in plugin that watches Task events to tell when programs start or stop. This way, if you want to control TheaterTek and iTunes, you don't need to use exclusion macros, you can just let the software send the events to the program that was most recently in focus. Second, when the event gets sent to a specific program (most recently in focus), if the remote key ("play") matches an action name, it will automatically be called - the user doesn't have to assign every event to every action.
With these two ideas, a lot of the work users do to just get EG up and running work right away in my fork.
And if the plugin developer assigns the name "left" to a functor with AutoRepeat already set up, the user can have a pretty robust experience right out of the box.
And that seems like a great way to use functors....
Brett