// Copyright (c) 2021 homuler // // Use of this source code is governed by an MIT-style // license that can be found in the LICENSE file or at // https://opensource.org/licenses/MIT. using System; namespace Mediapipe { public abstract class Packet : MpResourceHandle { /// /// The native resource won't be initialized. /// protected Packet() : base() { } /// /// If is set to false, the native resource won't be initialized. /// protected Packet(bool isOwner) : base(isOwner) { if (isOwner) { UnsafeNativeMethods.mp_Packet__(out var ptr).Assert(); this.ptr = ptr; } } protected Packet(IntPtr ptr, bool isOwner) : base(ptr, isOwner) { } /// /// Creates a read-write instance. /// /// /// This is a slow operation that makes use of internally, so you should avoid calling it in a loop.
/// If you need to call it in a loop and is set to false, call instead. ///
public static TPacket Create(IntPtr packetPtr, bool isOwner) where TPacket : Packet, new() { return (TPacket)Activator.CreateInstance(typeof(TPacket), packetPtr, isOwner); } public void SwitchNativePtr(IntPtr packetPtr) { if (isOwner) { throw new InvalidOperationException("This operation is permitted only when the packet instance is for reference"); } ptr = packetPtr; } /// Thrown when the value is not set public abstract TValue Get(); public abstract StatusOr Consume(); public bool IsEmpty() { return SafeNativeMethods.mp_Packet__IsEmpty(mpPtr); } public Status ValidateAsProtoMessageLite() { UnsafeNativeMethods.mp_Packet__ValidateAsProtoMessageLite(mpPtr, out var statusPtr).Assert(); GC.KeepAlive(this); return new Status(statusPtr); } // TODO: declare as abstract public virtual Status ValidateAsType() { throw new NotImplementedException(); } public Timestamp Timestamp() { UnsafeNativeMethods.mp_Packet__Timestamp(mpPtr, out var timestampPtr).Assert(); GC.KeepAlive(this); return new Timestamp(timestampPtr); } public string DebugString() { return MarshalStringFromNative(UnsafeNativeMethods.mp_Packet__DebugString); } public string RegisteredTypeName() { var typeName = MarshalStringFromNative(UnsafeNativeMethods.mp_Packet__RegisteredTypeName); return typeName ?? ""; } public string DebugTypeName() { return MarshalStringFromNative(UnsafeNativeMethods.mp_Packet__DebugTypeName); } protected override void DeleteMpPtr() { UnsafeNativeMethods.mp_Packet__delete(ptr); } /// /// This method will copy the value and create another packet internally. /// To avoid copying the value, it's preferable to instantiate the packet with timestamp in the first place. /// /// New packet with the given timestamp and the copied value protected TPacket At(Timestamp timestamp) where TPacket : Packet, new() { UnsafeNativeMethods.mp_Packet__At__Rt(mpPtr, timestamp.mpPtr, out var packetPtr).Assert(); GC.KeepAlive(timestamp); return Create(packetPtr, true); } } }