medit/moo/mooscript/mooscript-classes-base.h
2010-10-18 23:20:09 -07:00

131 lines
3.2 KiB
C++

#ifndef MOO_SCRIPT_CLASSES_BASE_H
#define MOO_SCRIPT_CLASSES_BASE_H
#include "mooscript.h"
#include <mooedit/mooeditwindow.h>
namespace mom {
template<typename T>
class _Singleton : public Object
{
public:
static T &get_instance()
{
if (!s_instance)
s_instance = new T;
return *s_instance;
}
static void cleanup() NOTHROW
{
if (s_instance)
s_instance->remove();
moo_assert(s_instance == 0);
}
protected:
_Singleton(MetaObject &meta)
: Object(meta)
{
mooThrowIfFalse(s_instance == 0);
s_instance = static_cast<T*>(this);
}
~_Singleton() NOTHROW
{
mooThrowIfFalse(s_instance == 0 || s_instance == this);
s_instance = 0;
}
private:
static T *s_instance;
};
#define MOM_SINGLETON_DECL(Class) \
private: \
MOM_OBJECT_DECL(Class) \
friend class _Singleton<Class>; \
Class() \
: _Singleton<Class>(s_meta) \
{ \
}
#define MOM_SINGLETON_DEFN(Class) \
MOM_OBJECT_DEFN(Class) \
template<> Class *_Singleton<Class>::s_instance = 0;
template<typename T, typename GT>
class _GObjectWrapper : public Object
{
public:
GT *gobj() const throw() { return m_gobj; }
static T *wrap(GT *gobj)
{
if (!gobj)
return 0;
mooThrowIfFalse(G_IS_OBJECT(gobj));
void *pwrapper = g_object_get_qdata(G_OBJECT(gobj), wrapper_quark());
if (pwrapper)
return static_cast<T*>(pwrapper);
else
return new T(gobj);
}
protected:
static GQuark wrapper_quark() G_GNUC_CONST
{
static GQuark q;
if (G_UNLIKELY(!q))
q = g_quark_from_string(T::class_name() + "-mom-script-wrapper");
return q;
}
_GObjectWrapper(GT *gobj, MetaObject &meta)
: Object(meta)
, m_gobj(gobj)
{
mooThrowIfFalse(G_IS_OBJECT(gobj));
g_object_set_qdata(G_OBJECT(gobj), wrapper_quark(), this);
g_object_weak_ref(G_OBJECT(gobj), (GWeakNotify) gobject_weak_notify, this);
}
~_GObjectWrapper()
{
if (m_gobj)
{
g_object_weak_unref(G_OBJECT(m_gobj), (GWeakNotify) gobject_weak_notify, this);
g_object_set_qdata(G_OBJECT(m_gobj), wrapper_quark(), 0);
}
}
private:
static void gobject_weak_notify(_GObjectWrapper *wrapper)
{
wrapper->m_gobj = 0;
}
private:
MOO_DISABLE_COPY_AND_ASSIGN(_GObjectWrapper)
private:
GT *m_gobj;
};
#define MOM_GOBJECT_DECL(Class, GClass) \
protected: \
friend class _GObjectWrapper<Class, GClass>; \
Class(GClass *gobj) : \
_GObjectWrapper<Class, GClass>(gobj, s_meta) \
{ \
} \
MOM_OBJECT_DECL(Class)
#define MOM_GOBJECT_DEFN(Class, GClass) \
MOM_OBJECT_DEFN(Class)
} // namespace mom
#endif /* MOO_SCRIPT_CLASSES_BASE_H */