packages feed

hsqml-0.1.0: cbits/HsQMLClass.cpp

#include <cstdlib>
#include <HsFFI.h>
#include <QAtomicInt>
#include <QMetaObject>
#include <QString>
#include <QDebug>

#include "hsqml.h"
#include "HsQMLClass.h"
#include "HsQMLManager.h"

QAtomicInt gClassId;

HsQMLClass::HsQMLClass(
    unsigned int*  metaData,
    char*          metaStrData,
    HsQMLUniformFunc* methods,
    HsQMLUniformFunc* properties)
    : mRefCount(0)
    , mMetaData(metaData)
    , mMetaStrData(metaStrData)
    , mMethods(methods)
    , mProperties(properties)
    , mMethodCount(metaData[MD_METHOD_COUNT])
    , mPropertyCount(metaData[MD_PROPERTY_COUNT])
    , mMetaObject(QMetaObject {{
          &QObject::staticMetaObject,
          mMetaStrData,
          mMetaData,
          0}})
{
    ref(Handle);
}

HsQMLClass::~HsQMLClass()
{
    for (int i=0; i<mMethodCount; i++) {
        gManager->freeFun((HsFunPtr)mMethods[i]);
    }
    for (unsigned int i=0; i<2*mPropertyCount; i++) {
        if (mProperties[i]) {
            gManager->freeFun((HsFunPtr)mProperties[i]);
        }
    }
    std::free(mMetaData);
    std::free(mMetaStrData);
    std::free(mMethods);
    std::free(mProperties);
}

const char* HsQMLClass::name()
{
    return mMetaObject.className();
} 

const HsQMLUniformFunc* HsQMLClass::methods()
{
    return mMethods;
}

const HsQMLUniformFunc* HsQMLClass::properties()
{
    return mProperties;
}

void HsQMLClass::ref(RefSrc src)
{
    int count = mRefCount.fetchAndAddOrdered(1);

    if (gLogLevel >= (count == 0 ? 1 : 2)) {
        qDebug() << QString().sprintf(
            "HsQML: %s Class, name=%s, src=%d, count=%d.",
            count ? "Ref" : "New", name(), src, count+1);
    }
}

void HsQMLClass::deref(RefSrc src)
{
    int count = mRefCount.fetchAndAddOrdered(-1);

    if (gLogLevel >= (count == 1 ? 1 : 2)) {
        qDebug() << QString().sprintf(
            "HsQML: %s Class, name=%s, src=%d, count=%d.",
            count > 1 ? "Deref" : "Delete", name(), src, count);
    }

    if (count == 1) {
        delete this;
    }
}

extern "C" int hsqml_get_next_class_id()
{
    return gClassId.fetchAndAddRelaxed(1);
}

extern "C" HsQMLClassHandle* hsqml_create_class(
    unsigned int*  metaData,
    char*          metaStrData,
    HsQMLUniformFunc* methods,
    HsQMLUniformFunc* properties)
{
    HsQMLClass* klass = new HsQMLClass(
            metaData, metaStrData, methods, properties);
    return (HsQMLClassHandle*)klass;
}

extern "C" void hsqml_finalise_class_handle(
    HsQMLClassHandle* hndl)
{
    HsQMLClass* klass = (HsQMLClass*)hndl;
    klass->deref(HsQMLClass::Handle);
}