Luski.Net/Luski.net/Sound/Timer.cs

65 lines
1.9 KiB
C#
Raw Normal View History

2023-01-01 22:50:39 -05:00
using System;
using System.Runtime.InteropServices;
namespace Luski.net.Sound
{
internal class EventTimer
{
internal EventTimer()
{
m_DelegateTimeEvent = new Win32.TimerEventHandler(OnTimer);
}
private bool m_IsRunning = false;
private uint m_Milliseconds = 20;
private uint m_TimerId = 0;
private GCHandle m_GCHandleTimer;
private uint m_UserData = 0;
private uint m_ResolutionInMilliseconds = 0;
private readonly Win32.TimerEventHandler m_DelegateTimeEvent;
internal delegate void DelegateTimerTick();
internal event DelegateTimerTick? TimerTick;
internal void Start(uint milliseconds)
{
m_Milliseconds = milliseconds;
Win32.TimeCaps tc = new();
Win32.TimeGetDevCaps(ref tc, (uint)Marshal.SizeOf(typeof(Win32.TimeCaps)));
m_ResolutionInMilliseconds = Math.Max(tc.wPeriodMin, 0);
Win32.TimeBeginPeriod(m_ResolutionInMilliseconds);
m_TimerId = Win32.TimeSetEvent(m_Milliseconds, m_ResolutionInMilliseconds, m_DelegateTimeEvent, ref m_UserData, Win32.TIME_PERIODIC);
if (m_TimerId > 0)
{
m_GCHandleTimer = GCHandle.Alloc(m_TimerId, GCHandleType.Pinned);
m_IsRunning = true;
}
}
internal void Stop()
{
if (m_TimerId > 0)
{
_ = Win32.TimeKillEvent(m_TimerId);
Win32.TimeEndPeriod(m_ResolutionInMilliseconds);
if (m_GCHandleTimer.IsAllocated)
{
m_GCHandleTimer.Free();
}
m_TimerId = 0;
m_IsRunning = false;
}
}
private void OnTimer(uint id, uint msg, ref uint userCtx, uint rsv1, uint rsv2)
{
TimerTick?.Invoke();
}
}
}