2017-07-23 5 views
4

J'essaie de comprendre comment structurer mon programme pour utiliser RX dans une matière performante.
Mon application a un vecteur d'objets dans le monde 3D. chaque objet occupait une case et disposait d'un flux "hit" qui représentait un survol de la souris.
Je pensais que deux options sur la façon de structurer:

Option 1RX - comment l'utiliser de manière performante?

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_ 
}; 

Option 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 
}; 

Maintenant, la question est de savoir comment la chaîne du résultat de la fonction de succès à le flux object_t :: hit.
Je vois deux façons:

  1. Option 1, est entièrement fonctionnel, mais très peu performants, puisque pour chaque point de la souris, tous les flux objets devront calculer leur valeur.
  2. L'option 2. n'est pas entièrement fonctionnelle, car j'utilise sous réserve de les valeurs vers le flux droit, de manière impérative. mais est très performant car seul le (ou les) objet (s) droit (s) frappé (s) arrive (nt) à tirer.

Note: La mise en œuvre est en rxcpp, mais son général à une langue que nous avons RX, ou paradigme général de FRP, voilà pourquoi je tagged rxjs \ rx.net \ frp etc.
merci d'avance :-)

+0

Vous ne savez pas ce que vous demandez: Vous vous dites déjà que l'option 2 fonctionne mieux - alors pourquoi ne voudriez-vous pas cette méthode? Je suis tombé sur cette question à cause de "rxjs" ... mais de ce que je peux vous dire il y a, que tout dépend du cas, il y a et ne sera jamais cette "solution parfaite", en plus il y a quelques différences dans les modèles et les pratiques entre JS et cpp, donc je suggère de supprimer ce rxjs-tag que je doute que quelque chose de utile en ressortira. – olsn

+0

Je demande exactement cela, "Comment dans le paradigme FRP, ce problème devrait être résolu?". Je crois que le PRF ne devrait pas être aussi inefficace, et que son style fonctionnel doit être rompu, afin d'atteindre la performance. Je pense que les gens qui travaillent avec FRP dans n'importe quelle langue, ont dû faire face à de tels problèmes, et peuvent avoir une autre solution que les deux que j'ai présentés. Si vous pensez que je dois traduire le code à RxJS afin de demander l'aide de cette communauté, je serai heureux de le faire. Merci pour votre contribution. – ShaulF

+0

Probablement le meilleur moyen serait de le rendre langage-agnostique et d'utiliser ces petits diagrammes de flux '---- 1 ----- 2 ------ 3 --- 4-5 --- |' combinaison avec pseudo-code - mais je comprends maintenant d'où vient votre question – olsn

Répondre

0

S'il y a une source observable et N abonnés, il doit y avoir au moins N calculs chaque fois que la source émet. Il n'y a aucun moyen de contourner ce que je peux penser.

+0

Il n'y a qu'un seul flux de hit (hover) à la fois, donc seulement deux abonnés doivent être signalés, celui que nous quittons et celui que nous venons de frapper (commencer à survoler). Il y a N objets, mais, comme le problème est défini, ils n'ont pas besoin d'être calculés à chaque fois. – ShaulF

+0

Je suis d'accord. Vous n'avez pas besoin de plus de N opérations si vous avez plusieurs sources. Cependant, la façon dont les observables fonctionnent, si vous avez une source et qu'elle émet, cela fonctionnera pour chaque abonné. – Pace