hsqml-0.2.0.0: cbits/HsQMLClass.cpp
#include <cstdlib>
#include <HsFFI.h>
#include <QtCore/QMetaObject>
#include <QtCore/QMetaType>
#include <QtCore/QString>
#include "hsqml.h"
#include "HsQMLClass.h"
#include "HsQMLManager.h"
enum MDFields {
MD_METHOD_COUNT = 4,
MD_PROPERTY_COUNT = 6,
};
static const char* cRefSrcNames[] = {"Hndl", "Proxy"};
HsQMLClass::HsQMLClass(
unsigned int* metaData,
char* metaStrData,
HsStablePtr hsTypeRep,
HsQMLUniformFunc* methods,
HsQMLUniformFunc* properties)
: mRefCount(0)
, mMetaData(metaData)
, mMetaStrData(metaStrData)
, mHsTypeRep(hsTypeRep)
, mMethodCount(metaData[MD_METHOD_COUNT])
, mPropertyCount(metaData[MD_PROPERTY_COUNT])
, mMethods(methods)
, mProperties(properties)
{
// Create meta-object
QMetaObject tmp = {
&QObject::staticMetaObject,
mMetaStrData,
mMetaData,
0};
mMetaObject = new QMetaObject(tmp);
// Add reference
ref(Handle);
gManager->updateCounter(HsQMLManager::ClassCount, 1);
}
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]);
}
}
gManager->freeStable(mHsTypeRep);
std::free(mMetaData);
std::free(mMetaStrData);
std::free(mMethods);
std::free(mProperties);
delete mMetaObject;
gManager->updateCounter(HsQMLManager::ClassCount, -1);
}
const char* HsQMLClass::name()
{
return mMetaObject->className();
}
HsStablePtr HsQMLClass::hsTypeRep()
{
return mHsTypeRep;
}
int HsQMLClass::methodCount()
{
return mMethodCount;
}
int HsQMLClass::propertyCount()
{
return mPropertyCount;
}
const HsQMLUniformFunc* HsQMLClass::methods()
{
return mMethods;
}
const HsQMLUniformFunc* HsQMLClass::properties()
{
return mProperties;
}
const QMetaObject* HsQMLClass::metaObj()
{
return mMetaObject;
}
void HsQMLClass::ref(RefSrc src)
{
int count = mRefCount.fetchAndAddOrdered(1);
HSQML_LOG(count == 0 ? 1 : 2,
QString().sprintf("%s Class, name=%s, src=%s, count=%d.",
count ? "Ref" : "New", name(), cRefSrcNames[src], count+1));
}
void HsQMLClass::deref(RefSrc src)
{
int count = mRefCount.fetchAndAddOrdered(-1);
HSQML_LOG(count == 1 ? 1 : 2,
QString().sprintf("%s Class, name=%s, src=%s, count=%d.",
count > 1 ? "Deref" : "Delete", name(), cRefSrcNames[src], count));
if (count == 1) {
delete this;
}
}
extern "C" int hsqml_get_next_class_id()
{
return gManager->updateCounter(HsQMLManager::ClassSerial, 1);
}
extern "C" HsQMLClassHandle* hsqml_create_class(
unsigned int* metaData,
char* metaStrData,
HsStablePtr hsTypeRep,
HsQMLUniformFunc* methods,
HsQMLUniformFunc* properties)
{
HsQMLClass* klass = new HsQMLClass(
metaData, metaStrData, hsTypeRep, methods, properties);
return (HsQMLClassHandle*)klass;
}
extern "C" void hsqml_finalise_class_handle(
HsQMLClassHandle* hndl)
{
HsQMLClass* klass = (HsQMLClass*)hndl;
klass->deref(HsQMLClass::Handle);
}