Skip to content

Commit 5db5761

Browse files
committed
Return exact error code from native methods
2 parents da96575 + 085f64f commit 5db5761

39 files changed

+1204
-1292
lines changed

DryWetMidi.Tests/Multimedia/Playback/CurrentTimeWatcher/PlaybackCurrentTimeWatcherTests.Common.cs

Lines changed: 15 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
using NUnit.Framework;
88
using Melanchall.DryWetMidi.Tests.Common;
99
using NUnit.Framework.Legacy;
10+
using System.Diagnostics;
1011

1112
namespace Melanchall.DryWetMidi.Tests.Multimedia
1213
{
@@ -284,25 +285,32 @@ public void DisposePlaybackCurrentTimeWatcher()
284285
new NoteOffEvent()
285286
};
286287

287-
var objects = new List<object>();
288-
var objectsCount = 0;
288+
var times = new List<long>();
289+
var stopwatch = new Stopwatch();
290+
291+
int timesCount;
292+
long stoptime;
289293

290294
using (var playback = events.GetPlayback(TempoMap.Default))
291295
using (var watcher = new PlaybackCurrentTimeWatcher())
292296
{
293297
watcher.AddPlayback(playback);
294-
watcher.CurrentTimeChanged += (_, __) => objects.Add(new object());
298+
watcher.CurrentTimeChanged += (_, __) => times.Add(stopwatch.ElapsedMilliseconds);
295299

296300
watcher.Start();
301+
stopwatch.Start();
297302
WaitOperations.WaitPrecisely(TimeSpan.FromSeconds(1));
298303
watcher.Stop();
299-
300-
objectsCount = objects.Count;
301-
ClassicAssert.Greater(objectsCount, 0, "Objects count is invalid.");
304+
305+
stoptime = stopwatch.ElapsedMilliseconds;
306+
timesCount = times.Count;
302307
}
303308

304309
WaitOperations.Wait(TimeSpan.FromSeconds(1));
305-
ClassicAssert.AreEqual(objectsCount, objects.Count, "New objects added after watcher disposed.");
310+
311+
ClassicAssert.Greater(timesCount, 0, "No events fired.");
312+
ClassicAssert.AreEqual(timesCount, times.Count(o => o <= stoptime), "Invalid count of fired event.");
313+
ClassicAssert.LessOrEqual(times.Count(o => o > stoptime), 1, "Event was fired many times after watcher stopped.");
306314
}
307315

308316
#endregion

DryWetMidi/Multimedia/Clock/TickGenerator/HighPrecisionTickGenerator.cs

Lines changed: 25 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -67,18 +67,21 @@ protected override void Start(TimeSpan interval)
6767

6868
var intervalInMilliseconds = (int)interval.TotalMilliseconds;
6969

70-
var apiType = CommonApiProvider.Api.Api_GetApiType();
70+
var apiType = CommonApi.Api_GetApiType();
7171
var sessionHandle = TickGeneratorSession.GetSessionHandle();
7272

73+
TickGeneratorApi.TG_STARTRESULT result;
74+
int errorCode;
75+
7376
switch (apiType)
7477
{
7578
case CommonApi.API_TYPE.API_TYPE_WIN:
76-
NativeApiUtilities.HandleTickGeneratorNativeApiResult(
77-
StartHighPrecisionTickGenerator_Win(intervalInMilliseconds, out _tickGeneratorInfo));
79+
result = StartHighPrecisionTickGenerator_Win(intervalInMilliseconds, out _tickGeneratorInfo, out errorCode);
80+
NativeApiUtilities.HandleTickGeneratorNativeApiResult(result, errorCode);
7881
break;
7982
case CommonApi.API_TYPE.API_TYPE_MAC:
80-
NativeApiUtilities.HandleTickGeneratorNativeApiResult(
81-
StartHighPrecisionTickGenerator_Mac(intervalInMilliseconds, out _tickGeneratorInfo));
83+
result = StartHighPrecisionTickGenerator_Mac(intervalInMilliseconds, out _tickGeneratorInfo, out errorCode);
84+
NativeApiUtilities.HandleTickGeneratorNativeApiResult(result, errorCode);
8285
break;
8386
}
8487
}
@@ -88,8 +91,9 @@ protected override void Start(TimeSpan interval)
8891
/// </summary>
8992
protected override void Stop()
9093
{
91-
NativeApiUtilities.HandleTickGeneratorNativeApiResult(
92-
StopInternal());
94+
int errorCode;
95+
var result = StopInternal(out errorCode);
96+
NativeApiUtilities.HandleTickGeneratorNativeApiResult(result, errorCode);
9397
}
9498

9599
#endregion
@@ -114,8 +118,10 @@ private void OnTick()
114118
GenerateTick();
115119
}
116120

