2008-11-16 4 views
2

기본적으로 이 로우 레버 ​​SlimDX 래퍼 라이브러리를 둘러 싸고 XBOX 360 컨트롤러에 대해 관리가 쉬운 API를 제공하는 작은 XBox 360 무선 컨트롤러 관리 인터페이스를 작성했습니다.타이머, UI 프레임 워크 및 불량 커플 링 - 모든 아이디어?

내부적으로 클래스는 N ms마다 게임 패드를 폴링하고 컨트롤러의 기본 상태 변화를 감지 할 때 이벤트를 촬영합니다.

내가 basiclly 적은 두 가지 악 사이에서 선택을 강요 타이머 죽은 것을 끝 약간의 경험 해요 :

  • 하나 내 XBox360GamePad 클래스 UI 프레임 워크의 특정을 (즉 지원 WPF/윈폼이 될 것입니다 클래스에서 하드 코딩되고 클래스는 이러한 프레임 워크를 참조해야합니다.)

  • 클래스를 완전히 프레임 워크에 독립적으로 설정하지만 Dispatcher.Invoke/Invoke() 호출로 코드를 뿌리도록 사용자에게 강요하십시오. 생성 된 이벤트에 따라 UI를 업데이트 할 수 있습니다.

내가 (불가지론 코드 UI를 만드는) 후자의 옵션을 선택하면, 나는 기본적으로 "일반적인"System.Timers.Timer 또는 어떤 UI 종속성이없는 모든 타이머를 사용합니다. 그런 경우에는 UI를 직접 업데이트 할 수없는 스레드 (즉, WPF)에서 발생하는 이벤트 생성/호출이 끝나면 Dispatcher의 (추악한) 사용을 통해 발생하는 모든 업데이트 양식을 360 컨트롤러 클래스로 보내야합니다. 호출.

반면 DispatcherTimer를 XBox 360 Controller 클래스에서 사용하는 경우 UI를 직접 업데이트 할 수있는 작동하는 구성 요소가 있지만 지금은 전체 컨트롤러 클래스가 WPF에 결합되어 있습니다. WPF에 의존하지 않고 사용할 수 있습니다. (즉, 순수한 콘솔 앱에서)

제가보기에는 일종의 정렬 솔루션으로 프레임 워크에 전혀 영향을 미치지 않고 UI를 업데이트 할 수 있습니다. Dispatcher.Invoke() 기법의 종류 ... 예를 들어 모든 타이머에 대한 공유 기본 클래스가있는 경우 관련 시나리오에 따라 종속성으로 타이머를 주입 할 수 있습니다. 누구든지이 정렬을 성공적으로 처리했습니다 문제가 뭐야?

답변

0

이렇게 ... 정보/코드 @http://geekswithblogs.net/robp/archive/2008/03/28/why-doesnt-dispatcher-implement-isynchronizeinvoke.aspx은 실제로 작동하는 해결책을 제공합니다. 코드는 모든 UI와 완전히 독립적이며 올바른 UI/스레드 통합을 위해 ISynchronizeInvoke에만 의존합니다.

방금이 문서를 사용 했음에도 불구하고 그대로두고 나가기를 여전히 다소 꺼려합니다.

내 문제의 요점은 모든 이벤트 호출 기능을 이런 식으로 뭔가를 보이는 것입니다 :

protected virtual void OnLeftThumbStickMove(ThumbStickEventArgs e) 
{ 
    if (LeftThumbStickMove == null) return; 

    if (_syncObj == null || !_syncObj.InvokeRequired) 
    LeftThumbStickMove(this, e); 
    else 
    _syncObj.BeginInvoke(LeftThumbStickMove, new object[] { this, e }); 
} 

그것은 코드 이런 식으로 작성하는 매우 성가신과 혼란, 그것은 너무 많은 소란 주위처럼, 나에게 보인다 그냥 일하는 것을 망 쳤어. 기본적으로 모든 이벤트 호출을 많은 논리로 랩핑하는 것을 좋아하지 않습니다.() 기본적으로 XBox360GamePad 클래스의 생성자는 다음과 같습니다.

public XBox360GamePad(UserIndex controllerIndex, Func<int, Action, object> timerSetupAction) 
{ 
    CurrentController = new Controller(controllerIndex); 
    _timerState = timerSetupAction(10, UpdateState); 
} 

여기서 알 수 있듯이 타이머 생성 및 연결을 담당하는 Func을 허용합니다.

는 기본적으로 360 개 컨트롤러 클래스 안쪽에 나는 본질적으로 ... 어떤 UI 특정 타이머를 사용할 필요가 없습니다 것을 의미 컨트롤러에 대한 내 "기본"생성자는 다음과 같습니다

