Show a patch.

GET /api/patches/1822/?format=api
HTTP 200 OK
Allow: GET, PUT, PATCH, HEAD, OPTIONS
Content-Type: application/json
Vary: Accept

{
    "id": 1822,
    "url": "https://patchwork.libcamera.org/api/patches/1822/?format=api",
    "web_url": "https://patchwork.libcamera.org/patch/1822/",
    "project": {
        "id": 1,
        "url": "https://patchwork.libcamera.org/api/projects/1/?format=api",
        "name": "libcamera",
        "link_name": "libcamera",
        "list_id": "libcamera_core",
        "list_email": "libcamera-devel@lists.libcamera.org",
        "web_url": "",
        "scm_url": "",
        "webscm_url": ""
    },
    "msgid": "<20190817152104.10834-5-laurent.pinchart@ideasonboard.com>",
    "date": "2019-08-17T15:20:50",
    "name": "[libcamera-devel,v2,04/18] libcamera: signal: Split Slot implementation to reusable classes",
    "commit_ref": null,
    "pull_url": null,
    "state": "accepted",
    "archived": false,
    "hash": "988335b10ca921f3b8f3903aa69f9bb86464f37b",
    "submitter": {
        "id": 2,
        "url": "https://patchwork.libcamera.org/api/people/2/?format=api",
        "name": "Laurent Pinchart",
        "email": "laurent.pinchart@ideasonboard.com"
    },
    "delegate": null,
    "mbox": "https://patchwork.libcamera.org/patch/1822/mbox/",
    "series": [
        {
            "id": 463,
            "url": "https://patchwork.libcamera.org/api/series/463/?format=api",
            "web_url": "https://patchwork.libcamera.org/project/libcamera/list/?series=463",
            "date": "2019-08-17T15:20:46",
            "name": "Object & Thread enhancements",
            "version": 2,
            "mbox": "https://patchwork.libcamera.org/series/463/mbox/"
        }
    ],
    "comments": "https://patchwork.libcamera.org/api/patches/1822/comments/",
    "check": "pending",
    "checks": "https://patchwork.libcamera.org/api/patches/1822/checks/",
    "tags": {},
    "headers": {
        "Return-Path": "<laurent.pinchart@ideasonboard.com>",
        "Received": [
            "from perceval.ideasonboard.com (perceval.ideasonboard.com\n\t[IPv6:2001:4b98:dc2:55:216:3eff:fef7:d647])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTPS id 79581600F9\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tSat, 17 Aug 2019 17:21:14 +0200 (CEST)",
            "from pendragon.bb.dnainternet.fi\n\t(dfj612yhrgyx302h3jwwy-3.rev.dnainternet.fi\n\t[IPv6:2001:14ba:21f5:5b00:ce28:277f:58d7:3ca4])\n\tby perceval.ideasonboard.com (Postfix) with ESMTPSA id 05D2F556\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tSat, 17 Aug 2019 17:21:13 +0200 (CEST)"
        ],
        "DKIM-Signature": "v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com;\n\ts=mail; t=1566055274;\n\tbh=N1nhpGCceXX233na9XiWqIb0tLQyPSqx5nhPM+nNN58=;\n\th=From:To:Subject:Date:In-Reply-To:References:From;\n\tb=vapdTzwpcPofQkj1GCGDqVbdxwIU1f0F5nSR9ite3hPr32L9veeL1KT7OO5U5yiDk\n\tNr41aXyMrKQkPknHZpfluM3kUBDNe4S2I8rFVwYWPZKjo9FgIkEkJgWC8oXxhuU0kD\n\tiAUM1RQbj1PYSdODVAi3CrK5MKzQjnMD9BEhvHRc=",
        "From": "Laurent Pinchart <laurent.pinchart@ideasonboard.com>",
        "To": "libcamera-devel@lists.libcamera.org",
        "Date": "Sat, 17 Aug 2019 18:20:50 +0300",
        "Message-Id": "<20190817152104.10834-5-laurent.pinchart@ideasonboard.com>",
        "X-Mailer": "git-send-email 2.21.0",
        "In-Reply-To": "<20190817152104.10834-1-laurent.pinchart@ideasonboard.com>",
        "References": "<20190817152104.10834-1-laurent.pinchart@ideasonboard.com>",
        "MIME-Version": "1.0",
        "Content-Type": "text/plain; charset=UTF-8",
        "Content-Transfer-Encoding": "8bit",
        "Subject": "[libcamera-devel] [PATCH v2 04/18] libcamera: signal: Split Slot\n\timplementation to reusable classes",
        "X-BeenThere": "libcamera-devel@lists.libcamera.org",
        "X-Mailman-Version": "2.1.23",
        "Precedence": "list",
        "List-Id": "<libcamera-devel.lists.libcamera.org>",
        "List-Unsubscribe": "<https://lists.libcamera.org/options/libcamera-devel>,\n\t<mailto:libcamera-devel-request@lists.libcamera.org?subject=unsubscribe>",
        "List-Archive": "<https://lists.libcamera.org/pipermail/libcamera-devel/>",
        "List-Post": "<mailto:libcamera-devel@lists.libcamera.org>",
        "List-Help": "<mailto:libcamera-devel-request@lists.libcamera.org?subject=help>",
        "List-Subscribe": "<https://lists.libcamera.org/listinfo/libcamera-devel>,\n\t<mailto:libcamera-devel-request@lists.libcamera.org?subject=subscribe>",
        "X-List-Received-Date": "Sat, 17 Aug 2019 15:21:14 -0000"
    },
    "content": "Move the Slot* classes to bound_method.{h,cpp} and rename them to\nBound*Method*. They will be reused to implement asynchronous method\ninvocation similar to cross-thread signal delivery.\n\nThis is only a move and rename, no functional changes are included.\n\nSigned-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>\nReviewed-by: Jacopo Mondi <jacopo@jmondi.org>\nReviewed-by: Niklas Söderlund <niklas.soderlund@ragnatech.se>\n---\n Documentation/Doxyfile.in        |  10 +--\n include/libcamera/bound_method.h | 131 ++++++++++++++++++++++++++++\n include/libcamera/meson.build    |   1 +\n include/libcamera/object.h       |   5 +-\n include/libcamera/signal.h       | 145 ++++---------------------------\n src/libcamera/bound_method.cpp   |  33 +++++++\n src/libcamera/include/message.h  |   8 +-\n src/libcamera/meson.build        |   1 +\n src/libcamera/message.cpp        |   4 +-\n src/libcamera/object.cpp         |   2 +-\n src/libcamera/signal.cpp         |  23 -----\n 11 files changed, 197 insertions(+), 166 deletions(-)\n create mode 100644 include/libcamera/bound_method.h\n create mode 100644 src/libcamera/bound_method.cpp",
    "diff": "diff --git a/Documentation/Doxyfile.in b/Documentation/Doxyfile.in\nindex 3d94623a4b8f..a9596c2a32d8 100644\n--- a/Documentation/Doxyfile.in\n+++ b/Documentation/Doxyfile.in\n@@ -865,11 +865,11 @@ EXCLUDE_PATTERNS       =\n # Note that the wildcards are matched against the file with absolute path, so to\n # exclude all test directories use the pattern */test/*\n \n-EXCLUDE_SYMBOLS        = libcamera::SignalBase \\\n-                         libcamera::SlotArgs \\\n-                         libcamera::SlotBase \\\n-                         libcamera::SlotMember \\\n-                         libcamera::SlotStatic \\\n+EXCLUDE_SYMBOLS        = libcamera::BoundMemberMethod \\\n+                         libcamera::BoundMethodArgs \\\n+                         libcamera::BoundMethodBase \\\n+                         libcamera::BoundStaticMethod \\\n+                         libcamera::SignalBase \\\n                          std::*\n \n # The EXAMPLE_PATH tag can be used to specify one or more files or directories\ndiff --git a/include/libcamera/bound_method.h b/include/libcamera/bound_method.h\nnew file mode 100644\nindex 000000000000..38c44b923ba1\n--- /dev/null\n+++ b/include/libcamera/bound_method.h\n@@ -0,0 +1,131 @@\n+/* SPDX-License-Identifier: LGPL-2.1-or-later */\n+/*\n+ * Copyright (C) 2019, Google Inc.\n+ *\n+ * bound_method.h - Method bind and invocation\n+ */\n+#ifndef __LIBCAMERA_BOUND_METHOD_H__\n+#define __LIBCAMERA_BOUND_METHOD_H__\n+\n+#include <tuple>\n+#include <type_traits>\n+\n+namespace libcamera {\n+\n+class Object;\n+template<typename... Args>\n+class Signal;\n+class SignalBase;\n+\n+class BoundMethodBase\n+{\n+public:\n+\tBoundMethodBase(void *obj, Object *object)\n+\t\t: obj_(obj), object_(object) {}\n+\tvirtual ~BoundMethodBase() {}\n+\n+\ttemplate<typename T, typename std::enable_if<!std::is_same<Object, T>::value>::type * = nullptr>\n+\tbool match(T *obj) { return obj == obj_; }\n+\tbool match(Object *object) { return object == object_; }\n+\n+\tvoid disconnect(SignalBase *signal);\n+\n+\tvoid activatePack(void *pack);\n+\tvirtual void invokePack(void *pack) = 0;\n+\n+protected:\n+\tvoid *obj_;\n+\tObject *object_;\n+};\n+\n+template<typename... Args>\n+class BoundMethodArgs : public BoundMethodBase\n+{\n+private:\n+#ifndef __DOXYGEN__\n+\t/*\n+\t * This is a cheap partial implementation of std::integer_sequence<>\n+\t * from C++14.\n+\t */\n+\ttemplate<int...>\n+\tstruct sequence {\n+\t};\n+\n+\ttemplate<int N, int... S>\n+\tstruct generator : generator<N-1, N-1, S...> {\n+\t};\n+\n+\ttemplate<int... S>\n+\tstruct generator<0, S...> {\n+\t\ttypedef sequence<S...> type;\n+\t};\n+#endif\n+\n+\tusing PackType = std::tuple<typename std::remove_reference<Args>::type...>;\n+\n+\ttemplate<int... S>\n+\tvoid invokePack(void *pack, sequence<S...>)\n+\t{\n+\t\tPackType *args = static_cast<PackType *>(pack);\n+\t\tinvoke(std::get<S>(*args)...);\n+\t\tdelete args;\n+\t}\n+\n+public:\n+\tBoundMethodArgs(void *obj, Object *object)\n+\t\t: BoundMethodBase(obj, object) {}\n+\n+\tvoid invokePack(void *pack) override\n+\t{\n+\t\tinvokePack(pack, typename generator<sizeof...(Args)>::type());\n+\t}\n+\n+\tvirtual void activate(Args... args) = 0;\n+\tvirtual void invoke(Args... args) = 0;\n+};\n+\n+template<typename T, typename... Args>\n+class BoundMemberMethod : public BoundMethodArgs<Args...>\n+{\n+public:\n+\tusing PackType = std::tuple<typename std::remove_reference<Args>::type...>;\n+\n+\tBoundMemberMethod(T *obj, Object *object, void (T::*func)(Args...))\n+\t\t: BoundMethodArgs<Args...>(obj, object), func_(func) {}\n+\n+\tvoid activate(Args... args)\n+\t{\n+\t\tif (this->object_)\n+\t\t\tBoundMethodBase::activatePack(new PackType{ args... });\n+\t\telse\n+\t\t\t(static_cast<T *>(this->obj_)->*func_)(args...);\n+\t}\n+\n+\tvoid invoke(Args... args)\n+\t{\n+\t\t(static_cast<T *>(this->obj_)->*func_)(args...);\n+\t}\n+\n+private:\n+\tfriend class Signal<Args...>;\n+\tvoid (T::*func_)(Args...);\n+};\n+\n+template<typename... Args>\n+class BoundStaticMethod : public BoundMethodArgs<Args...>\n+{\n+public:\n+\tBoundStaticMethod(void (*func)(Args...))\n+\t\t: BoundMethodArgs<Args...>(nullptr, nullptr), func_(func) {}\n+\n+\tvoid activate(Args... args) { (*func_)(args...); }\n+\tvoid invoke(Args... args) {}\n+\n+private:\n+\tfriend class Signal<Args...>;\n+\tvoid (*func_)(Args...);\n+};\n+\n+}; /* namespace libcamera */\n+\n+#endif /* __LIBCAMERA_BOUND_METHOD_H__ */\ndiff --git a/include/libcamera/meson.build b/include/libcamera/meson.build\nindex 920eb5fcbfd1..a8a38a9b1db7 100644\n--- a/include/libcamera/meson.build\n+++ b/include/libcamera/meson.build\n@@ -1,4 +1,5 @@\n libcamera_api = files([\n+    'bound_method.h',\n     'buffer.h',\n     'camera.h',\n     'camera_manager.h',\ndiff --git a/include/libcamera/object.h b/include/libcamera/object.h\nindex 3d08d69a9044..e3b39cf547b0 100644\n--- a/include/libcamera/object.h\n+++ b/include/libcamera/object.h\n@@ -10,13 +10,14 @@\n #include <list>\n #include <memory>\n \n+#include <libcamera/bound_method.h>\n+\n namespace libcamera {\n \n class Message;\n template<typename... Args>\n class Signal;\n class SignalBase;\n-class SlotBase;\n class Thread;\n \n class Object\n@@ -36,7 +37,7 @@ protected:\n private:\n \ttemplate<typename... Args>\n \tfriend class Signal;\n-\tfriend class SlotBase;\n+\tfriend class BoundMethodBase;\n \tfriend class Thread;\n \n \tvoid connect(SignalBase *signal);\ndiff --git a/include/libcamera/signal.h b/include/libcamera/signal.h\nindex 8f6db700cd80..3b6de30f7d35 100644\n--- a/include/libcamera/signal.h\n+++ b/include/libcamera/signal.h\n@@ -8,127 +8,14 @@\n #define __LIBCAMERA_SIGNAL_H__\n \n #include <list>\n-#include <tuple>\n #include <type_traits>\n #include <vector>\n \n+#include <libcamera/bound_method.h>\n #include <libcamera/object.h>\n \n namespace libcamera {\n \n-template<typename... Args>\n-class Signal;\n-class SignalBase;\n-\n-class SlotBase\n-{\n-public:\n-\tSlotBase(void *obj, Object *object)\n-\t\t: obj_(obj), object_(object) {}\n-\tvirtual ~SlotBase() {}\n-\n-\ttemplate<typename T, typename std::enable_if<!std::is_same<Object, T>::value>::type * = nullptr>\n-\tbool match(T *obj) { return obj == obj_; }\n-\tbool match(Object *object) { return object == object_; }\n-\n-\tvoid disconnect(SignalBase *signal);\n-\n-\tvoid activatePack(void *pack);\n-\tvirtual void invokePack(void *pack) = 0;\n-\n-protected:\n-\tvoid *obj_;\n-\tObject *object_;\n-};\n-\n-template<typename... Args>\n-class SlotArgs : public SlotBase\n-{\n-private:\n-#ifndef __DOXYGEN__\n-\t/*\n-\t * This is a cheap partial implementation of std::integer_sequence<>\n-\t * from C++14.\n-\t */\n-\ttemplate<int...>\n-\tstruct sequence {\n-\t};\n-\n-\ttemplate<int N, int... S>\n-\tstruct generator : generator<N-1, N-1, S...> {\n-\t};\n-\n-\ttemplate<int... S>\n-\tstruct generator<0, S...> {\n-\t\ttypedef sequence<S...> type;\n-\t};\n-#endif\n-\n-\tusing PackType = std::tuple<typename std::remove_reference<Args>::type...>;\n-\n-\ttemplate<int... S>\n-\tvoid invokePack(void *pack, sequence<S...>)\n-\t{\n-\t\tPackType *args = static_cast<PackType *>(pack);\n-\t\tinvoke(std::get<S>(*args)...);\n-\t\tdelete args;\n-\t}\n-\n-public:\n-\tSlotArgs(void *obj, Object *object)\n-\t\t: SlotBase(obj, object) {}\n-\n-\tvoid invokePack(void *pack) override\n-\t{\n-\t\tinvokePack(pack, typename generator<sizeof...(Args)>::type());\n-\t}\n-\n-\tvirtual void activate(Args... args) = 0;\n-\tvirtual void invoke(Args... args) = 0;\n-};\n-\n-template<typename T, typename... Args>\n-class SlotMember : public SlotArgs<Args...>\n-{\n-public:\n-\tusing PackType = std::tuple<typename std::remove_reference<Args>::type...>;\n-\n-\tSlotMember(T *obj, Object *object, void (T::*func)(Args...))\n-\t\t: SlotArgs<Args...>(obj, object), func_(func) {}\n-\n-\tvoid activate(Args... args)\n-\t{\n-\t\tif (this->object_)\n-\t\t\tSlotBase::activatePack(new PackType{ args... });\n-\t\telse\n-\t\t\t(static_cast<T *>(this->obj_)->*func_)(args...);\n-\t}\n-\n-\tvoid invoke(Args... args)\n-\t{\n-\t\t(static_cast<T *>(this->obj_)->*func_)(args...);\n-\t}\n-\n-private:\n-\tfriend class Signal<Args...>;\n-\tvoid (T::*func_)(Args...);\n-};\n-\n-template<typename... Args>\n-class SlotStatic : public SlotArgs<Args...>\n-{\n-public:\n-\tSlotStatic(void (*func)(Args...))\n-\t\t: SlotArgs<Args...>(nullptr, nullptr), func_(func) {}\n-\n-\tvoid activate(Args... args) { (*func_)(args...); }\n-\tvoid invoke(Args... args) {}\n-\n-private:\n-\tfriend class Signal<Args...>;\n-\tvoid (*func_)(Args...);\n-};\n-\n class SignalBase\n {\n public:\n@@ -136,7 +23,7 @@ public:\n \tvoid disconnect(T *obj)\n \t{\n \t\tfor (auto iter = slots_.begin(); iter != slots_.end(); ) {\n-\t\t\tSlotBase *slot = *iter;\n+\t\t\tBoundMethodBase *slot = *iter;\n \t\t\tif (slot->match(obj)) {\n \t\t\t\titer = slots_.erase(iter);\n \t\t\t\tdelete slot;\n@@ -148,7 +35,7 @@ public:\n \n protected:\n \tfriend class Object;\n-\tstd::list<SlotBase *> slots_;\n+\tstd::list<BoundMethodBase *> slots_;\n };\n \n template<typename... Args>\n@@ -158,7 +45,7 @@ public:\n \tSignal() {}\n \t~Signal()\n \t{\n-\t\tfor (SlotBase *slot : slots_) {\n+\t\tfor (BoundMethodBase *slot : slots_) {\n \t\t\tslot->disconnect(this);\n \t\t\tdelete slot;\n \t\t}\n@@ -170,7 +57,7 @@ public:\n \t{\n \t\tObject *object = static_cast<Object *>(obj);\n \t\tobject->connect(this);\n-\t\tslots_.push_back(new SlotMember<T, Args...>(obj, object, func));\n+\t\tslots_.push_back(new BoundMemberMethod<T, Args...>(obj, object, func));\n \t}\n \n \ttemplate<typename T, typename std::enable_if<!std::is_base_of<Object, T>::value>::type * = nullptr>\n@@ -179,17 +66,17 @@ public:\n #endif\n \tvoid connect(T *obj, void (T::*func)(Args...))\n \t{\n-\t\tslots_.push_back(new SlotMember<T, Args...>(obj, nullptr, func));\n+\t\tslots_.push_back(new BoundMemberMethod<T, Args...>(obj, nullptr, func));\n \t}\n \n \tvoid connect(void (*func)(Args...))\n \t{\n-\t\tslots_.push_back(new SlotStatic<Args...>(func));\n+\t\tslots_.push_back(new BoundStaticMethod<Args...>(func));\n \t}\n \n \tvoid disconnect()\n \t{\n-\t\tfor (SlotBase *slot : slots_)\n+\t\tfor (BoundMethodBase *slot : slots_)\n \t\t\tdelete slot;\n \t\tslots_.clear();\n \t}\n@@ -204,15 +91,15 @@ public:\n \tvoid disconnect(T *obj, void (T::*func)(Args...))\n \t{\n \t\tfor (auto iter = slots_.begin(); iter != slots_.end(); ) {\n-\t\t\tSlotArgs<Args...> *slot = static_cast<SlotArgs<Args...> *>(*iter);\n+\t\t\tBoundMethodArgs<Args...> *slot = static_cast<BoundMethodArgs<Args...> *>(*iter);\n \t\t\t/*\n \t\t\t * If the object matches the slot, the slot is\n \t\t\t * guaranteed to be a member slot, so we can safely\n-\t\t\t * cast it to SlotMember<T, Args...> and access its\n+\t\t\t * cast it to BoundMemberMethod<T, Args...> and access its\n \t\t\t * func_ member.\n \t\t\t */\n \t\t\tif (slot->match(obj) &&\n-\t\t\t    static_cast<SlotMember<T, Args...> *>(slot)->func_ == func) {\n+\t\t\t    static_cast<BoundMemberMethod<T, Args...> *>(slot)->func_ == func) {\n \t\t\t\titer = slots_.erase(iter);\n \t\t\t\tdelete slot;\n \t\t\t} else {\n@@ -224,9 +111,9 @@ public:\n \tvoid disconnect(void (*func)(Args...))\n \t{\n \t\tfor (auto iter = slots_.begin(); iter != slots_.end(); ) {\n-\t\t\tSlotArgs<Args...> *slot = *iter;\n+\t\t\tBoundMethodArgs<Args...> *slot = *iter;\n \t\t\tif (slot->match(nullptr) &&\n-\t\t\t    static_cast<SlotStatic<Args...> *>(slot)->func_ == func) {\n+\t\t\t    static_cast<BoundStaticMethod<Args...> *>(slot)->func_ == func) {\n \t\t\t\titer = slots_.erase(iter);\n \t\t\t\tdelete slot;\n \t\t\t} else {\n@@ -241,9 +128,9 @@ public:\n \t\t * Make a copy of the slots list as the slot could call the\n \t\t * disconnect operation, invalidating the iterator.\n \t\t */\n-\t\tstd::vector<SlotBase *> slots{ slots_.begin(), slots_.end() };\n-\t\tfor (SlotBase *slot : slots)\n-\t\t\tstatic_cast<SlotArgs<Args...> *>(slot)->activate(args...);\n+\t\tstd::vector<BoundMethodBase *> slots{ slots_.begin(), slots_.end() };\n+\t\tfor (BoundMethodBase *slot : slots)\n+\t\t\tstatic_cast<BoundMethodArgs<Args...> *>(slot)->activate(args...);\n \t}\n };\n \ndiff --git a/src/libcamera/bound_method.cpp b/src/libcamera/bound_method.cpp\nnew file mode 100644\nindex 000000000000..0a2d61a6c805\n--- /dev/null\n+++ b/src/libcamera/bound_method.cpp\n@@ -0,0 +1,33 @@\n+/* SPDX-License-Identifier: LGPL-2.1-or-later */\n+/*\n+ * Copyright (C) 2019, Google Inc.\n+ *\n+ * bound_method.cpp - Method bind and invocation\n+ */\n+\n+#include <libcamera/bound_method.h>\n+\n+#include \"message.h\"\n+#include \"thread.h\"\n+#include \"utils.h\"\n+\n+namespace libcamera {\n+\n+void BoundMethodBase::disconnect(SignalBase *signal)\n+{\n+\tif (object_)\n+\t\tobject_->disconnect(signal);\n+}\n+\n+void BoundMethodBase::activatePack(void *pack)\n+{\n+\tif (Thread::current() == object_->thread()) {\n+\t\tinvokePack(pack);\n+\t} else {\n+\t\tstd::unique_ptr<Message> msg =\n+\t\t\tutils::make_unique<SignalMessage>(this, pack);\n+\t\tobject_->postMessage(std::move(msg));\n+\t}\n+}\n+\n+} /* namespace libcamera */\ndiff --git a/src/libcamera/include/message.h b/src/libcamera/include/message.h\nindex 416fe74b10ad..b4670c0eab76 100644\n--- a/src/libcamera/include/message.h\n+++ b/src/libcamera/include/message.h\n@@ -11,8 +11,8 @@\n \n namespace libcamera {\n \n+class BoundMethodBase;\n class Object;\n-class SlotBase;\n class Thread;\n \n class Message\n@@ -44,12 +44,12 @@ private:\n class SignalMessage : public Message\n {\n public:\n-\tSignalMessage(SlotBase *slot, void *pack)\n-\t\t: Message(Message::SignalMessage), slot_(slot), pack_(pack)\n+\tSignalMessage(BoundMethodBase *method, void *pack)\n+\t\t: Message(Message::SignalMessage), method_(method), pack_(pack)\n \t{\n \t}\n \n-\tSlotBase *slot_;\n+\tBoundMethodBase *method_;\n \tvoid *pack_;\n };\n \ndiff --git a/src/libcamera/meson.build b/src/libcamera/meson.build\nindex 7d5d3c04fba0..c5d8f116ffc6 100644\n--- a/src/libcamera/meson.build\n+++ b/src/libcamera/meson.build\n@@ -1,4 +1,5 @@\n libcamera_sources = files([\n+    'bound_method.cpp',\n     'buffer.cpp',\n     'camera.cpp',\n     'camera_manager.cpp',\ndiff --git a/src/libcamera/message.cpp b/src/libcamera/message.cpp\nindex d44d2a4c73a8..8d3376d8a533 100644\n--- a/src/libcamera/message.cpp\n+++ b/src/libcamera/message.cpp\n@@ -114,12 +114,12 @@ Message::Type Message::registerMessageType()\n /**\n  * \\fn SignalMessage::SignalMessage()\n  * \\brief Construct a SignalMessage\n- * \\param[in] slot The slot that the signal targets\n+ * \\param[in] method The slot that the signal targets\n  * \\param[in] pack The signal arguments\n  */\n \n /**\n- * \\var SignalMessage::slot_\n+ * \\var SignalMessage::method_\n  * \\brief The slot that the signal targets\n  */\n \ndiff --git a/src/libcamera/object.cpp b/src/libcamera/object.cpp\nindex 61787fadac0b..0adbc203add8 100644\n--- a/src/libcamera/object.cpp\n+++ b/src/libcamera/object.cpp\n@@ -90,7 +90,7 @@ void Object::message(Message *msg)\n \tswitch (msg->type()) {\n \tcase Message::SignalMessage: {\n \t\tSignalMessage *smsg = static_cast<SignalMessage *>(msg);\n-\t\tsmsg->slot_->invokePack(smsg->pack_);\n+\t\tsmsg->method_->invokePack(smsg->pack_);\n \t\tbreak;\n \t}\n \ndiff --git a/src/libcamera/signal.cpp b/src/libcamera/signal.cpp\nindex ab7dba508dfb..6ee348acc8d4 100644\n--- a/src/libcamera/signal.cpp\n+++ b/src/libcamera/signal.cpp\n@@ -7,10 +7,6 @@\n \n #include <libcamera/signal.h>\n \n-#include \"message.h\"\n-#include \"thread.h\"\n-#include \"utils.h\"\n-\n /**\n  * \\file signal.h\n  * \\brief Signal & slot implementation\n@@ -57,25 +53,6 @@ namespace libcamera {\n  * passed through the signal will remain valid after the signal is emitted.\n  */\n \n-void SlotBase::disconnect(SignalBase *signal)\n-{\n-\tif (object_)\n-\t\tobject_->disconnect(signal);\n-}\n-\n-void SlotBase::activatePack(void *pack)\n-{\n-\tObject *obj = static_cast<Object *>(object_);\n-\n-\tif (Thread::current() == obj->thread()) {\n-\t\tinvokePack(pack);\n-\t} else {\n-\t\tstd::unique_ptr<Message> msg =\n-\t\t\tutils::make_unique<SignalMessage>(this, pack);\n-\t\tobj->postMessage(std::move(msg));\n-\t}\n-}\n-\n /**\n  * \\fn Signal::connect(T *object, void(T::*func)(Args...))\n  * \\brief Connect the signal to a member function slot\n",
    "prefixes": [
        "libcamera-devel",
        "v2",
        "04/18"
    ]
}