more ground work brainstorming
This commit is contained in:
parent
6377a4142f
commit
36c7048f37
5 changed files with 354 additions and 33 deletions
|
@ -19,6 +19,8 @@
|
|||
|
||||
using System;
|
||||
|
||||
using VoiceAttack;
|
||||
|
||||
namespace alterNERDtive.Yavapf.Example
|
||||
{
|
||||
public class ExamplePlugin
|
||||
|
@ -27,13 +29,17 @@ namespace alterNERDtive.Yavapf.Example
|
|||
|
||||
static ExamplePlugin()
|
||||
{
|
||||
Plugin = new ()
|
||||
{
|
||||
Name = "Example Plugin",
|
||||
Version = "0.0.1",
|
||||
Info = "This is a description",
|
||||
Guid = "{76FE674F-F729-45FD-A1DD-E53E9E66B360}",
|
||||
};
|
||||
Plugin = new (
|
||||
name: "Example Plugin",
|
||||
version: "0.0.1",
|
||||
info: "This is a description",
|
||||
guid: "{76FE674F-F729-45FD-A1DD-E53E9E66B360}");
|
||||
|
||||
Plugin.Init += Init;
|
||||
Plugin.Exit += Exit;
|
||||
Plugin.Stop += Stop;
|
||||
|
||||
Plugin.Contexts += Test;
|
||||
}
|
||||
|
||||
public static string VA_DisplayName() => Plugin.VA_DisplayName();
|
||||
|
@ -49,5 +55,24 @@ namespace alterNERDtive.Yavapf.Example
|
|||
public static void VA_Exit1(dynamic vaProxy) => Plugin.VA_Exit1(vaProxy);
|
||||
|
||||
public static void VA_StopCommand() => Plugin.VA_StopCommand();
|
||||
|
||||
private static void Init(VoiceAttackInitProxyClass vaProxy)
|
||||
{
|
||||
}
|
||||
|
||||
private static void Exit(VoiceAttackProxyClass vaProxy)
|
||||
{
|
||||
}
|
||||
|
||||
private static void Stop()
|
||||
{
|
||||
}
|
||||
|
||||
[Context("test")]
|
||||
[Context("other name")]
|
||||
private static void Test(VoiceAttackInvokeProxyClass vaProxy)
|
||||
{
|
||||
Plugin.Log.Notice($"Plugin context '{vaProxy.Context}' invoked.");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -6,10 +6,21 @@
|
|||
<Nullable>enable</Nullable>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Microsoft.CSharp" Version="4.7.0" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\VoiceAttack-Framework\VoiceAttack-Framework.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<Reference Include="VoiceAttack">
|
||||
<HintPath>C:\Program Files\VoiceAttack\VoiceAttack.exe</HintPath>
|
||||
<Private>False</Private>
|
||||
</Reference>
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<Compile Update="Properties\Settings.Designer.cs">
|
||||
<DesignTimeSharedInput>True</DesignTimeSharedInput>
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFrameworks>net48</TargetFrameworks>
|
||||
<RootNamespace>alterNERDtive.YAVAPF</RootNamespace>
|
||||
<RootNamespace>alterNERDtive.Yavapf</RootNamespace>
|
||||
<PackageId>alterNERDtive.YAVAPF</PackageId>
|
||||
<Version>0.0.1</Version>
|
||||
<Company>alterNERDtive</Company>
|
||||
|
@ -38,7 +38,11 @@
|
|||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="ImpromptuInterface" Version="7.0.1" />
|
||||
<Reference Include="Microsoft.CSharp" />
|
||||
<Reference Include="VoiceAttack">
|
||||
<HintPath>C:\Program Files\VoiceAttack\VoiceAttack.exe</HintPath>
|
||||
<Private>False</Private>
|
||||
</Reference>
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
|
|
117
VoiceAttack-Framework/VoiceAttackLog.cs
Normal file
117
VoiceAttack-Framework/VoiceAttackLog.cs
Normal file
|
@ -0,0 +1,117 @@
|
|||
// <copyright file="VoiceAttackLog.cs" company="alterNERDtive">
|
||||
// Copyright 2022 alterNERDtive.
|
||||
//
|
||||
// This file is part of YAVAPF.
|
||||
//
|
||||
// YAVAPF is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// YAVAPF is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with YAVAPF. If not, see <https://www.gnu.org/licenses/>.
|
||||
// </copyright>
|
||||
|
||||
using System;
|
||||
|
||||
using VoiceAttack;
|
||||
|
||||
namespace alterNERDtive.Yavapf
|
||||
{
|
||||
public class VoiceAttackLog
|
||||
{
|
||||
private static readonly string[] LogColour = { "red", "yellow", "green", "blue", "gray" };
|
||||
|
||||
private static LogLevel? logLevel;
|
||||
|
||||
private readonly VoiceAttackInitProxyClass vaProxy;
|
||||
private readonly string id;
|
||||
|
||||
public VoiceAttackLog(VoiceAttackInitProxyClass vaProxy, string id)
|
||||
{
|
||||
this.vaProxy = vaProxy;
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public LogLevel? LogLevel
|
||||
{
|
||||
get => logLevel ?? Yavapf.LogLevel.NOTICE;
|
||||
set
|
||||
{
|
||||
logLevel = value;
|
||||
this.Notice($"Log level set to {value ?? Yavapf.LogLevel.NOTICE}.");
|
||||
}
|
||||
}
|
||||
|
||||
public void SetLogLevel(string level)
|
||||
{
|
||||
if (level == null)
|
||||
{
|
||||
this.LogLevel = null;
|
||||
}
|
||||
else
|
||||
{
|
||||
this.LogLevel = (LogLevel)Enum.Parse(typeof(LogLevel), level.ToUpper());
|
||||
}
|
||||
}
|
||||
|
||||
public void Log(string message, LogLevel level = Yavapf.LogLevel.INFO)
|
||||
{
|
||||
_ = message ?? throw new ArgumentNullException("message");
|
||||
|
||||
if (level <= this.LogLevel)
|
||||
{
|
||||
this.vaProxy.WriteToLog($"{level} | {this.id}: {message}", LogColour[(int)level]);
|
||||
}
|
||||
}
|
||||
|
||||
public void Error(string message) => this.Log(message, Yavapf.LogLevel.ERROR);
|
||||
|
||||
public void Warn(string message) => this.Log(message, Yavapf.LogLevel.WARN);
|
||||
|
||||
public void Notice(string message) => this.Log(message, Yavapf.LogLevel.NOTICE);
|
||||
|
||||
public void Info(string message) => this.Log(message, Yavapf.LogLevel.INFO);
|
||||
|
||||
public void Debug(string message) => this.Log(message, Yavapf.LogLevel.DEBUG);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Log levels that can be used when writing to the VoiceAttack log.
|
||||
/// </summary>
|
||||
public enum LogLevel
|
||||
{
|
||||
/// <summary>
|
||||
/// Log level for error messages. Errors cause execution to abort.
|
||||
/// </summary>
|
||||
ERROR,
|
||||
|
||||
/// <summary>
|
||||
/// Log level for warning messages. Warnings should not cause execution
|
||||
/// to abort.
|
||||
/// </summary>
|
||||
WARN,
|
||||
|
||||
/// <summary>
|
||||
/// Log level for notices. Notices should be noteworthy.
|
||||
/// </summary>
|
||||
NOTICE,
|
||||
|
||||
/// <summary>
|
||||
/// Log level for informational messages. These should not be
|
||||
/// noteworthy.
|
||||
/// </summary>
|
||||
INFO,
|
||||
|
||||
/// <summary>
|
||||
/// Log level for debug messages. They should be useful only for
|
||||
/// debugging.
|
||||
/// </summary>
|
||||
DEBUG,
|
||||
}
|
||||
}
|
|
@ -18,64 +18,228 @@
|
|||
// </copyright>
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Reflection;
|
||||
using VoiceAttack;
|
||||
|
||||
namespace alterNERDtive.Yavapf
|
||||
{
|
||||
public class VoiceAttackPlugin
|
||||
{
|
||||
public string Name { get; set; }
|
||||
public VoiceAttackPlugin(string name, string version, string info, string guid)
|
||||
=> (this.Name, this.Version, this.Info, this.Guid)
|
||||
= (name, version, info, new (guid));
|
||||
|
||||
public string Version { get; set; }
|
||||
// this just hides the default constructor to make sure Properties are set.
|
||||
private VoiceAttackPlugin()
|
||||
{
|
||||
}
|
||||
|
||||
public string Info { get; set; }
|
||||
public event Action<VoiceAttackInitProxyClass>? Init;
|
||||
|
||||
public string Guid { get; set; }
|
||||
public event Action<VoiceAttackProxyClass>? Exit;
|
||||
|
||||
private dynamic? vaProxy;
|
||||
public event Action? Stop;
|
||||
|
||||
public HandlerList<Action<VoiceAttackInvokeProxyClass>> Contexts { get; set; } = new ();
|
||||
|
||||
public VoiceAttackInitProxyClass Proxy
|
||||
{
|
||||
get => this.vaProxy;
|
||||
}
|
||||
|
||||
public string Name { get; }
|
||||
|
||||
public string Version { get; }
|
||||
|
||||
public string Info { get; }
|
||||
|
||||
public Guid Guid { get; }
|
||||
|
||||
public VoiceAttackLog Log {
|
||||
get => this.log ??= new VoiceAttackLog(this.vaProxy, this.Name);
|
||||
}
|
||||
|
||||
private VoiceAttackLog log;
|
||||
|
||||
protected VoiceAttackInitProxyClass vaProxy;
|
||||
|
||||
public void Set<T>(string name, T? value)
|
||||
{
|
||||
switch (value)
|
||||
{
|
||||
case bool b:
|
||||
this.vaProxy.SetBoolean(name, b);
|
||||
break;
|
||||
case DateTime d:
|
||||
this.vaProxy.SetDate(name, d);
|
||||
break;
|
||||
case decimal d:
|
||||
this.vaProxy.SetDecimal(name, d);
|
||||
break;
|
||||
case int i:
|
||||
this.vaProxy.SetInt(name, i);
|
||||
break;
|
||||
case short s:
|
||||
this.vaProxy.SetSmallInt(name, s);
|
||||
break;
|
||||
case string s:
|
||||
this.vaProxy.SetText(name, s);
|
||||
break;
|
||||
default:
|
||||
throw new InvalidDataException($"Cannot set variable '{name}': invalid type '{typeof(T).Name}'.");
|
||||
}
|
||||
}
|
||||
|
||||
public T? Get<T>(string name)
|
||||
{
|
||||
dynamic? ret = null;
|
||||
|
||||
switch (default(T))
|
||||
{
|
||||
case bool _:
|
||||
ret = this.vaProxy.GetBoolean(name);
|
||||
break;
|
||||
case DateTime _:
|
||||
ret = this.vaProxy.GetDate(name);
|
||||
break;
|
||||
case decimal _:
|
||||
ret = this.vaProxy.GetDecimal(name);
|
||||
break;
|
||||
case int _:
|
||||
ret = this.vaProxy.GetInt(name);
|
||||
break;
|
||||
case short _:
|
||||
ret = this.vaProxy.GetSmallInt(name);
|
||||
break;
|
||||
case string _:
|
||||
ret = this.vaProxy.GetText(name);
|
||||
break;
|
||||
default:
|
||||
throw new InvalidDataException($"Cannot get variable '{name}': invalid type '{typeof(T).Name}'.");
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
public string VA_DisplayName() => $"{this.Name} v{this.Version}";
|
||||
|
||||
public string VA_DisplayInfo() => this.Info;
|
||||
|
||||
public Guid VA_Id() => new (this.Guid);
|
||||
public Guid VA_Id() => this.Guid;
|
||||
|
||||
public void VA_Init1(dynamic vaProxy)
|
||||
public void VA_Init1(VoiceAttackInitProxyClass vaProxy)
|
||||
{
|
||||
this.vaProxy = vaProxy;
|
||||
this.vaProxy.TextVariableChanged += new Action<string, string, string, Guid?>(this.TextVariableChanged);
|
||||
this.vaProxy.IntegerVariableChanged += new Action<string, int?, int?, Guid?>(this.IntegerVariableChanged);
|
||||
this.vaProxy.DecimalVariableChanged += new Action<string, decimal?, decimal?, Guid?>(this.DecimalVariableChanged);
|
||||
this.vaProxy.BooleanVariableChanged += new Action<string, bool?, bool?, Guid?>(this.BooleanVariableChanged);
|
||||
this.vaProxy.DateVariableChanged += new Action<string, DateTime?, DateTime?, Guid?>(this.DateVariableChanged);
|
||||
|
||||
this.Set<string>($"{this.Name}.version", this.Version);
|
||||
this.Log.Debug($"Initializing v{this.Version} …");
|
||||
|
||||
this.vaProxy.TextVariableChanged += this.TextVariableChanged;
|
||||
this.vaProxy.IntegerVariableChanged += this.IntegerVariableChanged;
|
||||
this.vaProxy.DecimalVariableChanged += this.DecimalVariableChanged;
|
||||
this.vaProxy.BooleanVariableChanged += this.BooleanVariableChanged;
|
||||
this.vaProxy.DateVariableChanged += this.DateVariableChanged;
|
||||
|
||||
this.Log.Debug("Running Init handlers …");
|
||||
this.Init?.Invoke(vaProxy);
|
||||
this.Log.Debug("Finished running Init handlers.");
|
||||
|
||||
this.Set<bool>($"{this.Name}.initialized", true);
|
||||
this.Log.Debug("Initialized.");
|
||||
}
|
||||
|
||||
public void VA_Invoke1(dynamic vaProxy)
|
||||
public void VA_Invoke1(VoiceAttackInvokeProxyClass vaProxy)
|
||||
{
|
||||
this.vaProxy = vaProxy;
|
||||
|
||||
string context = vaProxy.Context.ToLower();
|
||||
|
||||
try
|
||||
{
|
||||
bool exists = false;
|
||||
foreach (Action<VoiceAttackInvokeProxyClass> action in Contexts)
|
||||
{
|
||||
foreach (ContextAttribute attr in action.Method.GetCustomAttributes<ContextAttribute>())
|
||||
{
|
||||
if (attr.Name == context)
|
||||
{
|
||||
exists = true;
|
||||
action.Invoke(vaProxy);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!exists)
|
||||
{
|
||||
this.Log.Error($"Invalid plugin context '{vaProxy.Context}'.");
|
||||
}
|
||||
}
|
||||
catch (ArgumentNullException e)
|
||||
{
|
||||
this.Log.Error($"Missing parameter '{e.ParamName}' for context '{context}'");
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
this.Log.Error($"Unhandled exception while executing plugin context '{context}'. ({e.Message})");
|
||||
}
|
||||
}
|
||||
|
||||
public void VA_Exit1(dynamic vaProxy)
|
||||
public void VA_Exit1(VoiceAttackProxyClass vaProxy)
|
||||
{
|
||||
this.vaProxy = vaProxy;
|
||||
this.Exit?.Invoke(vaProxy);
|
||||
}
|
||||
|
||||
public void VA_StopCommand()
|
||||
{
|
||||
this.Stop?.Invoke();
|
||||
}
|
||||
|
||||
private void TextVariableChanged(string name, string from, string to, Guid? internalID = null)
|
||||
{ }
|
||||
{
|
||||
}
|
||||
|
||||
private void IntegerVariableChanged(string name, int? from, int? to, Guid? internalID = null)
|
||||
{ }
|
||||
{
|
||||
}
|
||||
|
||||
private void DecimalVariableChanged(string name, decimal? from, decimal? to, Guid? internalID = null)
|
||||
{ }
|
||||
protected void DecimalVariableChanged(string name, decimal? from, decimal? to, Guid? internalID = null)
|
||||
{
|
||||
}
|
||||
|
||||
private void BooleanVariableChanged(string name, bool? from, bool? to, Guid? internalID = null)
|
||||
{ }
|
||||
protected void BooleanVariableChanged(string name, bool? from, bool? to, Guid? internalID = null)
|
||||
{
|
||||
}
|
||||
|
||||
private void DateVariableChanged(string name, DateTime? from, DateTime? to, Guid? internalID = null)
|
||||
{ }
|
||||
protected void DateVariableChanged(string name, DateTime? from, DateTime? to, Guid? internalID = null)
|
||||
{
|
||||
}
|
||||
|
||||
public class HandlerList<T> : List<T>
|
||||
{
|
||||
public static HandlerList<T> operator +(HandlerList<T> handlers, T item)
|
||||
{
|
||||
handlers.Add(item);
|
||||
return handlers;
|
||||
}
|
||||
|
||||
public static HandlerList<T> operator -(HandlerList<T> handlers, T item)
|
||||
{
|
||||
handlers.Remove(item);
|
||||
return handlers;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
[AttributeUsage(AttributeTargets.Method, AllowMultiple = true)]
|
||||
public class ContextAttribute : Attribute
|
||||
{
|
||||
public string Name { get; }
|
||||
|
||||
public ContextAttribute(string context)
|
||||
{
|
||||
this.Name = context;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue