gpt4 book ai didi

c++ - rxcpp:嵌套的 while 循环或类似的 "classic"程序命令结构

转载 作者:太空狗 更新时间:2023-10-29 20:21:48 30 4
gpt4 key购买 nike

我有一个设备可以流式传输一些事件。我想使用响应式扩展来模拟以下行为:

  1. 检测用户何时连接加密狗(我的程序检查连接加密狗的事件)。
  2. 加密狗连接后开始从加密狗捕获数据流。
  3. 能够检测加密狗何时断开连接并返回到 1.,稍后如果用户再次连接加密狗,我想转到 2. 在我流式传输数据的状态下,如果键盘被击中,则程序结束.

我知道如何等待加密狗连接 (1.):

auto waitForDongle = events.take_while([](auto const & event) {
return event == DongleConnected
}).subscribe([](auto) {});

而且我知道如何捕获流 (2.):

auto streamMotionData = events.take_while([](auto const &) { return !keyboardPressed(); })
.map([](auto const & evt) -> boost::optional<std::vector<double>> {
...
return data;
}).subscribe([](vector<double> const &) { ...});

我的问题是我不知道如何组合流以便返回到 1 和之后的 2。我只知道如何按顺序执行一次。但我想要上述行为。

最佳答案

这与Rx中常见的UX拖动示例有关。在这种情况下,按下是加密狗连接,释放是加密狗移除。

此解决方案要求一次只能连接一个加密狗(预计在下一次连接之前将其移除)。事件中必须有更多信息才能允许多个连接重叠。

这是解决方案的核心。整个程序如下。

    auto DatasFromConnectedDongle = DongleConnects. // when connected
map([=](DongleEvent const & event){
assert(event == DongleEvent::Connected);
cout << "Connected - " << flush;
return DongleDatas. // return all the datas
take_until(DongleRemoves). // stop when removed
finally([](){
cout << "- Removed" << endl;
});
}).
switch_on_next(). // only listen to datas from the most recent connected dongle
take_until(Exits); // stop everything when key is pressed

我确实最终使用了 repeat(),但只是为了生成测试事件数据。

#include <rxcpp/rx.hpp>

namespace Rx {
using namespace rxcpp;
using namespace rxcpp::sources;
using namespace rxcpp::operators;
using namespace rxcpp::util;
}
using namespace Rx;

#include <cassert>
using namespace std;
using namespace std::chrono;

int main()
{
//
// test code
//

auto keyboardPressed = [](){
return false;
};

enum class DongleEvent {
Connected,
Removed,
Data,
Other
};
auto events = from(
DongleEvent::Data, DongleEvent::Other,
DongleEvent::Connected, DongleEvent::Data,
DongleEvent::Other, DongleEvent::Other,
DongleEvent::Data, DongleEvent::Removed,
DongleEvent::Other, DongleEvent::Data).
repeat(5). // send the above events five times over
zip(take_at<0>(), interval(milliseconds(200))). // pace our test data
publish().
ref_count(); // publish and ref_count make the events sharable

//
// the solution
//

// fires when connected
auto DongleConnects = events.
filter([](DongleEvent const & event) {
return event == DongleEvent::Connected;
});

// fires when data arrives
auto DongleDatas = events.
filter([](DongleEvent const & event) {
return event == DongleEvent::Data;
});

// fires when removed
auto DongleRemoves = events.
filter([](DongleEvent const & event) {
return event == DongleEvent::Removed;
});

// fires when key pressed
auto Exits = interval(milliseconds(200)).
filter([=](long){
return keyboardPressed();
});

auto DatasFromConnectedDongle = DongleConnects.
map([=](DongleEvent const & event){
assert(event == DongleEvent::Connected);
cout << "Connected - " << flush;
return DongleDatas. // return all the datas
take_until(DongleRemoves). // stop when removed
finally([](){
cout << "- Removed" << endl;
});
}).
switch_on_next(). // only listen to datas from the most recent connected dongle
take_until(Exits); // stop everything when key is pressed

DatasFromConnectedDongle.subscribe([](DongleEvent const & event){
assert(event == DongleEvent::Data);
cout << "Data " << flush;
});

return 0;
}

产生

~/source/rxcpp/Rx/v2/examples/dongle (master)$ cmake .
...
~/source/rxcpp/Rx/v2/examples/dongle (master)$ make
Scanning dependencies of target dongle
[ 50%] Building CXX object CMakeFiles/dongle.dir/main.cpp.o
[100%] Linking CXX executable dongle
[100%] Built target dongle
~/source/rxcpp/Rx/v2/examples/dongle (master)$ ./dongle
Connected - Data Data - Removed
Connected - Data Data - Removed
Connected - Data Data - Removed
Connected - Data Data - Removed
Connected - Data Data - Removed
~/source/rxcpp/Rx/v2/examples/dongle (master)$

关于c++ - rxcpp:嵌套的 while 循环或类似的 "classic"程序命令结构,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41373792/

30 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com