如何为遗留相机系统创建 Observable?
How to create Observable for a legacy camera system?
我有一个旧相机客户端可以与相机通信。它的工作方式在这个时代有点尴尬。作为我自己的“反应式”东西的粉丝,我想以一种反应式的方式与相机交流。
这是它的运作方式
每当你想开始捕获帧时,你调用 Start 它开始每 0.5 秒捕获一个帧,你会收到订阅“捕获时”事件的每一帧的通知.在您调用 Stop.
之前,该事件会一直发生
因此,相机具有:
- 开始捕获帧的方法
- 另一种方法停止捕获
- 捕获新帧时引发的事件
这就是我想要的
我想将相机封装到一个更方便的抽象中,其中 Start 和 Stop 方法被替换为 IObservable<bool>
,并且生成的 observable 应该发出批量捕获 (Frames
)。
更多详情
这是旧相机 class:
class Camera
{
void StartRecording();
void StopRecording();
public event CaptureEventHandler OnCapture;
public delegate void CaptureEventHandler(Camera sender, Frame capture);
}
我想要的是像这样将相机包裹成class(我只创建了骨架):
public class ObservableCamera
{
public ObservableCamera(Camera camera, IObservable<bool> enableCapture)
{
// TODO: Define the 'Captures' observable using the parameters above
}
IObservable<Frame[]> Captures { get; }
}
相机应该在 enableCapture observable 发出 true
时开始捕获帧,并在它按下 false
时停止捕获。
为了澄清一点,这是显示交互的弹珠图:
- 第一个序列是
enableCapture
- 第二个应该是从
OnCapture
事件创建的辅助序列。
除此之外,只要 Start 操作开始,enableCapture
observable 终止或失败时也应调用 StopRecording
。
那么,我要求什么?
我收到评论说我的目标不明确。澄清一下,这是我的问题:
我应该如何实现 observable 来处理遗留相机?我不知道如何开始。
这是一种方法,它使用 Window
运算符来定义启用相机时的 windows(周期)。 Camera.OnCapture
事件在每个 window 开始时订阅,并在 window 结束时取消订阅。
Camera camera;
IObservable<bool> enableCapture;
IObservable<Frame[]> observableCamera = enableCapture
.DistinctUntilChanged()
.Publish(published => published
.Window(published.Where(enabled => enabled), _ => published.Where(enabled => !enabled))
.Select(w =>
Observable
.FromEvent<Camera.CaptureEventHandler, Frame>(
h => (sender, capture) => h(capture),
h =>
{
camera.OnCapture += h;
camera.StartRecording();
},
h =>
{
camera.StopRecording();
camera.OnCapture -= h;
})
.TakeUntil(w.LastOrDefaultAsync())
.ToArray()
)
.Concat()
);
DistinctUntilChanged
运算符用于忽略连续的 true 或 false。使用 Publish
运算符是为了避免对 enableCapture
序列进行多次订阅。这个序列很可能是 Subject<bool>
,所以已经很热了,使得 Publish
本质上是多余的,但原则上最好避免多次订阅。
未考虑 StartRecording
或 StopRecording
方法失败的情况。在这种情况下,对 OnCapture
事件的订阅将被泄露。
我有一个旧相机客户端可以与相机通信。它的工作方式在这个时代有点尴尬。作为我自己的“反应式”东西的粉丝,我想以一种反应式的方式与相机交流。
这是它的运作方式
每当你想开始捕获帧时,你调用 Start 它开始每 0.5 秒捕获一个帧,你会收到订阅“捕获时”事件的每一帧的通知.在您调用 Stop.
之前,该事件会一直发生因此,相机具有:
- 开始捕获帧的方法
- 另一种方法停止捕获
- 捕获新帧时引发的事件
这就是我想要的
我想将相机封装到一个更方便的抽象中,其中 Start 和 Stop 方法被替换为 IObservable<bool>
,并且生成的 observable 应该发出批量捕获 (Frames
)。
更多详情
这是旧相机 class:
class Camera
{
void StartRecording();
void StopRecording();
public event CaptureEventHandler OnCapture;
public delegate void CaptureEventHandler(Camera sender, Frame capture);
}
我想要的是像这样将相机包裹成class(我只创建了骨架):
public class ObservableCamera
{
public ObservableCamera(Camera camera, IObservable<bool> enableCapture)
{
// TODO: Define the 'Captures' observable using the parameters above
}
IObservable<Frame[]> Captures { get; }
}
相机应该在 enableCapture observable 发出 true
时开始捕获帧,并在它按下 false
时停止捕获。
为了澄清一点,这是显示交互的弹珠图:
- 第一个序列是
enableCapture
- 第二个应该是从
OnCapture
事件创建的辅助序列。
除此之外,只要 Start 操作开始,enableCapture
observable 终止或失败时也应调用 StopRecording
。
那么,我要求什么?
我收到评论说我的目标不明确。澄清一下,这是我的问题:
我应该如何实现 observable 来处理遗留相机?我不知道如何开始。
这是一种方法,它使用 Window
运算符来定义启用相机时的 windows(周期)。 Camera.OnCapture
事件在每个 window 开始时订阅,并在 window 结束时取消订阅。
Camera camera;
IObservable<bool> enableCapture;
IObservable<Frame[]> observableCamera = enableCapture
.DistinctUntilChanged()
.Publish(published => published
.Window(published.Where(enabled => enabled), _ => published.Where(enabled => !enabled))
.Select(w =>
Observable
.FromEvent<Camera.CaptureEventHandler, Frame>(
h => (sender, capture) => h(capture),
h =>
{
camera.OnCapture += h;
camera.StartRecording();
},
h =>
{
camera.StopRecording();
camera.OnCapture -= h;
})
.TakeUntil(w.LastOrDefaultAsync())
.ToArray()
)
.Concat()
);
DistinctUntilChanged
运算符用于忽略连续的 true 或 false。使用 Publish
运算符是为了避免对 enableCapture
序列进行多次订阅。这个序列很可能是 Subject<bool>
,所以已经很热了,使得 Publish
本质上是多余的,但原则上最好避免多次订阅。
未考虑 StartRecording
或 StopRecording
方法失败的情况。在这种情况下,对 OnCapture
事件的订阅将被泄露。