Home > Back-end >  Generic task wrapper
Generic task wrapper

Time:11-01

Let's say this is how I dispatch a task to the gui thread:

void DispatchToGuiThread(std::function<void(void)> task);

I want a generic GUIDispatchedTask class that turns this:

// foo takes some arguments and must be run in the gui thread

auto guiDispatchedTask = [] (A a, B b, C c, D d) {
  DispatchToGuiThread(
    [a = a, b = b, c = c] {
      foo(a, b, c);
    }
  );
};

to this:

auto guiDispatchedTask = GUIDispatchedTask{ foo };

I don't want to repeat the arguments of foo like GUIDispatchedTask<A, B, C> because foo is likely going to be a lambda and repeating the arguments is tedious. I could not make that work.

CodePudding user response:

Using an idea from the comments, here's what I did:

#include <stdio.h>
#include <functional>

void DispatchToGuiThread(std::function<void(void)> task) {
  puts("in gui thread");
  task();
}

template <class Func>
struct GUIDispatchedTask
{
private:
  Func _func;

public:
  GUIDispatchedTask(Func func)
    : _func(std::move(func))
  {}

  template <class ...T>
  void operator()(T... args) {
    DispatchToGuiThread([this, ...args = args] {
        _func(args...);
    });
  }
};

void foo(int a, int b, int c) {
  printf("a = %d\nb = %d\nc = %d\n", a, b, c);
}

int main() {
  auto guiFoo = GUIDispatchedTask{foo};

  guiFoo(1, 2, 3);
}

Demo

CodePudding user response:

You can also do it with generic lambda.

template<typename F>
auto GUIDispatchedTask(F f){
    return [=](auto&&... args){
        DispatchToGuiThread([=]{f(args...);});
    };
}
  •  Tags:  
  • c
  • Related