Reducing C# memory allocations in Input. Hand Joints still alloc, but this is slightly better?
@@ -48,7 +48,7 @@ namespace StereoKit
/// <summary>Information about a hand!</summary>
[StructLayout(LayoutKind.Sequential)]
- public struct Hand {
+ public class Hand {
/// <summary>This is a 2D array with 25 HandJoints. You can get the
/// right joint by `finger*5 + joint`, but really, just use Hand.Get
/// or Hand[] instead. See Hand.Get for more info!</summary>
@@ -171,7 +171,7 @@ namespace StereoKit
/// information, buttons, analog sticks and triggers! There's also a Menu
/// button that's tracked separately at Input.ContollerMenu.</summary>
[StructLayout(LayoutKind.Sequential)]
- public struct Controller
+ public class Controller
{
/// <summary>The grip pose of the controller. This approximately
/// represents the center of the hand's position. Check `trackedPos`
@@ -300,6 +300,8 @@ namespace StereoKit
static List<EventListener> listeners = new List<EventListener>();
static bool initialized = false;
static InputEventCallback callback;
+ static Hand[] hands = new Hand[2] { new Hand(), new Hand() };
+ static Controller[] controllers = new Controller[2] { new Controller(), new Controller() };
/// <summary>If the device has eye tracking hardware and the app has
/// permission to use it, then this is the most recently tracked eye
@@ -331,8 +333,22 @@ namespace StereoKit
/// </summary>
public static Mouse Mouse => Marshal.PtrToStructure<Mouse>(NativeAPI.input_mouse());
+ /// <summary>Gets raw controller input data from the system. Note that
+ /// not all buttons provided here are guaranteed to be present on the
+ /// user's physical controller. Controllers are also not guaranteed to
+ /// be available on the system, and are never simulated.</summary>
+ /// <param name="handed">The handedness of the controller to get the
+ /// state of.</param>
+ /// <returns>A reference to a class that contains state information
+ /// about the indicated controller.</returns>
public static Controller Controller(Handed handed)
- => Marshal.PtrToStructure<Controller>(NativeAPI.input_controller(handed));
+ {
+ Marshal.PtrToStructure(NativeAPI.input_controller(handed), controllers[(int)handed]);
+ return controllers[(int)handed];
+ }
+ /// <summary>This is the state of the controller's menu button, this
+ /// is not attached to any particular hand, so it's independent of a
+ /// left or right controller.</summary>
public static BtnState ControllerMenuButton
=> NativeAPI.input_controller_menu();
@@ -349,10 +365,14 @@ namespace StereoKit
/// <param name="handed">Do you want the left or the right hand?
/// </param>
/// <returns>A copy of the entire set of hand data!</returns>
- public static Hand Hand(Handed handed)
- => Marshal.PtrToStructure<Hand>(NativeAPI.input_hand(handed));
- public static Hand Hand(int handed)
- => Marshal.PtrToStructure<Hand>(NativeAPI.input_hand((Handed)handed));
+ public static Hand Hand(Handed handed) {
+ Marshal.PtrToStructure(NativeAPI.input_hand(handed), hands[(int)handed]);
+ return hands[(int)handed];
+ }
+ public static Hand Hand(int handed){
+ Marshal.PtrToStructure(NativeAPI.input_hand((Handed)handed), hands[handed]);
+ return hands[handed];
+ }
/// <summary>This allows you to completely override the hand's pose
/// information! It is still treated like the user's hand, so this is