public XBox360GamePad(UserIndex controllerIndex) : 
    this(controllerIndex, (i,f) => new Timer(delegate { f(); }, null, i, i)) {} 

저는 람다 함수를 사용하여 타이머 "service"에 컨트롤러 클래스의 종속성을 코딩합니다.

_gamePad = new XBox360GamePad(UserIndex.One, (i, f) => { 
    var t = new DispatcherTimer(DispatcherPriority.Render) {Interval = new TimeSpan(0, 0, 0, 0, i) }; 
    t.Tick += delegate { f(); }; 
    t.Start(); 
    return t; 
    }); 

이 방법은, 내가 기본적으로 타이머를 제공하기 위해 "사용자"에게 맡겨 :

는 WPF에서, 나는 컨트롤이 같은 DispatcherTimer를 사용하게 될 수 있도록 더 일반적인 생성자를 사용하여 기본 구현에서 WPF 또는 WinForms 특정 코드를 사용할 필요가없는 컨트롤 구현.

개인적으로 ISynchronizeInvoke를 사용하는 것보다이 유용하거나 더 멋진 디자인을 찾습니다.

나는이를 좋아하는 사람의 의견을 듣고 싶어요 /이 향상시키고 자 /로 혐오하는이 등 또한 마이크로 소프트 로봇의 일부인 동시성 및 조정 런타임, 한 번 봐 걸릴 수

1

폴링 아키텍처가 유일한 옵션입니까?

어쨌든 저는 개인적으로 외부 세계가 컨트롤러 클래스에서 시작된 이벤트를 구독 할 수 있도록 시스템을 재구성 할 것입니다.

오른쪽 스레드 컨텍스트에서 컨트롤러가 이벤트를 시작하게하려면 ISynchronizeInvoke 인터페이스에 대한 속성을 추가하고이 속성이 컨트롤러 내부에서 null이 아닌 경우 인터페이스를 사용하십시오. 그렇지 않으면 인터페이스를 사용하십시오. 이벤트가 컨트롤러에서 실행되는 스레드에서 직접 발생합니다.

예를 들어 전체 폴링 작업을 N 밀리 초마다 실행하여 작업을 수행하거나 이벤트 객체를 사용하여 이벤트를 기다릴 수 있습니다 (360 컨트롤러 아키텍처에 이와 비슷한 기능이있는 경우) .

0

360 컨트롤러는 현재 상태 만보고 할 수 있습니다. 폴링하지 않고 상태를 가져 오는 다른 방법은 없습니다. System.Threading.Timer를 사용하거나 Thread.Sleep()을 실행하는 새 스레드를 여는 것은 내보기에서 실제로 동일합니다. 둘 다 UI가없는 타이머 클래스의 기능을 수행합니다.

덕분에 ISynchronizeInvoke 언급, 나는 좀 더 봤 내 고통을 공유하고 심지어 솔루션있을 수 있습니다 사람을 발견했습니다 : 나는 그의 코드를 시도하고이 스레드에 게시하겠습니다 http://geekswithblogs.net/robp/archive/2008/03/28/why-doesnt-dispatcher-implement-isynchronizeinvoke.aspx

을 ... 감사합니다 팁!

0

개발자 Studio (그러나 곧 독립형 제품이 될 예정입니다).

CCR은 MRDS가 로봇을 조종하는 조이스틱을 완벽하게 지원하고 메시지 전달 모델에서 작동 할 수있게 해주는 스레드 조정자입니다. XBox 조이스틱에서 데이터를 요청하는 타이머를 설정할 수 있으며, 데이터를 포트 (대기열)에 게시합니다. 그런 다음 데이터를 조이스틱 포트에 게시 할 때 호출되는 (수신자) 메소드를 설정하여 조치를 처리합니다. WinForms 용 어댑터가 제공되며 WPF 용 어댑터를 작성하는 것은 어렵지 않습니다.

본격적인 MRDS없이 CCR을 사용하는 방법을 보여주는 멋진 기사가 있습니다. http://msdn.microsoft.com/en-us/magazine/cc163556.aspx

내 경험에 따르면, CCR의 기본 지식을 얻은 후에는 멀티 스레드 동시 비동기 프로그래밍을 수행하는 것이 실제로 쉽습니다.

0

@MattValerio : CCR에 대해 알고 있습니다. 그러나 googlecode에 대한 제어 권한을 부여 할 계획이므로 여기에 맞지 않습니다. CCR은 프레임 워크 또는 opensource의 일부가 아닙니다.

관련 문제