2

Switch/Case または IF Boolean チェックを使用するのではなく、非常に長く非常に退屈になる可能性があるため、コマンドを処理および処理するためのより良い方法を探すことができるのではないかと考えています。

例えば:

if(settings.getName == Command)
{
Speak("I am here");
}

if("Get News Feed" == Command)
{
MyRSSFeed RSSNewsFeed = new MyRSSFeed();
RSSNewsFeed.GetFeed();
}

if コマンドは続きます... これが私の Switch ステートメントのスニペットです。

switch (Command)
        {
            #region <-- Get Time Command -->

            case "Time Please":
            case "Whats the Time":
            case "What Time is it":
                GetCurrentTime();
                break;

            #endregion <-- Get Time Command -->

            #region <-- Get Date Command -->

            case "Whats the Date":
            case "What Date is it":
            case "Whats the Date Today":
            case "What is the Date Today":
                GetCurrentDate();
                break;

            #endregion <-- Get Date Command -->


            #region <-- Media Player Commands -->

            case "Play Bamboo Forest":

                Data.MusicPlayer.Play(@"\Bamboo Forest Play List.wpl");

                break;

            case "Next Song":

                Data.MusicPlayer.Next();

                break;

            case "Previous Song":

                Data.MusicPlayer.Previous();

                break;

            case "Stop Music":

                Data.MusicPlayer.Stop();

                break;

            case "Pause Music":

                Data.MusicPlayer.Pause();

                break;

            case "Resume Music":

                Data.MusicPlayer.Resume();

                break;


            case "Mute Music":

                Data.MusicPlayer.Mute();

                break;

            case "Volume Up":

                Data.MusicPlayer.VolumeUp();

                break;

            case "Volume Down":

                Data.MusicPlayer.VolumeDown();

                break;

            #endregion <-- Media Player Commands -->

            #region <-- Voice Recognition Control Commands -->

            case "Stop Listening":
                Audio.Listen.NewCommandRecognitionEngine.RecognizeAsyncCancel();
                Audio.Voice.Speak("Ok");
                Audio.Listen.Initialise(main);
                break;

            #endregion <-- Voice Recognition Control Commands -->

            #region <-- Application Commands -->

            case "Quiet":
                Audio.Voice.Stop();
                break;

            case "Download":
                Audio.Voice.Speak("Opening Download Window.");
                main.dlInterface.ShowBitsJobs();
                break;

            case "Settings":
                Audio.Voice.Speak("Opening Settings Window.");
                main.settings.Show();
                break;

            case "Close":
                if (main.dlInterface.Visable == true)
                {
                    main.dlInterface.Hide();
                    Audio.Voice.Speak("Closing Download Window.");
                }
                if (main.settings.Visible == true)
                {
                    main.settings.Hide();
                    Audio.Voice.Speak("Closing Settings Window.");
                }
                break;

            case "Out of the way":
                if (main.WindowState == System.Windows.Forms.FormWindowState.Normal)
                {
                    main.WindowState = System.Windows.Forms.FormWindowState.Minimized;
                    Audio.Voice.Speak("My apologies");
                }
                break;

            case "Where Are You":
                if (main.WindowState == System.Windows.Forms.FormWindowState.Minimized)
                {
                    main.WindowState = System.Windows.Forms.FormWindowState.Normal;
                    Audio.Voice.Speak("Here");
                }
                break;


            default:
                // Do Nothing here...
                break;
        }

コマンドを含む SQL データベースがあります。必要に応じてコマンドをロードします。コマンド名列と値列があります。これらを変更して、必要に応じて列を追加または削除できます。

現在、コマンドが認識されると、IF ステートメントと Switch/Case Catch の組み合わせを使用して、認識されたコマンドをキャッチします。

どうにかして dll をフォルダーにドロップし、アプリの読み込み時にスキャンする方法を考えました。コマンドを追加すると、何らかの方法で値フィールドを使用して、dll でコマンドを実行します。

これはかなり複雑な状況であることは承知していますが、このプロセスをより簡単にするためのより良い解決策が見つかると思います。

編集:私はすでにこれを見てきました: http://social.msdn.microsoft.com/Forums/en-US/4f962dc0-aec2-4191-9fe2-e1dfeb1da5dd/voice-command-api

さらに情報が必要な場合はお尋ねください。

[編集] Paqogomez はこの質問に答えました。以下の私の作業例を参照してください。

using System;
using System.Linq;
using MyApp.AppCommands;
using System.Reflection;
using System.Collections.Generic;

namespace MyApp
{
class Program
{
static void Main(string[] args)
{
MethodInfo myMethod;

var methods = new Commands();

myMethod = CommandFactory.GetCommandMethods("Time Please");
myMethod.Invoke(methods, null);

myMethod = CommandFactory.GetCommandMethods("Volume Down");
myMethod.Invoke(methods, null);

myMethod = CommandFactory.GetCommandMethods("Volume Up");
myMethod.Invoke(methods, null);

Console.ReadLine();
}
}

public static class CommandFactory
{
private static Dictionary<string, MethodInfo> commandMethods = new Dictionary<string, MethodInfo>();

public static MethodInfo GetCommandMethods(string Command)
{
MethodInfo methodInfo;

var myCommandMethods = new Commands();

if (commandMethods.Count == 0)
{
var methodNames = typeof(Commands).GetMethods(BindingFlags.Public | BindingFlags.DeclaredOnly | BindingFlags.Instance);

var speechAttributeMethods = methodNames.Where(y => y.GetCustomAttributes().OfType<CommandAttribute>().Any());

foreach (var speechAttributeMethod in speechAttributeMethods)
{
foreach (var attribute in speechAttributeMethod.GetCustomAttributes(true))
{
commandMethods.Add(((CommandAttribute)attribute).CommandValue, speechAttributeMethod);
}
}
methodInfo = commandMethods[Command];
}
else
{
methodInfo = commandMethods[Command];
}

return methodInfo;
}
}
}

