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);
}