Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. General and Desktop
  4. client-side implementation of QMetaObject::invokeMethod(QObject *context, Functor function, Qt::ConnectionType type = Qt::AutoConnection)?
Forum Updated to NodeBB v4.3 + New Features

client-side implementation of QMetaObject::invokeMethod(QObject *context, Functor function, Qt::ConnectionType type = Qt::AutoConnection)?

Scheduled Pinned Locked Moved Unsolved General and Desktop
3 Posts 2 Posters 257 Views 2 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • R Offline
    R Offline
    RJV B
    wrote on last edited by
    #1

    I'm working on a "retro-computing" project where I'd like to target Qt 5.8 at the latest.

    Is there any possibility to provide a client-side equivalent implementation of QMetaObject::invokeMethod(QObject *context, Functor function, Qt::ConnectionType type = Qt::AutoConnection), allowing me to do something like

    Qustom::invokeMethod(obj, [=](){ obj->method(a,b,c); }, Qt::BlockingQueuedConnection);
    

    I suppose this variant should be cheaper than the old invokeMethod(obj, "method", Qt::BlockingQueuedConnection, Q_ARG(?,a), Q_ARG(?, b), Q_ARG(?,c));?

    Pl45m4P 1 Reply Last reply
    0
    • R RJV B

      I'm working on a "retro-computing" project where I'd like to target Qt 5.8 at the latest.

      Is there any possibility to provide a client-side equivalent implementation of QMetaObject::invokeMethod(QObject *context, Functor function, Qt::ConnectionType type = Qt::AutoConnection), allowing me to do something like

      Qustom::invokeMethod(obj, [=](){ obj->method(a,b,c); }, Qt::BlockingQueuedConnection);
      

      I suppose this variant should be cheaper than the old invokeMethod(obj, "method", Qt::BlockingQueuedConnection, Q_ARG(?,a), Q_ARG(?, b), Q_ARG(?,c));?

      Pl45m4P Offline
      Pl45m4P Offline
      Pl45m4
      wrote on last edited by
      #2

      @RJV-B said in client-side implementation of QMetaObject::invokeMethod(QObject *context, Functor function, Qt::ConnectionType type = Qt::AutoConnection)?:

      where I'd like to target Qt 5.8 at the latest

      Depends on how far you want to go back. If you want your retro-project to support Qt4 versions, you cannot use lambdas.

      Qustom
      

      I like that name :)


      If debugging is the process of removing software bugs, then programming must be the process of putting them in.

      ~E. W. Dijkstra

      1 Reply Last reply
      0
      • R Offline
        R Offline
        RJV B
        wrote on last edited by RJV B
        #3

        No, I do plan to stick with Qt5, and may not need to go older than Qt 5.8 (the last to support OS X 10.9) and don't really want to go older than 5.6 .

        Looking at the 5.10 sources I'd have to derive QSlotObjectBase class (looks like that might work) but also provide a custom QFunctorSlotObject class, to be used via a QFunctorSlotObjectWithNoArgs template. That one has a static void impl() function, and the instance I'd create gets handed to the QMetaCallEvent ctor, meaning I'd probably have to derive that class too in hope that gets me deep enough?

        I wonder if I didn't already try to go down this rabbit hole once for Qt 5.9 . I'd forgotten, but invokeMethod support for "functors" is actually among the tidbits that I ended up backporting to my patched Qt 5.9 . This time I'm not planning to "just patch Qt already" ;)

        Googling for a lib[std]c++ mechanism to execute a function on a specific thread I found this answer: https://stackoverflow.com/a/21653558/1460868 , suggesting in particular this bit of code:

        void postToMainThread(std::function<void()> && fun) {
          QObject signalSource;
          QObject::connect(&signalSource, &QObject::destroyed, qApp, [fun(std::move(fun))](QObject*){
            fun();
          });
        }
        

        It appears to do the trick (at the cost of some additional overhead due to the temp. object). There's also

        namespace detail {
        template <typename F>
        struct FEvent : public QEvent {
           using Fun = typename std::decay<F>::type;
           Fun fun;
           FEvent(Fun && fun) : QEvent(QEvent::None), fun(std::move(fun)) {}
           FEvent(const Fun & fun) : QEvent(QEvent::None), fun(fun) {}
           ~FEvent() { fun(); }
        }; }
        
        template <typename F>
        static void postToObject(F && fun, QObject * obj = qApp) {
           QCoreApplication::postEvent(obj, new detail::FEvent<F>(std::forward<F>(fun)));
        }
        

        In both cases I'd need to verify if they do synchronous execution and, if not, figure out how to make them that.

        EDIT: note to self: the 1st solution requires C++14, the second is C++11 compatible.

        1 Reply Last reply
        0

        • Login

        • Login or register to search.
        • First post
          Last post
        0
        • Categories
        • Recent
        • Tags
        • Popular
        • Users
        • Groups
        • Search
        • Get Qt Extensions
        • Unsolved