0

I have class:

class base_event;

Several classes derive from it:

class event_1 : base_event;
class event_2 : base_event; 

I have an observable:

observable<base_event> o;

I would like to subscribe to o and get event_1 and event_2 seperately.

o.of_type(event_1).subscribe([](event_1& e){});
o.of_type(event_2).subscribe([](event_2& e){});

Is there a way to create the of_type operator like this?

jc211
  • 397
  • 2
  • 9

1 Answers1

1

One way to express of_type is to use

o.filter([](const shared_ptr<base_event>& be){ 
  return dynamic_cast<event_1*>(be.get()) != nullptr;
})
.map([](const shared_ptr<base_event>& be){
  return static_pointer_cast<event_1>(be);
})

Another is to use

.map([](const shared_ptr<base_event>& be){
  auto event = dynamic_pointer_cast<event_1>(be);
  if (event == nullptr) { return empty<event_1>().as_dynamic();}
  return just<event_1>(event).as_dynamic();
})
.concat()

I prefer the first one.

Kirk Shoop
  • 1,274
  • 9
  • 13
  • Hi Kirk, thats what I ended up doing. Unfortunately, I couldn't figure out how to do it without shared pointers because dyamic_cast wasn't working with the references. I haven't tested why, but my rough guess may be that somewhere within rxcpp an explicit copy is being made and somehow information is being lost about the derived copy. I may be far off from the real reason. In any case, what you posed works. Thanks! – jc211 Apr 06 '20 at 06:27
  • Yes, rxcpp is not reference clean. I did not make the effort because of the many places that must take copies. All the multicast and time and scheduler based operators take copies because they let go of the calling stack or pass the same value to multiple consumers. – Kirk Shoop Apr 06 '20 at 17:45