117-
private TickGeneratorApi.TG_STOPRESULT StopInternal()
121+
private TickGeneratorApi.TG_STOPRESULT StopInternal(out int errorCode)
118122
{
123+
errorCode = 0;
124+
119125
if (_tickGeneratorInfo == IntPtr.Zero)
120126
return TickGeneratorApi.TG_STOPRESULT.TG_STOPRESULT_OK;
121127

@@ -124,30 +130,32 @@ private TickGeneratorApi.TG_STOPRESULT StopInternal()
124130
if (_tickGeneratorInfo == IntPtr.Zero)
125131
return TickGeneratorApi.TG_STOPRESULT.TG_STOPRESULT_OK;
126132

127-
var result = TickGeneratorApiProvider.Api.Api_StopHighPrecisionTickGenerator(TickGeneratorSession.GetSessionHandle(), _tickGeneratorInfo);
133+
var result = TickGeneratorApi.Api_StopHighPrecisionTickGenerator(TickGeneratorSession.GetSessionHandle(), _tickGeneratorInfo, out errorCode);
128134
_tickGeneratorInfo = IntPtr.Zero;
129135
return result;
130136
}
131137
}
132138

133-
private TickGeneratorApi.TG_STARTRESULT StartHighPrecisionTickGenerator_Win(int intervalInMilliseconds, out IntPtr tickGeneratorInfo)
139+
private TickGeneratorApi.TG_STARTRESULT StartHighPrecisionTickGenerator_Win(int intervalInMilliseconds, out IntPtr tickGeneratorInfo, out int errorCode)
134140
{
135141
_tickCallback_Win = OnTick_Win;
136-
return TickGeneratorApiProvider.Api.Api_StartHighPrecisionTickGenerator_Win(
142+
return TickGeneratorApi.Api_StartHighPrecisionTickGenerator_Win(
137143
intervalInMilliseconds,
138144
TickGeneratorSession.GetSessionHandle(),
139145
_tickCallback_Win,
140-
out tickGeneratorInfo);
146+
out tickGeneratorInfo,
147+
out errorCode);
141148
}
142149

143-
private TickGeneratorApi.TG_STARTRESULT StartHighPrecisionTickGenerator_Mac(int intervalInMilliseconds, out IntPtr tickGeneratorInfo)
150+
private TickGeneratorApi.TG_STARTRESULT StartHighPrecisionTickGenerator_Mac(int intervalInMilliseconds, out IntPtr tickGeneratorInfo, out int errorCode)
144151
{
145152
_tickCallback_Mac = OnTick_Mac;
146-
return TickGeneratorApiProvider.Api.Api_StartHighPrecisionTickGenerator_Mac(
153+
return TickGeneratorApi.Api_StartHighPrecisionTickGenerator_Mac(
147154
intervalInMilliseconds,
148155
TickGeneratorSession.GetSessionHandle(),
149156
_tickCallback_Mac,
150-
out tickGeneratorInfo);
157+
out tickGeneratorInfo,
158+
out errorCode);
151159
}
152160

153161
private void EnsureSessionIsCreated()
@@ -180,7 +188,8 @@ protected override void Dispose(bool disposing)
180188
{
181189
}
182190

183-
StopInternal();
191+
int errorCode;
192+
StopInternal(out errorCode);
184193

185194
_disposed = true;
186195
}

DryWetMidi/Multimedia/Clock/TickGenerator/Session/TickGeneratorSession.cs

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -16,16 +16,20 @@ internal static class TickGeneratorSession
1616

1717
public static IntPtr GetSessionHandle()
1818
{
19-
lock (_lockObject)
19+
if (_handle == IntPtr.Zero)
2020
{
21-
if (_handle == IntPtr.Zero)
21+
lock (_lockObject)
2222
{
23-
NativeApiUtilities.HandleTickGeneratorNativeApiResult(
24-
TickGeneratorSessionApiProvider.Api.Api_OpenSession(out _handle));
23+
if (_handle == IntPtr.Zero)
24+
{
25+
int errorCode;
26+
var result = TickGeneratorSessionApi.Api_OpenSession(out _handle, out errorCode);
27+
NativeApiUtilities.HandleTickGeneratorNativeApiResult(result, errorCode);
28+
}
2529
}
26-
27-
return _handle;
2830
}
31+
32+
return _handle;
2933
}
3034

3135
#endregion

DryWetMidi/Multimedia/Clock/TickGenerator/Session/TickGeneratorSessionApi.cs

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,9 @@
11
using System;
2+
using System.Runtime.InteropServices;
23

