Author Topic: Ability for plugin to execute VoiceAttack commands  (Read 25847 times)

cmdrmcdonald

  • Guest
Re: Ability for plugin to execute VoiceAttack commands
« Reply #30 on: October 02, 2016, 02:47:46 PM »
I popped this in, compiled and it worked straight away (shows, 'Hello world in the log with a red icon).

Does it initialize when you take out that line?

Are you sure you are building to the right directory?

Are you using .net framework 4 (not 4.5... probably doesn't matter but you never know)?

Attached is what I built just now.

I just uninstalled VoiceAttack and removed the entire C:\Program Files (X86)\VoiceAttack directory.  I then installed the beta and put the DLL you supplied in to an Apps\VATest directory.  Exact same response when I started VoiceAttack as I showed in the image in my previous post.

I shut down VoiceAttack, renamed my %APPDATA%\VoiceAttack and %LOCALAPPDATA%\VoiceAttack.com directories and restarted VoiceAttack.  Enabled plugin support, restarted VoiceAttack and again the same response again.

I'm a little lost as to what to do at this stage.  None of my code is in the VoiceAttack directory, I'm using a fresh install and virgin configuration (unless there's another configuration directory somewhere I don't know about).  Any ideas?

(Sorry didn't see your post; I was busy writing up my findings.  Hanging on  :))

Gary

  • Administrator
  • Hero Member
  • *****
  • Posts: 2832
Re: Ability for plugin to execute VoiceAttack commands
« Reply #31 on: October 02, 2016, 03:03:10 PM »
Ok... I put a new version out in, 'unofficial' bin:  http://www.voiceattack.com/unofficial



cmdrmcdonald

  • Guest
Re: Ability for plugin to execute VoiceAttack commands
« Reply #32 on: October 02, 2016, 03:54:53 PM »
And it works - fantastic!  Thanks.

I'll have a play tomorrow and let you know how it goes.  Thanks again.

cmdrmcdonald

  • Guest
Re: Ability for plugin to execute VoiceAttack commands
« Reply #33 on: October 03, 2016, 11:47:26 AM »
I spent a few hours updating my plugin to work with the new version of VoiceAttack.  And, for me at least, it's fantastic.  I stripped out a lot of code, removed a lot of profile commands, and user setup and customisation are both significantly easier.

A couple of questions/comments:
  • When calling a plugin method the bit that asks for the variables that I pass to the script (the "Variables to pass to the plugin function" bit) seem to be ignored.  I'm fine with this (and it's preferable for me, to be honest), just wanted to check that this is what you intended
  • With the old way of calling the methods the explicit dictionaries meant that you could do things like traverse it looking for particular keys.  With the GetText() etc that is no longer possible.  Although not critical for me (at least, not unless you change the previous point) it would be nice to be able to traverse the various types of value by key

Thank you again for this, it's made plugin development and use significantly easier and more fun.

Gary

  • Administrator
  • Hero Member
  • *****
  • Posts: 2832
Re: Ability for plugin to execute VoiceAttack commands
« Reply #34 on: October 03, 2016, 12:46:14 PM »
Quote
With the old way of calling the methods the explicit dictionaries meant that you could do things like traverse it looking for particular keys.  With the GetText() etc that is no longer possible.  Although not critical for me (at least, not unless you change the previous point) it would be nice to be able to traverse the various types of value by key

You'll need to just check if a value is null to see if it exists or not:

if (GetText("myVariable").HasValue)
{
    //exists
}
else
    //doesn't exist

The whole thing with dictionaries before was to keep VA as disconnected from the plugins as possible.  There are still dictionaries being used, just not exposed to the user (sessionstate is still a dictionary, but va does nothing with it other than hold on to it).


Quote
Quote
When calling a plugin method the bit that asks for the variables that I pass to the script (the "Variables to pass to the plugin function" bit) seem to be ignored.  I'm fine with this (and it's preferable for me, to be honest), just wanted to check that this is what you intended

It is the intention.  The documentation explains that they are going to be left in there for backward-compatibility.  Taking them out would cause problems for previous versions.  There's a part of me that wants to just rip it off like a bandaid and let the pieces fall where they may o_O

Quote
Thank you again for this, it's made plugin development and use significantly easier and more fun.

This seems like its going to open up a lot more possibilities.  I've got, 'scoped variables' on the list so we can have command-level and profile-level variables at some point.  Then again... with sessionstate it's really probably not terribly necessary.  Glad it's working out for you ;)

Antaniserse

  • Global Moderator
  • Jr. Member
  • *****
  • Posts: 87
    • My VA plugins
Re: Ability for plugin to execute VoiceAttack commands
« Reply #35 on: October 04, 2016, 04:03:53 PM »
Quote
Quote
When calling a plugin method the bit that asks for the variables that I pass to the script (the "Variables to pass to the plugin function" bit) seem to be ignored.  I'm fine with this (and it's preferable for me, to be honest), just wanted to check that this is what you intended

It is the intention.  The documentation explains that they are going to be left in there for backward-compatibility.  Taking them out would cause problems for previous versions.  There's a part of me that wants to just rip it off like a bandaid and let the pieces fall where they may o_O

So, if I understand correctly, this means that the profile commands need to specifically reset any previously used variable before calling the plugin, right?

Because, the current behaviour is something like this:
  • The profile command 'A' sets Var1 and Var2 and execute a plugin call, passing both in the "variables to pass" dialog; plugin sees both values in the dictionaries and behaves accordingly
  • The profile command 'B' then sets Var1, leave Var2 untouched and execute a plugin call, passing only Var1 in the "variables to pass" dialog; plugin sees just Var1 in the dictionaries and behaves accordingly

