Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Connect with unique objects #2

Closed
vainamon opened this issue Apr 20, 2021 · 2 comments
Closed

Connect with unique objects #2

vainamon opened this issue Apr 20, 2021 · 2 comments

Comments

@vainamon
Copy link
Contributor

Hello!
Thanks for the useful nice little tool.
Consider the following example:

class other_class
{
public:
    other_class() = default;
    other_class(int v) : nr(v) {}

    void clicked()
    {
    	xil_printf("clicked:");
    }

    void clicked_again(int v)
    {
    	xil_printf("clicked_again:");
    }


private:

    int nr = 23;
};

class my_class
{
public:

    my_class(int f) : mf(f) {}

    void some_method()
    {
        emit click();
    }

    miso::signal<> click;
    int mf = 0;

};

int main() {
    my_class src(56);
    my_class src2(5656);

    other_class dst(4);
    other_class dst2(100500);

    miso::connect(src.click, std::bind(&other_class::clicked, dst));
    miso::connect(src2.click, std::bind(&other_class::clicked, dst2));

    src.some_method();

    return 0;
}

Slot clicked() will be called twice, which is unexpected, but is not surprise - because of static nature of SHT in connect_i function. For solve this I replace static SHT sh to

static std::unordered_map<std::string, SHT> sh_hash;    

auto sh_key = typeid(T).name() + std::string(typeid(FT).name()) + static_cast<std::ostringstream&>(
                        std::ostringstream().flush() << reinterpret_cast<void*>(&sholders)
                      ).str();

SHT &sh = sh_hash[sh_key];

But there is another problem if objects dynamically and repeatedly created, connected, emitted and destroyed: sh_hash would not be cleared and would be overfull sometime. That is why I changed connect_i function to:

        template<class T, class FT, class SHT>
        void connect_i(T &&f, std::vector<common_slot_base *> &sholders, bool active = true) {
            static std::unordered_map<std::string, SHT> sh_hash;
            
            auto sh_key = typeid(T).name() + std::string(typeid(FT).name()) + static_cast<std::ostringstream&>(
                        std::ostringstream().flush() << reinterpret_cast<void*>(&sholders)
                      ).str();

            SHT &sh = sh_hash[sh_key];

            func_and_bool<FT> fb{std::make_shared<FT>(std::forward<T>(f)), active, reinterpret_cast<void *>(&f)};
            bool already_in = false;
            bool active_status = active;
            
            std::for_each(sh.slots.begin(), sh.slots.end(),
                          [&](func_and_bool<FT> &s) { if (s.addr == fb.addr){s.active = active; already_in = true;} active_status |= s.active; });
            
            if (active_status) {
                if (!already_in) sh.slots.emplace_back(fb);
                if (std::find(sholders.begin(), sholders.end(), static_cast<common_slot_base *>(&sh)) == sholders.end()) {
                    sholders.push_back(&sh);
                }
            } else {
                remove(sholders.begin(), sholders.end(), static_cast<common_slot_base *>(&sh));
                sh_hash.erase(sh_key);
            }
        }

That's all.

@fritzone
Copy link
Owner

Hi,

Thanks for taking time to fix this issue, indeed the problem you have reported is a valid and serious one. I would be happy to have it fixed, so, in case you would open a pull request, I would be happy to have it merged back, and considering the amount of code you have wrote for this, I'd be happy to add you as a project developer too if you want this, using the motto: "more eyes see more!"!

Cheers, f.

@vainamon
Copy link
Contributor Author

Ok, I would open a pull request. And of course these changes must be reviewed and tested by someone else. I think there's no need for add me as a project developer - I'll plan to use miso in my projects and if there's another issues, then I'll be definitely let you know.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants