diff --git a/ExamplePlugin/ExamplePlugin.cs b/ExamplePlugin/ExamplePlugin.cs
index c9e6095..59650d9 100644
--- a/ExamplePlugin/ExamplePlugin.cs
+++ b/ExamplePlugin/ExamplePlugin.cs
@@ -23,56 +23,196 @@ using VoiceAttack;
namespace alterNERDtive.Yavapf.Example
{
+ ///
+ /// This is an example for a VoiceAttack plugin using YAVAPF.
+ ///
+ /// You can use this class and this project as base for your own implementation.
+ ///
public class ExamplePlugin
{
private static readonly VoiceAttackPlugin Plugin;
+ ///
+ /// Initializes static members of the class.
+ ///
+ /// Since VoiceAttack’s plugin API requires a bunch of static methods
+ /// instead of instantiating a plugin class, the “Constructor” here also
+ /// needs to be static. It is executed right before a static method is
+ /// used for the first time, which would usually be when VoiceAttack
+ /// calls the method.
+ ///
static ExamplePlugin()
{
+ // You can generate a GUID in Visual Studio under “Tools” → “Create
+ // GUID”. Choose “Registry Format”.
Plugin = new (
name: "Example Plugin",
version: "0.0.1",
info: "This is a description",
guid: "{76FE674F-F729-45FD-A1DD-E53E9E66B360}");
+ // Add handlers for the Init, Exit and Stop events here. The plugin
+ // will execute them whenever VA_Init1, VA_Exit1 or VA_StopCommand
+ // are run by VoiceAttack.
+ // You can add none or as many as you need.
Plugin.Init += Init;
Plugin.Exit += Exit;
Plugin.Stop += Stop;
+ // Add handlers for plugin contexts. The methods added here must
+ // have at least one “Context” attribute specifying the contexts
+ // they are to be executed for.
+ // See the definition of the “Test” method below.
Plugin.Contexts += Test;
+ Plugin.Contexts += EmptyContext;
+ Plugin.Contexts += RegexContext;
}
+ ///
+ /// The plugin’s display name, as required by the VoiceAttack plugin
+ /// API.
+ ///
+ /// Since it is required to be static, it must be defined in your plugin
+ /// class for VoiceAttack to pick it up as a plugin.
+ ///
+ /// The display name.
public static string VA_DisplayName() => Plugin.VA_DisplayName();
+ ///
+ /// The plugin’s description, as required by the VoiceAttack plugin API.
+ ///
+ /// Since it is required to be static, it must be defined in your plugin
+ /// class for VoiceAttack to pick it up as a plugin.
+ ///
+ /// The description.
public static string VA_DisplayInfo() => Plugin.VA_DisplayInfo();
+ ///
+ /// The plugin’s GUID, as required by the VoiceAttack plugin API.
+ ///
+ /// Since it is required to be static, it must be defined in your plugin
+ /// class for VoiceAttack to pick it up as a plugin.
+ ///
+ /// The GUID.
public static Guid VA_Id() => Plugin.VA_Id();
+ ///
+ /// The Init method, as required by the VoiceAttack plugin API.
+ /// Runs when the plugin is initially loaded.
+ ///
+ /// Since it is required to be static, it must be defined in your plugin
+ /// class for VoiceAttack to pick it up as a plugin.
+ ///
+ /// The VoiceAttack proxy object.
public static void VA_Init1(dynamic vaProxy) => Plugin.VA_Init1(vaProxy);
+ ///
+ /// The Invoke method, as required by the VoiceAttack plugin API.
+ /// Runs whenever a plugin context is invoked.
+ ///
+ /// Since it is required to be static, it must be defined in your plugin
+ /// class for VoiceAttack to pick it up as a plugin.
+ ///
+ /// The VoiceAttack proxy object.
public static void VA_Invoke1(dynamic vaProxy) => Plugin.VA_Invoke1(vaProxy);
+ ///
+ /// The Exit method, as required by the VoiceAttack plugin API.
+ /// Runs when VoiceAttack is shut down.
+ ///
+ /// Since it is required to be static, it must be defined in your plugin
+ /// class for VoiceAttack to pick it up as a plugin.
+ ///
+ /// The VoiceAttack proxy object.
public static void VA_Exit1(dynamic vaProxy) => Plugin.VA_Exit1(vaProxy);
+ ///
+ /// The StopCommand method, as required by the VoiceAttack plugin API.
+ /// Runs whenever all commands are stopped using the “Stop All Commands”
+ /// button or action.
+ ///
+ /// Since it is required to be static, it must be defined in your plugin
+ /// class for VoiceAttack to pick it up as a plugin.
+ ///
public static void VA_StopCommand() => Plugin.VA_StopCommand();
+ ///
+ /// An example handler for VA_Init1. Init handlers are the place to do
+ /// anything that your plugin needs to set up when it is initially
+ /// loaded at VoiceAttack start.
+ ///
+ /// The current VoiceAttack proxy object.
private static void Init(VoiceAttackInitProxyClass vaProxy)
{
+ Plugin.Log.Notice("This is the example Init handler method.");
}
+ ///
+ /// An example handler for VA_Exit1. Exit handlers have to make sure
+ /// your plugin is properly shut down with VoiceAttack. Do note that
+ /// there is a default timeout of 5s.
+ ///
+ /// The current VoiceAttack proxy object.
private static void Exit(VoiceAttackProxyClass vaProxy)
{
+ Plugin.Log.Notice("This is the example Exit handler method.");
}
+ ///
+ /// An example handler for VA_StopCommand. If your plugin needs to
+ /// execute anything when all commands are stopped this is the place.
+ ///
private static void Stop()
{
+ Plugin.Log.Notice("This is the example Stop handler method.");
}
+ ///
+ /// An example handler for plugin contexts. The context(s) must be
+ /// specified with “Context” attributes. Contexts must be all lower case.
+ ///
+ /// This example handles the “test” and “different test” plugin
+ /// contexts. They expect that a text parameter “~test” is set in
+ /// VoiceAttack.
+ ///
+ /// The current VoiceAttack proxy object.
[Context("test")]
- [Context("other name")]
+ [Context("different test")]
private static void Test(VoiceAttackInvokeProxyClass vaProxy)
{
- Plugin.Log.Notice($"Plugin context '{vaProxy.Context}' invoked.");
+ Plugin.Log.Notice(
+ $"This is the example handler for the plugin contexts “test” and “different test”. It has been invoked with '{vaProxy.Context}'.");
+ _ = Plugin.Get("~test") ?? throw new ArgumentNullException("~test");
+ }
+
+ ///
+ /// An example handler for plugin contexts. The context(s) must be
+ /// specified with “Context” attributes. Contexts must be all lower case.
+ ///
+ /// This example demonstrates using regular expressions. It handles all
+ /// contexts that begin with “foo” or contain.
+ ///
+ /// The current VoiceAttack proxy object.
+ [Context("^foo.*")]
+ [Context("^.*bar.*")]
+ private static void RegexContext(VoiceAttackInvokeProxyClass vaProxy)
+ {
+ Plugin.Log.Notice(
+ $"This is the example handler for the plugin contexts “^foo.*” and “^.*bar.*”. It has been invoked with '{vaProxy.Context}'.");
+ }
+
+ ///
+ /// An example handler for plugin contexts. The context(s) must be
+ /// specified with “Context” attributes. Contexts must be all lower case.
+ ///
+ /// This example displays a custom error message when the plugin is
+ /// invoked with no context (= empty context).
+ ///
+ /// The current VoiceAttack proxy object.
+ [Context("")]
+ private static void EmptyContext(VoiceAttackInvokeProxyClass vaProxy)
+ {
+ Plugin.Log.Error($"Invoking this plugin without a context is not allowed.");
}
}
}
diff --git a/ExamplePlugin/GlobalSuppressions.cs b/ExamplePlugin/GlobalSuppressions.cs
new file mode 100644
index 0000000..c03bb2a
--- /dev/null
+++ b/ExamplePlugin/GlobalSuppressions.cs
@@ -0,0 +1,8 @@
+// This file is used by Code Analysis to maintain SuppressMessage
+// attributes that are applied to this project.
+// Project-level suppressions either have no target or are given
+// a specific target and scoped to a namespace, type, member, etc.
+
+using System.Diagnostics.CodeAnalysis;
+
+[assembly: SuppressMessage("StyleCop.CSharp.NamingRules", "SA1300:Element should begin with upper-case letter", Justification = "It’s my name, you prick :)", Scope = "namespace", Target = "~N:alterNERDtive.Yavapf.Example")]