2013-09-04 3 views
2

매우 길고 지루할 수있는 스위치/사례 또는 IF 부울 검사를 사용하는 대신 명령 처리 및 처리를위한 더 나은 방법을 찾을 수 있을지 궁금합니다.명령에서 동작하는 코드에서 음성 명령을 처리하는 스마트 방법

예컨대 :

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

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

명령이에 가면 ... 여기 내 스위치 문의 조각입니다 :

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 문과 스위치/사례 캐치를 조합하여 인식 된 명령을 잡습니다.

나는 어쨌든 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); 
+0

실제로 이것은 매우 공통적 인 문제입니다. 내가 열거 한 패턴들이 길 위에서 당신을 설정할 것입니다. – paqogomez

+0

더 많은 코드를 게시하면 아마도 내 대답을 더 자세히 설명 할 수 있습니다. – paqogomez

+0

예, 죄송합니다. 방금 좀 더 게시했습니다. –

답변

3

정의 here.

이렇게하면 여러 개의 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; 
     } 
    } 
} 
+0

나는이 아이디어를 정말 좋아한다! 오늘 그것을 실행 해보고 그것이 나에게 어떤 결과를 주는지 볼 것입니다. 덕분에 Paqogomez! –

+1

간단히 예쁘다! 예, 이것은 매우 우아하고 매력적입니다! 나는 아래에 완성 된 코드와 무응답을 게시 할 것이다. –

+1

내 질문에 내 버전의 코드를 게시했습니다. 매력을 발휘합니다! 감사. –