Giter Site home page Giter Site logo

Comments (28)

mincequi avatar mincequi commented on May 24, 2024 2

@victimsnino
Sorry for my late replies. I am quite busy atm.
But yes, this exactly does the trick for me. Thanks a lot!

Once i have a useable state, i will let you know about my project.

from reactiveplusplus.

mincequi avatar mincequi commented on May 24, 2024 1

Yeah, true, but Homebrew packages are usually precompiled with clang/libc++.
For GCC I would have to rebuild everything using GCC ;)
https://docs.brew.sh/Custom-GCC-and-cross-compilers

However, looking forward to your W/As :)

from reactiveplusplus.

victimsnino avatar victimsnino commented on May 24, 2024 1

Ohhhh, I see, it makes sense =) Looks like I'm not so experienced Mac user =)
Ok, then I would check what I can to do with that

from reactiveplusplus.

mincequi avatar mincequi commented on May 24, 2024 1

@victimsnino compilation and usage is confirmed from my side. I will switch over to ReactivePlusPlus again.

Great stuff, thanks a lot!

from reactiveplusplus.

victimsnino avatar victimsnino commented on May 24, 2024 1

@mincequi, debounce implemented =)

from reactiveplusplus.

victimsnino avatar victimsnino commented on May 24, 2024 1

I'm closing this issue due to original issue resolved.
If you have any other issues/feature requests and etc, then create new one for them =)

from reactiveplusplus.

victimsnino avatar victimsnino commented on May 24, 2024

Hey!
Yeah, I know about this problem. To be honest, I don't have such a plans, because...
While std::ranges is pretty easy to fix, I'm really not sure about std::stop_token - some internal logic relies on this heavily. If you can provide some good idea how to adapt it for Apple Clang - you are welcome =) One more thing: concepts - RPP uses them everywhere but Apple Clang has "partial" support for it...

Or would you accept PRs fixing macOS/clang compilation?

Yeah, I'm fully open to any PRs if it would not be too overcomplicated.

from reactiveplusplus.

mincequi avatar mincequi commented on May 24, 2024

Hey there,
thanks for your feedback.
Although, i am pretty experienced with C++ in general, i would rate my knowledge in newer aspects (C++17 and later) somewhat lower. When I will find an easy way to adapt, i will keep you posted.
However, i believe, that clang and/or apple will adapt to C++20 in the near future.
So, any effort from me (and you) might be pointless, that's why i completely understand your decition.

I will continue using rxcpp for now, but i am pretty open to switch over to your lib as soon as it is usable on macOS.

Anyway, awesome effort from your side and keep going. I will have an eye on this :)

from reactiveplusplus.

victimsnino avatar victimsnino commented on May 24, 2024

Hi @mincequi ,

Yeah, I see. But I’m not sure about your hopes related to Apple/Clang. I can suggest you using gcc or clang (not Apple) instead of Apple Clang if it is applicable in your case

from reactiveplusplus.

mincequi avatar mincequi commented on May 24, 2024

Hi @victimsnino ,

