LampArray 基础知识
本页描述如何注册 LampArray 回调以及如何与 ILampArray 和 ILampInfo 实例交互。
请注意:自 2023 年 3 月恢复起,GDK 照明 API 仅支持主机上的以下设备。 将来的恢复版本会添加对其他设备的支持。
- 适用于 Xbox One 的 Razer Turret(键盘和鼠标)
- Razer BlackWidow Tournament Edition Chroma V2
ILampArray 和 ILampInfo
连接到系统的每个兼容照明设备都由一个 ILampArray 实例表示。 ILampArray 提供有关设备的信息,如设备尺寸、设备类型、制造商和 Lamp 数量。 它还公开了更改其 Lamp 的亮度和颜色值的方法。
ILampInfo 对象封装 LampArray 中单个 Lamp 的属性,包括 Lamp 的相对位置、颜色支持和预期用途。 可以使用 ILampArray::GetLampInfo 检索 ILampInfo 实例。
注意:与图形、音频和 GameInput API 一样,ILampArray 和 ILampInfo 不是真正的 COM API,尽管它们公开了从 IUnknown 派生的接口。 这种风格的 API 有时被称为“COM lite”或“nano-COM”。虽然 IUnknown 用于引用计数和反射,但 ILampArray 或 ILampInfo 不使用 COM 运行时基础结构。 具体是指以下方面:
- 应用程序既不调用
CoInitialize
也不调用CoCreateInstance
来获取对象实例。- 不支持聚合之类的 COM 功能以及调用方提供的接口实现。
- 没有跨进程封送支持,也没有单元/线程模型。 所有对象都是敏捷对象。
- 接口指针可直接比较对象标识,而不需要经过 IUnknown。
- 不要求方法返回
HRESULT
代码,这常常会导致更简单的函数签名。
LampArray 回调
LampArray 回调是一种机制,用于获取 ILampArray 实例,并在 LampArray 连接到系统或从系统中删除时得到通知。
typedef interface ILampArray ILampArray;
typedef uint64_t LampArrayCallbackToken;
typedef void (CALLBACK * LampArrayCallback)(
_In_opt_ void * context,
bool isAttached,
_In_ ILampArray * lampArray);
HRESULT RegisterLampArrayCallback(
_In_ LampArrayCallback lampArrayCallback,
_In_opt_ void* context,
_Out_ _Result_zeroonfailure_ LampArrayCallbackToken* callbackToken);
回调线程处理
如果在注册回调时附加了任何 LampArray 设备,则 RegisterLampArrayCallback 函数将阻止,直到为每个附加设备调用该回调(这意味着将在调用线程上调用回调)。
注册第一个回调时,LampArray API 将启动一个工作线程来处理 ILampArray 设备附加和删除通知。 这些事件很少发生,否则工作线程将保持等待状态。 注册调用返回后,将在此工作线程上按顺序调用所有后续 LampArrayCallback。
LampArray 工作线程的处理器相关性可以使用 TrySetLampArrayWorkerThreadAffinityMask 进行控制。 每个进程最多可以调用一次此 API。 对 API 的任何后续调用都不会生效。
HRESULT TrySetLampArrayWorkerThreadAffinityMask(
uint64_t threadAffinityMask);
注销回调
在成功注册某一回调后,应用程序必须确保执行该回调所需的任何资源仍然有效。 这包括回调代码占用的资源以及回调函数本身,例如,如果回调函数托管在应用程序按需加载和卸载的 DLL 中。
若要安全地回收这些资源,应用程序必须先注销回调,方式是把从 RegisterLampArrayCallback 方法接收的令牌传递到 UnregisterLampArrayCallback 方法。 不支持从已注册的 LampArray 回调内注销 LampArray 回调,尝试这样做将终止进程。
bool UnregisterLampArrayCallback(
LampArrayCallbackToken callbackToken,
uint64_t timeoutInMicroseconds);