RX - 如何以高效的方式使用它?

时间:2017-07-23 00:00:35

标签: rxjs system.reactive reactive-programming frp rxcpp

我正在尝试了解如何构建我的程序以在高性能事物中使用RX。
我的应用程序在3D世界中有一个对象向量。每个物体占据一个盒子,并且有一个“击中”物体。流,代表鼠标悬停在它上面。
我想到了两种结构选择:

选项1

struct object_t
{
  string name_;
  box bounding_box_;
  observable<bool> hit_;
};

struct scene_t
{
  scene_t(observable<point> mouse) : hit_(hit(mouse)) 
  {
    add({"background", {/* ... */}, {}};
  }

  object_t& add(object_t o)
  {
    int object_index = objects_.size();
    o.hit_ = hit_
             .map([=](int index){ return index == object_index; })
             .distinct_until_changed();
    objects_.push_back(o);
    return objects_.back();
  }

  //! given a stream of mouse points,
  //! calculate on which object index(in objects_) the mouse is hover over. 
  //! 0 if its over the background. 
  observable<int> hit(observable<point> mouse);

  using objects_t = std::vector<object_t>;
  objects_t objects_; 
  observable<int> hit_
};

选项2

struct object_t
{
  string name_;
  box bounding_box_;

  void signal_hit(boot is_hit) { hit_.get_observer().on_next(is_hit); }

  observable<bool> hit() const { return hit_.get_observable(); }

private:
  subject<bool> hit_;
};

struct scene_t
{
  scene_t(observable<point> mouse) : hit_(hit(mouse)) 
  {
    add({"background", {/* ... */}, {}};
    hit_
       .start_with(0)
       .buffer(2, 1) // take two hits together, the current and the previos
       .subscribe([this](std::vector<int> indices) {
          objects_[indices[1]].signal_hit(false); // we leave this one 
          objects_[indices[0]].signal_hit(true); // and entering this one
        });        
  }

  object_t& add(object_t o)
  {
    objects_.push_back(o);
    return objects_.back();
  }
  //! ... as above
};

现在的问题是如何将hit函数的结果链接到object_t :: hit流。
我看到两种方式:

  1. 选项1功能齐全,但性能非常差,因为对于每个鼠标点,所有对象流都需要计算它们的值。
  2. 选项2.功能不完善,因为我使用值限制在右侧,以强制方式运行。 非常高效,因为只有正确的(两个)对象点击流才会触发。
  3. 注意: 实现是在rxcpp中,但它通用于我们在其中包含RX的任何语言,或者一般的FRP范例,这就是我标记rxjs \ rx.net \ frp等的原因。 提前谢谢: - )

1 个答案:

答案 0 :(得分:0)

如果有一个可观察的源和N个订户,则每次源发出时必须至少进行N次计算。没有办法解决我能想到的问题。