according to the link which i posted above, this is not related to Apple's clang, but the general clang/libc++ combination.
I also tried the stock clang v15, however without success.
Unfortunately, GCC is not an option, because it is very painful to use on macOS and Homebrew. :(

from reactiveplusplus.

victimsnino avatar victimsnino commented on May 24, 2024

Sounds strange, because I have ubuntu + clang combination in CI and it works fine
-- The CXX compiler identification is Clang 11.0.0

Are you sure that your clang was stock clang not Apple Clang? I mean, for example, by default if you are trying to use "gcc" on mac, it is just kind of symlink to Apple Clang. For example:

~ which gcc
/usr/bin/gcc
➜  ~ gcc --version
Apple clang version 14.0.0 (clang-1400.0.29.102)
Target: x86_64-apple-darwin21.6.0
Thread model: posix
InstalledDir: /Library/Developer/CommandLineTools/usr/bin

In this case to call "real installed gcc" I need to use more specific binary:

~ gcc-12 --version
gcc-12 (Homebrew GCC 12.2.0) 12.2.0
Copyright (C) 2022 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

I believe, there can be something similar for clang

from reactiveplusplus.

victimsnino avatar victimsnino commented on May 24, 2024

Double-checked with "not apple" clang on mac - same errors like for Apple Clang. Looks like "not apple" clang on mac uses libc++ while "ubuntu" clang uses libstdc++ (which has all implemented features)

from reactiveplusplus.

mincequi avatar mincequi commented on May 24, 2024

Ok, maybe this narrows down to libstdc++ vs libc++

from reactiveplusplus.

victimsnino avatar victimsnino commented on May 24, 2024

I will try to think about possible W/As.

BTW:

Unfortunately, GCC is not an option, because it is very painful to use on macOS and Homebrew. :(

Why? Just do

brew install gcc@12
export CC=gcc-12
export CXX=g++12

and you can build anything with gcc =)

from reactiveplusplus.

victimsnino avatar victimsnino commented on May 24, 2024

Hi @mincequi ,
I've merged PR to enable macos. Looks like CI passed on MacOS. Could you check if it helps you too?

from reactiveplusplus.

mincequi avatar mincequi commented on May 24, 2024

Hi @victimsnino ,
thanks a lot for your effort. I will try it within the next couple of days.

I have another question, which i came across when working with rxcpp. Is there any kind of combiner, that accepts a dynamically changing list of observables?
e.g. (pseudo code)

list<observable> observables
observable combinedObservable = combine(observables)

The list might also change during runtime.

from reactiveplusplus.

victimsnino avatar victimsnino commented on May 24, 2024

Not sure if I get your goal. I see two possible solutions but it is about totally different use cases. Could you provide some more context and example for such a usecase?

from reactiveplusplus.

mincequi avatar mincequi commented on May 24, 2024

Ok, i solved it already. Thanks.
I also did not want to get too off-topic here.

I will come back to you with feedback about my ReactivePlusPlus integration.

from reactiveplusplus.

victimsnino avatar victimsnino commented on May 24, 2024

@mincequi , cool! Thank you for feedback! Don’t shy to provide any feedback or feature requests :-)

from reactiveplusplus.

mincequi avatar mincequi commented on May 24, 2024

@victimsnino
Thanks for your support. Here we go, with my previously asked question on how to combine an arbitrary number of observables. I made usage of rxcpp's subjects::behaviour in the following way:

class Manager {
public:
    void setValue(const std::string& id, int value) {
        if (!_subjects.count(id)) {
            _subjects.insert( {id, rxcpp::subjects::behavior<int32_t>(0)} );
            _subjects.at(id).get_observable()
                    .timeout(10s, rxcpp::observe_on_event_loop())
                    .subscribe([this](const int32_t&) {
                int sum = 0;
                for (const auto& kv : _subjects) {
                    sum += kv.second.get_value();
                }
                sumValue.get_subscriber().on_next(sum);
            }, [this, id](std::exception_ptr ep) {
                _subjects.erase(id);
            });
        }
        _subjects.at(id).get_subscriber().on_next(value);
    }

    rxcpp::subjects::behavior<int32_t> sumValue;

private:
    std::map<std::string, rxcpp::subjects::behavior<int32_t>> _subjects;
};

This might be done better. However, my current "naive" implementation cannot be done with rpp, due to the lack of behavior subjects. What would you suggest? Thanks a lot!

from reactiveplusplus.

victimsnino avatar victimsnino commented on May 24, 2024

@mincequi,

If i get it correct, are you trying to keep sum of "last" values by different keys? And do you need to keep map of subjects? If you don't need to keep map of subjects, then you can do something like this:

    rpp::subjects::publish_subject<std::pair<std::string, int>> keyValueSubject{};
    rpp::subjects::publish_subject<int32_t>                     sumValueSubject{};

    keyValueSubject.get_observable().scan(std::map<std::string, int>{},
                                          [](std::map<std::string, int>&& seed, std::pair<std::string, int> newPair)
                                          {
                                              seed[newPair.first] = newPair.second;
                                              return std::move(seed);
                                          })
                   .map([](const std::map<std::string, int>& keyValue)
                   {
                       return std::accumulate(keyValue.cbegin(),
                                              keyValue.cend(),
                                              0,
                                              [](int val, const auto& pair) { return val + pair.second; });
                   })
                   .subscribe(sumValueSubject.get_subscriber());

    sumValueSubject.get_observable().subscribe([](int32_t sum) { std::cout << "sum is " << sum << std::endl; });

    keyValueSubject.get_subscriber().on_next({"first", 1});
    keyValueSubject.get_subscriber().on_next({"second", 2});
    keyValueSubject.get_subscriber().on_next({"first", 3});

    // sum is 1
    // sum is 3
    // sum is 5

