@@ -16,6 +16,8 @@ public sealed class Win2DCoreRunner : ICoreRunner, IDisposable
1616 private readonly IAudioPlayer AudioPlayer ;
1717 private readonly IInputManager InputManager ;
1818
19+ private TaskCompletionSource < bool > RequestedCoreOperationTCS ;
20+
1921 private CoreCoordinator Coordinator ;
2022
2123 public string GameID { get ; private set ; }
@@ -61,64 +63,74 @@ public void Dispose()
6163
6264 public IAsyncOperation < bool > LoadGameAsync ( ICore core , string mainGameFilePath )
6365 {
64- return Task . Run ( async ( ) =>
66+ if ( RequestedCoreOperationTCS != null )
6567 {
66- while ( Coordinator == null )
68+ return Task . FromResult ( false ) . AsAsyncOperation ( ) ;
69+ }
70+
71+ Func < bool > state = ( ) =>
72+ {
73+ GameID = null ;
74+ CoreIsExecuting = false ;
75+ Coordinator . AudioPlayer ? . Stop ( ) ;
76+
77+ if ( Coordinator . Core != core )
6778 {
68- //Ensure core doesn't try rendering before Win2D is ready.
69- //Some games load faster than the Win2D canvas is initialized
70- await Task . Delay ( 100 ) ;
79+ Coordinator . Core ? . UnloadGame ( ) ;
80+ Coordinator . Core = core ;
7181 }
7282
73- lock ( Coordinator )
83+ if ( core . LoadGame ( mainGameFilePath ) == false )
7484 {
75- GameID = null ;
76- CoreIsExecuting = false ;
77- Coordinator . AudioPlayer ? . Stop ( ) ;
78-
79- if ( Coordinator . Core != core )
80- {
81- Coordinator . Core ? . UnloadGame ( ) ;
82- Coordinator . Core = core ;
83- }
85+ return false ;
86+ }
8487
85- if ( core . LoadGame ( mainGameFilePath ) == false )
86- {
87- return false ;
88- }
88+ RenderTargetManager . InitializeVideoParameters ( core ) ;
89+ GameID = mainGameFilePath ;
90+ CoreIsExecuting = true ;
91+ return true ;
92+ } ;
8993
90- RenderTargetManager . InitializeVideoParameters ( core ) ;
91- GameID = mainGameFilePath ;
92- CoreIsExecuting = true ;
93- return true ;
94- }
95- } ) . AsAsyncOperation ( ) ;
94+ RequestedCoreOperationTCS = new TaskCompletionSource < bool > ( state ) ;
95+ return RequestedCoreOperationTCS . Task . AsAsyncOperation ( ) ;
9696 }
9797
9898 public IAsyncAction UnloadGameAsync ( )
9999 {
100- return Task . Run ( ( ) =>
100+ if ( RequestedCoreOperationTCS != null )
101101 {
102- lock ( Coordinator )
103- {
104- GameID = null ;
105- CoreIsExecuting = false ;
106- Coordinator . Core ? . UnloadGame ( ) ;
107- Coordinator . AudioPlayer ? . Stop ( ) ;
108- }
109- } ) . AsAsyncAction ( ) ;
102+ return Task . FromResult ( false ) . AsAsyncAction ( ) ;
103+ }
104+
105+ Func < bool > state = ( ) =>
106+ {
107+ GameID = null ;
108+ CoreIsExecuting = false ;
109+ Coordinator . Core ? . UnloadGame ( ) ;
110+ Coordinator . AudioPlayer ? . Stop ( ) ;
111+ return true ;
112+ } ;
113+
114+ RequestedCoreOperationTCS = new TaskCompletionSource < bool > ( state ) ;
115+ return RequestedCoreOperationTCS . Task . AsAsyncAction ( ) ;
110116 }
111117
112118 public IAsyncAction ResetGameAsync ( )
113119 {
114- return Task . Run ( ( ) =>
120+ if ( RequestedCoreOperationTCS != null )
115121 {
116- lock ( Coordinator )
117- {
118- Coordinator . AudioPlayer ? . Stop ( ) ;
119- Coordinator . Core ? . Reset ( ) ;
120- }
121- } ) . AsAsyncAction ( ) ;
122+ return Task . FromResult ( false ) . AsAsyncAction ( ) ;
123+ }
124+
125+ Func < bool > state = ( ) =>
126+ {
127+ Coordinator . AudioPlayer ? . Stop ( ) ;
128+ Coordinator . Core ? . Reset ( ) ;
129+ return true ;
130+ } ;
131+
132+ RequestedCoreOperationTCS = new TaskCompletionSource < bool > ( state ) ;
133+ return RequestedCoreOperationTCS . Task . AsAsyncAction ( ) ;
122134 }
123135
124136 public IAsyncAction PauseCoreExecutionAsync ( )
@@ -146,32 +158,42 @@ public IAsyncAction ResumeCoreExecutionAsync()
146158
147159 public IAsyncOperation < bool > SaveGameStateAsync ( [ WriteOnlyArray ] byte [ ] stateData )
148160 {
149- return Task . Run ( ( ) =>
161+ if ( RequestedCoreOperationTCS != null )
150162 {
151- lock ( Coordinator )
152- {
153- var core = Coordinator . Core ;
154- if ( core == null )
155- return false ;
163+ return Task . FromResult ( false ) . AsAsyncOperation ( ) ;
164+ }
156165
157- return core . Serialize ( stateData ) ;
158- }
159- } ) . AsAsyncOperation ( ) ;
166+ Func < bool > state = ( ) =>
167+ {
168+ var core = Coordinator . Core ;
169+ if ( core == null )
170+ return false ;
171+
172+ return core . Serialize ( stateData ) ;
173+ } ;
174+
175+ RequestedCoreOperationTCS = new TaskCompletionSource < bool > ( state ) ;
176+ return RequestedCoreOperationTCS . Task . AsAsyncOperation ( ) ;
160177 }
161178
162179 public IAsyncOperation < bool > LoadGameStateAsync ( [ ReadOnlyArray ] byte [ ] stateData )
163180 {
164- return Task . Run ( ( ) =>
181+ if ( RequestedCoreOperationTCS != null )
165182 {
166- lock ( Coordinator )
167- {
168- var core = Coordinator . Core ;
169- if ( core == null )
170- return false ;
183+ return Task . FromResult ( false ) . AsAsyncOperation ( ) ;
184+ }
171185
172- return core . Unserialize ( stateData ) ;
173- }
174- } ) . AsAsyncOperation ( ) ;
186+ Func < bool > state = ( ) =>
187+ {
188+ var core = Coordinator . Core ;
189+ if ( core == null )
190+ return false ;
191+
192+ return core . Unserialize ( stateData ) ;
193+ } ;
194+
195+ RequestedCoreOperationTCS = new TaskCompletionSource < bool > ( state ) ;
196+ return RequestedCoreOperationTCS . Task . AsAsyncOperation ( ) ;
175197 }
176198
177199 private void RenderPanelUnloaded ( object sender , Windows . UI . Xaml . RoutedEventArgs e )
@@ -207,6 +229,14 @@ private void RenderPanelUpdate(ICanvasAnimatedControl sender, CanvasAnimatedUpda
207229 {
208230 lock ( Coordinator )
209231 {
232+ if ( RequestedCoreOperationTCS != null )
233+ {
234+ var requestedOperation = ( Func < bool > ) RequestedCoreOperationTCS . Task . AsyncState ;
235+ var result = requestedOperation . Invoke ( ) ;
236+ RequestedCoreOperationTCS . SetResult ( result ) ;
237+ RequestedCoreOperationTCS = null ;
238+ }
239+
210240 if ( CoreIsExecuting && ! Coordinator . AudioPlayerRequestsFrameDelay )
211241 {
212242 try
0 commit comments