namespace MyApp.AppCommands
{
public class Commands
{
[Command("Time Please")]
[Command("Whats the Time")]
[Command("What Time is it")]
public void GetTime()
{
Console.WriteLine(DateTime.Now.ToLocalTime());
}

[Command("Volume Down")]
public void VolumeDown()
{
Console.WriteLine("Volume Down 1");
}

[Command("Volume Up")]
public void VolumeUp()
{
Console.WriteLine("Volume Up 1");
}
}

[System.AttributeUsage(System.AttributeTargets.Method, AllowMultiple = true)]
public class CommandAttribute : System.Attribute
{
public string CommandValue { get; set; }

public CommandAttribute(string textValue)
{
this.CommandValue = textValue;
}
}
}

美しい作品 Paqogomez と共有してくれてありがとう! これは高速で非常にエレガントです!.

私の場合、コードを呼び出す必要があるのは次のとおりです。

private static void CommandRecognized(object sender, SpeechRecognizedEventArgs e)
{
MethodInfo myMethod;

var methods = new Commands();

myMethod = CommandFactory.GetCommandMethods(e.Result.Text);
myMethod.Invoke(methods, null);
}

これは、音声認識エンジンのイベント ハンドラーです。

CommandRecognitionEngine.SpeechRecognized += new EventHandler<SpeechRecognizedEventArgs>(CommandRecognized);
4

1 に答える 1

3

here で定義されている Strategy パターンを探しています。

これにより、複数の if ステートメントを非常に簡単に処理できます。

工場のパターンもあなたに合っているかもしれません. ファクトリはリフレクションを使用して、作成するコマンドを決定できます。

すべてのコマンドを辞書にダンプすることもできます。

編集:

コード例の最後のビットを考えると、ファクトリが必要です。以下に一つにまとめました。

ファクトリは単に 内のすべてのメソッドを反映し、 を持つメソッドをMySpeechMethods探して、呼び出すためにSpeechAttributesを送り返します。MethodInfoメソッドからの戻り値が必要な場合は、すべてのメソッドを同じ型 (文字列など) を返すように設定するか、ジェネリックを調べることができますが、それはあなたに任せます。:)

using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using MyApp.SpeechMethods;

namespace MyApp
{
    class Program
    {
        static void Main(string[] args)
        {
            var methods = new MySpeechMethods();
            MethodInfo myMethod;
            myMethod = SpeechFactory.GetSpeechMethod("Time Please");
            myMethod.Invoke(methods, null);
            myMethod = SpeechFactory.GetSpeechMethod("Volume Down");
            myMethod.Invoke(methods, null);
            myMethod = SpeechFactory.GetSpeechMethod("Volume Up");
            myMethod.Invoke(methods, null);
        }
    }

    public static class SpeechFactory
    {
        private static Dictionary<string, MethodInfo> speechMethods = new Dictionary<string, MethodInfo>();
        public static MethodInfo GetSpeechMethod(string speechText)
        {
            MethodInfo methodInfo;
            var mySpeechMethods = new MySpeechMethods();
            if (speechMethods.Count == 0)
            {
                var methodNames =
                    typeof (MySpeechMethods).GetMethods(BindingFlags.Public | BindingFlags.DeclaredOnly | BindingFlags.Instance);
                var speechAttributeMethods = methodNames.Where(y => y.GetCustomAttributes().OfType<SpeechAttribute>().Any());
                foreach (var speechAttributeMethod in speechAttributeMethods)
                {
                    foreach (var attribute in speechAttributeMethod.GetCustomAttributes(true))
                    {
                        speechMethods.Add(((SpeechAttribute)attribute).SpeechValue, speechAttributeMethod);
                    }
                }
                methodInfo = speechMethods[speechText];
            }
            else
            {
                methodInfo = speechMethods[speechText];
            }

            return methodInfo;
        }
    }
}

namespace MyApp.SpeechMethods
{
    public class MySpeechMethods
    {
        [Speech("Time Please")]
        [Speech("Whats the Time")]
        [Speech("What Time is it")]
        public void GetTime()
        {
            Console.WriteLine(DateTime.Now.ToLocalTime());
        }

        [Speech("Volume Down")]
        public void VolumeDown()
        {
            Console.WriteLine("Volume Down 1");
        }

        [Speech("Volume Up")]
        public void VolumeUp()
        {
            Console.WriteLine("Volume Up 1");
        }
    }

    [System.AttributeUsage(System.AttributeTargets.Method, AllowMultiple = true)]
    public class SpeechAttribute : System.Attribute
    {
        public string SpeechValue { get; set; }

        public SpeechAttribute(string textValue)
        {
            this.SpeechValue = textValue;
        }
    }
}
于 2013-09-04T03:42:50.077 に答える