Only one difference from "behavior" in this case: it would not send "last" value on subscribe immediately.

Anyway i've added it for me #300

UPD: Looks like you also need timeout? If timeout reached, then value should be removed from sum?

from reactiveplusplus.

mincequi avatar mincequi commented on May 24, 2024

@victimsnino
Yes, this looks nice and emitting "last" value on subscribe is not needed.
But yes, i somehow need that timeout and the specific source shall be removed from accumulation.

from reactiveplusplus.

victimsnino avatar victimsnino commented on May 24, 2024

Ok, then it can be something like:

 rpp::subjects::publish_subject<std::pair<std::string, int>> keyValueSubject{};
    rpp::subjects::publish_subject<int32_t>                     sumValueSubject{};

    keyValueSubject.get_observable()
                   .group_by([](const auto& pair) { return pair.first; }, [](const auto& pair) { return pair.second; })
                   .flat_map([](const rpp::grouped_observable_group_by<std::string, int>& obs)
                   {
                       return obs.timeout(std::chrono::seconds{10}, rpp::source::just(0), rpp::schedulers::new_thread{})
                                 .map([key = obs.get_key()](int v)
                                 {
                                     return std::pair{key, v};
                                 })
                                 .repeat();
                   })
                   .scan(std::map<std::string, int>{},
                         [](std::map<std::string, int>&& seed, std::pair<std::string, int> newPair)
                         {
                             seed[newPair.first] = newPair.second;
                             return std::move(seed);
                         })
                   .map([](const std::map<std::string, int>& keyValue)
                   {
                       return std::accumulate(keyValue.cbegin(),
                                              keyValue.cend(),
                                              0,
                                              [](int val, const auto& pair) { return val + pair.second; });
                   })
                   .subscribe(sumValueSubject.get_subscriber());

    sumValueSubject.get_observable().subscribe([](int32_t sum) { std::cout << "sum is " << sum << std::endl; });

    keyValueSubject.get_subscriber().on_next({"first", 1});
    keyValueSubject.get_subscriber().on_next({"second", 2});
    keyValueSubject.get_subscriber().on_next({"first", 3});

std::cout << "SLEEP" << std::endl;
    std::this_thread::sleep_for(std::chrono::seconds{15});


/*
sum is 1
sum is 3
sum is 5
SLEEP
sum is 2
sum is 0
*/

One more thing: i need timeout variant which accepts "fallback" observable. I will do it in near time. Same as pool-based schedulers to replace event_loop

UPD: timeout with fallback obs merged

from reactiveplusplus.

mincequi avatar mincequi commented on May 24, 2024

...ok, as you might have guessed, i am missing another operator ;)

This time, i would like to request the time-based debounce operator.
Do you believe, this could be easily added?

from reactiveplusplus.

victimsnino avatar victimsnino commented on May 24, 2024

@mincequim, Yeah, sure, no problem =) Currently I'm implementing operators mostly by user's requests (to be sure that someone using it :-) )

To be sure that we have same understanding:
you need operator which emits emission if no any other emissions since emission during X interval? Like this:
image

Reason why I am asking: people often confused between debounce/throttle and sample =)

from reactiveplusplus.

mincequi avatar mincequi commented on May 24, 2024

@victimsnino
Yes, I definitely need the debounce operator. throttle is not the thing I need.

from reactiveplusplus.

victimsnino avatar victimsnino commented on May 24, 2024

added issue #306

from reactiveplusplus.

mincequi avatar mincequi commented on May 24, 2024

Tested and working :)

from reactiveplusplus.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.