AUI Framework  develop
Cross-platform base for C++ UI apps
Loading...
Searching...
No Matches
AObject.h
    1/*
    2 * AUI Framework - Declarative UI toolkit for modern C++20
    3 * Copyright (C) 2020-2025 Alex2772 and Contributors
    4 *
    5 * SPDX-License-Identifier: MPL-2.0
    6 *
    7 * This Source Code Form is subject to the terms of the Mozilla Public
    8 * License, v. 2.0. If a copy of the MPL was not distributed with this
    9 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
   10 */
   11
   12#pragma once
   13
   14#include "AObjectBase.h"
   15
   16namespace aui::detail {
   17  template<typename Object, typename Lambda>
   18  Lambda&& makeLambda(Object*, Lambda&& lambda) requires requires { std::is_class_v<Lambda>; } {
   19    return std::forward<Lambda>(lambda);
   20  }
   21
   22  template<typename Object1, typename Object2, typename Returns, typename... Args>
   23  auto makeLambda(Object1* object, Returns(Object2::*method)(Args...)) {
   24    return [object, method](Args... args) {
   25      (object->*method)(std::forward<Args>(args)...);
   26    };
   27  }
   28}
   29
   39class API_AUI_CORE AObject: public AObjectBase, public std::enable_shared_from_this<AObject>, public aui::noncopyable {
   40    friend class AAbstractSignal;
   41    template <typename ... Args>
   42    friend class ASignal;
   43
   44public:
   61    static constexpr AObjectBase* GENERIC_OBSERVER = nullptr;
   62
   63    AObject();
   64    virtual ~AObject() = default;
   65
   66    static void disconnect();
   67
   68    [[nodiscard]] _<AObject> sharedPtr() { return std::enable_shared_from_this<AObject>::shared_from_this(); }
   69
   70    [[nodiscard]] _weak<AObject> weakPtr() { return std::enable_shared_from_this<AObject>::weak_from_this(); }
   71
   85    template <AAnySignal Signal, aui::derived_from<AObjectBase> Object, ACompatibleSlotFor<Signal> Function>
   86    static decltype(auto) connect(const Signal& signal, Object* object, Function&& function) {
   87        return const_cast<Signal&>(signal).connect(object, aui::detail::makeLambda(object, std::forward<Function>(function)));
   88    }
   89
  105    template <AAnyProperty Property, aui::derived_from<AObjectBase> Object, typename Function>
  106    static decltype(auto) connect(const Property& property, Object* object, Function&& function) {
  107        auto lambda = aui::detail::makeLambda(object, std::forward<Function>(function));
  108        property.changed.makeRawInvocable(lambda)(*property);
  109        return connect(property.changed, object, std::move(lambda));
  110    }
  111
  126    template <APropertyReadable PropertySource, APropertyWritable PropertyDestination>
  127    static void connect(PropertySource&& propertySource, PropertyDestination&& propertyDestination) requires requires {
  128            // source and destination properties must have compatible underlying types
  129            { *propertySource } -> aui::convertible_to<std::decay_t<decltype(*propertyDestination)>>;
  130        } {
  131        AObject::connect(propertySource,
  132                         propertyDestination.assignment());
  133    }
  134
  155    template <APropertyWritable PropertySource, APropertyWritable PropertyDestination>
  156    static void biConnect(PropertySource&& propertySource, PropertyDestination&& propertyDestination) requires requires {
  157            // source and destination properties must have compatible underlying types
  158            { *propertySource } -> aui::convertible_to<std::decay_t<decltype(*propertyDestination)>>;
  159            { *propertyDestination } -> aui::convertible_to<std::decay_t<decltype(*propertySource)>>;
  160        } {
  161        AObject::connect(propertySource,
  162                         propertyDestination.assignment());
  163        AObject::connect(propertyDestination.changed,
  164                         propertySource.assignment());
  165    }
  166
  180    template <AAnySignalOrProperty Connectable, aui::derived_from<AObjectBase> Object,
  181        ACompatibleSlotFor<Connectable> Function>
  182    static decltype(auto)
  183    connect(const Connectable& connectable, Object& object, Function&& function) {
  184        return connect(connectable, &object, std::forward<Function>(function));
  185    }
  186
  200    template <typename Connectable, ACompatibleSlotFor<Connectable> Function>
  201    decltype(auto) connect(const Connectable& connectable, Function&& function) {
  202        return connect(connectable, this, std::forward<Function>(function));
  203    }
  204
  223    template <AAnySignalOrProperty Connectable, aui::derived_from<AObjectBase> Object, ACompatibleSlotFor<Connectable> Function>
  224    static decltype(auto)
  225    connect(const Connectable& connectable, _<Object> object, Function&& function) {
  226        return connect(connectable, object.get(), std::forward<Function>(function));
  227    }
  228
  248    template <AAnySignalOrProperty Connectable, aui::derived_from<AObjectBase> Object, typename Function>
  249    static decltype(auto)
  250    connect(const Connectable& connectable, ASlotDef<Object*, Function> slotDef) {
  251        return connect(connectable, slotDef.boundObject, std::move(slotDef.invocable));
  252    }
  253
  271    template <AAnyProperty Property, typename Object, ACompatibleSlotFor<Property> Function>
  272    static void
  273    connect(const Property& property, _<Object> object, Function&& function)
  274        requires (!aui::derived_from<Object, AObject>)
  275    {
  276        property.changed.makeRawInvocable(function)(*property);
  277        connect(property.changed, object, std::forward<Function>(function));
  278        const_cast<std::decay_t<decltype(property.changed)>&>(property.changed).connectNonAObject(std::move(object), aui::detail::makeLambda(object,std::forward<Function>(function)));
  279    }
  280
  281    void setSignalsEnabled(bool enabled) { mSignalsEnabled = enabled; }
  282
  283    [[nodiscard]] bool isSignalsEnabled() const noexcept { return mSignalsEnabled; }
  284
  285    template <ASignalInvokable T>
  286    void operator^(T&& t) noexcept {
  287        if (mSignalsEnabled) {
  288            t.invokeSignal(this);
  289        }
  290    }
  291
  292    _<AAbstractThread> getThread() const { return mAttachedThread; }
  293
  294    bool isSlotsCallsOnlyOnMyThread() const noexcept { return mSlotsCallsOnlyOnMyThread; }
  295
  296    static void moveToThread(aui::no_escape<AObject> object, _<AAbstractThread> thread);
  297
  298    void setSlotsCallsOnlyOnMyThread(bool slotsCallsOnlyOnMyThread) {
  299        mSlotsCallsOnlyOnMyThread = slotsCallsOnlyOnMyThread;
  300    }
  301
  302protected:
  306    void setThread(_<AAbstractThread> thread) { mAttachedThread = std::move(thread); }
  307
  308private:
  309    _<AAbstractThread> mAttachedThread;
  310    bool mSignalsEnabled = true;
  311
  318    bool mSlotsCallsOnlyOnMyThread = false;
  319
  320    static bool& isDisconnected();
  321};
  322
  343#define emit (*this) ^
  344
  370#define AUI_EMIT_FOREIGN(object, signal, ...) (*object) ^ object->signal(__VA_ARGS__)
  371
  372#include "SharedPtr.h"
