Skip to content

Commit

Permalink
Do an example of a full serializable struct
Browse files Browse the repository at this point in the history
  • Loading branch information
ThadHouse committed Jan 15, 2024
1 parent a65d12b commit 660d826
Show file tree
Hide file tree
Showing 14 changed files with 391 additions and 120 deletions.
9 changes: 9 additions & 0 deletions WPILib.sln
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,10 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "cscore", "src\cscore\cscore
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "hal", "src\hal\hal.csproj", "{0F596472-F93A-4519-B8A5-FCCC321B3C44}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "dev", "dev", "{1CA9AB3B-4828-4F07-8C0E-88EF7C5A9ACD}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "desktopDev", "dev\desktopDev\desktopDev.csproj", "{7EF82002-5BBC-45DF-9A70-743A87EA5575}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Expand Down Expand Up @@ -52,6 +56,10 @@ Global
{0F596472-F93A-4519-B8A5-FCCC321B3C44}.Debug|Any CPU.Build.0 = Debug|Any CPU
{0F596472-F93A-4519-B8A5-FCCC321B3C44}.Release|Any CPU.ActiveCfg = Release|Any CPU
{0F596472-F93A-4519-B8A5-FCCC321B3C44}.Release|Any CPU.Build.0 = Release|Any CPU
{7EF82002-5BBC-45DF-9A70-743A87EA5575}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{7EF82002-5BBC-45DF-9A70-743A87EA5575}.Debug|Any CPU.Build.0 = Debug|Any CPU
{7EF82002-5BBC-45DF-9A70-743A87EA5575}.Release|Any CPU.ActiveCfg = Release|Any CPU
{7EF82002-5BBC-45DF-9A70-743A87EA5575}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(NestedProjects) = preSolution
{8F38C25E-641E-47FC-AC0A-0717F2159E8F} = {DB664556-4BF0-4874-8CB6-DC24E60A67AF}
Expand All @@ -60,5 +68,6 @@ Global
{E616A4EB-E1C1-4493-B23D-96CC32C83B28} = {AD95ECD8-E708-4FB4-9B7E-A8A8EF3FCB3E}
{33E753D6-DFC1-41F8-B488-59834326E4DB} = {DB664556-4BF0-4874-8CB6-DC24E60A67AF}
{0F596472-F93A-4519-B8A5-FCCC321B3C44} = {DB664556-4BF0-4874-8CB6-DC24E60A67AF}
{7EF82002-5BBC-45DF-9A70-743A87EA5575} = {1CA9AB3B-4828-4F07-8C0E-88EF7C5A9ACD}
EndGlobalSection
EndGlobal
90 changes: 13 additions & 77 deletions dev/desktopDev/Program.cs
Original file line number Diff line number Diff line change
@@ -1,83 +1,19 @@
using Hal;
using NetworkTables;
using NetworkTables.Natives;
using System;
using System.Linq;
using WPILib;
using System;
using System.Text.Json;
using UnitsNet.NumberExtensions.NumberToAngle;
using WPIMath.Geometry;