With VA interface 4, when command 'B' makes the call, the plugin will still see Var1 and Var2 regardless, where Var1 is updated but Var2 is retaining the old value from the previous call, so it can't really perceive the fact that the user choosed to transmit only one value in the invoke... correct?

More so, does this means that if a profile references more than one plugin, the new 'vaProxy' object will allow access to variables used/created by any other plugin, with potential name conflict/unintended overwriting?
(this was possible even before if the plugin code injected new variable in the dictionaries, but if the code was only referencing the variables originally received in VA_Invoke1, all others were safe)

This is not a big problem per se, but even after the plugin is updated it may require a carefull check of all the profiles (adding a bunch of 'Not Set') to prevent unexpected behaviour....
"I am not perfect and neither was my career. In the end tennis is like life, messy."
Marat Safin

Gary

  • Administrator
  • Hero Member
  • *****
  • Posts: 2832
Re: Ability for plugin to execute VoiceAttack commands
« Reply #36 on: October 04, 2016, 05:36:48 PM »
Quote
More so, does this means that if a profile references more than one plugin, the new 'vaProxy' object will allow access to variables used/created by any other plugin, with potential name conflict/unintended overwriting?
In VA as it stands, all variables are global.  The commands are not compiled and everybody can see and step on everything.  It's really, really open.

In the previous plugin interface (v3), in order for the plugin to receive ANY variables, you had to first set the variables somewhere in a command and then indicate what variables are going to be pushed over to the plugin via the execute plugin screen.  The variable values were then gathered up (in various typed dictionaries), and pushed to the plugin.  Then the plugin would use whatever you pushed over, make any additions/subtractions/modifications to the dictionary items and then when the call (invoke, init) went out of scope, the dictionaries were then used to update the variables in VoiceAttack.  So, whatever work was done on the dictionaries within the plugin would have been as if the dictionaries were local (because they were).  VoiceAttack would just run through the dictionary on return and make all necessary adjustments.  I thought that this was good, because it meant that the plugin was totally isolated other than through these very controlled areas.

What v3 did not allow was for was any interaction with VA other than through waiting for a call FROM VA.  That means you have to have a command that loops and calls a plugin function continually.  Not necessarily a *bad* thing (its the best you can do with a transaction model), but it requires that the user has to do something in order to get the ball rolling.  Then, if the user clicks, 'stop running commands', the whole thing comes to a halt and then it requires the user to be involved again.  In order to have a clean link between VA and the plugin, the transaction model had to be updated to allow direct access to variables inside of VA and to be able to execute VA's commands.  This is where v4 comes in.  This way, variable monitoring can be done within the plugin without having to wait for VA to call, and commands can be executed without having a VA loop looking for a specific value to invoke a command (it's actually been whiteboarded for a long time to have command triggers on variable set... not writing that just yet lol).

If you are relying on the content of the dictionaries passed in to indicate context, you're going to need to use either the the context value of vaProxy (set on the, 'execute plugin' screen... uses tokens), or rely on a variable flag (using caution in a multi-threaded environment) for this new interface.


The new interface provides a different way of doing things, and in order to do those things it has to be opened up like it is.  It is possible to continue using the old plugin interfaces if you need to, as VA will still recognize them.

Gary

  • Administrator
  • Hero Member
  • *****
  • Posts: 2832
Re: Ability for plugin to execute VoiceAttack commands
« Reply #37 on: October 04, 2016, 06:08:46 PM »
The ExecuteCommand function's documentation should look like this:

ExecuteCommand(String CommandName, optional Boolean WaitForReturn = false)

Setting that to true will cause the function to wait until the command completes.  Updating doc now.

Antaniserse

  • Global Moderator
  • Jr. Member
  • *****
  • Posts: 87
    • My VA plugins
Re: Ability for plugin to execute VoiceAttack commands
« Reply #38 on: October 04, 2016, 06:25:49 PM »
If you are relying on the content of the dictionaries passed in to indicate context, you're going to need to use either the the context value of vaProxy (set on the, 'execute plugin' screen... uses tokens), or rely on a variable flag (using caution in a multi-threaded environment) for this new interface.

The new interface provides a different way of doing things, and in order to do those things it has to be opened up like it is.  It is possible to continue using the old plugin interfaces if you need to, as VA will still recognize them.
Sure, I understand how versatile v4 is (basically, the moment you invoke the plugin once, you could potentially control a full profile from within the code without ever returning from the call), it's just that I'm a little worried that existing profiles might break in some very subtle way, even if the plugin itself is fully compliant with v4

I guess this is a problem mostly for me than others, since my main plugin is not specialized, but very general purpose, and so I'm already using "context" to determine the main job to do, while asking the user to submit a bunch of variable with the same name, for consistency, in different methods (a few of them could actually also work with unknown variable names, just operating on whatever list of integer submitted...  I guess this has to be re-coded differently now)

Again, this is just more of a theoretical issue than actual, it's not that I have a real user base  around ;), and I understand how to re-work my personal profiles to make them safe... and i guess this will become entirely a non-issue the moment limited scope variables kicks in, in the future

EDIT: Now that I think of it, a "quick & dirty" way to give scope to variables would be just a small option like this
« Last Edit: October 04, 2016, 06:45:28 PM by Antaniserse »
"I am not perfect and neither was my career. In the end tennis is like life, messy."
Marat Safin

Gary

  • Administrator
  • Hero Member
  • *****
  • Posts: 2832
Re: Ability for plugin to execute VoiceAttack commands
« Reply #39 on: October 05, 2016, 08:51:51 AM »
I'm going to send vaProxy down with the state array.  That way v3 users can continue to use their various workarounds with the older interfaces as well as have the benefit of the the new proxy class.