34
namespace Melanchall.DryWetMidi.Multimedia
45
{
5-
internal abstract class TickGeneratorSessionApi : NativeApi
6+
internal static class TickGeneratorSessionApi
67
{
78
#region Nested enums
89

@@ -22,9 +23,19 @@ public enum TGSESSION_CLOSERESULT
2223

2324
#endregion
2425

26+
#region Extern functions
27+
28+
[DllImport(NativeApi.LibraryName, ExactSpelling = true, CallingConvention = CallingConvention.StdCall)]
29+
private static extern TGSESSION_OPENRESULT OpenTickGeneratorSession(out IntPtr handle, out int errorCode);
30+
31+
#endregion
32+
2533
#region Methods
2634

27-
public abstract TGSESSION_OPENRESULT Api_OpenSession(out IntPtr handle);
35+
public static TGSESSION_OPENRESULT Api_OpenSession(out IntPtr handle, out int errorCode)
36+
{
37+
return OpenTickGeneratorSession(out handle, out errorCode);
38+
}
2839

2940
#endregion
3041
}

DryWetMidi/Multimedia/Clock/TickGenerator/Session/TickGeneratorSessionApi64.cs

Lines changed: 0 additions & 30 deletions
This file was deleted.

DryWetMidi/Multimedia/Clock/TickGenerator/Session/TickGeneratorSessionApiProvider.cs

Lines changed: 0 additions & 26 deletions
This file was deleted.

DryWetMidi/Multimedia/Clock/TickGenerator/TickGeneratorApi.cs

Lines changed: 27 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,9 @@
11
using System;
2+
using System.Runtime.InteropServices;
23

34
namespace Melanchall.DryWetMidi.Multimedia
45
{
5-
internal abstract class TickGeneratorApi : NativeApi
6+
internal static class TickGeneratorApi
67
{
78
#region Nested enums
89

@@ -36,13 +37,35 @@ public enum TG_STOPRESULT
3637

3738
#endregion
3839

40+
#region Extern functions
41+
42+
[DllImport(NativeApi.LibraryName, ExactSpelling = true, CallingConvention = CallingConvention.StdCall)]
43+
public static extern TG_STARTRESULT StartHighPrecisionTickGenerator_Win(int interval, IntPtr sessionHandle, TimerCallback_Win callback, out IntPtr info, out int errorCode);
44+
45+
[DllImport(NativeApi.LibraryName, ExactSpelling = true, CallingConvention = CallingConvention.StdCall)]
46+
public static extern TG_STARTRESULT StartHighPrecisionTickGenerator_Mac(int interval, IntPtr sessionHandle, TimerCallback_Mac callback, out IntPtr info, out int errorCode);
47+
48+
[DllImport(NativeApi.LibraryName, ExactSpelling = true, CallingConvention = CallingConvention.StdCall)]
49+
public static extern TG_STOPRESULT StopHighPrecisionTickGenerator(IntPtr sessionHandle, IntPtr info, out int errorCode);
50+
51+
#endregion
52+
3953
#region Methods
4054

41-
public abstract TG_STARTRESULT Api_StartHighPrecisionTickGenerator_Win(int interval, IntPtr sessionHandle, TimerCallback_Win callback, out IntPtr info);
55+
public static TG_STARTRESULT Api_StartHighPrecisionTickGenerator_Win(int interval, IntPtr sessionHandle, TimerCallback_Win callback, out IntPtr info, out int errorCode)
56+
{
57+
return StartHighPrecisionTickGenerator_Win(interval, sessionHandle, callback, out info, out errorCode);
58+
}
4259

43-
public abstract TG_STARTRESULT Api_StartHighPrecisionTickGenerator_Mac(int interval, IntPtr sessionHandle, TimerCallback_Mac callback, out IntPtr info);
60+
public static TG_STARTRESULT Api_StartHighPrecisionTickGenerator_Mac(int interval, IntPtr sessionHandle, TimerCallback_Mac callback, out IntPtr info, out int errorCode)
61+
{
62+
return StartHighPrecisionTickGenerator_Mac(interval, sessionHandle, callback, out info, out errorCode);
63+
}
4464

45-
public abstract TG_STOPRESULT Api_StopHighPrecisionTickGenerator(IntPtr sessionHandle, IntPtr info);
65+
public static TG_STOPRESULT Api_StopHighPrecisionTickGenerator(IntPtr sessionHandle, IntPtr info, out int errorCode)
66+
{
67+
return StopHighPrecisionTickGenerator(sessionHandle, info, out errorCode);
68+
}
4669

4770
#endregion
4871
}

DryWetMidi/Multimedia/Clock/TickGenerator/TickGeneratorApi64.cs

Lines changed: 0 additions & 46 deletions
This file was deleted.

DryWetMidi/Multimedia/Clock/TickGenerator/TickGeneratorApiProvider.cs

Lines changed: 0 additions & 26 deletions
This file was deleted.

0 commit comments

Comments
 (0)