namespace desktopDev
{
public class Robot : TimedRobot
{
private TimeSpan lastTime = Timer.FPGATimestamp;
readonly double[] buffer = new double[50];
int idx = 0;

private readonly int pwm = Hal.PWMLowLevel.InitializePort(HALLowLevel.GetPort(42));

private readonly int can = CANAPILowLevel.Initialize(CANManufacturer.kTeamUse, 1, CANDeviceType.kMiscellaneous);



public override unsafe void RobotPeriodic()
{
int idxLocal = idx;
CANAPILowLevel.WritePacket(can, new Span<byte>(&idxLocal, 4), 42);

var current = Timer.FPGATimestamp;
var delta = current - lastTime;
lastTime = current;
buffer[idx] = delta.TotalMilliseconds;
idx++;
if (idx == 50)
{
Console.WriteLine(buffer.Average());
idx = 0;
}
base.RobotPeriodic();
}
}
namespace DesktopDev;

class Program
class Program
{
static void Main(string[] args)
{
Rotation2d rot = new(5.Radians());
string serialized = JsonSerializer.Serialize(rot);
Console.WriteLine(serialized);

public class HolderMethod
{
public void doThing()
{

}
}

public class Container
{
public Action holder;

public Container(HolderMethod holder)
{
this.holder = holder.doThing;
}
}

static void Main(string[] args)
{
NtCore.Initialize();
NetworkTableInstance instance = NetworkTableInstance.Default;
GC.KeepAlive(instance);
//var i = SendableRegistry.Instance;

//var map = new ConditionalWeakTable<HolderMethod, Container>();

//var holder = new HolderMethod();
//map.Add(holder, new Container(holder));
////holder = null;

////while (map.Any())
////{
//// //Console.WriteLine(map.Count());
//// GC.Collect();
////}
//RobotBase.StartRobot<Robot>();
}
Rotation2d r = JsonSerializer.Deserialize<Rotation2d>(serialized);
Console.WriteLine(r.Angle.Radians);
}
}
6 changes: 1 addition & 5 deletions dev/desktopDev/desktopDev.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -6,15 +6,11 @@
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
</PropertyGroup>

<ItemGroup>
<PackageReference Include="UnitsNet.NumberExtensions" Version="4.83.0" />
</ItemGroup>

<ItemGroup>
<ProjectReference Include="..\..\src\hal\hal.csproj" />
<ProjectReference Include="..\..\src\ntcore\ntcore.csproj" />
<ProjectReference Include="..\..\src\thirdparty\SparkMax\SparkMax.csproj" />
<ProjectReference Include="..\..\src\wpilibsharp\wpilibsharp.csproj" />
<ProjectReference Include="..\..\src\wpinet\wpinet.csproj" />
<ProjectReference Include="..\..\src\wpiutil\wpiutil.csproj" />
</ItemGroup>

Expand Down
10 changes: 5 additions & 5 deletions src/ntcore/StructArrayTopic.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,24 +5,24 @@ namespace NetworkTables;

public sealed class StructArrayTopic<T> : Topic
{
public Struct<T> Struct { get; }
public IStruct<T> Struct { get; }

private StructArrayTopic(Topic topic, Struct<T> value) : base(topic.Instance, topic.Handle)
private StructArrayTopic(Topic topic, IStruct<T> value) : base(topic.Instance, topic.Handle)
{
Struct = value;
}

private StructArrayTopic(NetworkTableInstance inst, NtTopic handle, Struct<T> value) : base(inst, handle)
private StructArrayTopic(NetworkTableInstance inst, NtTopic handle, IStruct<T> value) : base(inst, handle)
{
Struct = value;
}

public static StructArrayTopic<T> Wrap(Topic topic, Struct<T> value)
public static StructArrayTopic<T> Wrap(Topic topic, IStruct<T> value)
{
return new StructArrayTopic<T>(topic, value);
}

public static StructArrayTopic<T> Wrap(NetworkTableInstance inst, NtTopic handle, Struct<T> value)
public static StructArrayTopic<T> Wrap(NetworkTableInstance inst, NtTopic handle, IStruct<T> value)
{
return new StructArrayTopic<T>(inst, handle, value);
}
Expand Down
40 changes: 39 additions & 1 deletion src/wpiutil/DataLog.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
global using EntryHandle = int;

using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using WPIUtil.Handles;
Expand Down Expand Up @@ -67,10 +69,46 @@ public void AppendRaw(DataLogEntryHandle entry, ReadOnlySpan<byte> data, long ti
DataLogNative.DataLogAppend(NativeHandle, entry, data, (ulong)timestamp);
}

public void AddSchema<T>(Struct<T> value, long timestamp = 0)
public void AddSchema<T>(IStruct<T> value, long timestamp = 0)
{
throw new NotImplementedException();
}

public bool HasSchema(string name)
{
return m_schemaMap.ContainsKey(name);
}

public void AddSchema(string name, string type, string schema, long timestamp = 0)
{
if (!m_schemaMap.TryAdd(name, 1))
{
return;
}
// TODO add schema functions
// DataLogNative
}

private void AddSchemaImpl(IStructBase value, long timestamp, HashSet<string> seen)
{
string typeString = value.TypeString;
if (HasSchema(typeString))
{
return;
}
if (!seen.Add(typeString))
{
throw new InvalidOperationException($"{typeString}: circular reference with {seen}");
}
AddSchema(typeString, "structschema", value.Schema, timestamp);
foreach (var inner in value.Nested)
{
AddSchemaImpl(inner, timestamp, seen);
}
seen.Remove(typeString);
}

private readonly ConcurrentDictionary<string, int> m_schemaMap = [];

public unsafe OpaqueDataLog* NativeHandle { get; } = null;
}
11 changes: 8 additions & 3 deletions src/wpiutil/Logging/StructArrayLogEntry.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,22 +4,27 @@

namespace WPIUtil.Logging;

public sealed class StructArrayLogEntry<T> : DataLogEntry
public sealed class StructArrayLogEntry<T> : DataLogEntry where T : IStructSerializable<T>
{
private StructBuffer<T> m_storage;
private readonly object m_lockObject = new();

private StructArrayLogEntry(DataLog log, string name, Struct<T> value, string metadata, long timestamp) : base(log, name, $"{value.TypeString}[]", metadata, timestamp)
private StructArrayLogEntry(DataLog log, string name, IStruct<T> value, string metadata, long timestamp) : base(log, name, $"{value.TypeString}[]", metadata, timestamp)
{
m_storage = StructBuffer<T>.Create(value);
log.AddSchema(value, timestamp);
}

public StructArrayLogEntry<T> Create(DataLog log, string name, Struct<T> value, string metadata = "", long timestamp = 0)
public StructArrayLogEntry<T> Create(DataLog log, string name, IStruct<T> value, string metadata = "", long timestamp = 0)
{
return new StructArrayLogEntry<T>(log, name, value, metadata, timestamp);
}

public StructArrayLogEntry<T> Create(DataLog log, string name, string metadata = "", long timestamp = 0)
{
return new StructArrayLogEntry<T>(log, name, T.Struct, metadata, timestamp);
}

public void Reserve(int nelem)
{
lock (m_lockObject)
Expand Down
25 changes: 13 additions & 12 deletions src/wpiutil/Logging/StructLogEntry.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,31 +3,32 @@

namespace WPIUtil.Logging;

public sealed class StructLogEntry<T> : DataLogEntry
public sealed class StructLogEntry<T> : DataLogEntry where T : IStructSerializable<T>
{
private readonly Struct<T> m_struct;
private readonly byte[] m_storage;
private StructBuffer<T> m_storage;
private readonly object m_lockObject = new();

private StructLogEntry(DataLog log, string name, Struct<T> value, string metadata, long timestamp) : base(log, name, value.TypeString, metadata, timestamp)
private StructLogEntry(DataLog log, string name, IStruct<T> value, string metadata, long timestamp) : base(log, name, value.TypeString, metadata, timestamp)
{
m_struct = value;
m_storage = new byte[value.Size];
m_storage = StructBuffer<T>.Create(value);
log.AddSchema(value, timestamp);
}

public StructLogEntry<T> Create(DataLog log, string name, Struct<T> value, string metadata = "", long timestamp = 0)
public StructLogEntry<T> Create(DataLog log, string name, IStruct<T> value, string metadata = "", long timestamp = 0)
{
return new StructLogEntry<T>(log, name, value, metadata, timestamp);
}

public StructLogEntry<T> Create(DataLog log, string name, string metadata = "", long timestamp = 0)
{
return new StructLogEntry<T>(log, name, T.Struct, metadata, timestamp);
}

public void Append(T value, long timestamp = 0)
{
ReadOnlySpan<byte> toWrite;
lock (m_storage)
lock (m_lockObject)
{
toWrite = m_struct.Pack(m_storage, value);

m_log.AppendRaw(m_entry, m_storage.Write(value), timestamp);
}
m_log.AppendRaw(m_entry, toWrite, timestamp);
}
}
Loading

0 comments on commit 660d826

Please sign in to comment.