ReactiveX / RxCpp

Reactive Extensions for C++
Apache License 2.0
3.07k stars 396 forks source link

Can anyone say how to track changes of a variable? #402

Open kornerr opened 7 years ago

kornerr commented 7 years ago

I think it's best to sum up what I want to do in C++ by showing you what actually works in Swift with RxSwift.

  1. Declare collection and its items:
    
    struct Item {
    var name = ""
    }

class Collection { let items: Variable<[Item]> = Variable([]) }

2. Define collection:

var collection = Collection()

3. Subscribe to collection items' changes:

collection.asObservable().subscribe(onNext: { items in NSLog("Items changed. Here they are: (items)") }) .disposed(by: disposeBag)

4. Change items from anywhere on the collection instance:

collection.items.value = [item1, item2]



Whenever I do change collection items like that, the subscription runs and prints all items.

I want to do the same in C++. Is it possible?
kirkshoop commented 7 years ago

this is very close to a behavior<vector<Item>> the missing piece today is .value = [item1, item2]. this can be emulated.

untested

auto make_set_items(const behavior<vector<Item>>& items) {
  auto out = items.get_subscriber();
  return [out](vector<Item>& i){
    out.next(i);
  };
}

behavior<vector<Item>> items;
auto set_items = make_set_items(items);

items.subscribe([](const vector<Item>& v){
  cout << "Items changed. Here they are: ";
  for(auto& i : v) {
    cout << i << ", ";
  }
  cout << endl;
});

set_items({{item1, item2}});
kornerr commented 7 years ago

So I can't just assign an array and get notifications. I always need to create my own function. However, creating more functions pretty much defeats the prettyness of RxCpp. Too bad.

kirkshoop commented 7 years ago

set_items is just there to simplify this -

items.get_subscriber().on_next({{item1, item2}});

A PR to add set_value to behavior<> would result in

behavior<vector<Item>> items;

items.subscribe([](const vector<Item>& v){
  cout << "Items changed. Here they are: ";
  for(auto& i : v) {
    cout << i << ", ";
  }
  cout << endl;
});

items.set_value({{item1, item2}});

is this good enough?

kornerr commented 7 years ago

Looks almost great. But the reporting should also happen when I update/remove/add one item to vector, too.

kirkshoop commented 7 years ago

to do that you need to use an immutable C++ collection. a couple were discussed in C++Now talks this year.

https://www.youtube.com/watch?v=ZsryQp0UAC8 https://www.youtube.com/watch?v=WT9kmIE3Uis

RomeuG commented 5 years ago

So any news about this? Anything that has been tested to actually track changes to a variable?