Skip to content

Commit

Permalink
More sim wokr
Browse files Browse the repository at this point in the history
  • Loading branch information
ThadHouse committed Mar 5, 2024
1 parent 5e4965e commit a69c32a
Show file tree
Hide file tree
Showing 2 changed files with 79 additions and 0 deletions.
19 changes: 19 additions & 0 deletions src/wpilibsharp/Simulation/AddressableLEDSim.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
using WPIHal;
using WPIHal.Natives.Simulation;

namespace WPILib.Simulation;

public class AddressableLEDSim
{
private readonly int m_index;

public AddressableLEDSim()
{
m_index = 0;
}

public unsafe CallbackStore registerInitializedCallback(Action<string, HalValue> callback, bool initialNotify)
{
return new CallbackStore(callback, m_index, initialNotify, &HalAddressableLEDData.RegisterAddressableLEDInitializedCallback, &HalAddressableLEDData.CancelAddressableLEDInitializedCallback);
}
}
60 changes: 60 additions & 0 deletions src/wpilibsharp/Simulation/CallbackStore.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using WPIHal;
using unsafe HalGlobalCreate = delegate* managed<delegate* unmanaged[Cdecl]<byte*, void*, WPIHal.HalValue*, void>, void*, bool, int>;
using unsafe HalGlobalFree = delegate* managed<int, void>;
using unsafe HalIndexedCreate = delegate* managed<int, delegate* unmanaged[Cdecl]<byte*, void*, WPIHal.HalValue*, void>, void*, bool, int>;
using unsafe HalIndexedFree = delegate* managed<int, int, void>;
using unsafe HalNativeNotifyCallback = delegate* unmanaged[Cdecl]<byte*, void*, WPIHal.HalValue*, void>;

namespace WPILib.Simulation;

public class CallbackStore : IDisposable
{
private GCHandle delegateHandle;
private readonly int nativeHandle;
private readonly int? index;
private unsafe readonly HalIndexedFree indexedFree;
private unsafe readonly HalGlobalFree globalFree;

[UnmanagedCallersOnly(CallConvs = [typeof(CallConvCdecl)])]
public static unsafe void HalNotifyCallback(byte* name, void* param, HalValue* value)
{
GCHandle handle = GCHandle.FromIntPtr((nint)param);
if (handle.Target is Action<string, HalValue> stringCallback)
{
string n = Marshal.PtrToStringUTF8((nint)name) ?? "";
stringCallback(n, *value);
}
}

public unsafe void Dispose()
{
GC.SuppressFinalize(this);
if (index is { } x)
{
indexedFree(x, nativeHandle);
}
else
{
globalFree(nativeHandle);
}
delegateHandle.Free();
}

public unsafe CallbackStore(Action<string, HalValue> callback, bool immediateNotify, HalGlobalCreate create, HalGlobalFree free)
{
delegateHandle = GCHandle.Alloc(callback);
nativeHandle = create(&HalNotifyCallback, (void*)(nint)delegateHandle, immediateNotify);
index = null;
globalFree = free;
}

public unsafe CallbackStore(Action<string, HalValue> callback, int index, bool immediateNotify, HalIndexedCreate create, HalIndexedFree free)
{
delegateHandle = GCHandle.Alloc(callback);
nativeHandle = create(index, &HalNotifyCallback, (void*)(nint)delegateHandle, immediateNotify);
this.index = index;
indexedFree = free;
}
}

0 comments on commit a69c32a

Please sign in to comment.