You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
198 lines
6.3 KiB
198 lines
6.3 KiB
// License: Apache 2.0. See LICENSE file in root directory.
|
|
// Copyright(c) 2017 Intel Corporation. All Rights Reserved.
|
|
|
|
namespace Intel.RealSense
|
|
{
|
|
using System;
|
|
using System.Runtime.InteropServices;
|
|
using Microsoft.Win32.SafeHandles;
|
|
using System.Runtime.ConstrainedExecution;
|
|
using System.Security.Permissions;
|
|
|
|
|
|
[SecurityPermission(SecurityAction.LinkDemand, UnmanagedCode = true)]
|
|
public sealed class ContextHandle : SafeHandleZeroOrMinusOneIsInvalid
|
|
{
|
|
public ContextHandle()
|
|
: base(true)
|
|
{
|
|
}
|
|
|
|
[ReliabilityContract(Consistency.WillNotCorruptState, Cer.MayFail)]
|
|
override protected bool ReleaseHandle()
|
|
{
|
|
if (!IsClosed)
|
|
{
|
|
NativeMethods.rs2_delete_context(this);
|
|
}
|
|
return true;
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// default librealsense context class
|
|
/// </summary>
|
|
public class Context : IDisposable
|
|
{
|
|
private ContextHandle handle;
|
|
|
|
static Context()
|
|
{
|
|
object error;
|
|
ApiVersion = NativeMethods.rs2_get_api_version(out error);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Initializes a new instance of the <see cref="Context"/> class.
|
|
/// </summary>
|
|
public Context()
|
|
{
|
|
object error;
|
|
handle = NativeMethods.rs2_create_context(ApiVersion, out error);
|
|
onDevicesChangedCallback = new rs2_devices_changed_callback(OnDevicesChangedInternal);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Gets the safe handle
|
|
/// </summary>
|
|
/// <exception cref="ObjectDisposedException">Thrown when <see cref="SafeHandle.IsInvalid"/></exception>
|
|
public ContextHandle Handle
|
|
{
|
|
get
|
|
{
|
|
if (handle.IsInvalid)
|
|
{
|
|
throw new ObjectDisposedException(GetType().Name);
|
|
}
|
|
|
|
return handle;
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// the version API encoded into integer value "1.9.3" -> 10903
|
|
/// </summary>
|
|
public static readonly int ApiVersion;
|
|
|
|
/// <summary>
|
|
/// Gets the API version
|
|
/// </summary>
|
|
public string Version
|
|
{
|
|
get
|
|
{
|
|
if (ApiVersion / 10000 == 0)
|
|
{
|
|
return ApiVersion.ToString();
|
|
}
|
|
|
|
return $"{ApiVersion / 10000}.{(ApiVersion % 10000) / 100}.{ApiVersion % 100}";
|
|
}
|
|
}
|
|
|
|
// Keeps the delegate alive, if we were to assign onDevicesChanged directly, there'll be
|
|
// no managed reference it, it will be collected and cause a native exception.
|
|
private readonly rs2_devices_changed_callback onDevicesChangedCallback;
|
|
|
|
/// <summary>
|
|
/// Delegate to register as per-notifications callback
|
|
/// </summary>
|
|
/// <param name="removed">list of removed devices</param>
|
|
/// <param name="added">list of added devices</param>
|
|
public delegate void OnDevicesChangedDelegate(DeviceList removed, DeviceList added);
|
|
|
|
private event OnDevicesChangedDelegate OnDevicesChangedEvent;
|
|
|
|
private readonly object deviceChangedEventLock = new object();
|
|
|
|
/// <summary>
|
|
/// these events will be raised by the context whenever new RealSense device is connected or existing device gets disconnected
|
|
/// </summary>
|
|
public event OnDevicesChangedDelegate OnDevicesChanged
|
|
{
|
|
add
|
|
{
|
|
lock (deviceChangedEventLock)
|
|
{
|
|
if (OnDevicesChangedEvent == null)
|
|
{
|
|
object error;
|
|
NativeMethods.rs2_set_devices_changed_callback(handle, onDevicesChangedCallback, IntPtr.Zero, out error);
|
|
}
|
|
|
|
OnDevicesChangedEvent += value;
|
|
}
|
|
}
|
|
|
|
remove
|
|
{
|
|
lock (deviceChangedEventLock)
|
|
{
|
|
OnDevicesChangedEvent -= value;
|
|
}
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Create a static snapshot of all connected devices at the time of the call
|
|
/// </summary>
|
|
/// <param name="include_platform_camera">Controls what kind of devices will be returned</param>
|
|
/// <returns>the list of devices</returns>
|
|
/// <remarks>devices in the collection should be disposed</remarks>
|
|
public DeviceList QueryDevices(bool include_platform_camera = false)
|
|
{
|
|
object error;
|
|
var ptr = NativeMethods.rs2_query_devices_ex(handle, include_platform_camera ? 0xff : 0xfe, out error);
|
|
return new DeviceList(ptr);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Gets a static snapshot of all connected devices at the time of the call
|
|
/// </summary>
|
|
/// <value>the list of devices</value>
|
|
public DeviceList Devices
|
|
{
|
|
get
|
|
{
|
|
return QueryDevices();
|
|
}
|
|
}
|
|
|
|
/// <summary>Create a new device and add it to the context</summary>
|
|
/// <param name="file">The file from which the device should be created</param>
|
|
/// <returns>a device that plays data from the file</returns>
|
|
public PlaybackDevice AddDevice(string file)
|
|
{
|
|
object error;
|
|
var ptr = NativeMethods.rs2_context_add_device(handle, file, out error);
|
|
return Device.Create<PlaybackDevice>(ptr);
|
|
}
|
|
|
|
/// <summary>Removes a playback device from the context, if exists</summary>
|
|
/// <param name="file">The file name that was used to add the device</param>
|
|
public void RemoveDevice(string file)
|
|
{
|
|
object error;
|
|
NativeMethods.rs2_context_remove_device(handle, file, out error);
|
|
}
|
|
|
|
private void OnDevicesChangedInternal(IntPtr removedList, IntPtr addedList, IntPtr userData)
|
|
{
|
|
var e = OnDevicesChangedEvent;
|
|
if (e != null)
|
|
{
|
|
using (var removed = new DeviceList(removedList))
|
|
using (var added = new DeviceList(addedList))
|
|
{
|
|
e(removed, added);
|
|
}
|
|
}
|
|
}
|
|
|
|
public void Dispose()
|
|
{
|
|
handle.Dispose();
|
|
}
|
|
}
|
|
}
|