
/**
 * PyOtherSide: Asynchronous Python 3 Bindings for Qt 5
 * Copyright (c) 2014, Thomas Perl <m@thp.io>
 *
 * Permission to use, copy, modify, and/or distribute this software for any
 * purpose with or without fee is hereby granted, provided that the above
 * copyright notice and this permission notice appear in all copies.
 *
 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
 * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
 * FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
 * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
 * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
 * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
 * PERFORMANCE OF THIS SOFTWARE.
 **/

#include "qobject_ref.h"

QObjectRef::QObjectRef(QObject *obj)
    : qobject(obj)
{
    if (qobject) {
        QObject::connect(qobject, SIGNAL(destroyed(QObject *)),
                         this, SLOT(handleDestroyed(QObject *)));
    }
}

QObjectRef::QObjectRef(const QObjectRef &other)
    : qobject(other.qobject)
{
    if (qobject) {
        QObject::connect(qobject, SIGNAL(destroyed(QObject *)),
                         this, SLOT(handleDestroyed(QObject *)));
    }
}

QObjectRef::~QObjectRef()
{
    if (qobject) {
        QObject::disconnect(qobject, SIGNAL(destroyed(QObject *)),
                            this, SLOT(handleDestroyed(QObject *)));
    }
}

QObjectRef &
QObjectRef::operator=(const QObjectRef &other)
{
    if (this != &other) {
        if (qobject != other.qobject) {
            if (qobject) {
                QObject::disconnect(qobject, SIGNAL(destroyed(QObject *)),
                                    this, SLOT(handleDestroyed(QObject *)));
            }

            if (other.qobject) {
                qobject = other.qobject;
                QObject::connect(qobject, SIGNAL(destroyed(QObject *)),
                                 this, SLOT(handleDestroyed(QObject *)));
            }
        }
    }

    return *this;
}

void
QObjectRef::handleDestroyed(QObject *obj)
{
    if (obj == qobject) {
        // Have to remove internal reference, as qobject is destroyed
        qobject = NULL;
    }
}