static decltype(auto) connect(const Connectable &connectable, ASlotDef< Object *, Function > slotDef)
Connects signal to the slot of the specified object. Slot is packed to single argument.
Definition AObject.h:250
void setThread(_< AAbstractThread > thread)
Set thread of the object.
Definition AObject.h:306
static constexpr AObjectBase * GENERIC_OBSERVER
Indicates that a connection should not be explicitly linked to receiver's lifetime.
Definition AObject.h:61
An std::weak_ptr with AUI extensions.
Definition SharedPtrTypes.h:179
Definition concepts.h:42
Definition concepts.h:25
type_of< T > t
Selects views that are of the specified C++ types.
Definition type_of.h:71
API_AUI_CORE const ACommandLineArgs & args() noexcept
static decltype(auto) connect(const Property &property, Object *object, Function &&function)
Connects property to the slot of the specified object.
Definition AObject.h:106
static void biConnect(PropertySource &&propertySource, PropertyDestination &&propertyDestination)
Connects source property to the destination property and opposite (bidirectionally).
Definition AObject.h:156
static void connect(const Property &property, _< Object > object, Function &&function)
Connects signal or property to the slot of the specified non-AObject type.
Definition AObject.h:273
static void connect(PropertySource &&propertySource, PropertyDestination &&propertyDestination)
Connects source property to the destination property.
Definition AObject.h:127
static decltype(auto) connect(const Connectable &connectable, Object &object, Function &&function)
Connects signal or property to the slot of the specified object.
Definition AObject.h:183
static decltype(auto) connect(const Signal &signal, Object *object, Function &&function)
Connects signal to the slot of the specified object.
Definition AObject.h:86
static decltype(auto) connect(const Connectable &connectable, _< Object > object, Function &&function)
Connects signal or property to the slot of the specified object.
Definition AObject.h:225
decltype(auto) connect(const Connectable &connectable, Function &&function)
Connects signal or property to slot of "this" object.
Definition AObject.h:201
Definition concepts.h:188
An std::weak_ptr with AUI extensions.
Definition SharedPtrTypes.h:52
Forbids copy of your class.
Definition values.h:45