so I've tried to comprehend ReactiveX as a library for some time now and I believe I'm starting to get the hang of the fundamentals, however, there is one problem I have which I can't find a solution to in the docs...
tldr: I want to either connect an observable to a class without actually creating the class inside the observable lambda or, create the class inside the observable but then be able to extract the class. In the end all I want to to is in some way or form make an observable of a class and then be able to use the class outside the scope of the observable.
Situation: I have three layers of classes, I have class A, B, and C, where A holds in all Bs and later all Bs, holds in multiple Cs. Both classes B and C may exist in multiple instances (A is always only one instance).
Problem: So in my application, class A will create an instance of C, and make it observable using Rx. When C is instantiated and ready I want to take the class and pass it to one of the B instances. However, my problem is that since I need to create the C class in a lambda in the observable create method I can't actually do anything with the new C Class, it only exists in the lambda scope. So what I want to do is either pass in a reference of C to the observable and give it the subscriber or somehow return the C instance out from the observable lambda. I tried giving the lambda a pointer to my class and make the lambda mutable but when doing that rx gave me compile errors and complained about the Rx method being const.
const auto test = rx::observable<>::create<something>([&](rx::subscriber<something> subscriber) {
C c(subscriber);
});
// Here I want to access c
I tried passing it in like this but with no success
class C {
C(rx::subscriber<someting> subscriber) {
subscriber.on_next(55);
}
};
C* c = nullptr;
const auto test = rx::observable<>::create<something>([cLambda = c](rx::subscriber<something> subscriber) mutable {
cLambda = new C(subscriber);
});
test.subscribe([](something input) {
std::cout << "Called " << input<< std::endl;
});
// Compile error: C3848: expression having type 'const main::<lambda_d3f00...>' would lose some const-volatile qualifiers in order to call 'void main::<lambda_d3f00...>::operator ()(rxcpp::subscriber<something,rxcpp::observer<T,void,void,void,void>>)'
// with
// [
// T=container
// ]
Do any other methods exist to accomplish what I want or have I just misunderstood the concept of something here?
Okay I solved it after a couple of days
Turns out that I used the wrong type. From my understanding, it seems like the observable type is in fact limited to only run a method inside and not distribute the subscriber anywhere else. However, after further reading in the documentation, I found the type rx::subjects::subject<T>
which is exactly what I want. A subject can generate multiple observables and subscribers as needed this making it possible to get a subscriber and pass it to the C class.
Here is the working code:
rx::subjects::subject<something> cSubject;
auto subscriber = cSubject.get_subscriber();
auto observable = cSubject.get_observable();
// Give C an Emiter/subscriber
C* c = new C(&subscriber);
// Listener
observable.subscribe([](something var) {
std::cout << "I was called!!!" << std::endl;
});
// Now I can call c.doStuff() and trigger the listener from there